summaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorAnton Arapov <anton@redhat.com>2012-08-07 11:21:50 +0200
committerAnton Arapov <anton@redhat.com>2012-08-07 12:52:25 +0200
commit1d44b6f3fcf6058fb7c960b7558766967e8028f7 (patch)
tree53d88547c973ba048d233091a3f91f3173ad01df /arch/sparc
parentd91eda5d7b0383e6a0c83e0146ff141ff3b1355b (diff)
downloadkernel-uprobes-1d44b6f3fcf6058fb7c960b7558766967e8028f7.tar.gz
kernel-uprobes-1d44b6f3fcf6058fb7c960b7558766967e8028f7.tar.xz
kernel-uprobes-1d44b6f3fcf6058fb7c960b7558766967e8028f7.zip
fedora kernel: 222b075b3ff0d9e88aa9353e3c80667756ed7361v3.5.0-4
Signed-off-by: Anton Arapov <anton@redhat.com>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kbuild8
-rw-r--r--arch/sparc/Kconfig23
-rw-r--r--arch/sparc/Makefile48
-rw-r--r--arch/sparc/boot/Makefile61
-rw-r--r--arch/sparc/boot/btfixupprep.c386
-rw-r--r--arch/sparc/configs/sparc64_defconfig2
-rw-r--r--arch/sparc/include/asm/Kbuild1
-rw-r--r--arch/sparc/include/asm/asi.h18
-rw-r--r--arch/sparc/include/asm/asmmacro.h37
-rw-r--r--arch/sparc/include/asm/btfixup.h208
-rw-r--r--arch/sparc/include/asm/cache.h114
-rw-r--r--arch/sparc/include/asm/cacheflush.h4
-rw-r--r--arch/sparc/include/asm/cacheflush_32.h73
-rw-r--r--arch/sparc/include/asm/cacheflush_64.h3
-rw-r--r--arch/sparc/include/asm/cachetlb_32.h29
-rw-r--r--arch/sparc/include/asm/cmpxchg_32.h27
-rw-r--r--arch/sparc/include/asm/cmt.h59
-rw-r--r--arch/sparc/include/asm/contregs.h22
-rw-r--r--arch/sparc/include/asm/cpu_type.h20
-rw-r--r--arch/sparc/include/asm/cpudata_32.h1
-rw-r--r--arch/sparc/include/asm/cypress.h79
-rw-r--r--arch/sparc/include/asm/dma-mapping.h9
-rw-r--r--arch/sparc/include/asm/dma.h52
-rw-r--r--arch/sparc/include/asm/elf_32.h13
-rw-r--r--arch/sparc/include/asm/floppy_32.h45
-rw-r--r--arch/sparc/include/asm/floppy_64.h6
-rw-r--r--arch/sparc/include/asm/gpio.h40
-rw-r--r--arch/sparc/include/asm/head_32.h21
-rw-r--r--arch/sparc/include/asm/kvm_para.h1
-rw-r--r--arch/sparc/include/asm/leon.h144
-rw-r--r--arch/sparc/include/asm/leon_amba.h4
-rw-r--r--arch/sparc/include/asm/machines.h23
-rw-r--r--arch/sparc/include/asm/mbus.h4
-rw-r--r--arch/sparc/include/asm/memreg.h51
-rw-r--r--arch/sparc/include/asm/mmu_context_32.h11
-rw-r--r--arch/sparc/include/asm/mpmbox.h67
-rw-r--r--arch/sparc/include/asm/obio.h13
-rw-r--r--arch/sparc/include/asm/oplib_32.h8
-rw-r--r--arch/sparc/include/asm/page_32.h13
-rw-r--r--arch/sparc/include/asm/pgalloc_32.h76
-rw-r--r--arch/sparc/include/asm/pgtable_32.h387
-rw-r--r--arch/sparc/include/asm/pgtable_64.h4
-rw-r--r--arch/sparc/include/asm/pgtsrmmu.h136
-rw-r--r--arch/sparc/include/asm/pgtsun4c.h172
-rw-r--r--arch/sparc/include/asm/posix_types.h5
-rw-r--r--arch/sparc/include/asm/processor_32.h4
-rw-r--r--arch/sparc/include/asm/processor_64.h7
-rw-r--r--arch/sparc/include/asm/psr.h8
-rw-r--r--arch/sparc/include/asm/sections.h3
-rw-r--r--arch/sparc/include/asm/setup.h3
-rw-r--r--arch/sparc/include/asm/shmparam_32.h4
-rw-r--r--arch/sparc/include/asm/smp_32.h114
-rw-r--r--arch/sparc/include/asm/smpprim.h54
-rw-r--r--arch/sparc/include/asm/string_32.h63
-rw-r--r--arch/sparc/include/asm/sysen.h15
-rw-r--r--arch/sparc/include/asm/thread_info_32.h20
-rw-r--r--arch/sparc/include/asm/thread_info_64.h43
-rw-r--r--arch/sparc/include/asm/timer_32.h33
-rw-r--r--arch/sparc/include/asm/timex_32.h1
-rw-r--r--arch/sparc/include/asm/tlbflush_32.h56
-rw-r--r--arch/sparc/include/asm/topology_64.h19
-rw-r--r--arch/sparc/include/asm/uaccess.h6
-rw-r--r--arch/sparc/include/asm/uaccess_32.h33
-rw-r--r--arch/sparc/include/asm/uaccess_64.h12
-rw-r--r--arch/sparc/include/asm/vac-ops.h127
-rw-r--r--arch/sparc/include/asm/vaddrs.h16
-rw-r--r--arch/sparc/include/asm/winmacro.h49
-rw-r--r--arch/sparc/kernel/Makefile8
-rw-r--r--arch/sparc/kernel/auxio_32.c13
-rw-r--r--arch/sparc/kernel/cpu.c18
-rw-r--r--arch/sparc/kernel/devices.c4
-rw-r--r--arch/sparc/kernel/ds.c2
-rw-r--r--arch/sparc/kernel/entry.S442
-rw-r--r--arch/sparc/kernel/etrap_32.S68
-rw-r--r--arch/sparc/kernel/head_32.S765
-rw-r--r--arch/sparc/kernel/head_64.S2
-rw-r--r--arch/sparc/kernel/idprom.c19
-rw-r--r--arch/sparc/kernel/init_task.c22
-rw-r--r--arch/sparc/kernel/ioport.c47
-rw-r--r--arch/sparc/kernel/irq.h60
-rw-r--r--arch/sparc/kernel/irq_32.c41
-rw-r--r--arch/sparc/kernel/irq_64.c2
-rw-r--r--arch/sparc/kernel/kernel.h13
-rw-r--r--arch/sparc/kernel/leon_kernel.c99
-rw-r--r--arch/sparc/kernel/leon_pmc.c15
-rw-r--r--arch/sparc/kernel/leon_smp.c130
-rw-r--r--arch/sparc/kernel/module.c21
-rw-r--r--arch/sparc/kernel/muldiv.c238
-rw-r--r--arch/sparc/kernel/of_device_32.c4
-rw-r--r--arch/sparc/kernel/pcic.c55
-rw-r--r--arch/sparc/kernel/perf_event.c4
-rw-r--r--arch/sparc/kernel/process_32.c151
-rw-r--r--arch/sparc/kernel/prom_common.c1
-rw-r--r--arch/sparc/kernel/ptrace_64.c2
-rw-r--r--arch/sparc/kernel/rtrap_32.S94
-rw-r--r--arch/sparc/kernel/rtrap_64.S12
-rw-r--r--arch/sparc/kernel/setup_32.c132
-rw-r--r--arch/sparc/kernel/signal32.c37
-rw-r--r--arch/sparc/kernel/signal_32.c60
-rw-r--r--arch/sparc/kernel/signal_64.c49
-rw-r--r--arch/sparc/kernel/smp_32.c187
-rw-r--r--arch/sparc/kernel/smp_64.c12
-rw-r--r--arch/sparc/kernel/sparc_ksyms_32.c14
-rw-r--r--arch/sparc/kernel/sun4c_irq.c264
-rw-r--r--arch/sparc/kernel/sun4d_irq.c48
-rw-r--r--arch/sparc/kernel/sun4d_smp.c127
-rw-r--r--arch/sparc/kernel/sun4m_irq.c58
-rw-r--r--arch/sparc/kernel/sun4m_smp.c124
-rw-r--r--arch/sparc/kernel/sys_sparc32.c4
-rw-r--r--arch/sparc/kernel/sys_sparc_32.c28
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c11
-rw-r--r--arch/sparc/kernel/time_32.c220
-rw-r--r--arch/sparc/kernel/trampoline_32.S28
-rw-r--r--arch/sparc/kernel/traps_32.c2
-rw-r--r--arch/sparc/kernel/traps_64.c12
-rw-r--r--arch/sparc/kernel/ttable_32.S417
-rw-r--r--arch/sparc/kernel/ttable_64.S (renamed from arch/sparc/kernel/ttable.S)0
-rw-r--r--arch/sparc/kernel/unaligned_64.c1
-rw-r--r--arch/sparc/kernel/vio.c2
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S5
-rw-r--r--arch/sparc/kernel/wof.S90
-rw-r--r--arch/sparc/kernel/wuf.S87
-rw-r--r--arch/sparc/lib/Makefile7
-rw-r--r--arch/sparc/lib/ashldi3.S7
-rw-r--r--arch/sparc/lib/ashrdi3.S7
-rw-r--r--arch/sparc/lib/atomic_32.S44
-rw-r--r--arch/sparc/lib/atomic_64.S49
-rw-r--r--arch/sparc/lib/bitops.S37
-rw-r--r--arch/sparc/lib/blockops.S10
-rw-r--r--arch/sparc/lib/bzero.S20
-rw-r--r--arch/sparc/lib/divdi3.S4
-rw-r--r--arch/sparc/lib/ipcsum.S9
-rw-r--r--arch/sparc/lib/ksyms.c27
-rw-r--r--arch/sparc/lib/lshrdi3.S5
-rw-r--r--arch/sparc/lib/memmove.S9
-rw-r--r--arch/sparc/lib/mul.S137
-rw-r--r--arch/sparc/lib/muldi3.S4
-rw-r--r--arch/sparc/lib/rem.S384
-rw-r--r--arch/sparc/lib/sdiv.S381
-rw-r--r--arch/sparc/lib/strlen_user_32.S109
-rw-r--r--arch/sparc/lib/strlen_user_64.S95
-rw-r--r--arch/sparc/lib/strncmp_32.S8
-rw-r--r--arch/sparc/lib/strncmp_64.S8
-rw-r--r--arch/sparc/lib/strncpy_from_user_32.S47
-rw-r--r--arch/sparc/lib/strncpy_from_user_64.S135
-rw-r--r--arch/sparc/lib/ucmpdi2.c19
-rw-r--r--arch/sparc/lib/udiv.S357
-rw-r--r--arch/sparc/lib/udivdi3.S3
-rw-r--r--arch/sparc/lib/umul.S171
-rw-r--r--arch/sparc/lib/urem.S357
-rw-r--r--arch/sparc/lib/usercopy.c1
-rw-r--r--arch/sparc/lib/xor.S50
-rw-r--r--arch/sparc/math-emu/math_64.c20
-rw-r--r--arch/sparc/mm/Makefile12
-rw-r--r--arch/sparc/mm/btfixup.c328
-rw-r--r--arch/sparc/mm/fault_32.c207
-rw-r--r--arch/sparc/mm/init_32.c51
-rw-r--r--arch/sparc/mm/init_64.c121
-rw-r--r--arch/sparc/mm/io-unit.c35
-rw-r--r--arch/sparc/mm/iommu.c71
-rw-r--r--arch/sparc/mm/leon_mm.c97
-rw-r--r--arch/sparc/mm/loadmmu.c43
-rw-r--r--arch/sparc/mm/nosun4c.c77
-rw-r--r--arch/sparc/mm/srmmu.c1278
-rw-r--r--arch/sparc/mm/srmmu.h4
-rw-r--r--arch/sparc/mm/srmmu_access.S82
-rw-r--r--arch/sparc/mm/sun4c.c2166
-rw-r--r--arch/sparc/mm/viking.S1
-rw-r--r--arch/sparc/net/Makefile4
-rw-r--r--arch/sparc/net/bpf_jit.h68
-rw-r--r--arch/sparc/net/bpf_jit_asm.S205
-rw-r--r--arch/sparc/net/bpf_jit_comp.c802
-rw-r--r--arch/sparc/prom/Makefile1
-rw-r--r--arch/sparc/prom/segment.c28
174 files changed, 3835 insertions, 11956 deletions
diff --git a/arch/sparc/Kbuild b/arch/sparc/Kbuild
new file mode 100644
index 00000000000..5cd01161fd0
--- /dev/null
+++ b/arch/sparc/Kbuild
@@ -0,0 +1,8 @@
+#
+# core part of the sparc kernel
+#
+
+obj-y += kernel/
+obj-y += mm/
+obj-y += math-emu/
+obj-y += net/
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 76c7ccfb1eb..e74ff137762 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -30,6 +30,12 @@ config SPARC
select USE_GENERIC_SMP_HELPERS if SMP
select GENERIC_PCI_IOMAP
select HAVE_NMI_WATCHDOG if SPARC64
+ select HAVE_BPF_JIT
+ select GENERIC_SMP_IDLE_THREAD
+ select GENERIC_CMOS_UPDATE
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
config SPARC32
def_bool !64BIT
@@ -61,6 +67,7 @@ config SPARC64
select IRQ_PREFLOW_FASTEOI
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select HAVE_C_RECORDMCOUNT
+ select NO_BOOTMEM
config ARCH_DEFCONFIG
string
@@ -73,18 +80,6 @@ config BITS
default 32 if SPARC32
default 64 if SPARC64
-config ARCH_USES_GETTIMEOFFSET
- bool
- default y if SPARC32
-
-config GENERIC_CMOS_UPDATE
- bool
- default y
-
-config GENERIC_CLOCKEVENTS
- bool
- default y if SPARC64
-
config IOMMU_HELPER
bool
default y if SPARC64
@@ -154,7 +149,7 @@ source "kernel/Kconfig.freezer"
menu "Processor type and features"
config SMP
- bool "Symmetric multi-processing support (does not work on sun4/sun4c)"
+ bool "Symmetric multi-processing support"
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, say N. If you have a system with more
@@ -275,8 +270,6 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
-source "kernel/time/Kconfig"
-
if SPARC64
source "drivers/cpufreq/Kconfig"
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index eddcfb36aaf..541b8b075c7 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -19,39 +19,27 @@ ifeq ($(CONFIG_SPARC32),y)
# sparc32
#
-#
-# Uncomment the first KBUILD_CFLAGS if you are doing kgdb source level
-# debugging of the kernel to get the proper debugging information.
-
-AS := $(AS) -32
-LDFLAGS := -m elf32_sparc
CHECKFLAGS += -D__sparc__
+LDFLAGS := -m elf32_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
-KBUILD_AFLAGS += -m32 -Wa,-Av8
-
-#LDFLAGS_vmlinux = -N -Ttext 0xf0004000
-# Since 2.5.40, the first stage is left not btfix-ed.
-# Actual linking is done with "make image".
-LDFLAGS_vmlinux = -r
+KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
+KBUILD_AFLAGS += -m32 -Wa,-Av8
else
#####
# sparc64
#
-CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64
+CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64
+LDFLAGS := -m elf64_sparc
+export BITS := 64
+UTS_MACHINE := sparc64
-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 \
- -Wa,--undeclared-regs
+KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow
+KBUILD_CFLAGS += -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare
+KBUILD_CFLAGS += -Wa,--undeclared-regs
KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3)
KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs
@@ -62,27 +50,15 @@ endif
endif
head-y := arch/sparc/kernel/head_$(BITS).o
-head-y += arch/sparc/kernel/init_task.o
-core-y += arch/sparc/kernel/
-core-y += arch/sparc/mm/ arch/sparc/math-emu/
+# See arch/sparc/Kbuild for the core part of the kernel
+core-y += arch/sparc/
libs-y += arch/sparc/prom/
libs-y += arch/sparc/lib/
drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/
-# Export what is needed by arch/sparc/boot/Makefile
-export VMLINUX_INIT VMLINUX_MAIN
-VMLINUX_INIT := $(head-y) $(init-y)
-VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/
-VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
-VMLINUX_MAIN += $(drivers-y) $(net-y)
-
-ifdef CONFIG_KALLSYMS
-export kallsyms.o := .tmp_kallsyms2.o
-endif
-
boot := arch/sparc/boot
# Default target
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile
index d56d199c1aa..6e63afb128d 100644
--- a/arch/sparc/boot/Makefile
+++ b/arch/sparc/boot/Makefile
@@ -6,8 +6,8 @@
ROOT_IMG := /usr/src/root.img
ELFTOAOUT := elftoaout
-hostprogs-y := piggyback btfixupprep
-targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout
+hostprogs-y := piggyback
+targets := tftpboot.img image zImage vmlinux.aout
clean-files := System.map
quiet_cmd_elftoaout = ELFTOAOUT $@
@@ -17,58 +17,9 @@ quiet_cmd_piggy = PIGGY $@
quiet_cmd_strip = STRIP $@
cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start $< -o $@
-ifeq ($(CONFIG_SPARC32),y)
-quiet_cmd_btfix = BTFIX $@
- cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@
-quiet_cmd_sysmap = SYSMAP $(obj)/System.map
- cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
-quiet_cmd_image = LD $@
- cmd_image = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) -o $@
-
-define rule_image
- $(if $($(quiet)cmd_image), \
- echo ' $($(quiet)cmd_image)' &&) \
- $(cmd_image); \
- $(if $($(quiet)cmd_sysmap), \
- echo ' $($(quiet)cmd_sysmap)' &&) \
- $(cmd_sysmap) $@ $(obj)/System.map; \
- if [ $$? -ne 0 ]; then \
- rm -f $@; \
- /bin/false; \
- fi; \
- echo 'cmd_$@ := $(cmd_image)' > $(@D)/.$(@F).cmd
-endef
-
-BTOBJS := $(patsubst %/, %/built-in.o, $(VMLINUX_INIT))
-BTLIBS := $(patsubst %/, %/built-in.o, $(VMLINUX_MAIN))
-LDFLAGS_image := -T arch/sparc/kernel/vmlinux.lds $(BTOBJS) \
- --start-group $(BTLIBS) --end-group \
- $(kallsyms.o) $(obj)/btfix.o
-
-# Link the final image including btfixup'ed symbols.
-# This is a replacement for the link done in the top-level Makefile.
-# Note: No dependency on the prerequisite files since that would require
-# make to try check if they are updated - and due to changes
-# in gcc options (path for example) this would result in
-# these files being recompiled for each build.
-$(obj)/image: $(obj)/btfix.o FORCE
- $(call if_changed_rule,image)
-
-$(obj)/zImage: $(obj)/image
- $(call if_changed,strip)
- @echo ' kernel: $@ is ready'
-
-$(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE
- $(call if_changed,btfix)
-
-endif
-
ifeq ($(CONFIG_SPARC64),y)
# Actual linking
-$(obj)/image: vmlinux FORCE
- $(call if_changed,strip)
- @echo ' kernel: $@ is ready'
$(obj)/zImage: $(obj)/image
$(call if_changed,gzip)
@@ -79,6 +30,10 @@ $(obj)/vmlinux.aout: vmlinux FORCE
@echo ' kernel: $@ is ready'
else
+$(obj)/zImage: $(obj)/image
+ $(call if_changed,strip)
+ @echo ' kernel: $@ is ready'
+
# The following lines make a readable image for U-Boot.
# uImage - Binary file read by U-boot
# uImage.o - object file of uImage for loading with a
@@ -107,6 +62,10 @@ $(obj)/uImage: $(obj)/image.gz
endif
+$(obj)/image: vmlinux FORCE
+ $(call if_changed,strip)
+ @echo ' kernel: $@ is ready'
+
$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE
$(call if_changed,elftoaout)
$(call if_changed,piggy)
diff --git a/arch/sparc/boot/btfixupprep.c b/arch/sparc/boot/btfixupprep.c
deleted file mode 100644
index da031159e2b..00000000000
--- a/arch/sparc/boot/btfixupprep.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- Simple utility to prepare vmlinux image for sparc.
- Resolves all BTFIXUP uses and settings and creates
- a special .s object to link to the image.
-
- Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <malloc.h>
-
-#define MAXSYMS 1024
-
-static char *symtab = "SYMBOL TABLE:";
-static char *relrec = "RELOCATION RECORDS FOR [";
-static int rellen;
-static int symlen;
-int mode;
-
-struct _btfixup;
-
-typedef struct _btfixuprel {
- char *sect;
- unsigned long offset;
- struct _btfixup *f;
- int frel;
- struct _btfixuprel *next;
-} btfixuprel;
-
-typedef struct _btfixup {
- int type;
- int setinitval;
- unsigned int initval;
- char *initvalstr;
- char *name;
- btfixuprel *rel;
-} btfixup;
-
-btfixup array[MAXSYMS];
-int last = 0;
-char buffer[1024];
-unsigned long lastfoffset = -1;
-unsigned long lastfrelno;
-btfixup *lastf;
-
-static void fatal(void) __attribute__((noreturn));
-static void fatal(void)
-{
- fprintf(stderr, "Malformed output from objdump\n%s\n", buffer);
- exit(1);
-}
-
-static btfixup *find(int type, char *name)
-{
- int i;
- for (i = 0; i < last; i++) {
- if (array[i].type == type && !strcmp(array[i].name, name))
- return array + i;
- }
- array[last].type = type;
- array[last].name = strdup(name);
- array[last].setinitval = 0;
- if (!array[last].name) fatal();
- array[last].rel = NULL;
- last++;
- if (last >= MAXSYMS) {
- fprintf(stderr, "Ugh. Something strange. More than %d different BTFIXUP symbols\n", MAXSYMS);
- exit(1);
- }
- return array + last - 1;
-}
-
-static void set_mode (char *buffer)
-{
- for (mode = 0;; mode++)
- if (buffer[mode] < '0' || buffer[mode] > '9')
- break;
- if (mode != 8 && mode != 16)
- fatal();
-}
-
-
-int main(int argc,char **argv)
-{
- char *p, *q;
- char *sect;
- int i, j, k;
- unsigned int initval;
- int shift;
- btfixup *f;
- btfixuprel *r, **rr;
- unsigned long offset;
- char *initvalstr;
-
- symlen = strlen(symtab);
- while (fgets (buffer, 1024, stdin) != NULL)
- if (!strncmp (buffer, symtab, symlen))
- goto main0;
- fatal();
-main0:
- rellen = strlen(relrec);
- while (fgets (buffer, 1024, stdin) != NULL)
- if (!strncmp (buffer, relrec, rellen))
- goto main1;
- fatal();
-main1:
- sect = malloc(strlen (buffer + rellen) + 1);
- if (!sect) fatal();
- strcpy (sect, buffer + rellen);
- p = strchr (sect, ']');
- if (!p) fatal();
- *p = 0;
- if (fgets (buffer, 1024, stdin) == NULL)
- fatal();
- while (fgets (buffer, 1024, stdin) != NULL) {
- int nbase;
- if (!strncmp (buffer, relrec, rellen))
- goto main1;
- if (mode == 0)
- set_mode (buffer);
- p = strchr (buffer, '\n');
- if (p) *p = 0;
- if (strlen (buffer) < 22+mode)
- continue;
- if (strncmp (buffer + mode, " R_SPARC_", 9))
- continue;
- nbase = 27 - 8 + mode;
- if (buffer[nbase] != '_' || buffer[nbase+1] != '_' || buffer[nbase+2] != '_')
- continue;
- switch (buffer[nbase+3]) {
- case 'f': /* CALL */
- case 'b': /* BLACKBOX */
- case 's': /* SIMM13 */
- case 'a': /* HALF */
- case 'h': /* SETHI */
- case 'i': /* INT */
- break;
- default:
- continue;
- }
- p = strchr (buffer + nbase+5, '+');
- if (p) *p = 0;
- shift = nbase + 5;
- if (buffer[nbase+4] == 's' && buffer[nbase+5] == '_') {
- shift = nbase + 6;
- if (strcmp (sect, ".init.text")) {
- fprintf(stderr,
- "Wrong use of '%s' BTFIXUPSET in '%s' section.\n"
- "BTFIXUPSET_CALL can be used only in"
- " __init sections\n",
- buffer + shift, sect);
- exit(1);
- }
- } else if (buffer[nbase+4] != '_')
- continue;
- if (!strcmp (sect, ".text.exit"))
- continue;
- if (strcmp (sect, ".text") &&
- strcmp (sect, ".init.text") &&
- strcmp (sect, ".fixup") &&
- (strcmp (sect, "__ksymtab") || buffer[nbase+3] != 'f')) {
- if (buffer[nbase+3] == 'f')
- fprintf(stderr,
- "Wrong use of '%s' in '%s' section.\n"
- " It can be used only in .text, .init.text,"
- " .fixup and __ksymtab\n",
- buffer + shift, sect);
- else
- fprintf(stderr,
- "Wrong use of '%s' in '%s' section.\n"
- " It can be only used in .text, .init.text,"
- " and .fixup\n", buffer + shift, sect);
- exit(1);
- }
- p = strstr (buffer + shift, "__btset_");
- if (p && buffer[nbase+4] == 's') {
- fprintf(stderr, "__btset_ in BTFIXUP name can only be used when defining the variable, not for setting\n%s\n", buffer);
- exit(1);
- }
- initval = 0;
- initvalstr = NULL;
- if (p) {
- if (p[8] != '0' || p[9] != 'x') {
- fprintf(stderr, "Pre-initialized values can be only initialized with hexadecimal constants starting 0x\n%s\n", buffer);
- exit(1);
- }
- initval = strtoul(p + 10, &q, 16);
- if (*q || !initval) {
- fprintf(stderr, "Pre-initialized values can be only in the form name__btset_0xXXXXXXXX where X are hex digits.\nThey cannot be name__btset_0x00000000 though. Use BTFIXUPDEF_XX instead of BTFIXUPDEF_XX_INIT then.\n%s\n", buffer);
- exit(1);
- }
- initvalstr = p + 10;
- *p = 0;
- }
- f = find(buffer[nbase+3], buffer + shift);
- if (buffer[nbase+4] == 's')
- continue;
- switch (buffer[nbase+3]) {
- case 'f':
- if (initval) {
- fprintf(stderr, "Cannot use pre-initialized fixups for calls\n%s\n", buffer);
- exit(1);
- }
- if (!strcmp (sect, "__ksymtab")) {
- if (strncmp (buffer + mode+9, "32 ", 10)) {
- fprintf(stderr, "BTFIXUP_CALL in EXPORT_SYMBOL results in relocation other than R_SPARC_32\n\%s\n", buffer);
- exit(1);
- }
- } else if (strncmp (buffer + mode+9, "WDISP30 ", 10) &&
- strncmp (buffer + mode+9, "HI22 ", 10) &&
- strncmp (buffer + mode+9, "LO10 ", 10)) {
- fprintf(stderr, "BTFIXUP_CALL results in relocation other than R_SPARC_WDISP30, R_SPARC_HI22 or R_SPARC_LO10\n%s\n", buffer);
- exit(1);
- }
- break;
- case 'b':
- if (initval) {
- fprintf(stderr, "Cannot use pre-initialized fixups for blackboxes\n%s\n", buffer);
- exit(1);
- }
- if (strncmp (buffer + mode+9, "HI22 ", 10)) {
- fprintf(stderr, "BTFIXUP_BLACKBOX results in relocation other than R_SPARC_HI22\n%s\n", buffer);
- exit(1);
- }
- break;
- case 's':
- if (initval + 0x1000 >= 0x2000) {
- fprintf(stderr, "Wrong initializer for SIMM13. Has to be from $fffff000 to $00000fff\n%s\n", buffer);
- exit(1);
- }
- if (strncmp (buffer + mode+9, "13 ", 10)) {
- fprintf(stderr, "BTFIXUP_SIMM13 results in relocation other than R_SPARC_13\n%s\n", buffer);
- exit(1);
- }
- break;
- case 'a':
- if (initval + 0x1000 >= 0x2000 && (initval & 0x3ff)) {
- fprintf(stderr, "Wrong initializer for HALF.\n%s\n", buffer);
- exit(1);
- }
- if (strncmp (buffer + mode+9, "13 ", 10)) {
- fprintf(stderr, "BTFIXUP_HALF results in relocation other than R_SPARC_13\n%s\n", buffer);
- exit(1);
- }
- break;
- case 'h':
- if (initval & 0x3ff) {
- fprintf(stderr, "Wrong initializer for SETHI. Cannot have set low 10 bits\n%s\n", buffer);
- exit(1);
- }
- if (strncmp (buffer + mode+9, "HI22 ", 10)) {
- fprintf(stderr, "BTFIXUP_SETHI results in relocation other than R_SPARC_HI22\n%s\n", buffer);
- exit(1);
- }
- break;
- case 'i':
- if (initval) {
- fprintf(stderr, "Cannot use pre-initialized fixups for INT\n%s\n", buffer);
- exit(1);
- }
- if (strncmp (buffer + mode+9, "HI22 ", 10) && strncmp (buffer + mode+9, "LO10 ", 10)) {
- fprintf(stderr, "BTFIXUP_INT results in relocation other than R_SPARC_HI22 and R_SPARC_LO10\n%s\n", buffer);
- exit(1);
- }
- break;
- }
- if (!f->setinitval) {
- f->initval = initval;
- if (initvalstr) {
- f->initvalstr = strdup(initvalstr);
- if (!f->initvalstr) fatal();
- }
- f->setinitval = 1;
- } else if (f->initval != initval) {
- fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer\n%s\n",
- f->name, f->initvalstr ? : "0x00000000", buffer);
- exit(1);
- } else if (initval && strcmp(f->initvalstr, initvalstr)) {
- fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer.\n"
- "Initializers have to match literally as well.\n%s\n",
- f->name, f->initvalstr, buffer);
- exit(1);
- }
- offset = strtoul(buffer, &q, 16);
- if (q != buffer + mode || (!offset && (mode == 8 ? strncmp (buffer, "00000000 ", 9) : strncmp (buffer, "0000000000000000 ", 17)))) {
- fprintf(stderr, "Malformed relocation address in\n%s\n", buffer);
- exit(1);
- }
- for (k = 0, r = f->rel, rr = &f->rel; r; rr = &r->next, r = r->next, k++)
- if (r->offset == offset && !strcmp(r->sect, sect)) {
- fprintf(stderr, "Ugh. One address has two relocation records\n");
- exit(1);
- }
- *rr = malloc(sizeof(btfixuprel));
- if (!*rr) fatal();
- (*rr)->offset = offset;
- (*rr)->f = NULL;
- if (buffer[nbase+3] == 'f') {
- lastf = f;
- lastfoffset = offset;
- lastfrelno = k;
- } else if (lastfoffset + 4 == offset) {
- (*rr)->f = lastf;
- (*rr)->frel = lastfrelno;
- }
- (*rr)->sect = sect;
- (*rr)->next = NULL;
- }
- printf("! Generated by btfixupprep. Do not edit.\n\n");
- printf("\t.section\t\".data..init\",#alloc,#write\n\t.align\t4\n\n");
- printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n");
- for (i = 0; i < last; i++) {
- f = array + i;
- printf("\t.global\t___%cs_%s\n", f->type, f->name);
- if (f->type == 'f')
- printf("___%cs_%s:\n\t.word 0x%08x,0,0,", f->type, f->name, f->type << 24);
- else
- printf("___%cs_%s:\n\t.word 0x%08x,0,", f->type, f->name, f->type << 24);
- for (j = 0, r = f->rel; r != NULL; j++, r = r->next);
- if (j)
- printf("%d\n\t.word\t", j * 2);
- else
- printf("0\n");
- for (r = f->rel, j--; r != NULL; j--, r = r->next) {
- if (!strcmp (r->sect, ".text"))
- printf ("_stext+0x%08lx", r->offset);
- else if (!strcmp (r->sect, ".init.text"))
- printf ("__init_begin+0x%08lx", r->offset);
- else if (!strcmp (r->sect, "__ksymtab"))
- printf ("__start___ksymtab+0x%08lx", r->offset);
- else if (!strcmp (r->sect, ".fixup"))
- printf ("__start___fixup+0x%08lx", r->offset);
- else
- fatal();
- if (f->type == 'f' || !r->f)
- printf (",0");
- else
- printf (",___fs_%s+0x%08x", r->f->name, (4 + r->frel*2)*4 + 4);
- if (j) printf (",");
- else printf ("\n");
- }
- printf("\n");
- }
- printf("\n\t.global\t___btfixup_end\n___btfixup_end:\n");
- printf("\n\n! Define undefined references\n\n");
- for (i = 0; i < last; i++) {
- f = array + i;
- if (f->type == 'f') {
- printf("\t.global\t___f_%s\n", f->name);
- printf("___f_%s:\n", f->name);
- }
- }
- printf("\tretl\n\t nop\n\n");
- for (i = 0; i < last; i++) {
- f = array + i;
- if (f->type != 'f') {
- if (!f->initval) {
- printf("\t.global\t___%c_%s\n", f->type, f->name);
- printf("___%c_%s = 0\n", f->type, f->name);
- } else {
- printf("\t.global\t___%c_%s__btset_0x%s\n", f->type, f->name, f->initvalstr);
- printf("___%c_%s__btset_0x%s = 0x%08x\n", f->type, f->name, f->initvalstr, f->initval);
- }
- }
- }
- printf("\n\n");
- exit(0);
-}
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index 3c1e8580740..9d8521b8c85 100644
--- a/arch/sparc/configs/sparc64_defconfig
+++ b/arch/sparc/configs/sparc64_defconfig
@@ -5,7 +5,7 @@ CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_BLK_DEV_INITRD=y
-CONFIG_PERF_COUNTERS=y
+CONFIG_PERF_EVENTS=y
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
CONFIG_PROFILING=y
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 2c2e38821f6..67f83e0a0d6 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -21,3 +21,4 @@ generic-y += div64.h
generic-y += local64.h
generic-y += irq_regs.h
generic-y += local.h
+generic-y += word-at-a-time.h
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/asm/asi.h
index b2e3db63a64..61ebe7411ce 100644
--- a/arch/sparc/include/asm/asi.h
+++ b/arch/sparc/include/asm/asi.h
@@ -40,11 +40,7 @@
#define ASI_M_UNA01 0x01 /* Same here... */
#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */
#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */
-#ifndef CONFIG_SPARC_LEON
#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */
-#else
-#define ASI_M_MMUREGS 0x19
-#endif /* CONFIG_SPARC_LEON */
#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */
#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */
#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */
@@ -112,6 +108,20 @@
#define ASI_M_ACTION 0x4c /* Breakpoint Action Register (GNU/Viking) */
+/* LEON ASI */
+#define ASI_LEON_NOCACHE 0x01
+
+#define ASI_LEON_DCACHE_MISS 0x01
+
+#define ASI_LEON_CACHEREGS 0x02
+#define ASI_LEON_IFLUSH 0x10
+#define ASI_LEON_DFLUSH 0x11
+
+#define ASI_LEON_MMUFLUSH 0x18
+#define ASI_LEON_MMUREGS 0x19
+#define ASI_LEON_BYPASS 0x1c
+#define ASI_LEON_FLUSH_PAGE 0x10
+
/* V9 Architecture mandary ASIs. */
#define ASI_N 0x04 /* Nucleus */
#define ASI_NL 0x0c /* Nucleus, little endian */
diff --git a/arch/sparc/include/asm/asmmacro.h b/arch/sparc/include/asm/asmmacro.h
index a995bf8aba3..a0e28ef0255 100644
--- a/arch/sparc/include/asm/asmmacro.h
+++ b/arch/sparc/include/asm/asmmacro.h
@@ -6,17 +6,6 @@
#ifndef _SPARC_ASMMACRO_H
#define _SPARC_ASMMACRO_H
-#include <asm/btfixup.h>
-#include <asm/asi.h>
-
-#define GET_PROCESSOR4M_ID(reg) \
- rd %tbr, %reg; \
- srl %reg, 12, %reg; \
- and %reg, 3, %reg;
-
-#define GET_PROCESSOR4D_ID(reg) \
- lda [%g0] ASI_M_VIKING_TMP1, %reg;
-
/* All trap entry points _must_ begin with this macro or else you
* lose. It makes sure the kernel has a proper window so that
* c-code can be called.
@@ -31,10 +20,26 @@
/* All traps low-level code here must end with this macro. */
#define RESTORE_ALL b ret_trap_entry; clr %l6;
-/* sun4 probably wants half word accesses to ASI_SEGMAP, while sun4c+
- likes byte accesses. These are to avoid ifdef mania. */
-
-#define lduXa lduba
-#define stXa stba
+/* Support for run-time patching of single instructions.
+ * This is used to handle the differences in the ASI for
+ * MMUREGS for LEON and SUN.
+ *
+ * Sample:
+ * LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0
+ * SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0
+ * PI == Patch Instruction
+ *
+ * For LEON we will use the first variant,
+ * and for all other we will use the SUN variant.
+ * The order is important.
+ */
+#define LEON_PI(...) \
+662: __VA_ARGS__
+
+#define SUN_PI_(...) \
+ .section .leon_1insn_patch, "ax"; \
+ .word 662b; \
+ __VA_ARGS__; \
+ .previous
#endif /* !(_SPARC_ASMMACRO_H) */
diff --git a/arch/sparc/include/asm/btfixup.h b/arch/sparc/include/asm/btfixup.h
deleted file mode 100644
index 797722cf69f..00000000000
--- a/arch/sparc/include/asm/btfixup.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * asm/btfixup.h: Macros for boot time linking.
- *
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#ifndef _SPARC_BTFIXUP_H
-#define _SPARC_BTFIXUP_H
-
-#include <linux/init.h>
-
-#ifndef __ASSEMBLY__
-
-#ifdef MODULE
-extern unsigned int ___illegal_use_of_BTFIXUP_SIMM13_in_module(void);
-extern unsigned int ___illegal_use_of_BTFIXUP_SETHI_in_module(void);
-extern unsigned int ___illegal_use_of_BTFIXUP_HALF_in_module(void);
-extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
-
-#define BTFIXUP_SIMM13(__name) ___illegal_use_of_BTFIXUP_SIMM13_in_module()
-#define BTFIXUP_HALF(__name) ___illegal_use_of_BTFIXUP_HALF_in_module()
-#define BTFIXUP_SETHI(__name) ___illegal_use_of_BTFIXUP_SETHI_in_module()
-#define BTFIXUP_INT(__name) ___illegal_use_of_BTFIXUP_INT_in_module()
-#define BTFIXUP_BLACKBOX(__name) ___illegal_use_of_BTFIXUP_BLACKBOX_in_module
-
-#else
-
-#define BTFIXUP_SIMM13(__name) ___sf_##__name()
-#define BTFIXUP_HALF(__name) ___af_##__name()
-#define BTFIXUP_SETHI(__name) ___hf_##__name()
-#define BTFIXUP_INT(__name) ((unsigned int)&___i_##__name)
-/* This must be written in assembly and present in a sethi */
-#define BTFIXUP_BLACKBOX(__name) ___b_##__name
-#endif /* MODULE */
-
-/* Fixup call xx */
-
-#define BTFIXUPDEF_CALL(__type, __name, __args...) \
- extern __type ___f_##__name(__args); \
- extern unsigned ___fs_##__name[3];
-#define BTFIXUPDEF_CALL_CONST(__type, __name, __args...) \
- extern __type ___f_##__name(__args) __attribute_const__; \
- extern unsigned ___fs_##__name[3];
-#define BTFIXUP_CALL(__name) ___f_##__name
-
-#define BTFIXUPDEF_BLACKBOX(__name) \
- extern unsigned ___bs_##__name[2];
-
-/* Put bottom 13bits into some register variable */
-
-#define BTFIXUPDEF_SIMM13(__name) \
- static inline unsigned int ___sf_##__name(void) __attribute_const__; \
- extern unsigned ___ss_##__name[2]; \
- static inline unsigned int ___sf_##__name(void) { \
- unsigned int ret; \
- __asm__ ("or %%g0, ___s_" #__name ", %0" : "=r"(ret)); \
- return ret; \
- }
-#define BTFIXUPDEF_SIMM13_INIT(__name,__val) \
- static inline unsigned int ___sf_##__name(void) __attribute_const__; \
- extern unsigned ___ss_##__name[2]; \
- static inline unsigned int ___sf_##__name(void) { \
- unsigned int ret; \
- __asm__ ("or %%g0, ___s_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
- return ret; \
- }
-
-/* Put either bottom 13 bits, or upper 22 bits into some register variable
- * (depending on the value, this will lead into sethi FIX, reg; or
- * mov FIX, reg; )
- */
-
-#define BTFIXUPDEF_HALF(__name) \
- static inline unsigned int ___af_##__name(void) __attribute_const__; \
- extern unsigned ___as_##__name[2]; \
- static inline unsigned int ___af_##__name(void) { \
- unsigned int ret; \
- __asm__ ("or %%g0, ___a_" #__name ", %0" : "=r"(ret)); \
- return ret; \
- }
-#define BTFIXUPDEF_HALF_INIT(__name,__val) \
- static inline unsigned int ___af_##__name(void) __attribute_const__; \
- extern unsigned ___as_##__name[2]; \
- static inline unsigned int ___af_##__name(void) { \
- unsigned int ret; \
- __asm__ ("or %%g0, ___a_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
- return ret; \
- }
-
-/* Put upper 22 bits into some register variable */
-
-#define BTFIXUPDEF_SETHI(__name) \
- static inline unsigned int ___hf_##__name(void) __attribute_const__; \
- extern unsigned ___hs_##__name[2]; \
- static inline unsigned int ___hf_##__name(void) { \
- unsigned int ret; \
- __asm__ ("sethi %%hi(___h_" #__name "), %0" : "=r"(ret)); \
- return ret; \
- }
-#define BTFIXUPDEF_SETHI_INIT(__name,__val) \
- static inline unsigned int ___hf_##__name(void) __attribute_const__; \
- extern unsigned ___hs_##__name[2]; \
- static inline unsigned int ___hf_##__name(void) { \
- unsigned int ret; \
- __asm__ ("sethi %%hi(___h_" #__name "__btset_" #__val "), %0" : \
- "=r"(ret)); \
- return ret; \
- }
-
-/* Put a full 32bit integer into some register variable */
-
-#define BTFIXUPDEF_INT(__name) \
- extern unsigned char ___i_##__name; \
- extern unsigned ___is_##__name[2];
-
-#define BTFIXUPCALL_NORM 0x00000000 /* Always call */
-#define BTFIXUPCALL_NOP 0x01000000 /* Possibly optimize to nop */
-#define BTFIXUPCALL_RETINT(i) (0x90102000|((i) & 0x1fff)) /* Possibly optimize to mov i, %o0 */
-#define BTFIXUPCALL_ORINT(i) (0x90122000|((i) & 0x1fff)) /* Possibly optimize to or %o0, i, %o0 */
-#define BTFIXUPCALL_RETO0 0x01000000 /* Return first parameter, actually a nop */
-#define BTFIXUPCALL_ANDNINT(i) (0x902a2000|((i) & 0x1fff)) /* Possibly optimize to andn %o0, i, %o0 */
-#define BTFIXUPCALL_SWAPO0O1 0xd27a0000 /* Possibly optimize to swap [%o0],%o1 */
-#define BTFIXUPCALL_SWAPO0G0 0xc07a0000 /* Possibly optimize to swap [%o0],%g0 */
-#define BTFIXUPCALL_SWAPG1G2 0xc4784000 /* Possibly optimize to swap [%g1],%g2 */
-#define BTFIXUPCALL_STG0O0 0xc0220000 /* Possibly optimize to st %g0,[%o0] */
-#define BTFIXUPCALL_STO1O0 0xd2220000 /* Possibly optimize to st %o1,[%o0] */
-
-#define BTFIXUPSET_CALL(__name, __addr, __insn) \
- do { \
- ___fs_##__name[0] |= 1; \
- ___fs_##__name[1] = (unsigned long)__addr; \
- ___fs_##__name[2] = __insn; \
- } while (0)
-
-#define BTFIXUPSET_BLACKBOX(__name, __func) \
- do { \
- ___bs_##__name[0] |= 1; \
- ___bs_##__name[1] = (unsigned long)__func; \
- } while (0)
-
-#define BTFIXUPCOPY_CALL(__name, __from) \
- do { \
- ___fs_##__name[0] |= 1; \
- ___fs_##__name[1] = ___fs_##__from[1]; \
- ___fs_##__name[2] = ___fs_##__from[2]; \
- } while (0)
-
-#define BTFIXUPSET_SIMM13(__name, __val) \
- do { \
- ___ss_##__name[0] |= 1; \
- ___ss_##__name[1] = (unsigned)__val; \
- } while (0)
-
-#define BTFIXUPCOPY_SIMM13(__name, __from) \
- do { \
- ___ss_##__name[0] |= 1; \
- ___ss_##__name[1] = ___ss_##__from[1]; \
- } while (0)
-
-#define BTFIXUPSET_HALF(__name, __val) \
- do { \
- ___as_##__name[0] |= 1; \
- ___as_##__name[1] = (unsigned)__val; \
- } while (0)
-
-#define BTFIXUPCOPY_HALF(__name, __from) \
- do { \
- ___as_##__name[0] |= 1; \
- ___as_##__name[1] = ___as_##__from[1]; \
- } while (0)
-
-#define BTFIXUPSET_SETHI(__name, __val) \
- do { \
- ___hs_##__name[0] |= 1; \
- ___hs_##__name[1] = (unsigned)__val; \
- } while (0)
-
-#define BTFIXUPCOPY_SETHI(__name, __from) \
- do { \
- ___hs_##__name[0] |= 1; \
- ___hs_##__name[1] = ___hs_##__from[1]; \
- } while (0)
-
-#define BTFIXUPSET_INT(__name, __val) \
- do { \
- ___is_##__name[0] |= 1; \
- ___is_##__name[1] = (unsigned)__val; \
- } while (0)
-
-#define BTFIXUPCOPY_INT(__name, __from) \
- do { \
- ___is_##__name[0] |= 1; \
- ___is_##__name[1] = ___is_##__from[1]; \
- } while (0)
-
-#define BTFIXUPVAL_CALL(__name) \
- ((unsigned long)___fs_##__name[1])
-
-extern void btfixup(void);
-
-#else /* __ASSEMBLY__ */
-
-#define BTFIXUP_SETHI(__name) %hi(___h_ ## __name)
-#define BTFIXUP_SETHI_INIT(__name,__val) %hi(___h_ ## __name ## __btset_ ## __val)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* !(_SPARC_BTFIXUP_H) */
diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h
index 69358b590c9..5bb6991b485 100644
--- a/arch/sparc/include/asm/cache.h
+++ b/arch/sparc/include/asm/cache.h
@@ -22,118 +22,4 @@
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
-#ifdef CONFIG_SPARC32
-#include <asm/asi.h>
-
-/* Direct access to the instruction cache is provided through and
- * alternate address space. The IDC bit must be off in the ICCR on
- * HyperSparcs for these accesses to work. The code below does not do
- * any checking, the caller must do so. These routines are for
- * diagnostics only, but could end up being useful. Use with care.
- * Also, you are asking for trouble if you execute these in one of the
- * three instructions following a %asr/%psr access or modification.
- */
-
-/* First, cache-tag access. */
-static inline unsigned int get_icache_tag(int setnum, int tagnum)
-{
- unsigned int vaddr, retval;
-
- vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5);
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (retval) :
- "r" (vaddr), "i" (ASI_M_TXTC_TAG));
- return retval;
-}
-
-static inline void put_icache_tag(int setnum, int tagnum, unsigned int entry)
-{
- unsigned int vaddr;
-
- vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5);
- __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
- "r" (entry), "r" (vaddr), "i" (ASI_M_TXTC_TAG) :
- "memory");
-}
-
-/* Second cache-data access. The data is returned two-32bit quantities
- * at a time.
- */
-static inline void get_icache_data(int setnum, int tagnum, int subblock,
- unsigned int *data)
-{
- unsigned int value1, value2, vaddr;
-
- vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) |
- ((subblock&0x3) << 3);
- __asm__ __volatile__("ldda [%2] %3, %%g2\n\t"
- "or %%g0, %%g2, %0\n\t"
- "or %%g0, %%g3, %1\n\t" :
- "=r" (value1), "=r" (value2) :
- "r" (vaddr), "i" (ASI_M_TXTC_DATA) :
- "g2", "g3");
- data[0] = value1; data[1] = value2;
-}
-
-static inline void put_icache_data(int setnum, int tagnum, int subblock,
- unsigned int *data)
-{
- unsigned int value1, value2, vaddr;
-
- vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) |
- ((subblock&0x3) << 3);
- value1 = data[0]; value2 = data[1];
- __asm__ __volatile__("or %%g0, %0, %%g2\n\t"
- "or %%g0, %1, %%g3\n\t"
- "stda %%g2, [%2] %3\n\t" : :
- "r" (value1), "r" (value2),
- "r" (vaddr), "i" (ASI_M_TXTC_DATA) :
- "g2", "g3", "memory" /* no joke */);
-}
-
-/* Different types of flushes with the ICACHE. Some of the flushes
- * affect both the ICACHE and the external cache. Others only clear
- * the ICACHE entries on the cpu itself. V8's (most) allow
- * granularity of flushes on the packet (element in line), whole line,
- * and entire cache (ie. all lines) level. The ICACHE only flushes are
- * ROSS HyperSparc specific and are in ross.h
- */
-
-/* Flushes which clear out both the on-chip and external caches */
-static inline void flush_ei_page(unsigned int addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (addr), "i" (ASI_M_FLUSH_PAGE) :
- "memory");
-}
-
-static inline void flush_ei_seg(unsigned int addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (addr), "i" (ASI_M_FLUSH_SEG) :
- "memory");
-}
-
-static inline void flush_ei_region(unsigned int addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (addr), "i" (ASI_M_FLUSH_REGION) :
- "memory");
-}
-
-static inline void flush_ei_ctx(unsigned int addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (addr), "i" (ASI_M_FLUSH_CTX) :
- "memory");
-}
-
-static inline void flush_ei_user(unsigned int addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (addr), "i" (ASI_M_FLUSH_USER) :
- "memory");
-}
-#endif /* CONFIG_SPARC32 */
-
#endif /* !(_SPARC_CACHE_H) */
diff --git a/arch/sparc/include/asm/cacheflush.h b/arch/sparc/include/asm/cacheflush.h
index 049168087b1..f6c4839b838 100644
--- a/arch/sparc/include/asm/cacheflush.h
+++ b/arch/sparc/include/asm/cacheflush.h
@@ -1,5 +1,9 @@
#ifndef ___ASM_SPARC_CACHEFLUSH_H
#define ___ASM_SPARC_CACHEFLUSH_H
+
+/* flush addr - to allow use of self-modifying code */
+#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
+
#if defined(__sparc__) && defined(__arch64__)
#include <asm/cacheflush_64.h>
#else
diff --git a/arch/sparc/include/asm/cacheflush_32.h b/arch/sparc/include/asm/cacheflush_32.h
index 68431b47a22..bb014c24f31 100644
--- a/arch/sparc/include/asm/cacheflush_32.h
+++ b/arch/sparc/include/asm/cacheflush_32.h
@@ -1,56 +1,18 @@
#ifndef _SPARC_CACHEFLUSH_H
#define _SPARC_CACHEFLUSH_H
-#include <linux/mm.h> /* Common for other includes */
-// #include <linux/kernel.h> from pgalloc.h
-// #include <linux/sched.h> from pgalloc.h
-
-// #include <asm/page.h>
-#include <asm/btfixup.h>
-
-/*
- * Fine grained cache flushing.
- */
-#ifdef CONFIG_SMP
-
-BTFIXUPDEF_CALL(void, local_flush_cache_all, void)
-BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long)
-
-#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
-#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
-#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
-#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
-
-BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long)
-
-#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
-#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
-
-extern void smp_flush_cache_all(void);
-extern void smp_flush_cache_mm(struct mm_struct *mm);
-extern void smp_flush_cache_range(struct vm_area_struct *vma,
- unsigned long start,
- unsigned long end);
-extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
-
-extern void smp_flush_page_to_ram(unsigned long page);
-extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-
-#endif /* CONFIG_SMP */
-
-BTFIXUPDEF_CALL(void, flush_cache_all, void)
-BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
-
-#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
-#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
-#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
-#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
-#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr)
+#include <asm/cachetlb_32.h>
+
+#define flush_cache_all() \
+ sparc32_cachetlb_ops->cache_all()
+#define flush_cache_mm(mm) \
+ sparc32_cachetlb_ops->cache_mm(mm)
+#define flush_cache_dup_mm(mm) \
+ sparc32_cachetlb_ops->cache_mm(mm)
+#define flush_cache_range(vma,start,end) \
+ sparc32_cachetlb_ops->cache_range(vma, start, end)
+#define flush_cache_page(vma,addr,pfn) \
+ sparc32_cachetlb_ops->cache_page(vma, addr)
#define flush_icache_range(start, end) do { } while (0)
#define flush_icache_page(vma, pg) do { } while (0)
@@ -67,11 +29,12 @@ BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
memcpy(dst, src, len); \
} while (0)
-BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
-BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
-
-#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
-#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
+#define __flush_page_to_ram(addr) \
+ sparc32_cachetlb_ops->page_to_ram(addr)
+#define flush_sig_insns(mm,insn_addr) \
+ sparc32_cachetlb_ops->sig_insns(mm, insn_addr)
+#define flush_page_for_dma(addr) \
+ sparc32_cachetlb_ops->page_for_dma(addr)
extern void sparc_flush_page_to_ram(struct page *page);
diff --git a/arch/sparc/include/asm/cacheflush_64.h b/arch/sparc/include/asm/cacheflush_64.h
index 2efea2ff88b..301736d9e7a 100644
--- a/arch/sparc/include/asm/cacheflush_64.h
+++ b/arch/sparc/include/asm/cacheflush_64.h
@@ -8,9 +8,6 @@
#include <linux/mm.h>
/* Cache flush operations. */
-
-
-#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
#define flushw_all() __asm__ __volatile__("flushw")
extern void __flushw_user(void);
diff --git a/arch/sparc/include/asm/cachetlb_32.h b/arch/sparc/include/asm/cachetlb_32.h
new file mode 100644
index 00000000000..efb19889a08
--- /dev/null
+++ b/arch/sparc/include/asm/cachetlb_32.h
@@ -0,0 +1,29 @@
+#ifndef _SPARC_CACHETLB_H
+#define _SPARC_CACHETLB_H
+
+struct mm_struct;
+struct vm_area_struct;
+
+struct sparc32_cachetlb_ops {
+ void (*cache_all)(void);
+ void (*cache_mm)(struct mm_struct *);
+ void (*cache_range)(struct vm_area_struct *, unsigned long,
+ unsigned long);
+ void (*cache_page)(struct vm_area_struct *, unsigned long);
+
+ void (*tlb_all)(void);
+ void (*tlb_mm)(struct mm_struct *);
+ void (*tlb_range)(struct vm_area_struct *, unsigned long,
+ unsigned long);
+ void (*tlb_page)(struct vm_area_struct *, unsigned long);
+
+ void (*page_to_ram)(unsigned long);
+ void (*sig_insns)(struct mm_struct *, unsigned long);
+ void (*page_for_dma)(unsigned long);
+};
+extern const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops;
+#ifdef CONFIG_SMP
+extern const struct sparc32_cachetlb_ops *local_ops;
+#endif
+
+#endif /* SPARC_CACHETLB_H */
diff --git a/arch/sparc/include/asm/cmpxchg_32.h b/arch/sparc/include/asm/cmpxchg_32.h
index c786b0a92b5..1fae1a02e3c 100644
--- a/arch/sparc/include/asm/cmpxchg_32.h
+++ b/arch/sparc/include/asm/cmpxchg_32.h
@@ -11,40 +11,13 @@
#ifndef __ARCH_SPARC_CMPXCHG__
#define __ARCH_SPARC_CMPXCHG__
-#include <asm/btfixup.h>
-
-/* This has special calling conventions */
-#ifndef CONFIG_SMP
-BTFIXUPDEF_CALL(void, ___xchg32, void)
-#endif
-
static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
{
-#ifdef CONFIG_SMP
__asm__ __volatile__("swap [%2], %0"
: "=&r" (val)
: "0" (val), "r" (m)
: "memory");
return val;
-#else
- register unsigned long *ptr asm("g1");
- register unsigned long ret asm("g2");
-
- ptr = (unsigned long *) m;
- ret = val;
-
- /* Note: this is magic and the nop there is
- really needed. */
- __asm__ __volatile__(
- "mov %%o7, %%g4\n\t"
- "call ___f____xchg32\n\t"
- " nop\n\t"
- : "=&r" (ret)
- : "0" (ret), "r" (ptr)
- : "g3", "g4", "g7", "memory", "cc");
-
- return ret;
-#endif
}
extern void __xchg_called_with_bad_pointer(void);
diff --git a/arch/sparc/include/asm/cmt.h b/arch/sparc/include/asm/cmt.h
deleted file mode 100644
index 870db592857..00000000000
--- a/arch/sparc/include/asm/cmt.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef _SPARC64_CMT_H
-#define _SPARC64_CMT_H
-
-/* cmt.h: Chip Multi-Threading register definitions
- *
- * Copyright (C) 2004 David S. Miller (davem@redhat.com)
- */
-
-/* ASI_CORE_ID - private */
-#define LP_ID 0x0000000000000010UL
-#define LP_ID_MAX 0x00000000003f0000UL
-#define LP_ID_ID 0x000000000000003fUL
-
-/* ASI_INTR_ID - private */
-#define LP_INTR_ID 0x0000000000000000UL
-#define LP_INTR_ID_ID 0x00000000000003ffUL
-
-/* ASI_CESR_ID - private */
-#define CESR_ID 0x0000000000000040UL
-#define CESR_ID_ID 0x00000000000000ffUL
-
-/* ASI_CORE_AVAILABLE - shared */
-#define LP_AVAIL 0x0000000000000000UL
-#define LP_AVAIL_1 0x0000000000000002UL
-#define LP_AVAIL_0 0x0000000000000001UL
-
-/* ASI_CORE_ENABLE_STATUS - shared */
-#define LP_ENAB_STAT 0x0000000000000010UL
-#define LP_ENAB_STAT_1 0x0000000000000002UL
-#define LP_ENAB_STAT_0 0x0000000000000001UL
-
-/* ASI_CORE_ENABLE - shared */
-#define LP_ENAB 0x0000000000000020UL
-#define LP_ENAB_1 0x0000000000000002UL
-#define LP_ENAB_0 0x0000000000000001UL
-
-/* ASI_CORE_RUNNING - shared */
-#define LP_RUNNING_RW 0x0000000000000050UL
-#define LP_RUNNING_W1S 0x0000000000000060UL
-#define LP_RUNNING_W1C 0x0000000000000068UL
-#define LP_RUNNING_1 0x0000000000000002UL
-#define LP_RUNNING_0 0x0000000000000001UL
-
-/* ASI_CORE_RUNNING_STAT - shared */
-#define LP_RUN_STAT 0x0000000000000058UL
-#define LP_RUN_STAT_1 0x0000000000000002UL
-#define LP_RUN_STAT_0 0x0000000000000001UL
-
-/* ASI_XIR_STEERING - shared */
-#define LP_XIR_STEER 0x0000000000000030UL
-#define LP_XIR_STEER_1 0x0000000000000002UL
-#define LP_XIR_STEER_0 0x0000000000000001UL
-
-/* ASI_CMT_ERROR_STEERING - shared */
-#define CMT_ER_STEER 0x0000000000000040UL
-#define CMT_ER_STEER_1 0x0000000000000002UL
-#define CMT_ER_STEER_0 0x0000000000000001UL
-
-#endif /* _SPARC64_CMT_H */
diff --git a/arch/sparc/include/asm/contregs.h b/arch/sparc/include/asm/contregs.h
index 48fa8a4ef35..b8abdfcf555 100644
--- a/arch/sparc/include/asm/contregs.h
+++ b/arch/sparc/include/asm/contregs.h
@@ -7,28 +7,6 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-/* 3=sun3
- 4=sun4 (as in sun4 sysmaint student book)
- c=sun4c (according to davem) */
-
-#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */
-#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */
-#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */
-#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */
-#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/
-#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */
-#define AC_BUS_ERROR 0x60000000 /* 34 Not cleared on read, byte. */
-#define AC_SYNC_ERR 0x60000000 /* c fault type */
-#define AC_SYNC_VA 0x60000004 /* c fault virtual address */
-#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */
-#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */
-#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */
-#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */
-#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */
-#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */
-#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */
-#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/
-
/* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */
#define AC_M_PCR 0x0000 /* shv Processor Control Reg */
#define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */
diff --git a/arch/sparc/include/asm/cpu_type.h b/arch/sparc/include/asm/cpu_type.h
index 4ca184d95d8..84d7d83b808 100644
--- a/arch/sparc/include/asm/cpu_type.h
+++ b/arch/sparc/include/asm/cpu_type.h
@@ -5,30 +5,24 @@
* Sparc (general) CPU types
*/
enum sparc_cpu {
- sun4 = 0x00,
- sun4c = 0x01,
- sun4m = 0x02,
- sun4d = 0x03,
- sun4e = 0x04,
- sun4u = 0x05, /* V8 ploos ploos */
- sun_unknown = 0x06,
- ap1000 = 0x07, /* almost a sun4m */
- sparc_leon = 0x08, /* Leon SoC */
+ sun4m = 0x00,
+ sun4d = 0x01,
+ sun4e = 0x02,
+ sun4u = 0x03, /* V8 ploos ploos */
+ sun_unknown = 0x04,
+ ap1000 = 0x05, /* almost a sun4m */
+ sparc_leon = 0x06, /* Leon SoC */
};
#ifdef CONFIG_SPARC32
extern enum sparc_cpu sparc_cpu_model;
-#define ARCH_SUN4C (sparc_cpu_model==sun4c)
-
#define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */
#else
#define sparc_cpu_model sun4u
-/* This cannot ever be a sun4c :) That's just history. */
-#define ARCH_SUN4C 0
#endif
#endif /* __ASM_CPU_TYPE_H */
diff --git a/arch/sparc/include/asm/cpudata_32.h b/arch/sparc/include/asm/cpudata_32.h
index a4c5a938b93..0300d94c25b 100644
--- a/arch/sparc/include/asm/cpudata_32.h
+++ b/arch/sparc/include/asm/cpudata_32.h
@@ -14,7 +14,6 @@
typedef struct {
unsigned long udelay_val;
unsigned long clock_tick;
- unsigned int multiplier;
unsigned int counter;
#ifdef CONFIG_SMP
unsigned int irq_resched_count;
diff --git a/arch/sparc/include/asm/cypress.h b/arch/sparc/include/asm/cypress.h
deleted file mode 100644
index 95e9772ea39..00000000000
--- a/arch/sparc/include/asm/cypress.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * cypress.h: Cypress module specific definitions and defines.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_CYPRESS_H
-#define _SPARC_CYPRESS_H
-
-/* Cypress chips have %psr 'impl' of '0001' and 'vers' of '0001'. */
-
-/* The MMU control register fields on the Sparc Cypress 604/605 MMU's.
- *
- * ---------------------------------------------------------------
- * |implvers| MCA | MCM |MV| MID |BM| C|RSV|MR|CM|CL|CE|RSV|NF|ME|
- * ---------------------------------------------------------------
- * 31 24 23-22 21-20 19 18-15 14 13 12 11 10 9 8 7-2 1 0
- *
- * MCA: MultiChip Access -- Used for configuration of multiple
- * CY7C604/605 cache units.
- * MCM: MultiChip Mask -- Again, for multiple cache unit config.
- * MV: MultiChip Valid -- Indicates MCM and MCA have valid settings.
- * MID: ModuleID -- Unique processor ID for MBus transactions. (605 only)
- * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode
- * C: Cacheable -- Indicates whether accesses are cacheable while
- * the MMU is off. 0=no 1=yes
- * MR: MemoryReflection -- Indicates whether the bus attached to the
- * MBus supports memory reflection. 0=no 1=yes (605 only)
- * CM: CacheMode -- Indicates whether the cache is operating in write
- * through or copy-back mode. 0=write-through 1=copy-back
- * CL: CacheLock -- Indicates if the entire cache is locked or not.
- * 0=not-locked 1=locked (604 only)
- * CE: CacheEnable -- Is the virtual cache on? 0=no 1=yes
- * NF: NoFault -- Do faults generate traps? 0=yes 1=no
- * ME: MmuEnable -- Is the MMU doing translations? 0=no 1=yes
- */
-
-#define CYPRESS_MCA 0x00c00000
-#define CYPRESS_MCM 0x00300000
-#define CYPRESS_MVALID 0x00080000
-#define CYPRESS_MIDMASK 0x00078000 /* Only on 605 */
-#define CYPRESS_BMODE 0x00004000
-#define CYPRESS_ACENABLE 0x00002000
-#define CYPRESS_MRFLCT 0x00000800 /* Only on 605 */
-#define CYPRESS_CMODE 0x00000400
-#define CYPRESS_CLOCK 0x00000200 /* Only on 604 */
-#define CYPRESS_CENABLE 0x00000100
-#define CYPRESS_NFAULT 0x00000002
-#define CYPRESS_MENABLE 0x00000001
-
-static inline void cypress_flush_page(unsigned long page)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (page), "i" (ASI_M_FLUSH_PAGE));
-}
-
-static inline void cypress_flush_segment(unsigned long addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (addr), "i" (ASI_M_FLUSH_SEG));
-}
-
-static inline void cypress_flush_region(unsigned long addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (addr), "i" (ASI_M_FLUSH_REGION));
-}
-
-static inline void cypress_flush_context(void)
-{
- __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
- "i" (ASI_M_FLUSH_CTX));
-}
-
-/* XXX Displacement flushes for buggy chips and initial testing
- * XXX go here.
- */
-
-#endif /* !(_SPARC_CYPRESS_H) */
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 48a7c65731d..8493fd3c7ba 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -12,13 +12,18 @@ extern int dma_supported(struct device *dev, u64 mask);
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-extern struct dma_map_ops *dma_ops, pci32_dma_ops;
+extern struct dma_map_ops *dma_ops;
+extern struct dma_map_ops *leon_dma_ops;
+extern struct dma_map_ops pci32_dma_ops;
+
extern struct bus_type pci_bus_type;
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
- if (dev->bus == &pci_bus_type)
+ if (sparc_cpu_model == sparc_leon)
+ return leon_dma_ops;
+ else if (dev->bus == &pci_bus_type)
return &pci32_dma_ops;
#endif
return dma_ops;
diff --git a/arch/sparc/include/asm/dma.h b/arch/sparc/include/asm/dma.h
index b554927bbaf..3d434ef5eae 100644
--- a/arch/sparc/include/asm/dma.h
+++ b/arch/sparc/include/asm/dma.h
@@ -92,27 +92,31 @@ extern int isa_dma_bridge_buggy;
#ifdef CONFIG_SPARC32
/* Routines for data transfer buffers. */
-BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
-BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long)
-
-#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
-#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
-
-struct page;
struct device;
struct scatterlist;
-/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
-BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, struct device *, char *, unsigned long)
-BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct device *, struct scatterlist *, int)
-BTFIXUPDEF_CALL(void, mmu_release_scsi_one, struct device *, __u32, unsigned long)
-BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct device *, struct scatterlist *, int)
-
-#define mmu_get_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_get_scsi_one)(dev,vaddr,len)
-#define mmu_get_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_get_scsi_sgl)(dev,sg,sz)
-#define mmu_release_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_release_scsi_one)(dev,vaddr,len)
-#define mmu_release_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_release_scsi_sgl)(dev,sg,sz)
-
+struct sparc32_dma_ops {
+ __u32 (*get_scsi_one)(struct device *, char *, unsigned long);
+ void (*get_scsi_sgl)(struct device *, struct scatterlist *, int);
+ void (*release_scsi_one)(struct device *, __u32, unsigned long);
+ void (*release_scsi_sgl)(struct device *, struct scatterlist *,int);
+#ifdef CONFIG_SBUS
+ int (*map_dma_area)(struct device *, dma_addr_t *, unsigned long, unsigned long, int);
+ void (*unmap_dma_area)(struct device *, unsigned long, int);
+#endif
+};
+extern const struct sparc32_dma_ops *sparc32_dma_ops;
+
+#define mmu_get_scsi_one(dev,vaddr,len) \
+ sparc32_dma_ops->get_scsi_one(dev, vaddr, len)
+#define mmu_get_scsi_sgl(dev,sg,sz) \
+ sparc32_dma_ops->get_scsi_sgl(dev, sg, sz)
+#define mmu_release_scsi_one(dev,vaddr,len) \
+ sparc32_dma_ops->release_scsi_one(dev, vaddr,len)
+#define mmu_release_scsi_sgl(dev,sg,sz) \
+ sparc32_dma_ops->release_scsi_sgl(dev, sg, sz)
+
+#ifdef CONFIG_SBUS
/*
* mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
*
@@ -123,17 +127,17 @@ BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct device *, struct scatterlist
* Second mapping is for device visible address, or "bus" address.
* The bus address is returned at '*pba'.
*
- * These functions seem distinct, but are hard to split. On sun4c,
- * at least for now, 'a' is equal to bus address, and retured in *pba.
+ * These functions seem distinct, but are hard to split.
* On sun4m, page attributes depend on the CPU type, so we have to
* know if we are mapping RAM or I/O, so it has to be an additional argument
* to a separate mapping function for CPU visible mappings.
*/
-BTFIXUPDEF_CALL(int, mmu_map_dma_area, struct device *, dma_addr_t *, unsigned long, unsigned long, int len)
-BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, struct device *, unsigned long busa, int len)
+#define sbus_map_dma_area(dev,pba,va,a,len) \
+ sparc32_dma_ops->map_dma_area(dev, pba, va, a, len)
+#define sbus_unmap_dma_area(dev,ba,len) \
+ sparc32_dma_ops->unmap_dma_area(dev, ba, len)
+#endif /* CONFIG_SBUS */
-#define mmu_map_dma_area(dev,pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(dev,pba,va,a,len)
-#define mmu_unmap_dma_area(dev,ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(dev,ba,len)
#endif
#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index 4269ca6ad18..2d4d755cba9 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -118,16 +118,9 @@ typedef struct {
instruction set this cpu supports. This can NOT be done in userspace
on Sparc. */
-/* Sun4c has none of the capabilities, most sun4m's have them all.
- * XXX This is gross, set some global variable at boot time. -DaveM
- */
-#define ELF_HWCAP ((ARCH_SUN4C) ? 0 : \
- (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
- HWCAP_SPARC_SWAP | \
- ((srmmu_modtype != Cypress && \
- srmmu_modtype != Cypress_vE && \
- srmmu_modtype != Cypress_vD) ? \
- HWCAP_SPARC_MULDIV : 0)))
+/* Most sun4m's have them all. */
+#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
+ HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV)
/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h
index 698d9559fea..fb3f16954c6 100644
--- a/arch/sparc/include/asm/floppy_32.h
+++ b/arch/sparc/include/asm/floppy_32.h
@@ -12,7 +12,6 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/idprom.h>
-#include <asm/machines.h>
#include <asm/oplib.h>
#include <asm/auxio.h>
#include <asm/irq.h>
@@ -103,25 +102,13 @@ static struct sun_floppy_ops sun_fdops;
/* Routines unique to each controller type on a Sun. */
static void sun_set_dor(unsigned char value, int fdc_82077)
{
- if (sparc_cpu_model == sun4c) {
- unsigned int bits = 0;
- if (value & 0x10)
- bits |= AUXIO_FLPY_DSEL;
- if ((value & 0x80) == 0)
- bits |= AUXIO_FLPY_EJCT;
- set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
- }
- if (fdc_82077) {
+ if (fdc_82077)
sun_fdc->dor_82077 = value;
- }
}
static unsigned char sun_read_dir(void)
{
- if (sparc_cpu_model == sun4c)
- return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0;
- else
- return sun_fdc->dir_82077;
+ return sun_fdc->dir_82077;
}
static unsigned char sun_82072_fd_inb(int port)
@@ -242,10 +229,7 @@ static inline void virtual_dma_init(void)
static inline void sun_fd_disable_dma(void)
{
doing_pdma = 0;
- if (pdma_base) {
- mmu_unlockarea(pdma_base, pdma_areasize);
- pdma_base = NULL;
- }
+ pdma_base = NULL;
}
static inline void sun_fd_set_dma_mode(int mode)
@@ -275,7 +259,6 @@ static inline void sun_fd_set_dma_count(int length)
static inline void sun_fd_enable_dma(void)
{
- pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
pdma_base = pdma_vaddr;
pdma_areasize = pdma_size;
}
@@ -301,38 +284,36 @@ static int sun_floppy_init(void)
{
struct platform_device *op;
struct device_node *dp;
+ struct resource r;
char state[128];
- phandle tnode, fd_node;
+ phandle fd_node;
+ phandle tnode;
int num_regs;
- struct resource r;
use_virtual_dma = 1;
/* Forget it if we aren't on a machine that could possibly
* ever have a floppy drive.
*/
- if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) ||
- ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) ||
- (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) {
+ if (sparc_cpu_model != sun4m) {
/* We certainly don't have a floppy controller. */
goto no_sun_fdc;
}
/* Well, try to find one. */
tnode = prom_getchild(prom_root_node);
fd_node = prom_searchsiblings(tnode, "obio");
- if(fd_node != 0) {
+ if (fd_node != 0) {
tnode = prom_getchild(fd_node);
fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
} else {
fd_node = prom_searchsiblings(tnode, "fd");
}
- if(fd_node == 0) {
+ if (fd_node == 0) {
goto no_sun_fdc;
}
/* The sun4m lets us know if the controller is actually usable. */
- if(sparc_cpu_model == sun4m &&
- prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
+ if (prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
if(!strcmp(state, "disabled")) {
goto no_sun_fdc;
}
@@ -343,12 +324,12 @@ static int sun_floppy_init(void)
memset(&r, 0, sizeof(r));
r.flags = fd_regs[0].which_io;
r.start = fd_regs[0].phys_addr;
- sun_fdc = (struct sun_flpy_controller *)
- of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
+ sun_fdc = of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
/* Look up irq in platform_device.
* We try "SUNW,fdtwo" and "fd"
*/
+ op = NULL;
for_each_node_by_name(dp, "SUNW,fdtwo") {
op = of_find_device_by_node(dp);
if (op)
@@ -367,7 +348,7 @@ static int sun_floppy_init(void)
FLOPPY_IRQ = op->archdata.irqs[0];
/* Last minute sanity check... */
- if(sun_fdc->status_82072 == 0xff) {
+ if (sun_fdc->status_82072 == 0xff) {
sun_fdc = NULL;
goto no_sun_fdc;
}
diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h
index bcef1f5a2a6..e204f902e6c 100644
--- a/arch/sparc/include/asm/floppy_64.h
+++ b/arch/sparc/include/asm/floppy_64.h
@@ -161,10 +161,7 @@ unsigned long pdma_areasize;
static void sun_fd_disable_dma(void)
{
doing_pdma = 0;
- if (pdma_base) {
- mmu_unlockarea(pdma_base, pdma_areasize);
- pdma_base = NULL;
- }
+ pdma_base = NULL;
}
static void sun_fd_set_dma_mode(int mode)
@@ -194,7 +191,6 @@ static void sun_fd_set_dma_count(int length)
static void sun_fd_enable_dma(void)
{
- pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
pdma_base = pdma_vaddr;
pdma_areasize = pdma_size;
}
diff --git a/arch/sparc/include/asm/gpio.h b/arch/sparc/include/asm/gpio.h
index a0e3ac0af59..b3799d88ffc 100644
--- a/arch/sparc/include/asm/gpio.h
+++ b/arch/sparc/include/asm/gpio.h
@@ -1,36 +1,4 @@
-#ifndef __ASM_SPARC_GPIO_H
-#define __ASM_SPARC_GPIO_H
-
-#include <linux/errno.h>
-#include <asm-generic/gpio.h>
-
-#ifdef CONFIG_GPIOLIB
-
-static inline int gpio_get_value(unsigned int gpio)
-{
- return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned int gpio, int value)
-{
- __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned int gpio)
-{
- return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned int gpio)
-{
- return -ENOSYS;
-}
-
-static inline int irq_to_gpio(unsigned int irq)
-{
- return -EINVAL;
-}
-
-#endif /* CONFIG_GPIOLIB */
-
-#endif /* __ASM_SPARC_GPIO_H */
+#ifndef __LINUX_GPIO_H
+#warning Include linux/gpio.h instead of asm/gpio.h
+#include <linux/gpio.h>
+#endif
diff --git a/arch/sparc/include/asm/head_32.h b/arch/sparc/include/asm/head_32.h
index 7c35491a8b5..a76874838f6 100644
--- a/arch/sparc/include/asm/head_32.h
+++ b/arch/sparc/include/asm/head_32.h
@@ -2,15 +2,8 @@
#define __SPARC_HEAD_H
#define KERNBASE 0xf0000000 /* First address the kernel will eventually be */
-#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */
-#define SUN4C_SEGSZ (1 << 18)
-#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2) /* Used in boot remapping. */
-#define INTS_ENAB 0x01 /* entry.S uses this. */
-
-#define SUN4_PROM_VECTOR 0xFFE81000 /* SUN4 PROM needs to be hardwired */
#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
-#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */
/* Here are some trap goodies */
@@ -18,9 +11,7 @@
#define TRAP_ENTRY(type, label) \
rd %psr, %l0; b label; rd %wim, %l3; nop;
-/* Data/text faults. Defaults to sun4c version at boot time. */
-#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7;
-#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7;
+/* Data/text faults */
#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 1, %l7;
#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 0, %l7;
@@ -80,16 +71,6 @@
#define TRAP_ENTRY_INTERRUPT(int_level) \
mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3;
-/* NMI's (Non Maskable Interrupts) are special, you can't keep them
- * from coming in, and basically if you get one, the shows over. ;(
- * On the sun4c they are usually asynchronous memory errors, on the
- * the sun4m they could be either due to mem errors or a software
- * initiated interrupt from the prom/kern on an SMP box saying "I
- * command you to do CPU tricks, read your mailbox for more info."
- */
-#define NMI_TRAP \
- rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop;
-
/* Window overflows/underflows are special and we need to try to be as
* efficient as possible here....
*/
diff --git a/arch/sparc/include/asm/kvm_para.h b/arch/sparc/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/sparc/include/asm/kvm_para.h
@@ -0,0 +1 @@
+#include <asm-generic/kvm_para.h>
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
index a4e457f003e..3375c629389 100644
--- a/arch/sparc/include/asm/leon.h
+++ b/arch/sparc/include/asm/leon.h
@@ -8,21 +8,6 @@
#ifndef LEON_H_INCLUDE
#define LEON_H_INCLUDE
-#ifdef CONFIG_SPARC_LEON
-
-#define ASI_LEON_NOCACHE 0x01
-
-#define ASI_LEON_DCACHE_MISS 0x1
-
-#define ASI_LEON_CACHEREGS 0x02
-#define ASI_LEON_IFLUSH 0x10
-#define ASI_LEON_DFLUSH 0x11
-
-#define ASI_LEON_MMUFLUSH 0x18
-#define ASI_LEON_MMUREGS 0x19
-#define ASI_LEON_BYPASS 0x1c
-#define ASI_LEON_FLUSH_PAGE 0x10
-
/* mmu register access, ASI_LEON_MMUREGS */
#define LEON_CNR_CTRL 0x000
#define LEON_CNR_CTXP 0x100
@@ -57,29 +42,6 @@
#define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */
#define LEON_IRQPRIO_R 0xfffe0000 /* bit 31-17 of lregs.irqmask */
-/* leon uart register definitions */
-#define LEON_OFF_UDATA 0x0
-#define LEON_OFF_USTAT 0x4
-#define LEON_OFF_UCTRL 0x8
-#define LEON_OFF_USCAL 0xc
-
-#define LEON_UCTRL_RE 0x01
-#define LEON_UCTRL_TE 0x02
-#define LEON_UCTRL_RI 0x04
-#define LEON_UCTRL_TI 0x08
-#define LEON_UCTRL_PS 0x10
-#define LEON_UCTRL_PE 0x20
-#define LEON_UCTRL_FL 0x40
-#define LEON_UCTRL_LB 0x80
-
-#define LEON_USTAT_DR 0x01
-#define LEON_USTAT_TS 0x02
-#define LEON_USTAT_TH 0x04
-#define LEON_USTAT_BR 0x08
-#define LEON_USTAT_OV 0x10
-#define LEON_USTAT_PE 0x20
-#define LEON_USTAT_FE 0x40
-
#define LEON_MCFG2_SRAMDIS 0x00002000
#define LEON_MCFG2_SDRAMEN 0x00004000
#define LEON_MCFG2_SRAMBANKSZ 0x00001e00 /* [12-9] */
@@ -89,8 +51,6 @@
#define LEON_TCNT0_MASK 0x7fffff
-#define LEON_USTAT_ERROR (LEON_USTAT_OV | LEON_USTAT_PE | LEON_USTAT_FE)
-/* no break yet */
#define ASI_LEON3_SYSCTRL 0x02
#define ASI_LEON3_SYSCTRL_ICFG 0x08
@@ -100,15 +60,6 @@
#ifndef __ASSEMBLY__
-/* do a virtual address read without cache */
-static inline unsigned long leon_readnobuffer_reg(unsigned long paddr)
-{
- unsigned long retval;
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE));
- return retval;
-}
-
/* do a physical address bypass write, i.e. for 0x80000000 */
static inline void leon_store_reg(unsigned long paddr, unsigned long value)
{
@@ -125,47 +76,16 @@ static inline unsigned long leon_load_reg(unsigned long paddr)
return retval;
}
-static inline void leon_srmmu_disabletlb(void)
-{
- unsigned int retval;
- __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
- "i"(ASI_LEON_MMUREGS));
- retval |= LEON_CNR_CTRL_TLBDIS;
- __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
- "i"(ASI_LEON_MMUREGS) : "memory");
-}
-
-static inline void leon_srmmu_enabletlb(void)
-{
- unsigned int retval;
- __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
- "i"(ASI_LEON_MMUREGS));
- retval = retval & ~LEON_CNR_CTRL_TLBDIS;
- __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
- "i"(ASI_LEON_MMUREGS) : "memory");
-}
-
/* macro access for leon_load_reg() and leon_store_reg() */
#define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x)))
#define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v)))
-#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v)
-#define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v)
#define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x))
#define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v))
-#define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS)
-#define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v))
-#define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v))
-#define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v))
-
-/* macro access for leon_readnobuffer_reg() */
-#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
extern void leon_init(void);
extern void leon_switch_mm(void);
extern void leon_init_IRQ(void);
-extern unsigned long last_valid_pfn;
-
static inline unsigned long sparc_leon3_get_dcachecfg(void)
{
unsigned int retval;
@@ -268,9 +188,6 @@ static inline int sparc_leon3_cpuid(void)
#error cannot determine LEON_PAGE_SIZE_LEON
#endif
-#define PAGE_MIN_SHIFT (12)
-#define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT)
-
#define LEON3_XCCR_SETS_MASK 0x07000000UL
#define LEON3_XCCR_SSIZE_MASK 0x00f00000UL
@@ -278,18 +195,11 @@ static inline int sparc_leon3_cpuid(void)
#define LEON2_CFG_SSIZE_MASK 0x00007000UL
#ifndef __ASSEMBLY__
-extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
-extern void leon_flush_icache_all(void);
-extern void leon_flush_dcache_all(void);
-extern void leon_flush_cache_all(void);
-extern void leon_flush_tlb_all(void);
-extern int leon_flush_during_switch;
-extern int leon_flush_needed(void);
-
struct vm_area_struct;
+
+extern unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr);
extern void leon_flush_icache_all(void);
extern void leon_flush_dcache_all(void);
-extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
extern void leon_flush_cache_all(void);
extern void leon_flush_tlb_all(void);
extern int leon_flush_during_switch;
@@ -303,40 +213,23 @@ struct leon3_cacheregs {
unsigned long dccr; /* 0x0c - Data Cache Configuration Register */
};
-/* struct that hold LEON2 cache configuration register
- * & configuration register
- */
-struct leon2_cacheregs {
- unsigned long ccr, cfg;
-};
-
-#ifdef __KERNEL__
-
+#include <linux/irq.h>
#include <linux/interrupt.h>
struct device_node;
+struct task_struct;
extern unsigned int leon_build_device_irq(unsigned int real_irq,
irq_flow_handler_t flow_handler,
const char *name, int do_ack);
extern void leon_update_virq_handling(unsigned int virq,
irq_flow_handler_t flow_handler,
const char *name, int do_ack);
-extern void leon_clear_clock_irq(void);
-extern void leon_load_profile_irq(int cpu, unsigned int limit);
-extern void leon_init_timers(irq_handler_t counter_fn);
-extern void leon_clear_clock_irq(void);
-extern void leon_load_profile_irq(int cpu, unsigned int limit);
+extern void leon_init_timers(void);
extern void leon_trans_init(struct device_node *dp);
extern void leon_node_init(struct device_node *dp, struct device_node ***nextp);
-extern void leon_init_IRQ(void);
-extern void leon_init(void);
-extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
extern void init_leon(void);
extern void poke_leonsparc(void);
extern void leon3_getCacheRegs(struct leon3_cacheregs *regs);
-extern int leon_flush_needed(void);
-extern void leon_switch_mm(void);
-extern int srmmu_swprobe_trace;
extern int leon3_ticker_irq;
#ifdef CONFIG_SMP
@@ -344,26 +237,17 @@ 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);
+extern int leon_boot_one_cpu(int i, struct task_struct *);
void leon_init_smp(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 irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
-extern unsigned int real_irq_entry[];
extern unsigned int smpleon_ipi[];
-extern unsigned int patchme_maybe_smp_msg[];
-extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
-extern unsigned int linux_trap_ipi15_sun4m[];
+extern unsigned int linux_trap_ipi15_leon[];
extern int leon_ipi_irq;
#endif /* CONFIG_SMP */
-#endif /* __KERNEL__ */
-
#endif /* __ASSEMBLY__ */
/* macros used in leon_mm.c */
@@ -371,18 +255,4 @@ extern int leon_ipi_irq;
#define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base)))
#define _SRMMU_PTE_PMASK_LEON 0xffffffff
-#else /* defined(CONFIG_SPARC_LEON) */
-
-/* nop definitions for !LEON case */
-#define leon_init() do {} while (0)
-#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) */
-
#endif
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h
index e50f326e71b..f3034eddf46 100644
--- a/arch/sparc/include/asm/leon_amba.h
+++ b/arch/sparc/include/asm/leon_amba.h
@@ -87,8 +87,6 @@ struct amba_prom_registers {
#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7)
#define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0)
-#ifdef CONFIG_SPARC_LEON
-
#ifndef __ASSEMBLY__
struct leon3_irqctrl_regs_map {
@@ -264,6 +262,4 @@ extern unsigned int sparc_leon_eirq;
#define amba_device(x) (((x) >> 12) & 0xfff)
-#endif /* !defined(CONFIG_SPARC_LEON) */
-
#endif
diff --git a/arch/sparc/include/asm/machines.h b/arch/sparc/include/asm/machines.h
index cd9c099567e..fd6ddb05d1b 100644
--- a/arch/sparc/include/asm/machines.h
+++ b/arch/sparc/include/asm/machines.h
@@ -12,11 +12,6 @@ struct Sun_Machine_Models {
unsigned char id_machtype;
};
-/* Current number of machines we know about that has an IDPROM
- * machtype entry including one entry for the 0x80 OBP machines.
- */
-#define NUM_SUN_MACHINES 16
-
/* The machine type in the idprom area looks like this:
*
* ---------------
@@ -24,36 +19,20 @@ struct Sun_Machine_Models {
* ---------------
* 7 4 3 0
*
- * The ARCH field determines the architecture line (sun4, sun4c, etc).
+ * The ARCH field determines the architecture line (sun4m, etc).
* The MACH field determines the machine make within that architecture.
*/
#define SM_ARCH_MASK 0xf0
-#define SM_SUN4 0x20
#define M_LEON 0x30
-#define SM_SUN4C 0x50
#define SM_SUN4M 0x70
#define SM_SUN4M_OBP 0x80
#define SM_TYP_MASK 0x0f
-/* Sun4 machines */
-#define SM_4_260 0x01 /* Sun 4/200 series */
-#define SM_4_110 0x02 /* Sun 4/100 series */
-#define SM_4_330 0x03 /* Sun 4/300 series */
-#define SM_4_470 0x04 /* Sun 4/400 series */
/* Leon machines */
#define M_LEON3_SOC 0x02 /* Leon3 SoC */
-/* Sun4c machines Full Name - PROM NAME */
-#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */
-#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */
-#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */
-#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */
-#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */
-#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */
-#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */
-
/* Sun4m machines, these predate the OpenBoot. These values only mean
* something if the value in the ARCH field is SM_SUN4M, if it is
* SM_SUN4M_OBP then you have the following situation:
diff --git a/arch/sparc/include/asm/mbus.h b/arch/sparc/include/asm/mbus.h
index 69f07a022ee..14128bcc582 100644
--- a/arch/sparc/include/asm/mbus.h
+++ b/arch/sparc/include/asm/mbus.h
@@ -8,14 +8,10 @@
#define _SPARC_MBUS_H
#include <asm/ross.h> /* HyperSparc stuff */
-#include <asm/cypress.h> /* Cypress Chips */
#include <asm/viking.h> /* Ugh, bug city... */
enum mbus_module {
HyperSparc = 0,
- Cypress = 1,
- Cypress_vE = 2,
- Cypress_vD = 3,
Swift_ok = 4,
Swift_bad_c = 5,
Swift_lots_o_bugs = 6,
diff --git a/arch/sparc/include/asm/memreg.h b/arch/sparc/include/asm/memreg.h
deleted file mode 100644
index 845ad2b3918..00000000000
--- a/arch/sparc/include/asm/memreg.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _SPARC_MEMREG_H
-#define _SPARC_MEMREG_H
-/* memreg.h: Definitions of the values found in the synchronous
- * and asynchronous memory error registers when a fault
- * occurs on the sun4c.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-/* First the synchronous error codes, these are usually just
- * normal page faults.
- */
-
-#define SUN4C_SYNC_WDRESET 0x0001 /* watchdog reset */
-#define SUN4C_SYNC_SIZE 0x0002 /* bad access size? whuz this? */
-#define SUN4C_SYNC_PARITY 0x0008 /* bad ram chips caused a parity error */
-#define SUN4C_SYNC_SBUS 0x0010 /* the SBUS had some problems... */
-#define SUN4C_SYNC_NOMEM 0x0020 /* translation to non-existent ram */
-#define SUN4C_SYNC_PROT 0x0040 /* access violated pte protections */
-#define SUN4C_SYNC_NPRESENT 0x0080 /* pte said that page was not present */
-#define SUN4C_SYNC_BADWRITE 0x8000 /* while writing something went bogus */
-
-#define SUN4C_SYNC_BOLIXED \
- (SUN4C_SYNC_WDRESET | SUN4C_SYNC_SIZE | SUN4C_SYNC_SBUS | \
- SUN4C_SYNC_NOMEM | SUN4C_SYNC_PARITY)
-
-/* Now the asynchronous error codes, these are almost always produced
- * by the cache writing things back to memory and getting a bad translation.
- * Bad DVMA transactions can cause these faults too.
- */
-
-#define SUN4C_ASYNC_BADDVMA 0x0010 /* error during DVMA access */
-#define SUN4C_ASYNC_NOMEM 0x0020 /* write back pointed to bad phys addr */
-#define SUN4C_ASYNC_BADWB 0x0080 /* write back points to non-present page */
-
-/* Memory parity error register with associated bit constants. */
-#ifndef __ASSEMBLY__
-extern __volatile__ unsigned long __iomem *sun4c_memerr_reg;
-#endif
-
-#define SUN4C_MPE_ERROR 0x80 /* Parity error detected. (ro) */
-#define SUN4C_MPE_MULTI 0x40 /* Multiple parity errors detected. (ro) */
-#define SUN4C_MPE_TEST 0x20 /* Write inverse parity. (rw) */
-#define SUN4C_MPE_CHECK 0x10 /* Enable parity checking. (rw) */
-#define SUN4C_MPE_ERR00 0x08 /* Parity error in bits 0-7. (ro) */
-#define SUN4C_MPE_ERR08 0x04 /* Parity error in bits 8-15. (ro) */
-#define SUN4C_MPE_ERR16 0x02 /* Parity error in bits 16-23. (ro) */
-#define SUN4C_MPE_ERR24 0x01 /* Parity error in bits 24-31. (ro) */
-#define SUN4C_MPE_ERRS 0x0F /* Bit mask for the error bits. (ro) */
-
-#endif /* !(_SPARC_MEMREG_H) */
diff --git a/arch/sparc/include/asm/mmu_context_32.h b/arch/sparc/include/asm/mmu_context_32.h
index 671a997b9e6..01456c90072 100644
--- a/arch/sparc/include/asm/mmu_context_32.h
+++ b/arch/sparc/include/asm/mmu_context_32.h
@@ -1,8 +1,6 @@
#ifndef __SPARC_MMU_CONTEXT_H
#define __SPARC_MMU_CONTEXT_H
-#include <asm/btfixup.h>
-
#ifndef __ASSEMBLY__
#include <asm-generic/mm_hooks.h>
@@ -23,14 +21,11 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
* all the page tables have been flushed. Our job is to destroy
* any remaining processor-specific state.
*/
-BTFIXUPDEF_CALL(void, destroy_context, struct mm_struct *)
-
-#define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm)
+void destroy_context(struct mm_struct *mm);
/* Switch the current MM context. */
-BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct task_struct *)
-
-#define switch_mm(old_mm, mm, tsk) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk)
+void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
+ struct task_struct *tsk);
#define deactivate_mm(tsk,mm) do { } while (0)
diff --git a/arch/sparc/include/asm/mpmbox.h b/arch/sparc/include/asm/mpmbox.h
deleted file mode 100644
index f8423039b24..00000000000
--- a/arch/sparc/include/asm/mpmbox.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * mpmbox.h: Interface and defines for the OpenProm mailbox
- * facilities for MP machines under Linux.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_MPMBOX_H
-#define _SPARC_MPMBOX_H
-
-/* The prom allocates, for each CPU on the machine an unsigned
- * byte in physical ram. You probe the device tree prom nodes
- * for these values. The purpose of this byte is to be able to
- * pass messages from one cpu to another.
- */
-
-/* These are the main message types we have to look for in our
- * Cpu mailboxes, based upon these values we decide what course
- * of action to take.
- */
-
-/* The CPU is executing code in the kernel. */
-#define MAILBOX_ISRUNNING 0xf0
-
-/* Another CPU called romvec->pv_exit(), you should call
- * prom_stopcpu() when you see this in your mailbox.
- */
-#define MAILBOX_EXIT 0xfb
-
-/* Another CPU called romvec->pv_enter(), you should call
- * prom_cpuidle() when this is seen.
- */
-#define MAILBOX_GOSPIN 0xfc
-
-/* Another CPU has hit a breakpoint either into kadb or the prom
- * itself. Just like MAILBOX_GOSPIN, you should call prom_cpuidle()
- * at this point.
- */
-#define MAILBOX_BPT_SPIN 0xfd
-
-/* Oh geese, some other nitwit got a damn watchdog reset. The party's
- * over so go call prom_stopcpu().
- */
-#define MAILBOX_WDOG_STOP 0xfe
-
-#ifndef __ASSEMBLY__
-
-/* Handy macro's to determine a cpu's state. */
-
-/* Is the cpu still in Power On Self Test? */
-#define MBOX_POST_P(letter) ((letter) >= 0x00 && (letter) <= 0x7f)
-
-/* Is the cpu at the 'ok' prompt of the PROM? */
-#define MBOX_PROMPROMPT_P(letter) ((letter) >= 0x80 && (letter) <= 0x8f)
-
-/* Is the cpu spinning in the PROM? */
-#define MBOX_PROMSPIN_P(letter) ((letter) >= 0x90 && (letter) <= 0xef)
-
-/* Sanity check... This is junk mail, throw it out. */
-#define MBOX_BOGON_P(letter) ((letter) >= 0xf1 && (letter) <= 0xfa)
-
-/* Is the cpu actively running an application/kernel-code? */
-#define MBOX_RUNNING_P(letter) ((letter) == MAILBOX_ISRUNNING)
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(_SPARC_MPMBOX_H) */
diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h
index 4ade0c8a2c7..910c1d9af1f 100644
--- a/arch/sparc/include/asm/obio.h
+++ b/arch/sparc/include/asm/obio.h
@@ -220,19 +220,6 @@ static inline void cc_set_igen(unsigned gen)
"i" (ASI_M_MXCC));
}
-/* +-------+-------------+-----------+------------------------------------+
- * | bcast | devid | sid | levels mask |
- * +-------+-------------+-----------+------------------------------------+
- * 31 30 23 22 15 14 0
- */
-#define IGEN_MESSAGE(bcast, devid, sid, levels) \
- (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels))
-
-static inline void sun4d_send_ipi(int cpu, int level)
-{
- cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1)));
-}
-
#endif /* !__ASSEMBLY__ */
#endif /* !(_SPARC_OBIO_H) */
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index 71e5e9aeb67..27517879a6c 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -105,14 +105,6 @@ extern void prom_write(const char *buf, unsigned int len);
extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
int context, char *program_counter);
-/* Sun4/sun4c specific memory-management startup hook. */
-
-/* Map the passed segment in the given context at the passed
- * virtual address.
- */
-extern void prom_putsegment(int context, unsigned long virt_addr,
- int physical_segment);
-
/* Initialize the memory lists based upon the prom version. */
void prom_meminit(void);
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index bb5c2ac4055..fab78a308eb 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -14,8 +14,6 @@
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-#include <asm/btfixup.h>
-
#ifndef __ASSEMBLY__
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
@@ -45,12 +43,6 @@ struct sparc_phys_banks {
extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
-/* Cache alias structure. Entry is valid if context != -1. */
-struct cache_palias {
- unsigned long vaddr;
- int context;
-};
-
/* passing structs on the Sparc slow us down tremendously... */
/* #define STRICT_MM_TYPECHECKS */
@@ -116,10 +108,7 @@ typedef unsigned long iopgprot_t;
typedef struct page *pgtable_t;
extern unsigned long sparc_unmapped_base;
-
-BTFIXUPDEF_SETHI(sparc_unmapped_base)
-
-#define TASK_UNMAPPED_BASE BTFIXUP_SETHI(sparc_unmapped_base)
+#define TASK_UNMAPPED_BASE sparc_unmapped_base
#else /* !(__ASSEMBLY__) */
diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h
index ca2b34456c4..e5b169b46d2 100644
--- a/arch/sparc/include/asm/pgalloc_32.h
+++ b/arch/sparc/include/asm/pgalloc_32.h
@@ -4,8 +4,10 @@
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <asm/pgtsrmmu.h>
+#include <asm/pgtable.h>
+#include <asm/vaddrs.h>
#include <asm/page.h>
-#include <asm/btfixup.h>
struct page;
@@ -15,54 +17,74 @@ extern struct pgtable_cache_struct {
unsigned long pgtable_cache_sz;
unsigned long pgd_cache_sz;
} pgt_quicklists;
+
+unsigned long srmmu_get_nocache(int size, int align);
+void srmmu_free_nocache(unsigned long vaddr, int size);
+
#define pgd_quicklist (pgt_quicklists.pgd_cache)
#define pmd_quicklist ((unsigned long *)0)
#define pte_quicklist (pgt_quicklists.pte_cache)
#define pgtable_cache_size (pgt_quicklists.pgtable_cache_sz)
#define pgd_cache_size (pgt_quicklists.pgd_cache_sz)
-extern void check_pgt_cache(void);
-BTFIXUPDEF_CALL(void, do_check_pgt_cache, int, int)
-#define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high)
-
-BTFIXUPDEF_CALL(pgd_t *, get_pgd_fast, void)
-#define get_pgd_fast() BTFIXUP_CALL(get_pgd_fast)()
+#define check_pgt_cache() do { } while (0)
-BTFIXUPDEF_CALL(void, free_pgd_fast, pgd_t *)
-#define free_pgd_fast(pgd) BTFIXUP_CALL(free_pgd_fast)(pgd)
+pgd_t *get_pgd_fast(void);
+static inline void free_pgd_fast(pgd_t *pgd)
+{
+ srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE);
+}
#define pgd_free(mm, pgd) free_pgd_fast(pgd)
#define pgd_alloc(mm) get_pgd_fast()
-BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *)
-#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
+static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+{
+ unsigned long pa = __nocache_pa((unsigned long)pmdp);
+
+ set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (pa >> 4)));
+}
+
#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD)
-BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long)
-#define pmd_alloc_one(mm, address) BTFIXUP_CALL(pmd_alloc_one)(mm, address)
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+{
+ return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
+ SRMMU_PMD_TABLE_SIZE);
+}
-BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *)
-#define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd)
+static inline void free_pmd_fast(pmd_t * pmd)
+{
+ srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE);
+}
#define pmd_free(mm, pmd) free_pmd_fast(pmd)
#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
-BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *)
-#define pmd_populate(MM, PMD, PTE) BTFIXUP_CALL(pmd_populate)(PMD, PTE)
+void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep);
#define pmd_pgtable(pmd) pmd_page(pmd)
-BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *)
-#define pmd_populate_kernel(MM, PMD, PTE) BTFIXUP_CALL(pmd_set)(PMD, PTE)
-BTFIXUPDEF_CALL(pgtable_t , pte_alloc_one, struct mm_struct *, unsigned long)
-#define pte_alloc_one(mm, address) BTFIXUP_CALL(pte_alloc_one)(mm, address)
-BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_kernel, struct mm_struct *, unsigned long)
-#define pte_alloc_one_kernel(mm, addr) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr)
+void pmd_set(pmd_t *pmdp, pte_t *ptep);
+#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE)
+
+pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address);
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
+{
+ return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
+}
+
+
+static inline void free_pte_fast(pte_t *pte)
+{
+ srmmu_free_nocache((unsigned long)pte, PTE_SIZE);
+}
-BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *)
-#define pte_free_kernel(mm, pte) BTFIXUP_CALL(free_pte_fast)(pte)
+#define pte_free_kernel(mm, pte) free_pte_fast(pte)
-BTFIXUPDEF_CALL(void, pte_free, pgtable_t )
-#define pte_free(mm, pte) BTFIXUP_CALL(pte_free)(pte)
+void pte_free(struct mm_struct * mm, pgtable_t pte);
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
#endif /* _SPARC_PGALLOC_H */
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 3d7101860e6..cbbbed5cb3a 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -16,11 +16,9 @@
#include <linux/spinlock.h>
#include <linux/swap.h>
#include <asm/types.h>
-#include <asm/pgtsun4c.h>
#include <asm/pgtsrmmu.h>
-#include <asm/vac-ops.h>
+#include <asm/vaddrs.h>
#include <asm/oplib.h>
-#include <asm/btfixup.h>
#include <asm/cpu_type.h>
@@ -30,87 +28,55 @@ struct page;
extern void load_mmu(void);
extern unsigned long calc_highpages(void);
-BTFIXUPDEF_SIMM13(pgdir_shift)
-BTFIXUPDEF_SETHI(pgdir_size)
-BTFIXUPDEF_SETHI(pgdir_mask)
-
-BTFIXUPDEF_SIMM13(ptrs_per_pmd)
-BTFIXUPDEF_SIMM13(ptrs_per_pgd)
-BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
-
#define pte_ERROR(e) __builtin_trap()
#define pmd_ERROR(e) __builtin_trap()
#define pgd_ERROR(e) __builtin_trap()
-BTFIXUPDEF_INT(page_none)
-BTFIXUPDEF_INT(page_copy)
-BTFIXUPDEF_INT(page_readonly)
-BTFIXUPDEF_INT(page_kernel)
-
-#define PMD_SHIFT SUN4C_PMD_SHIFT
+#define PMD_SHIFT 22
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
#define PMD_ALIGN(__addr) (((__addr) + ~PMD_MASK) & PMD_MASK)
-#define PGDIR_SHIFT BTFIXUP_SIMM13(pgdir_shift)
-#define PGDIR_SIZE BTFIXUP_SETHI(pgdir_size)
-#define PGDIR_MASK BTFIXUP_SETHI(pgdir_mask)
+#define PGDIR_SHIFT SRMMU_PGDIR_SHIFT
+#define PGDIR_SIZE SRMMU_PGDIR_SIZE
+#define PGDIR_MASK SRMMU_PGDIR_MASK
#define PTRS_PER_PTE 1024
-#define PTRS_PER_PMD BTFIXUP_SIMM13(ptrs_per_pmd)
-#define PTRS_PER_PGD BTFIXUP_SIMM13(ptrs_per_pgd)
-#define USER_PTRS_PER_PGD BTFIXUP_SIMM13(user_ptrs_per_pgd)
+#define PTRS_PER_PMD SRMMU_PTRS_PER_PMD
+#define PTRS_PER_PGD SRMMU_PTRS_PER_PGD
+#define USER_PTRS_PER_PGD PAGE_OFFSET / SRMMU_PGDIR_SIZE
#define FIRST_USER_ADDRESS 0
#define PTE_SIZE (PTRS_PER_PTE*4)
-#define PAGE_NONE __pgprot(BTFIXUP_INT(page_none))
-extern pgprot_t PAGE_SHARED;
-#define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
-#define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
-
-extern unsigned long page_kernel;
-
-#ifdef MODULE
-#define PAGE_KERNEL page_kernel
-#else
-#define PAGE_KERNEL __pgprot(BTFIXUP_INT(page_kernel))
-#endif
+#define PAGE_NONE SRMMU_PAGE_NONE
+#define PAGE_SHARED SRMMU_PAGE_SHARED
+#define PAGE_COPY SRMMU_PAGE_COPY
+#define PAGE_READONLY SRMMU_PAGE_RDONLY
+#define PAGE_KERNEL SRMMU_PAGE_KERNEL
/* Top-level page directory */
extern pgd_t swapper_pg_dir[1024];
extern void paging_init(void);
-/* Page table for 0-4MB for everybody, on the Sparc this
- * holds the same as on the i386.
- */
-extern pte_t pg0[1024];
-extern pte_t pg1[1024];
-extern pte_t pg2[1024];
-extern pte_t pg3[1024];
-
extern unsigned long ptr_in_current_pgd;
-/* Here is a trick, since mmap.c need the initializer elements for
- * protection_map[] to be constant at compile time, I set the following
- * to all zeros. I set it to the real values after I link in the
- * appropriate MMU page table routines at boot time.
- */
-#define __P000 __pgprot(0)
-#define __P001 __pgprot(0)
-#define __P010 __pgprot(0)
-#define __P011 __pgprot(0)
-#define __P100 __pgprot(0)
-#define __P101 __pgprot(0)
-#define __P110 __pgprot(0)
-#define __P111 __pgprot(0)
-
-#define __S000 __pgprot(0)
-#define __S001 __pgprot(0)
-#define __S010 __pgprot(0)
-#define __S011 __pgprot(0)
-#define __S100 __pgprot(0)
-#define __S101 __pgprot(0)
-#define __S110 __pgprot(0)
-#define __S111 __pgprot(0)
+/* xwr */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY
+#define __P101 PAGE_READONLY
+#define __P110 PAGE_COPY
+#define __P111 PAGE_COPY
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY
+#define __S101 PAGE_READONLY
+#define __S110 PAGE_SHARED
+#define __S111 PAGE_SHARED
extern int num_contexts;
@@ -137,82 +103,137 @@ extern unsigned long empty_zero_page;
#define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
/*
+ * In general all page table modifications should use the V8 atomic
+ * swap instruction. This insures the mmu and the cpu are in sync
+ * with respect to ref/mod bits in the page tables.
+ */
+static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value)
+{
+ __asm__ __volatile__("swap [%2], %0" : "=&r" (value) : "0" (value), "r" (addr));
+ return value;
+}
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified. Thus, the following
+ * hook is made available.
*/
-BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t)
-BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t)
-#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
-#define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd)
+static inline void set_pte(pte_t *ptep, pte_t pteval)
+{
+ srmmu_swap((unsigned long *)ptep, pte_val(pteval));
+}
+
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+static inline int srmmu_device_memory(unsigned long x)
+{
+ return ((x & 0xF0000000) != 0);
+}
+
+static inline struct page *pmd_page(pmd_t pmd)
+{
+ if (srmmu_device_memory(pmd_val(pmd)))
+ BUG();
+ return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4));
+}
+
+static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+{
+ if (srmmu_device_memory(pgd_val(pgd))) {
+ return ~0;
+ } else {
+ unsigned long v = pgd_val(pgd) & SRMMU_PTD_PMASK;
+ return (unsigned long)__nocache_va(v << 4);
+ }
+}
-BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
-BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
+static inline int pte_present(pte_t pte)
+{
+ return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE);
+}
static inline int pte_none(pte_t pte)
{
return !pte_val(pte);
}
-#define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
-#define pte_clear(mm,addr,pte) BTFIXUP_CALL(pte_clear)(pte)
+static inline void __pte_clear(pte_t *ptep)
+{
+ set_pte(ptep, __pte(0));
+}
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ __pte_clear(ptep);
+}
+
+static inline int pmd_bad(pmd_t pmd)
+{
+ return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
+}
-BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t)
-BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t)
-BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
+static inline int pmd_present(pmd_t pmd)
+{
+ return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
+}
static inline int pmd_none(pmd_t pmd)
{
return !pmd_val(pmd);
}
-#define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
-#define pmd_present(pmd) BTFIXUP_CALL(pmd_present)(pmd)
-#define pmd_clear(pmd) BTFIXUP_CALL(pmd_clear)(pmd)
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ int i;
+ for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++)
+ set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
+}
-BTFIXUPDEF_CALL_CONST(int, pgd_none, pgd_t)
-BTFIXUPDEF_CALL_CONST(int, pgd_bad, pgd_t)
-BTFIXUPDEF_CALL_CONST(int, pgd_present, pgd_t)
-BTFIXUPDEF_CALL(void, pgd_clear, pgd_t *)
+static inline int pgd_none(pgd_t pgd)
+{
+ return !(pgd_val(pgd) & 0xFFFFFFF);
+}
-#define pgd_none(pgd) BTFIXUP_CALL(pgd_none)(pgd)
-#define pgd_bad(pgd) BTFIXUP_CALL(pgd_bad)(pgd)
-#define pgd_present(pgd) BTFIXUP_CALL(pgd_present)(pgd)
-#define pgd_clear(pgd) BTFIXUP_CALL(pgd_clear)(pgd)
+static inline int pgd_bad(pgd_t pgd)
+{
+ return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
+}
+
+static inline int pgd_present(pgd_t pgd)
+{
+ return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
+}
+
+static inline void pgd_clear(pgd_t *pgdp)
+{
+ set_pte((pte_t *)pgdp, __pte(0));
+}
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
-BTFIXUPDEF_HALF(pte_writei)
-BTFIXUPDEF_HALF(pte_dirtyi)
-BTFIXUPDEF_HALF(pte_youngi)
-
-static int pte_write(pte_t pte) __attribute_const__;
static inline int pte_write(pte_t pte)
{
- return pte_val(pte) & BTFIXUP_HALF(pte_writei);
+ return pte_val(pte) & SRMMU_WRITE;
}
-static int pte_dirty(pte_t pte) __attribute_const__;
static inline int pte_dirty(pte_t pte)
{
- return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi);
+ return pte_val(pte) & SRMMU_DIRTY;
}
-static int pte_young(pte_t pte) __attribute_const__;
static inline int pte_young(pte_t pte)
{
- return pte_val(pte) & BTFIXUP_HALF(pte_youngi);
+ return pte_val(pte) & SRMMU_REF;
}
/*
* The following only work if pte_present() is not true.
*/
-BTFIXUPDEF_HALF(pte_filei)
-
-static int pte_file(pte_t pte) __attribute_const__;
static inline int pte_file(pte_t pte)
{
- return pte_val(pte) & BTFIXUP_HALF(pte_filei);
+ return pte_val(pte) & SRMMU_FILE;
}
static inline int pte_special(pte_t pte)
@@ -220,68 +241,85 @@ static inline int pte_special(pte_t pte)
return 0;
}
-/*
- */
-BTFIXUPDEF_HALF(pte_wrprotecti)
-BTFIXUPDEF_HALF(pte_mkcleani)
-BTFIXUPDEF_HALF(pte_mkoldi)
-
-static pte_t pte_wrprotect(pte_t pte) __attribute_const__;
static inline pte_t pte_wrprotect(pte_t pte)
{
- return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti));
+ return __pte(pte_val(pte) & ~SRMMU_WRITE);
}
-static pte_t pte_mkclean(pte_t pte) __attribute_const__;
static inline pte_t pte_mkclean(pte_t pte)
{
- return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani));
+ return __pte(pte_val(pte) & ~SRMMU_DIRTY);
}
-static pte_t pte_mkold(pte_t pte) __attribute_const__;
static inline pte_t pte_mkold(pte_t pte)
{
- return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi));
+ return __pte(pte_val(pte) & ~SRMMU_REF);
}
-BTFIXUPDEF_CALL_CONST(pte_t, pte_mkwrite, pte_t)
-BTFIXUPDEF_CALL_CONST(pte_t, pte_mkdirty, pte_t)
-BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ return __pte(pte_val(pte) | SRMMU_WRITE);
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | SRMMU_DIRTY);
+}
-#define pte_mkwrite(pte) BTFIXUP_CALL(pte_mkwrite)(pte)
-#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
-#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ return __pte(pte_val(pte) | SRMMU_REF);
+}
#define pte_mkspecial(pte) (pte)
#define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot)
-BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t)
-#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte)
+static inline unsigned long pte_pfn(pte_t pte)
+{
+ if (srmmu_device_memory(pte_val(pte))) {
+ /* Just return something that will cause
+ * pfn_valid() to return false. This makes
+ * copy_one_pte() to just directly copy to
+ * PTE over.
+ */
+ return ~0UL;
+ }
+ return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4);
+}
+
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t)
-
-BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t)
-BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
-BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t)
+static inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
+{
+ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot));
+}
-#define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot)
-#define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot)
-#define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space)
+static inline pte_t mk_pte_phys(unsigned long page, pgprot_t pgprot)
+{
+ return __pte(((page) >> 4) | pgprot_val(pgprot));
+}
-#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot)
+static inline pte_t mk_pte_io(unsigned long page, pgprot_t pgprot, int space)
+{
+ return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot));
+}
-BTFIXUPDEF_INT(pte_modify_mask)
+#define pgprot_noncached pgprot_noncached
+static inline pgprot_t pgprot_noncached(pgprot_t prot)
+{
+ prot &= ~__pgprot(SRMMU_CACHE);
+ return prot;
+}
static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) |
+ return __pte((pte_val(pte) & SRMMU_CHG_MASK) |
pgprot_val(newprot));
}
@@ -294,74 +332,69 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
/* Find an entry in the second-level page table.. */
-BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
-#define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
+static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
+{
+ return (pmd_t *) pgd_page_vaddr(*dir) +
+ ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
+}
/* Find an entry in the third-level page table.. */
-BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
-#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr)
+pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address);
/*
- * This shortcut works on sun4m (and sun4d) because the nocache area is static,
- * and sun4c is guaranteed to have no highmem anyway.
+ * This shortcut works on sun4m (and sun4d) because the nocache area is static.
*/
#define pte_offset_map(d, a) pte_offset_kernel(d,a)
#define pte_unmap(pte) do{}while(0)
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified. Thus, the following
- * hook is made available.
- */
-
-BTFIXUPDEF_CALL(void, set_pte, pte_t *, pte_t)
-
-#define set_pte(ptep,pteval) BTFIXUP_CALL(set_pte)(ptep,pteval)
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-
struct seq_file;
-BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *)
-
-#define mmu_info(p) BTFIXUP_CALL(mmu_info)(p)
+void mmu_info(struct seq_file *m);
/* Fault handler stuff... */
#define FAULT_CODE_PROT 0x1
#define FAULT_CODE_WRITE 0x2
#define FAULT_CODE_USER 0x4
-BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t *)
-
-#define update_mmu_cache(vma,addr,ptep) BTFIXUP_CALL(update_mmu_cache)(vma,addr,ptep)
-
-BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long,
- unsigned long, unsigned int)
-BTFIXUPDEF_CALL(void, sparc_unmapiorange, unsigned long, unsigned int)
-#define sparc_mapiorange(bus,pa,va,len) BTFIXUP_CALL(sparc_mapiorange)(bus,pa,va,len)
-#define sparc_unmapiorange(va,len) BTFIXUP_CALL(sparc_unmapiorange)(va,len)
+#define update_mmu_cache(vma, address, ptep) do { } while (0)
-extern int invalid_segment;
+void srmmu_mapiorange(unsigned int bus, unsigned long xpa,
+ unsigned long xva, unsigned int len);
+void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len);
/* Encode and de-code a swap entry */
-BTFIXUPDEF_CALL(unsigned long, __swp_type, swp_entry_t)
-BTFIXUPDEF_CALL(unsigned long, __swp_offset, swp_entry_t)
-BTFIXUPDEF_CALL(swp_entry_t, __swp_entry, unsigned long, unsigned long)
+static inline unsigned long __swp_type(swp_entry_t entry)
+{
+ return (entry.val >> SRMMU_SWP_TYPE_SHIFT) & SRMMU_SWP_TYPE_MASK;
+}
+
+static inline unsigned long __swp_offset(swp_entry_t entry)
+{
+ return (entry.val >> SRMMU_SWP_OFF_SHIFT) & SRMMU_SWP_OFF_MASK;
+}
-#define __swp_type(__x) BTFIXUP_CALL(__swp_type)(__x)
-#define __swp_offset(__x) BTFIXUP_CALL(__swp_offset)(__x)
-#define __swp_entry(__type,__off) BTFIXUP_CALL(__swp_entry)(__type,__off)
+static inline swp_entry_t __swp_entry(unsigned long type, unsigned long offset)
+{
+ return (swp_entry_t) {
+ (type & SRMMU_SWP_TYPE_MASK) << SRMMU_SWP_TYPE_SHIFT
+ | (offset & SRMMU_SWP_OFF_MASK) << SRMMU_SWP_OFF_SHIFT };
+}
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
/* file-offset-in-pte helpers */
-BTFIXUPDEF_CALL(unsigned long, pte_to_pgoff, pte_t pte);
-BTFIXUPDEF_CALL(pte_t, pgoff_to_pte, unsigned long pgoff);
+static inline unsigned long pte_to_pgoff(pte_t pte)
+{
+ return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT;
+}
-#define pte_to_pgoff(pte) BTFIXUP_CALL(pte_to_pgoff)(pte)
-#define pgoff_to_pte(off) BTFIXUP_CALL(pgoff_to_pte)(off)
+static inline pte_t pgoff_to_pte(unsigned long pgoff)
+{
+ return __pte((pgoff << SRMMU_PTE_FILE_SHIFT) | SRMMU_FILE);
+}
/*
* This is made a constant because mm/fremap.c required a constant.
- * Note that layout of these bits is different between sun4c.c and srmmu.c.
*/
#define PTE_FILE_MAX_BITS 24
@@ -399,9 +432,6 @@ static inline unsigned long
__get_phys (unsigned long addr)
{
switch (sparc_cpu_model){
- case sun4:
- case sun4c:
- return sun4c_get_pte (addr) << PAGE_SHIFT;
case sun4m:
case sun4d:
return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
@@ -414,9 +444,6 @@ static inline int
__get_iospace (unsigned long addr)
{
switch (sparc_cpu_model){
- case sun4:
- case sun4c:
- return -1; /* Don't check iospace on sun4c */
case sun4m:
case sun4d:
return (srmmu_get_pte (addr) >> 28);
@@ -463,7 +490,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
flush_tlb_page(__vma, __address); \
} \
- (sparc_cpu_model == sun4c) || __changed; \
+ __changed; \
})
#include <asm-generic/pgtable.h>
@@ -471,10 +498,8 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
#endif /* !(__ASSEMBLY__) */
#define VMALLOC_START _AC(0xfe600000,UL)
-/* XXX Alter this when I get around to fixing sun4c - Anton */
#define VMALLOC_END _AC(0xffc00000,UL)
-
/* We provide our own get_unmapped_area to cope with VA holes for userland */
#define HAVE_ARCH_UNMAPPED_AREA
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 76e4a52aa85..61210db139f 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -717,10 +717,6 @@ extern unsigned long find_ecache_flush_span(unsigned long size);
struct seq_file;
extern void mmu_info(struct seq_file *);
-/* These do nothing with the way I have things setup. */
-#define mmu_lockarea(vaddr, len) (vaddr)
-#define mmu_unlockarea(vaddr, len) do { } while(0)
-
struct vm_area_struct;
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h
index f6ae2b2b687..79da17866fa 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -139,6 +139,7 @@
restore %g0, %g0, %g0;
#ifndef __ASSEMBLY__
+extern unsigned long last_valid_pfn;
/* This makes sense. Honest it does - Anton */
/* XXX Yes but it's ugly as sin. FIXME. -KMW */
@@ -148,78 +149,13 @@ extern void *srmmu_nocache_pool;
#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
/* Accessing the MMU control register. */
-static inline unsigned int srmmu_get_mmureg(void)
-{
- unsigned int retval;
- __asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
- "=r" (retval) :
- "i" (ASI_M_MMUREGS));
- return retval;
-}
-
-static inline void srmmu_set_mmureg(unsigned long regval)
-{
- __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
- "r" (regval), "i" (ASI_M_MMUREGS) : "memory");
-
-}
-
-static inline void srmmu_set_ctable_ptr(unsigned long paddr)
-{
- paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
- __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
- "r" (paddr), "r" (SRMMU_CTXTBL_PTR),
- "i" (ASI_M_MMUREGS) :
- "memory");
-}
-
-static inline unsigned long srmmu_get_ctable_ptr(void)
-{
- unsigned int retval;
-
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (retval) :
- "r" (SRMMU_CTXTBL_PTR),
- "i" (ASI_M_MMUREGS));
- return (retval & SRMMU_CTX_PMASK) << 4;
-}
-
-static inline void srmmu_set_context(int context)
-{
- __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
- "r" (context), "r" (SRMMU_CTX_REG),
- "i" (ASI_M_MMUREGS) : "memory");
-}
-
-static inline int srmmu_get_context(void)
-{
- register int retval;
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (retval) :
- "r" (SRMMU_CTX_REG),
- "i" (ASI_M_MMUREGS));
- return retval;
-}
-
-static inline unsigned int srmmu_get_fstatus(void)
-{
- unsigned int retval;
-
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (retval) :
- "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS));
- return retval;
-}
-
-static inline unsigned int srmmu_get_faddr(void)
-{
- unsigned int retval;
-
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (retval) :
- "r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS));
- return retval;
-}
+unsigned int srmmu_get_mmureg(void);
+void srmmu_set_mmureg(unsigned long regval);
+void srmmu_set_ctable_ptr(unsigned long paddr);
+void srmmu_set_context(int context);
+int srmmu_get_context(void);
+unsigned int srmmu_get_fstatus(void);
+unsigned int srmmu_get_faddr(void);
/* This is guaranteed on all SRMMU's. */
static inline void srmmu_flush_whole_tlb(void)
@@ -230,59 +166,6 @@ static inline void srmmu_flush_whole_tlb(void)
}
-/* These flush types are not available on all chips... */
-static inline void srmmu_flush_tlb_ctx(void)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
- "r" (0x300), /* Flush TLB ctx.. */
- "i" (ASI_M_FLUSH_PROBE) : "memory");
-
-}
-
-static inline void srmmu_flush_tlb_region(unsigned long addr)
-{
- addr &= SRMMU_PGDIR_MASK;
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
- "r" (addr | 0x200), /* Flush TLB region.. */
- "i" (ASI_M_FLUSH_PROBE) : "memory");
-
-}
-
-
-static inline void srmmu_flush_tlb_segment(unsigned long addr)
-{
- addr &= SRMMU_REAL_PMD_MASK;
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
- "r" (addr | 0x100), /* Flush TLB segment.. */
- "i" (ASI_M_FLUSH_PROBE) : "memory");
-
-}
-
-static inline void srmmu_flush_tlb_page(unsigned long page)
-{
- page &= PAGE_MASK;
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
- "r" (page), /* Flush TLB page.. */
- "i" (ASI_M_FLUSH_PROBE) : "memory");
-
-}
-
-#ifndef CONFIG_SPARC_LEON
-static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
-{
- unsigned long retval;
-
- vaddr &= PAGE_MASK;
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (retval) :
- "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
-
- return retval;
-}
-#else
-#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0)
-#endif
-
static inline int
srmmu_get_pte (unsigned long addr)
{
@@ -294,9 +177,6 @@ srmmu_get_pte (unsigned long addr)
return entry;
}
-extern unsigned long (*srmmu_read_physical)(unsigned long paddr);
-extern void (*srmmu_write_physical)(unsigned long paddr, unsigned long word);
-
#endif /* !(__ASSEMBLY__) */
#endif /* !(_SPARC_PGTSRMMU_H) */
diff --git a/arch/sparc/include/asm/pgtsun4c.h b/arch/sparc/include/asm/pgtsun4c.h
deleted file mode 100644
index aeb25e91217..00000000000
--- a/arch/sparc/include/asm/pgtsun4c.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * pgtsun4c.h: Sun4c specific pgtable.h defines and code.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#ifndef _SPARC_PGTSUN4C_H
-#define _SPARC_PGTSUN4C_H
-
-#include <asm/contregs.h>
-
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
-#define SUN4C_PMD_SHIFT 22
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define SUN4C_PGDIR_SHIFT 22
-#define SUN4C_PGDIR_SIZE (1UL << SUN4C_PGDIR_SHIFT)
-#define SUN4C_PGDIR_MASK (~(SUN4C_PGDIR_SIZE-1))
-#define SUN4C_PGDIR_ALIGN(addr) (((addr)+SUN4C_PGDIR_SIZE-1)&SUN4C_PGDIR_MASK)
-
-/* To represent how the sun4c mmu really lays things out. */
-#define SUN4C_REAL_PGDIR_SHIFT 18
-#define SUN4C_REAL_PGDIR_SIZE (1UL << SUN4C_REAL_PGDIR_SHIFT)
-#define SUN4C_REAL_PGDIR_MASK (~(SUN4C_REAL_PGDIR_SIZE-1))
-#define SUN4C_REAL_PGDIR_ALIGN(addr) (((addr)+SUN4C_REAL_PGDIR_SIZE-1)&SUN4C_REAL_PGDIR_MASK)
-
-/* 16 bit PFN on sun4c */
-#define SUN4C_PFN_MASK 0xffff
-
-/* Don't increase these unless the structures in sun4c.c are fixed */
-#define SUN4C_MAX_SEGMAPS 256
-#define SUN4C_MAX_CONTEXTS 16
-
-/*
- * To be efficient, and not have to worry about allocating such
- * a huge pgd, we make the kernel sun4c tables each hold 1024
- * entries and the pgd similarly just like the i386 tables.
- */
-#define SUN4C_PTRS_PER_PTE 1024
-#define SUN4C_PTRS_PER_PMD 1
-#define SUN4C_PTRS_PER_PGD 1024
-
-/*
- * Sparc SUN4C pte fields.
- */
-#define _SUN4C_PAGE_VALID 0x80000000
-#define _SUN4C_PAGE_SILENT_READ 0x80000000 /* synonym */
-#define _SUN4C_PAGE_DIRTY 0x40000000
-#define _SUN4C_PAGE_SILENT_WRITE 0x40000000 /* synonym */
-#define _SUN4C_PAGE_PRIV 0x20000000 /* privileged page */
-#define _SUN4C_PAGE_NOCACHE 0x10000000 /* non-cacheable page */
-#define _SUN4C_PAGE_PRESENT 0x08000000 /* implemented in software */
-#define _SUN4C_PAGE_IO 0x04000000 /* I/O page */
-#define _SUN4C_PAGE_FILE 0x02000000 /* implemented in software */
-#define _SUN4C_PAGE_READ 0x00800000 /* implemented in software */
-#define _SUN4C_PAGE_WRITE 0x00400000 /* implemented in software */
-#define _SUN4C_PAGE_ACCESSED 0x00200000 /* implemented in software */
-#define _SUN4C_PAGE_MODIFIED 0x00100000 /* implemented in software */
-
-#define _SUN4C_READABLE (_SUN4C_PAGE_READ|_SUN4C_PAGE_SILENT_READ|\
- _SUN4C_PAGE_ACCESSED)
-#define _SUN4C_WRITEABLE (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE|\
- _SUN4C_PAGE_MODIFIED)
-
-#define _SUN4C_PAGE_CHG_MASK (0xffff|_SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_MODIFIED)
-
-#define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_PRESENT)
-#define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE|\
- _SUN4C_PAGE_WRITE)
-#define SUN4C_PAGE_COPY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE)
-#define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE)
-#define SUN4C_PAGE_KERNEL __pgprot(_SUN4C_READABLE|_SUN4C_WRITEABLE|\
- _SUN4C_PAGE_DIRTY|_SUN4C_PAGE_PRIV)
-
-/* SUN4C swap entry encoding
- *
- * We use 5 bits for the type and 19 for the offset. This gives us
- * 32 swapfiles of 4GB each. Encoding looks like:
- *
- * RRRRRRRRooooooooooooooooooottttt
- * fedcba9876543210fedcba9876543210
- *
- * The top 8 bits are reserved for protection and status bits, especially
- * FILE and PRESENT.
- */
-#define SUN4C_SWP_TYPE_MASK 0x1f
-#define SUN4C_SWP_OFF_MASK 0x7ffff
-#define SUN4C_SWP_OFF_SHIFT 5
-
-#ifndef __ASSEMBLY__
-
-static inline unsigned long sun4c_get_synchronous_error(void)
-{
- unsigned long sync_err;
-
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (sync_err) :
- "r" (AC_SYNC_ERR), "i" (ASI_CONTROL));
- return sync_err;
-}
-
-static inline unsigned long sun4c_get_synchronous_address(void)
-{
- unsigned long sync_addr;
-
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (sync_addr) :
- "r" (AC_SYNC_VA), "i" (ASI_CONTROL));
- return sync_addr;
-}
-
-/* SUN4C pte, segmap, and context manipulation */
-static inline unsigned long sun4c_get_segmap(unsigned long addr)
-{
- register unsigned long entry;
-
- __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
- "=r" (entry) :
- "r" (addr), "i" (ASI_SEGMAP));
-
- return entry;
-}
-
-static inline void sun4c_put_segmap(unsigned long addr, unsigned long entry)
-{
-
- __asm__ __volatile__("\n\tstba %1, [%0] %2; nop; nop; nop;\n\t" : :
- "r" (addr), "r" (entry),
- "i" (ASI_SEGMAP)
- : "memory");
-}
-
-static inline unsigned long sun4c_get_pte(unsigned long addr)
-{
- register unsigned long entry;
-
- __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" :
- "=r" (entry) :
- "r" (addr), "i" (ASI_PTE));
- return entry;
-}
-
-static inline void sun4c_put_pte(unsigned long addr, unsigned long entry)
-{
- __asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : :
- "r" (addr),
- "r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE)
- : "memory");
-}
-
-static inline int sun4c_get_context(void)
-{
- register int ctx;
-
- __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
- "=r" (ctx) :
- "r" (AC_CONTEXT), "i" (ASI_CONTROL));
-
- return ctx;
-}
-
-static inline int sun4c_set_context(int ctx)
-{
- __asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : :
- "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)
- : "memory");
-
- return ctx;
-}
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(_SPARC_PGTSUN4C_H) */
diff --git a/arch/sparc/include/asm/posix_types.h b/arch/sparc/include/asm/posix_types.h
index 3070f25ae90..156220ed99e 100644
--- a/arch/sparc/include/asm/posix_types.h
+++ b/arch/sparc/include/asm/posix_types.h
@@ -9,8 +9,6 @@
#if defined(__sparc__) && defined(__arch64__)
/* sparc 64 bit */
-typedef unsigned int __kernel_nlink_t;
-#define __kernel_nlink_t __kernel_nlink_t
typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
@@ -38,9 +36,6 @@ typedef unsigned short __kernel_gid_t;
typedef unsigned short __kernel_mode_t;
#define __kernel_mode_t __kernel_mode_t
-typedef short __kernel_nlink_t;
-#define __kernel_nlink_t __kernel_nlink_t
-
typedef long __kernel_daddr_t;
#define __kernel_daddr_t __kernel_daddr_t
diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h
index 09521c6a5ed..f74ac9ee33a 100644
--- a/arch/sparc/include/asm/processor_32.h
+++ b/arch/sparc/include/asm/processor_32.h
@@ -16,7 +16,6 @@
#include <asm/ptrace.h>
#include <asm/head.h>
#include <asm/signal.h>
-#include <asm/btfixup.h>
#include <asm/page.h>
/*
@@ -109,9 +108,6 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,
#define release_thread(tsk) do { } while(0)
extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
-
extern unsigned long get_wchan(struct task_struct *);
#define task_pt_regs(tsk) ((tsk)->thread.kregs)
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h
index e713db24993..4e5a483122a 100644
--- a/arch/sparc/include/asm/processor_64.h
+++ b/arch/sparc/include/asm/processor_64.h
@@ -42,7 +42,9 @@
#define TASK_SIZE_OF(tsk) \
(test_tsk_thread_flag(tsk,TIF_32BIT) ? \
(1UL << 32UL) : ((unsigned long)-VPTE_SIZE))
-#define TASK_SIZE TASK_SIZE_OF(current)
+#define TASK_SIZE \
+ (test_thread_flag(TIF_32BIT) ? \
+ (1UL << 32UL) : ((unsigned long)-VPTE_SIZE))
#ifdef __KERNEL__
#define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
@@ -186,9 +188,6 @@ do { \
/* Free all resources held by a thread. */
#define release_thread(tsk) do { } while (0)
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
-
extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
extern unsigned long get_wchan(struct task_struct *task);
diff --git a/arch/sparc/include/asm/psr.h b/arch/sparc/include/asm/psr.h
index b8c0e5f0a66..cee7ed9c927 100644
--- a/arch/sparc/include/asm/psr.h
+++ b/arch/sparc/include/asm/psr.h
@@ -35,6 +35,14 @@
#define PSR_VERS 0x0f000000 /* cpu-version field */
#define PSR_IMPL 0xf0000000 /* cpu-implementation field */
+#define PSR_VERS_SHIFT 24
+#define PSR_IMPL_SHIFT 28
+#define PSR_VERS_SHIFTED_MASK 0xf
+#define PSR_IMPL_SHIFTED_MASK 0xf
+
+#define PSR_IMPL_TI 0x4
+#define PSR_IMPL_LEON 0xf
+
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
diff --git a/arch/sparc/include/asm/sections.h b/arch/sparc/include/asm/sections.h
index 0b0553bbd8a..f300d1a9b2b 100644
--- a/arch/sparc/include/asm/sections.h
+++ b/arch/sparc/include/asm/sections.h
@@ -7,4 +7,7 @@
/* sparc entry point */
extern char _start[];
+extern char __leon_1insn_patch[];
+extern char __leon_1insn_patch_end[];
+
#endif
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h
index 00497abec99..8a83699a550 100644
--- a/arch/sparc/include/asm/setup.h
+++ b/arch/sparc/include/asm/setup.h
@@ -20,10 +20,7 @@ extern char reboot_command[];
* Only sun4d + leon may have boot_cpu_id != 0
*/
extern unsigned char boot_cpu_id;
-extern unsigned char boot_cpu_id4;
-extern unsigned long empty_bad_page;
-extern unsigned long empty_bad_page_table;
extern unsigned long empty_zero_page;
extern int serial_console;
diff --git a/arch/sparc/include/asm/shmparam_32.h b/arch/sparc/include/asm/shmparam_32.h
index 59a1243c12f..142825c8d3a 100644
--- a/arch/sparc/include/asm/shmparam_32.h
+++ b/arch/sparc/include/asm/shmparam_32.h
@@ -4,8 +4,6 @@
#define __ARCH_FORCE_SHMLBA 1
extern int vac_cache_size;
-#define SHMLBA (vac_cache_size ? vac_cache_size : \
- (sparc_cpu_model == sun4c ? (64 * 1024) : \
- (sparc_cpu_model == sun4 ? (128 * 1024) : PAGE_SIZE)))
+#define SHMLBA (vac_cache_size ? vac_cache_size : PAGE_SIZE)
#endif /* _ASMSPARC_SHMPARAM_H */
diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h
index 01c51c70434..b73da3c5f10 100644
--- a/arch/sparc/include/asm/smp_32.h
+++ b/arch/sparc/include/asm/smp_32.h
@@ -8,7 +8,6 @@
#include <linux/threads.h>
#include <asm/head.h>
-#include <asm/btfixup.h>
#ifndef __ASSEMBLY__
@@ -58,104 +57,53 @@ struct seq_file;
void smp_bogo(struct seq_file *);
void smp_info(struct seq_file *);
-BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void)
-BTFIXUPDEF_CALL(void, smp_ipi_resched, int);
-BTFIXUPDEF_CALL(void, smp_ipi_single, int);
-BTFIXUPDEF_CALL(void, smp_ipi_mask_one, int);
-BTFIXUPDEF_BLACKBOX(hard_smp_processor_id)
-BTFIXUPDEF_BLACKBOX(load_current)
-
-#define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4)
+struct sparc32_ipi_ops {
+ void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4);
+ void (*resched)(int cpu);
+ void (*single)(int cpu);
+ void (*mask_one)(int cpu);
+};
+extern const struct sparc32_ipi_ops *sparc32_ipi_ops;
+
+static inline void xc0(smpfunc_t func)
+{
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0);
+}
-static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); }
static inline void xc1(smpfunc_t func, unsigned long arg1)
-{ smp_cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); }
-static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
-{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); }
-static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
- unsigned long arg3)
-{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, 0); }
-static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4)
-{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, arg4); }
-
-extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
-
-static inline int cpu_logical_map(int cpu)
{
- return cpu;
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0);
}
-
-static inline int hard_smp4m_processor_id(void)
+static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
{
- int cpuid;
-
- __asm__ __volatile__("rd %%tbr, %0\n\t"
- "srl %0, 12, %0\n\t"
- "and %0, 3, %0\n\t" :
- "=&r" (cpuid));
- return cpuid;
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0);
}
-static inline int hard_smp4d_processor_id(void)
+static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3)
{
- int cpuid;
-
- __asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
- "=&r" (cpuid) : "i" (ASI_M_VIKING_TMP1));
- return cpuid;
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
+ arg1, arg2, arg3, 0);
}
-extern inline int hard_smpleon_processor_id(void)
+static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4)
{
- int cpuid;
- __asm__ __volatile__("rd %%asr17,%0\n\t"
- "srl %0,28,%0" :
- "=&r" (cpuid) : );
- return cpuid;
+ sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
+ arg1, arg2, arg3, arg4);
}
-#ifndef MODULE
-static inline int hard_smp_processor_id(void)
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+
+static inline int cpu_logical_map(int cpu)
{
- int cpuid;
-
- /* Black box - sun4m
- __asm__ __volatile__("rd %%tbr, %0\n\t"
- "srl %0, 12, %0\n\t"
- "and %0, 3, %0\n\t" :
- "=&r" (cpuid));
- - sun4d
- __asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t"
- "nop; nop" :
- "=&r" (cpuid));
- - leon
- __asm__ __volatile__( "rd %asr17, %0\n\t"
- "srl %0, 0x1c, %0\n\t"
- "nop\n\t" :
- "=&r" (cpuid));
- See btfixup.h and btfixupprep.c to understand how a blackbox works.
- */
- __asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t"
- "sethi %%hi(boot_cpu_id), %0\n\t"
- "ldub [%0 + %%lo(boot_cpu_id)], %0\n\t" :
- "=&r" (cpuid));
- return cpuid;
+ return cpu;
}
-#else
-static inline int hard_smp_processor_id(void)
-{
- int cpuid;
- __asm__ __volatile__("mov %%o7, %%g1\n\t"
- "call ___f___hard_smp_processor_id\n\t"
- " nop\n\t"
- "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2");
- return cpuid;
-}
-#endif
+extern int hard_smp_processor_id(void);
#define raw_smp_processor_id() (current_thread_info()->cpu)
diff --git a/arch/sparc/include/asm/smpprim.h b/arch/sparc/include/asm/smpprim.h
deleted file mode 100644
index eb849d862c6..00000000000
--- a/arch/sparc/include/asm/smpprim.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * smpprim.h: SMP locking primitives on the Sparc
- *
- * God knows we won't be actually using this code for some time
- * but I thought I'd write it since I knew how.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __SPARC_SMPPRIM_H
-#define __SPARC_SMPPRIM_H
-
-/* Test and set the unsigned byte at ADDR to 1. Returns the previous
- * value. On the Sparc we use the ldstub instruction since it is
- * atomic.
- */
-
-static inline __volatile__ char test_and_set(void *addr)
-{
- char state = 0;
-
- __asm__ __volatile__("ldstub [%0], %1 ! test_and_set\n\t"
- "=r" (addr), "=r" (state) :
- "0" (addr), "1" (state) : "memory");
-
- return state;
-}
-
-/* Initialize a spin-lock. */
-static inline __volatile__ smp_initlock(void *spinlock)
-{
- /* Unset the lock. */
- *((unsigned char *) spinlock) = 0;
-
- return;
-}
-
-/* This routine spins until it acquires the lock at ADDR. */
-static inline __volatile__ smp_lock(void *addr)
-{
- while(test_and_set(addr) == 0xff)
- ;
-
- /* We now have the lock */
- return;
-}
-
-/* This routine releases the lock at ADDR. */
-static inline __volatile__ smp_unlock(void *addr)
-{
- *((unsigned char *) addr) = 0;
-}
-
-#endif /* !(__SPARC_SMPPRIM_H) */
diff --git a/arch/sparc/include/asm/string_32.h b/arch/sparc/include/asm/string_32.h
index edf196ee4ef..12f67857152 100644
--- a/arch/sparc/include/asm/string_32.h
+++ b/arch/sparc/include/asm/string_32.h
@@ -61,68 +61,7 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
extern __kernel_size_t strlen(const char *);
#define __HAVE_ARCH_STRNCMP
-
-extern int __strncmp(const char *, const char *, __kernel_size_t);
-
-static inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count)
-{
- register int retval;
- switch(count) {
- case 0: return 0;
- case 1: return (src[0] - dest[0]);
- case 2: retval = (src[0] - dest[0]);
- if(!retval && src[0])
- retval = (src[1] - dest[1]);
- return retval;
- case 3: retval = (src[0] - dest[0]);
- if(!retval && src[0]) {
- retval = (src[1] - dest[1]);
- if(!retval && src[1])
- retval = (src[2] - dest[2]);
- }
- return retval;
- case 4: retval = (src[0] - dest[0]);
- if(!retval && src[0]) {
- retval = (src[1] - dest[1]);
- if(!retval && src[1]) {
- retval = (src[2] - dest[2]);
- if (!retval && src[2])
- retval = (src[3] - dest[3]);
- }
- }
- return retval;
- case 5: retval = (src[0] - dest[0]);
- if(!retval && src[0]) {
- retval = (src[1] - dest[1]);
- if(!retval && src[1]) {
- retval = (src[2] - dest[2]);
- if (!retval && src[2]) {
- retval = (src[3] - dest[3]);
- if (!retval && src[3])
- retval = (src[4] - dest[4]);
- }
- }
- }
- return retval;
- default:
- retval = (src[0] - dest[0]);
- if(!retval && src[0]) {
- retval = (src[1] - dest[1]);
- if(!retval && src[1]) {
- retval = (src[2] - dest[2]);
- if(!retval && src[2])
- retval = __strncmp(src+3,dest+3,count-3);
- }
- }
- return retval;
- }
-}
-
-#undef strncmp
-#define strncmp(__arg0, __arg1, __arg2) \
-(__builtin_constant_p(__arg2) ? \
- __constant_strncmp(__arg0, __arg1, __arg2) : \
- __strncmp(__arg0, __arg1, __arg2))
+extern int strncmp(const char *, const char *, __kernel_size_t);
#endif /* !EXPORT_SYMTAB_STROPS */
diff --git a/arch/sparc/include/asm/sysen.h b/arch/sparc/include/asm/sysen.h
deleted file mode 100644
index 6af34abde6e..00000000000
--- a/arch/sparc/include/asm/sysen.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * sysen.h: Bit fields within the "System Enable" register accessed via
- * the ASI_CONTROL address space at address AC_SYSENABLE.
- *
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_SYSEN_H
-#define _SPARC_SYSEN_H
-
-#define SENABLE_DVMA 0x20 /* enable dvma transfers */
-#define SENABLE_CACHE 0x10 /* enable VAC cache */
-#define SENABLE_RESET 0x04 /* reset whole machine, danger Will Robinson */
-
-#endif /* _SPARC_SYSEN_H */
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index c2a1080cdd3..e6cd224506a 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -15,7 +15,6 @@
#ifndef __ASSEMBLY__
-#include <asm/btfixup.h>
#include <asm/ptrace.h>
#include <asm/page.h>
@@ -78,23 +77,11 @@ register struct thread_info *current_thread_info_reg asm("g6");
/*
* thread information allocation
*/
-#define THREAD_INFO_ORDER 1
-
-#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
-
-BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info_node, int)
-#define alloc_thread_info_node(tsk, node) BTFIXUP_CALL(alloc_thread_info_node)(node)
-
-BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
-#define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti)
+#define THREAD_SIZE_ORDER 1
#endif /* __ASSEMBLY__ */
-/*
- * Size of kernel stack for each process.
- * Observe the order of get_free_pages() in alloc_thread_info_node().
- * The sun4 has 8K stack too, because it's short on memory, and 16K is a waste.
- */
+/* Size of kernel stack for each process */
#define THREAD_SIZE (2 * PAGE_SIZE)
/*
@@ -144,8 +131,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
- _TIF_SIGPENDING | \
- _TIF_RESTORE_SIGMASK)
+ _TIF_SIGPENDING)
#endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 01d057fe6a3..cfa8c38fb9c 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -138,32 +138,11 @@ register struct thread_info *current_thread_info_reg asm("g6");
/* thread information allocation */
#if PAGE_SHIFT == 13
-#define __THREAD_INFO_ORDER 1
+#define THREAD_SIZE_ORDER 1
#else /* PAGE_SHIFT == 13 */
-#define __THREAD_INFO_ORDER 0
+#define THREAD_SIZE_ORDER 0
#endif /* PAGE_SHIFT == 13 */
-#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
-
-#ifdef CONFIG_DEBUG_STACK_USAGE
-#define THREAD_FLAGS (GFP_KERNEL | __GFP_ZERO)
-#else
-#define THREAD_FLAGS (GFP_KERNEL)
-#endif
-
-#define alloc_thread_info_node(tsk, node) \
-({ \
- struct page *page = alloc_pages_node(node, THREAD_FLAGS, \
- __THREAD_INFO_ORDER); \
- struct thread_info *ret; \
- \
- ret = page ? page_address(page) : NULL; \
- ret; \
-})
-
-#define free_thread_info(ti) \
- free_pages((unsigned long)(ti),__THREAD_INFO_ORDER)
-
#define __thread_flag_byte_ptr(ti) \
((unsigned char *)(&((ti)->flags)))
#define __cur_thread_flag_byte_ptr __thread_flag_byte_ptr(current_thread_info())
@@ -259,7 +238,23 @@ static inline void set_restore_sigmask(void)
{
struct thread_info *ti = current_thread_info();
ti->status |= TS_RESTORE_SIGMASK;
- set_bit(TIF_SIGPENDING, &ti->flags);
+ WARN_ON(!test_bit(TIF_SIGPENDING, &ti->flags));
+}
+static inline void clear_restore_sigmask(void)
+{
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+}
+static inline bool test_restore_sigmask(void)
+{
+ return current_thread_info()->status & TS_RESTORE_SIGMASK;
+}
+static inline bool test_and_clear_restore_sigmask(void)
+{
+ struct thread_info *ti = current_thread_info();
+ if (!(ti->status & TS_RESTORE_SIGMASK))
+ return false;
+ ti->status &= ~TS_RESTORE_SIGMASK;
+ return true;
}
#endif /* !__ASSEMBLY__ */
diff --git a/arch/sparc/include/asm/timer_32.h b/arch/sparc/include/asm/timer_32.h
index 1a91e11dd10..72f40a546de 100644
--- a/arch/sparc/include/asm/timer_32.h
+++ b/arch/sparc/include/asm/timer_32.h
@@ -8,14 +8,37 @@
#ifndef _SPARC_TIMER_H
#define _SPARC_TIMER_H
+#include <linux/clocksource.h>
+#include <linux/irqreturn.h>
+
+#include <asm-generic/percpu.h>
+
#include <asm/cpu_type.h> /* For SUN4M_NCPUS */
-#include <asm/btfixup.h>
+
+#define SBUS_CLOCK_RATE 2000000 /* 2MHz */
+#define TIMER_VALUE_SHIFT 9
+#define TIMER_VALUE_MASK 0x3fffff
+#define TIMER_LIMIT_BIT (1 << 31) /* Bit 31 in Counter-Timer register */
+
+/* The counter timer register has the value offset by 9 bits.
+ * From sun4m manual:
+ * When a counter reaches the value in the corresponding limit register,
+ * the Limit bit is set and the counter is set to 500 nS (i.e. 0x00000200).
+ *
+ * To compensate for this add one to the value.
+ */
+static inline unsigned int timer_value(unsigned int value)
+{
+ return (value + 1) << TIMER_VALUE_SHIFT;
+}
extern __volatile__ unsigned int *master_l10_counter;
-/* FIXME: Make do_[gs]ettimeofday btfixup calls */
-struct timespec;
-BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv)
-#define bus_do_settimeofday(tv) BTFIXUP_CALL(bus_do_settimeofday)(tv)
+extern irqreturn_t notrace timer_interrupt(int dummy, void *dev_id);
+
+#ifdef CONFIG_SMP
+DECLARE_PER_CPU(struct clock_event_device, sparc32_clockevent);
+extern void register_percpu_ce(int cpu);
+#endif
#endif /* !(_SPARC_TIMER_H) */
diff --git a/arch/sparc/include/asm/timex_32.h b/arch/sparc/include/asm/timex_32.h
index a254750e4c0..b6ccdb0d6f7 100644
--- a/arch/sparc/include/asm/timex_32.h
+++ b/arch/sparc/include/asm/timex_32.h
@@ -12,5 +12,4 @@
typedef unsigned long cycles_t;
#define get_cycles() (0)
-extern u32 (*do_arch_gettimeoffset)(void);
#endif
diff --git a/arch/sparc/include/asm/tlbflush_32.h b/arch/sparc/include/asm/tlbflush_32.h
index fe0a71abc9b..a5c4142130f 100644
--- a/arch/sparc/include/asm/tlbflush_32.h
+++ b/arch/sparc/include/asm/tlbflush_32.h
@@ -1,52 +1,16 @@
#ifndef _SPARC_TLBFLUSH_H
#define _SPARC_TLBFLUSH_H
-#include <linux/mm.h>
-// #include <asm/processor.h>
-
-/*
- * TLB flushing:
- *
- * - flush_tlb() flushes the current mm struct TLBs XXX Exists?
- * - flush_tlb_all() flushes all processes TLBs
- * - flush_tlb_mm(mm) flushes the specified mm context TLB's
- * - flush_tlb_page(vma, vmaddr) flushes one page
- * - flush_tlb_range(vma, start, end) flushes a range of pages
- * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- */
-
-#ifdef CONFIG_SMP
-
-BTFIXUPDEF_CALL(void, local_flush_tlb_all, void)
-BTFIXUPDEF_CALL(void, local_flush_tlb_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, local_flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_tlb_page, struct vm_area_struct *, unsigned long)
-
-#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)()
-#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm)
-#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end)
-#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr)
-
-extern void smp_flush_tlb_all(void);
-extern void smp_flush_tlb_mm(struct mm_struct *mm);
-extern void smp_flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start,
- unsigned long end);
-extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page);
-
-#endif /* CONFIG_SMP */
-
-BTFIXUPDEF_CALL(void, flush_tlb_all, void)
-BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
-
-#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
-#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
-#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
-#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr)
-
-// #define flush_tlb() flush_tlb_mm(current->active_mm) /* XXX Sure? */
+#include <asm/cachetlb_32.h>
+
+#define flush_tlb_all() \
+ sparc32_cachetlb_ops->tlb_all()
+#define flush_tlb_mm(mm) \
+ sparc32_cachetlb_ops->tlb_mm(mm)
+#define flush_tlb_range(vma, start, end) \
+ sparc32_cachetlb_ops->tlb_range(vma, start, end)
+#define flush_tlb_page(vma, addr) \
+ sparc32_cachetlb_ops->tlb_page(vma, addr)
/*
* This is a kludge, until I know better. --zaitcev XXX
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h
index 8b9c556d630..1754390a426 100644
--- a/arch/sparc/include/asm/topology_64.h
+++ b/arch/sparc/include/asm/topology_64.h
@@ -31,25 +31,6 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus)))
-#define SD_NODE_INIT (struct sched_domain) { \
- .min_interval = 8, \
- .max_interval = 32, \
- .busy_factor = 32, \
- .imbalance_pct = 125, \
- .cache_nice_tries = 2, \
- .busy_idx = 3, \
- .idle_idx = 2, \
- .newidle_idx = 0, \
- .wake_idx = 0, \
- .forkexec_idx = 0, \
- .flags = SD_LOAD_BALANCE \
- | SD_BALANCE_FORK \
- | SD_BALANCE_EXEC \
- | SD_SERIALIZE, \
- .last_balance = jiffies, \
- .balance_interval = 1, \
-}
-
#else /* CONFIG_NUMA */
#include <asm-generic/topology.h>
diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h
index e88fbe5c045..0167d26d0d1 100644
--- a/arch/sparc/include/asm/uaccess.h
+++ b/arch/sparc/include/asm/uaccess.h
@@ -5,4 +5,10 @@
#else
#include <asm/uaccess_32.h>
#endif
+
+#define user_addr_max() \
+ (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
+
+extern long strncpy_from_user(char *dest, const char __user *src, long count);
+
#endif
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 8303ac48103..53a28dd59f5 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -12,11 +12,12 @@
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
-#include <asm/vac-ops.h>
#endif
#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+
#define ARCH_HAS_SORT_EXTABLE
#define ARCH_HAS_SEARCH_EXTABLE
@@ -305,34 +306,8 @@ static inline unsigned long clear_user(void __user *addr, unsigned long n)
return n;
}
-extern long __strncpy_from_user(char *dest, const char __user *src, long count);
-
-static inline long strncpy_from_user(char *dest, const char __user *src, long count)
-{
- if (__access_ok((unsigned long) src, count))
- return __strncpy_from_user(dest, src, count);
- else
- return -EFAULT;
-}
-
-extern long __strlen_user(const char __user *);
-extern long __strnlen_user(const char __user *, long len);
-
-static inline long strlen_user(const char __user *str)
-{
- if (!access_ok(VERIFY_READ, str, 0))
- return 0;
- else
- return __strlen_user(str);
-}
-
-static inline long strnlen_user(const char __user *str, long len)
-{
- if (!access_ok(VERIFY_READ, str, 0))
- return 0;
- else
- return __strnlen_user(str, len);
-}
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
#endif /* __ASSEMBLY__ */
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index a1091afb883..7c831d848b4 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -17,6 +17,8 @@
#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+
/*
* Sparc64 is segmented, though more like the M68K than the I386.
* We use the secondary ASI to address user memory, which references a
@@ -257,15 +259,9 @@ extern unsigned long __must_check __clear_user(void __user *, unsigned long);
#define clear_user __clear_user
-extern long __must_check __strncpy_from_user(char *dest, const char __user *src, long count);
-
-#define strncpy_from_user __strncpy_from_user
-
-extern long __strlen_user(const char __user *);
-extern long __strnlen_user(const char __user *, long len);
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
-#define strlen_user __strlen_user
-#define strnlen_user __strnlen_user
#define __copy_to_user_inatomic ___copy_to_user
#define __copy_from_user_inatomic ___copy_from_user
diff --git a/arch/sparc/include/asm/vac-ops.h b/arch/sparc/include/asm/vac-ops.h
deleted file mode 100644
index a63e88ef042..00000000000
--- a/arch/sparc/include/asm/vac-ops.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef _SPARC_VAC_OPS_H
-#define _SPARC_VAC_OPS_H
-
-/* vac-ops.h: Inline assembly routines to do operations on the Sparc
- * VAC (virtual address cache) for the sun4c.
- *
- * Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <asm/sysen.h>
-#include <asm/contregs.h>
-#include <asm/asi.h>
-
-/* The SUN4C models have a virtually addressed write-through
- * cache.
- *
- * The cache tags are directly accessible through an ASI and
- * each have the form:
- *
- * ------------------------------------------------------------
- * | MBZ | CONTEXT | WRITE | PRIV | VALID | MBZ | TagID | MBZ |
- * ------------------------------------------------------------
- * 31 25 24 22 21 20 19 18 16 15 2 1 0
- *
- * MBZ: These bits are either unused and/or reserved and should
- * be written as zeroes.
- *
- * CONTEXT: Records the context to which this cache line belongs.
- *
- * WRITE: A copy of the writable bit from the mmu pte access bits.
- *
- * PRIV: A copy of the privileged bit from the pte access bits.
- *
- * VALID: If set, this line is valid, else invalid.
- *
- * TagID: Fourteen bits of tag ID.
- *
- * Every virtual address is seen by the cache like this:
- *
- * ----------------------------------------
- * | RESV | TagID | LINE | BYTE-in-LINE |
- * ----------------------------------------
- * 31 30 29 16 15 4 3 0
- *
- * RESV: Unused/reserved.
- *
- * TagID: Used to match the Tag-ID in that vac tags.
- *
- * LINE: Which line within the cache
- *
- * BYTE-in-LINE: Which byte within the cache line.
- */
-
-/* Sun4c VAC Tags */
-#define S4CVACTAG_CID 0x01c00000
-#define S4CVACTAG_W 0x00200000
-#define S4CVACTAG_P 0x00100000
-#define S4CVACTAG_V 0x00080000
-#define S4CVACTAG_TID 0x0000fffc
-
-/* Sun4c VAC Virtual Address */
-/* These aren't used, why bother? (Anton) */
-#if 0
-#define S4CVACVA_TID 0x3fff0000
-#define S4CVACVA_LINE 0x0000fff0
-#define S4CVACVA_BIL 0x0000000f
-#endif
-
-/* The indexing of cache lines creates a problem. Because the line
- * field of a virtual address extends past the page offset within
- * the virtual address it is possible to have what are called
- * 'bad aliases' which will create inconsistencies. So we must make
- * sure that within a context that if a physical page is mapped
- * more than once, that 'extra' line bits are the same. If this is
- * not the case, and thus is a 'bad alias' we must turn off the
- * cacheable bit in the pte's of all such pages.
- */
-
-#define S4CVAC_BADBITS 0x0000f000
-
-/* The following is true if vaddr1 and vaddr2 would cause
- * a 'bad alias'.
- */
-#define S4CVAC_BADALIAS(vaddr1, vaddr2) \
- ((((unsigned long) (vaddr1)) ^ ((unsigned long) (vaddr2))) & \
- (S4CVAC_BADBITS))
-
-/* The following structure describes the characteristics of a sun4c
- * VAC as probed from the prom during boot time.
- */
-struct sun4c_vac_props {
- unsigned int num_bytes; /* Size of the cache */
- unsigned int do_hwflushes; /* Hardware flushing available? */
- unsigned int linesize; /* Size of each line in bytes */
- unsigned int log2lsize; /* log2(linesize) */
- unsigned int on; /* VAC is enabled */
-};
-
-extern struct sun4c_vac_props sun4c_vacinfo;
-
-/* sun4c_enable_vac() enables the sun4c virtual address cache. */
-static inline void sun4c_enable_vac(void)
-{
- __asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
- "or %%g1, %2, %%g1\n\t"
- "stba %%g1, [%0] %1\n\t"
- : /* no outputs */
- : "r" ((unsigned int) AC_SENABLE),
- "i" (ASI_CONTROL), "i" (SENABLE_CACHE)
- : "g1", "memory");
- sun4c_vacinfo.on = 1;
-}
-
-/* sun4c_disable_vac() disables the virtual address cache. */
-static inline void sun4c_disable_vac(void)
-{
- __asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
- "andn %%g1, %2, %%g1\n\t"
- "stba %%g1, [%0] %1\n\t"
- : /* no outputs */
- : "r" ((unsigned int) AC_SENABLE),
- "i" (ASI_CONTROL), "i" (SENABLE_CACHE)
- : "g1", "memory");
- sun4c_vacinfo.on = 0;
-}
-
-#endif /* !(_SPARC_VAC_OPS_H) */
diff --git a/arch/sparc/include/asm/vaddrs.h b/arch/sparc/include/asm/vaddrs.h
index 541e13755ce..da6535d88a7 100644
--- a/arch/sparc/include/asm/vaddrs.h
+++ b/arch/sparc/include/asm/vaddrs.h
@@ -34,22 +34,6 @@
#define IOBASE_VADDR 0xfe000000
#define IOBASE_END 0xfe600000
-/*
- * On the sun4/4c we need a place
- * to reliably map locked down kernel data. This includes the
- * task_struct and kernel stack pages of each process plus the
- * scsi buffers during dvma IO transfers, also the floppy buffers
- * during pseudo dma which runs with traps off (no faults allowed).
- * Some quick calculations yield:
- * NR_TASKS <512> * (3 * PAGE_SIZE) == 0x600000
- * Subtract this from 0xc00000 and you get 0x927C0 of vm left
- * over to map SCSI dvma + floppy pseudo-dma buffers. So be
- * careful if you change NR_TASKS or else there won't be enough
- * room for it all.
- */
-#define SUN4C_LOCK_VADDR 0xff000000
-#define SUN4C_LOCK_END 0xffc00000
-
#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */
#define KADB_DEBUGGER_ENDVM 0xffd00000
#define DEBUG_FIRSTVADDR KADB_DEBUGGER_BEGVM
diff --git a/arch/sparc/include/asm/winmacro.h b/arch/sparc/include/asm/winmacro.h
index a9be04b0d04..9b7b21764cd 100644
--- a/arch/sparc/include/asm/winmacro.h
+++ b/arch/sparc/include/asm/winmacro.h
@@ -103,37 +103,24 @@
st %scratch, [%cur_reg + TI_W_SAVED];
#ifdef CONFIG_SMP
-/* Results of LOAD_CURRENT() after BTFIXUP for SUN4M, SUN4D & LEON (comments) */
-#define LOAD_CURRENT4M(dest_reg, idreg) \
- rd %tbr, %idreg; \
- sethi %hi(current_set), %dest_reg; \
- srl %idreg, 10, %idreg; \
- or %dest_reg, %lo(current_set), %dest_reg; \
- and %idreg, 0xc, %idreg; \
- ld [%idreg + %dest_reg], %dest_reg;
-
-#define LOAD_CURRENT4D(dest_reg, idreg) \
- lda [%g0] ASI_M_VIKING_TMP1, %idreg; \
- sethi %hi(C_LABEL(current_set)), %dest_reg; \
- sll %idreg, 2, %idreg; \
- or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \
- ld [%idreg + %dest_reg], %dest_reg;
-
-#define LOAD_CURRENT_LEON(dest_reg, idreg) \
- rd %asr17, %idreg; \
- sethi %hi(current_set), %dest_reg; \
- srl %idreg, 0x1c, %idreg; \
- or %dest_reg, %lo(current_set), %dest_reg; \
- sll %idreg, 0x2, %idreg; \
- ld [%idreg + %dest_reg], %dest_reg;
-
-/* Blackbox - take care with this... - check smp4m and smp4d before changing this. */
-#define LOAD_CURRENT(dest_reg, idreg) \
- sethi %hi(___b_load_current), %idreg; \
- sethi %hi(current_set), %dest_reg; \
- sethi %hi(boot_cpu_id4), %idreg; \
- or %dest_reg, %lo(current_set), %dest_reg; \
- ldub [%idreg + %lo(boot_cpu_id4)], %idreg; \
+#define LOAD_CURRENT(dest_reg, idreg) \
+661: rd %tbr, %idreg; \
+ srl %idreg, 10, %idreg; \
+ and %idreg, 0xc, %idreg; \
+ .section .cpuid_patch, "ax"; \
+ /* Instruction location. */ \
+ .word 661b; \
+ /* SUN4D implementation. */ \
+ lda [%g0] ASI_M_VIKING_TMP1, %idreg; \
+ sll %idreg, 2, %idreg; \
+ nop; \
+ /* LEON implementation. */ \
+ rd %asr17, %idreg; \
+ srl %idreg, 0x1c, %idreg; \
+ sll %idreg, 0x02, %idreg; \
+ .previous; \
+ sethi %hi(current_set), %dest_reg; \
+ or %dest_reg, %lo(current_set), %dest_reg;\
ld [%idreg + %dest_reg], %dest_reg;
#else
#define LOAD_CURRENT(dest_reg, idreg) \
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index cb85458f89d..6cf591b7e1c 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -6,7 +6,6 @@ asflags-y := -ansi
ccflags-y := -Werror
extra-y := head_$(BITS).o
-extra-y += init_task.o
# Undefine sparc when processing vmlinux.lds - it is used
# And teach CPP we are doing $(BITS) builds (for this case)
@@ -28,7 +27,7 @@ obj-y += traps_$(BITS).o
# IRQ
obj-y += irq_$(BITS).o
-obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o
+obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4d_irq.o
obj-y += process_$(BITS).o
obj-y += signal_$(BITS).o
@@ -46,15 +45,14 @@ obj-$(CONFIG_SPARC32) += tadpole.o
obj-y += ptrace_$(BITS).o
obj-y += unaligned_$(BITS).o
obj-y += una_asm_$(BITS).o
-obj-$(CONFIG_SPARC32) += muldiv.o
obj-y += prom_common.o
obj-y += prom_$(BITS).o
obj-y += of_device_common.o
obj-y += of_device_$(BITS).o
obj-$(CONFIG_SPARC64) += prom_irqtrans.o
-obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o
-obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o
+obj-$(CONFIG_SPARC32) += leon_kernel.o
+obj-$(CONFIG_SPARC32) += leon_pmc.o
obj-$(CONFIG_SPARC64) += reboot.o
obj-$(CONFIG_SPARC64) += sysfs.o
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c
index 56d0f52c3e6..e20cc55fb76 100644
--- a/arch/sparc/kernel/auxio_32.c
+++ b/arch/sparc/kernel/auxio_32.c
@@ -32,7 +32,6 @@ void __init auxio_probe(void)
switch (sparc_cpu_model) {
case sparc_leon:
case sun4d:
- case sun4:
return;
default:
break;
@@ -65,9 +64,8 @@ void __init auxio_probe(void)
r.start = auxregs[0].phys_addr;
r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1;
auxio_register = of_ioremap(&r, 0, auxregs[0].reg_size, "auxio");
- /* Fix the address on sun4m and sun4c. */
- if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 ||
- sparc_cpu_model == sun4c)
+ /* Fix the address on sun4m. */
+ if ((((unsigned long) auxregs[0].phys_addr) & 3) == 3)
auxio_register += (3 - ((unsigned long)auxio_register & 3));
set_auxio(AUXIO_LED, 0);
@@ -86,12 +84,7 @@ void set_auxio(unsigned char bits_on, unsigned char bits_off)
unsigned char regval;
unsigned long flags;
spin_lock_irqsave(&auxio_lock, flags);
- switch(sparc_cpu_model) {
- case sun4c:
- regval = sbus_readb(auxio_register);
- sbus_writeb(((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN,
- auxio_register);
- break;
+ switch (sparc_cpu_model) {
case sun4m:
if(!auxio_register)
break; /* VME chassis sun4m, no auxio. */
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 2d181964176..a6c94a2bf9d 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -121,7 +121,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
FPU(-1, NULL)
}
},{
- 4,
+ PSR_IMPL_TI,
.cpu_info = {
CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"),
/* SparcClassic -- borned STP1010TAB-50*/
@@ -191,7 +191,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
FPU(-1, NULL)
}
},{
- 0xF, /* Aeroflex Gaisler */
+ PSR_IMPL_LEON, /* Aeroflex Gaisler */
.cpu_info = {
CPU(3, "LEON"),
CPU(-1, NULL)
@@ -440,16 +440,16 @@ static int __init cpu_type_probe(void)
int psr_impl, psr_vers, fpu_vers;
int psr;
- psr_impl = ((get_psr() >> 28) & 0xf);
- psr_vers = ((get_psr() >> 24) & 0xf);
+ psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK);
+ psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK);
psr = get_psr();
put_psr(psr | PSR_EF);
-#ifdef CONFIG_SPARC_LEON
- fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7;
-#else
- fpu_vers = ((get_fsr() >> 17) & 0x7);
-#endif
+
+ if (psr_impl == PSR_IMPL_LEON)
+ fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7;
+ else
+ fpu_vers = ((get_fsr() >> 17) & 0x7);
put_psr(psr);
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
index 6b2f56a6f8a..3d465e87f7e 100644
--- a/arch/sparc/kernel/devices.c
+++ b/arch/sparc/kernel/devices.c
@@ -21,7 +21,6 @@
#include <asm/cpu_type.h>
extern void clock_stop_probe(void); /* tadpole.c */
-extern void sun4c_probe_memerr_reg(void);
static char *cpu_mid_prop(void)
{
@@ -139,7 +138,4 @@ void __init device_scan(void)
auxio_power_probe();
}
clock_stop_probe();
-
- if (ARCH_SUN4C)
- sun4c_probe_memerr_reg();
}
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index b93c2c9ccb1..f09257c8610 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -868,7 +868,7 @@ void ldom_power_off(void)
static void ds_conn_reset(struct ds_info *dp)
{
- printk(KERN_ERR "ds-%llu: ds_conn_reset() from %p\n",
+ printk(KERN_ERR "ds-%llu: ds_conn_reset() from %pf\n",
dp->id, __builtin_return_address(0));
}
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index f445e98463e..dcaa1cf0de4 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -7,6 +7,7 @@
* Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au)
*/
+#include <linux/linkage.h>
#include <linux/errno.h>
#include <asm/head.h>
@@ -17,10 +18,8 @@
#include <asm/asm-offsets.h>
#include <asm/psr.h>
#include <asm/vaddrs.h>
-#include <asm/memreg.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/pgtsun4c.h>
#include <asm/winmacro.h>
#include <asm/signal.h>
#include <asm/obio.h>
@@ -125,22 +124,11 @@ floppy_tdone:
set auxio_register, %l7
ld [%l7], %l7
- set sparc_cpu_model, %l5
- ld [%l5], %l5
- subcc %l5, 1, %g0 /* enum { sun4c = 1 }; */
- be 1f
- ldub [%l7], %l5
+ ldub [%l7], %l5
or %l5, 0xc2, %l5
stb %l5, [%l7]
andn %l5, 0x02, %l5
- b 2f
- nop
-
-1:
- or %l5, 0xf4, %l5
- stb %l5, [%l7]
- andn %l5, 0x04, %l5
2:
/* Kill some time so the bits set */
@@ -266,6 +254,11 @@ smp4m_ticker:
WRITE_PAUSE
RESTORE_ALL
+#define GET_PROCESSOR4M_ID(reg) \
+ rd %tbr, %reg; \
+ srl %reg, 12, %reg; \
+ and %reg, 3, %reg;
+
/* Here is where we check for possible SMP IPI passed to us
* on some level other than 15 which is the NMI and only used
* for cross calls. That has a separate entry point below.
@@ -328,7 +321,7 @@ linux_trap_ipi15_sun4m:
ld [%o5 + %o0], %o5
ld [%o5 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending
andcc %o3, %o2, %g0
- be 1f ! Must be an NMI async memory error
+ be sun4m_nmi_error ! Must be an NMI async memory error
st %o2, [%o5 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x80000000
WRITE_PAUSE
ld [%o5 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending
@@ -342,27 +335,6 @@ linux_trap_ipi15_sun4m:
nop
b ret_trap_lockless_ipi
clr %l6
-1:
- /* NMI async memory error handling. */
- sethi %hi(0x80000000), %l4
- sethi %hi(sun4m_irq_global), %o5
- ld [%o5 + %lo(sun4m_irq_global)], %l5
- st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000
- WRITE_PAUSE
- ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending
- WRITE_PAUSE
- or %l0, PSR_PIL, %l4
- wr %l4, 0x0, %psr
- WRITE_PAUSE
- wr %l4, PSR_ET, %psr
- WRITE_PAUSE
- call sun4m_nmi
- nop
- st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000
- WRITE_PAUSE
- ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending
- WRITE_PAUSE
- RESTORE_ALL
.globl smp4d_ticker
/* SMP per-cpu ticker interrupts are handled specially. */
@@ -421,7 +393,6 @@ linux_trap_ipi15_sun4d:
/* FIXME */
1: b,a 1b
-#ifdef CONFIG_SPARC_LEON
.globl smpleon_ipi
.extern leon_ipi_interrupt
/* SMP per-cpu IPI interrupts are handled specially. */
@@ -452,8 +423,6 @@ linux_trap_ipi15_leon:
b ret_trap_lockless_ipi
clr %l6
-#endif /* CONFIG_SPARC_LEON */
-
#endif /* CONFIG_SMP */
/* This routine handles illegal instructions and privileged
@@ -760,326 +729,37 @@ setcc_trap_handler:
jmp %l2 ! advance over trap instruction
rett %l2 + 0x4 ! like this...
- .align 4
- .globl linux_trap_nmi_sun4c
-linux_trap_nmi_sun4c:
- SAVE_ALL
-
- /* Ugh, we need to clear the IRQ line. This is now
- * a very sun4c specific trap handler...
- */
- sethi %hi(interrupt_enable), %l5
- ld [%l5 + %lo(interrupt_enable)], %l5
- ldub [%l5], %l6
- andn %l6, INTS_ENAB, %l6
- stb %l6, [%l5]
-
- /* Now it is safe to re-enable traps without recursion. */
- or %l0, PSR_PIL, %l0
- wr %l0, PSR_ET, %psr
+sun4m_nmi_error:
+ /* NMI async memory error handling. */
+ sethi %hi(0x80000000), %l4
+ sethi %hi(sun4m_irq_global), %o5
+ ld [%o5 + %lo(sun4m_irq_global)], %l5
+ st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000
WRITE_PAUSE
-
- /* Now call the c-code with the pt_regs frame ptr and the
- * memory error registers as arguments. The ordering chosen
- * here is due to unlatching semantics.
- */
- sethi %hi(AC_SYNC_ERR), %o0
- add %o0, 0x4, %o0
- lda [%o0] ASI_CONTROL, %o2 ! sync vaddr
- sub %o0, 0x4, %o0
- lda [%o0] ASI_CONTROL, %o1 ! sync error
- add %o0, 0xc, %o0
- lda [%o0] ASI_CONTROL, %o4 ! async vaddr
- sub %o0, 0x4, %o0
- lda [%o0] ASI_CONTROL, %o3 ! async error
- call sparc_lvl15_nmi
- add %sp, STACKFRAME_SZ, %o0
-
- RESTORE_ALL
-
- .align 4
- .globl invalid_segment_patch1_ff
- .globl invalid_segment_patch2_ff
-invalid_segment_patch1_ff: cmp %l4, 0xff
-invalid_segment_patch2_ff: mov 0xff, %l3
-
- .align 4
- .globl invalid_segment_patch1_1ff
- .globl invalid_segment_patch2_1ff
-invalid_segment_patch1_1ff: cmp %l4, 0x1ff
-invalid_segment_patch2_1ff: mov 0x1ff, %l3
-
- .align 4
- .globl num_context_patch1_16, num_context_patch2_16
-num_context_patch1_16: mov 0x10, %l7
-num_context_patch2_16: mov 0x10, %l7
-
- .align 4
- .globl vac_linesize_patch_32
-vac_linesize_patch_32: subcc %l7, 32, %l7
-
- .align 4
- .globl vac_hwflush_patch1_on, vac_hwflush_patch2_on
-
-/*
- * Ugly, but we can't use hardware flushing on the sun4 and we'd require
- * two instructions (Anton)
- */
-vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7
-
-vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG
-
- .globl invalid_segment_patch1, invalid_segment_patch2
- .globl num_context_patch1
- .globl vac_linesize_patch, vac_hwflush_patch1
- .globl vac_hwflush_patch2
-
- .align 4
- .globl sun4c_fault
-
-! %l0 = %psr
-! %l1 = %pc
-! %l2 = %npc
-! %l3 = %wim
-! %l7 = 1 for textfault
-! We want error in %l5, vaddr in %l6
-sun4c_fault:
- sethi %hi(AC_SYNC_ERR), %l4
- add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6
- lda [%l6] ASI_CONTROL, %l5 ! Address
- lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit
-
- andn %l5, 0xfff, %l5 ! Encode all info into l7
- srl %l6, 14, %l4
-
- and %l4, 2, %l4
- or %l5, %l4, %l4
-
- or %l4, %l7, %l7 ! l7 = [addr,write,txtfault]
-
- andcc %l0, PSR_PS, %g0
- be sun4c_fault_fromuser
- andcc %l7, 1, %g0 ! Text fault?
-
- be 1f
- sethi %hi(KERNBASE), %l4
-
- mov %l1, %l5 ! PC
-
-1:
- cmp %l5, %l4
- blu sun4c_fault_fromuser
- sethi %hi(~((1 << SUN4C_REAL_PGDIR_SHIFT) - 1)), %l4
-
- /* If the kernel references a bum kernel pointer, or a pte which
- * points to a non existent page in ram, we will run this code
- * _forever_ and lock up the machine!!!!! So we must check for
- * this condition, the AC_SYNC_ERR bits are what we must examine.
- * Also a parity error would make this happen as well. So we just
- * check that we are in fact servicing a tlb miss and not some
- * other type of fault for the kernel.
- */
- andcc %l6, 0x80, %g0
- be sun4c_fault_fromuser
- and %l5, %l4, %l5
-
- /* Test for NULL pte_t * in vmalloc area. */
- sethi %hi(VMALLOC_START), %l4
- cmp %l5, %l4
- blu,a invalid_segment_patch1
- lduXa [%l5] ASI_SEGMAP, %l4
-
- sethi %hi(swapper_pg_dir), %l4
- srl %l5, SUN4C_PGDIR_SHIFT, %l6
- or %l4, %lo(swapper_pg_dir), %l4
- sll %l6, 2, %l6
- ld [%l4 + %l6], %l4
- andcc %l4, PAGE_MASK, %g0
- be sun4c_fault_fromuser
- lduXa [%l5] ASI_SEGMAP, %l4
-
-invalid_segment_patch1:
- cmp %l4, 0x7f
- bne 1f
- sethi %hi(sun4c_kfree_ring), %l4
- or %l4, %lo(sun4c_kfree_ring), %l4
- ld [%l4 + 0x18], %l3
- deccc %l3 ! do we have a free entry?
- bcs,a 2f ! no, unmap one.
- sethi %hi(sun4c_kernel_ring), %l4
-
- st %l3, [%l4 + 0x18] ! sun4c_kfree_ring.num_entries--
-
- ld [%l4 + 0x00], %l6 ! entry = sun4c_kfree_ring.ringhd.next
- st %l5, [%l6 + 0x08] ! entry->vaddr = address
-
- ld [%l6 + 0x00], %l3 ! next = entry->next
- ld [%l6 + 0x04], %l7 ! entry->prev
-
- st %l7, [%l3 + 0x04] ! next->prev = entry->prev
- st %l3, [%l7 + 0x00] ! entry->prev->next = next
-
- sethi %hi(sun4c_kernel_ring), %l4
- or %l4, %lo(sun4c_kernel_ring), %l4
- ! head = &sun4c_kernel_ring.ringhd
-
- ld [%l4 + 0x00], %l7 ! head->next
-
- st %l4, [%l6 + 0x04] ! entry->prev = head
- st %l7, [%l6 + 0x00] ! entry->next = head->next
- st %l6, [%l7 + 0x04] ! head->next->prev = entry
-
- st %l6, [%l4 + 0x00] ! head->next = entry
-
- ld [%l4 + 0x18], %l3
- inc %l3 ! sun4c_kernel_ring.num_entries++
- st %l3, [%l4 + 0x18]
- b 4f
- ld [%l6 + 0x08], %l5
-
-2:
- or %l4, %lo(sun4c_kernel_ring), %l4
- ! head = &sun4c_kernel_ring.ringhd
-
- ld [%l4 + 0x04], %l6 ! entry = head->prev
-
- ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr
-
- ! Flush segment from the cache.
- sethi %hi((64 * 1024)), %l7
-9:
-vac_hwflush_patch1:
-vac_linesize_patch:
- subcc %l7, 16, %l7
- bne 9b
-vac_hwflush_patch2:
- sta %g0, [%l3 + %l7] ASI_FLUSHSEG
-
- st %l5, [%l6 + 0x08] ! entry->vaddr = address
-
- ld [%l6 + 0x00], %l5 ! next = entry->next
- ld [%l6 + 0x04], %l7 ! entry->prev
-
- st %l7, [%l5 + 0x04] ! next->prev = entry->prev
- st %l5, [%l7 + 0x00] ! entry->prev->next = next
- st %l4, [%l6 + 0x04] ! entry->prev = head
-
- ld [%l4 + 0x00], %l7 ! head->next
-
- st %l7, [%l6 + 0x00] ! entry->next = head->next
- st %l6, [%l7 + 0x04] ! head->next->prev = entry
- st %l6, [%l4 + 0x00] ! head->next = entry
-
- mov %l3, %l5 ! address = tmp
-
-4:
-num_context_patch1:
- mov 0x08, %l7
-
- ld [%l6 + 0x08], %l4
- ldub [%l6 + 0x0c], %l3
- or %l4, %l3, %l4 ! encode new vaddr/pseg into l4
-
- sethi %hi(AC_CONTEXT), %l3
- lduba [%l3] ASI_CONTROL, %l6
-
- /* Invalidate old mapping, instantiate new mapping,
- * for each context. Registers l6/l7 are live across
- * this loop.
- */
-3: deccc %l7
- sethi %hi(AC_CONTEXT), %l3
- stba %l7, [%l3] ASI_CONTROL
-invalid_segment_patch2:
- mov 0x7f, %l3
- stXa %l3, [%l5] ASI_SEGMAP
- andn %l4, 0x1ff, %l3
- bne 3b
- stXa %l4, [%l3] ASI_SEGMAP
-
- sethi %hi(AC_CONTEXT), %l3
- stba %l6, [%l3] ASI_CONTROL
-
- andn %l4, 0x1ff, %l5
-
-1:
- sethi %hi(VMALLOC_START), %l4
- cmp %l5, %l4
-
- bgeu 1f
- mov 1 << (SUN4C_REAL_PGDIR_SHIFT - PAGE_SHIFT), %l7
-
- sethi %hi(KERNBASE), %l6
-
- sub %l5, %l6, %l4
- srl %l4, PAGE_SHIFT, %l4
- sethi %hi((SUN4C_PAGE_KERNEL & 0xf4000000)), %l3
- or %l3, %l4, %l3
-
- sethi %hi(PAGE_SIZE), %l4
-
-2:
- sta %l3, [%l5] ASI_PTE
- deccc %l7
- inc %l3
- bne 2b
- add %l5, %l4, %l5
-
- b 7f
- sethi %hi(sun4c_kernel_faults), %l4
-
-1:
- srl %l5, SUN4C_PGDIR_SHIFT, %l3
- sethi %hi(swapper_pg_dir), %l4
- or %l4, %lo(swapper_pg_dir), %l4
- sll %l3, 2, %l3
- ld [%l4 + %l3], %l4
- and %l4, PAGE_MASK, %l4
-
- srl %l5, (PAGE_SHIFT - 2), %l6
- and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6
- add %l6, %l4, %l6
-
- sethi %hi(PAGE_SIZE), %l4
-
-2:
- ld [%l6], %l3
- deccc %l7
- sta %l3, [%l5] ASI_PTE
- add %l6, 0x4, %l6
- bne 2b
- add %l5, %l4, %l5
-
- sethi %hi(sun4c_kernel_faults), %l4
-7:
- ld [%l4 + %lo(sun4c_kernel_faults)], %l3
- inc %l3
- st %l3, [%l4 + %lo(sun4c_kernel_faults)]
-
- /* Restore condition codes */
- wr %l0, 0x0, %psr
+ ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending
WRITE_PAUSE
- jmp %l1
- rett %l2
-
-sun4c_fault_fromuser:
- SAVE_ALL
+ or %l0, PSR_PIL, %l4
+ wr %l4, 0x0, %psr
+ WRITE_PAUSE
+ wr %l4, PSR_ET, %psr
+ WRITE_PAUSE
+ call sun4m_nmi
nop
-
- mov %l7, %o1 ! Decode the info from %l7
- mov %l7, %o2
- and %o1, 1, %o1 ! arg2 = text_faultp
- mov %l7, %o3
- and %o2, 2, %o2 ! arg3 = writep
- andn %o3, 0xfff, %o3 ! arg4 = faulting address
-
- wr %l0, PSR_ET, %psr
+ st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000
+ WRITE_PAUSE
+ ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending
WRITE_PAUSE
+ RESTORE_ALL
- call do_sun4c_fault
- add %sp, STACKFRAME_SZ, %o0 ! arg1 = pt_regs ptr
+#ifndef CONFIG_SMP
+ .align 4
+ .globl linux_trap_ipi15_sun4m
+linux_trap_ipi15_sun4m:
+ SAVE_ALL
- RESTORE_ALL
+ ba sun4m_nmi_error
+ nop
+#endif /* CONFIG_SMP */
.align 4
.globl srmmu_fault
@@ -1087,8 +767,11 @@ srmmu_fault:
mov 0x400, %l5
mov 0x300, %l4
- lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first
- lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last
+LEON_PI(lda [%l5] ASI_LEON_MMUREGS, %l6) ! read sfar first
+SUN_PI_(lda [%l5] ASI_M_MMUREGS, %l6) ! read sfar first
+
+LEON_PI(lda [%l4] ASI_LEON_MMUREGS, %l5) ! read sfsr last
+SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) ! read sfsr last
andn %l6, 0xfff, %l6
srl %l5, 6, %l5 ! and encode all info into l7
@@ -1483,11 +1166,13 @@ fpload:
.globl __ndelay
__ndelay:
save %sp, -STACKFRAME_SZ, %sp
- mov %i0, %o0
- call .umul ! round multiplier up so large ns ok
- mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ)
- call .umul
- mov %i1, %o1 ! udelay_val
+ mov %i0, %o0 ! round multiplier up so large ns ok
+ mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ)
+ umul %o0, %o1, %o0
+ rd %y, %o1
+ mov %i1, %o1 ! udelay_val
+ umul %o0, %o1, %o0
+ rd %y, %o1
ba delay_continue
mov %o1, %o0 ! >>32 later for better resolution
@@ -1496,18 +1181,21 @@ __udelay:
save %sp, -STACKFRAME_SZ, %sp
mov %i0, %o0
sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok
- call .umul
- or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000
- call .umul
- mov %i1, %o1 ! udelay_val
+ or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000
+ umul %o0, %o1, %o0
+ rd %y, %o1
+ mov %i1, %o1 ! udelay_val
+ umul %o0, %o1, %o0
+ rd %y, %o1
sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32,
or %g0, %lo(0x028f4b62), %l0
addcc %o0, %l0, %o0 ! 2**32 * 0.009 999
bcs,a 3f
add %o1, 0x01, %o1
3:
- call .umul
- mov HZ, %o0 ! >>32 earlier for wider range
+ mov HZ, %o0 ! >>32 earlier for wider range
+ umul %o0, %o1, %o0
+ rd %y, %o1
delay_continue:
cmp %o0, 0x0
@@ -1670,4 +1358,26 @@ flushw_all:
ret
restore
+#ifdef CONFIG_SMP
+ENTRY(hard_smp_processor_id)
+661: rd %tbr, %g1
+ srl %g1, 12, %o0
+ and %o0, 3, %o0
+ .section .cpuid_patch, "ax"
+ /* Instruction location. */
+ .word 661b
+ /* SUN4D implementation. */
+ lda [%g0] ASI_M_VIKING_TMP1, %o0
+ nop
+ nop
+ /* LEON implementation. */
+ rd %asr17, %o0
+ srl %o0, 0x1c, %o0
+ nop
+ .previous
+ retl
+ nop
+ENDPROC(hard_smp_processor_id)
+#endif
+
/* End of entry.S */
diff --git a/arch/sparc/kernel/etrap_32.S b/arch/sparc/kernel/etrap_32.S
index e806fcdc46d..e3e80d65e39 100644
--- a/arch/sparc/kernel/etrap_32.S
+++ b/arch/sparc/kernel/etrap_32.S
@@ -216,9 +216,7 @@ tsetup_patch6:
/* Call MMU-architecture dependent stack checking
* routine.
*/
- .globl tsetup_mmu_patchme
-tsetup_mmu_patchme:
- b tsetup_sun4c_stackchk
+ b tsetup_srmmu_stackchk
andcc %sp, 0x7, %g0
/* Architecture specific stack checking routines. When either
@@ -228,52 +226,6 @@ tsetup_mmu_patchme:
*/
#define glob_tmp g1
-tsetup_sun4c_stackchk:
- /* Done by caller: andcc %sp, 0x7, %g0 */
- bne trap_setup_user_stack_is_bolixed
- sra %sp, 29, %glob_tmp
-
- add %glob_tmp, 0x1, %glob_tmp
- andncc %glob_tmp, 0x1, %g0
- bne trap_setup_user_stack_is_bolixed
- and %sp, 0xfff, %glob_tmp ! delay slot
-
- /* See if our dump area will be on more than one
- * page.
- */
- add %glob_tmp, 0x38, %glob_tmp
- andncc %glob_tmp, 0xff8, %g0
- be tsetup_sun4c_onepage ! only one page to check
- lda [%sp] ASI_PTE, %glob_tmp ! have to check first page anyways
-
-tsetup_sun4c_twopages:
- /* Is first page ok permission wise? */
- srl %glob_tmp, 29, %glob_tmp
- cmp %glob_tmp, 0x6
- bne trap_setup_user_stack_is_bolixed
- add %sp, 0x38, %glob_tmp /* Is second page in vma hole? */
-
- sra %glob_tmp, 29, %glob_tmp
- add %glob_tmp, 0x1, %glob_tmp
- andncc %glob_tmp, 0x1, %g0
- bne trap_setup_user_stack_is_bolixed
- add %sp, 0x38, %glob_tmp
-
- lda [%glob_tmp] ASI_PTE, %glob_tmp
-
-tsetup_sun4c_onepage:
- srl %glob_tmp, 29, %glob_tmp
- cmp %glob_tmp, 0x6 ! can user write to it?
- bne trap_setup_user_stack_is_bolixed ! failure
- nop
-
- STORE_WINDOW(sp)
-
- restore %g0, %g0, %g0
-
- jmpl %t_retpc + 0x8, %g0
- mov %t_kstack, %sp
-
.globl tsetup_srmmu_stackchk
tsetup_srmmu_stackchk:
/* Check results of callers andcc %sp, 0x7, %g0 */
@@ -282,7 +234,8 @@ tsetup_srmmu_stackchk:
cmp %glob_tmp, %sp
bleu,a 1f
- lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control
+LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
+SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
trap_setup_user_stack_is_bolixed:
/* From user/kernel into invalid window w/bad user
@@ -297,18 +250,25 @@ trap_setup_user_stack_is_bolixed:
1:
/* Clear the fault status and turn on the no_fault bit. */
or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
- sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it
+LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
+SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
/* Dump the registers and cross fingers. */
STORE_WINDOW(sp)
/* Clear the no_fault bit and check the status. */
andn %glob_tmp, 0x2, %glob_tmp
- sta %glob_tmp, [%g0] ASI_M_MMUREGS
+LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
+SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
+
mov AC_M_SFAR, %glob_tmp
- lda [%glob_tmp] ASI_M_MMUREGS, %g0
+LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
+SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
+
mov AC_M_SFSR, %glob_tmp
- lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp ! save away status of winstore
+LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore
+SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore
+
andcc %glob_tmp, 0x2, %g0 ! did we fault?
bne trap_setup_user_stack_is_bolixed ! failure
nop
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 58778575983..afeb1d77030 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -26,396 +26,41 @@
#include <asm/pgtsrmmu.h> /* SRMMU_PGDIR_SHIFT */
.data
-/*
- * The following are used with the prom_vector node-ops to figure out
- * the cpu-type
+/* The following are used with the prom_vector node-ops to figure out
+ * the cpu-type
*/
-
- .align 4
-cputyp:
- .word 1
-
.align 4
.globl cputypval
cputypval:
- .asciz "sun4c"
+ .asciz "sun4m"
.ascii " "
-cputypvalend:
-cputypvallen = cputypvar - cputypval
-
+/* Tested on SS-5, SS-10 */
.align 4
-/*
- * Sun people can't spell worth damn. "compatability" indeed.
- * At least we *know* we can't spell, and use a spell-checker.
- */
-
-/* Uh, actually Linus it is I who cannot spell. Too much murky
- * Sparc assembly will do this to ya.
- */
cputypvar:
- .asciz "compatability"
-
-/* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */
- .align 4
-cputypvar_sun4m:
.asciz "compatible"
.align 4
-sun4_notsup:
- .asciz "Sparc-Linux sun4 support does no longer exist.\n\n"
+notsup:
+ .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
.align 4
sun4e_notsup:
.asciz "Sparc-Linux sun4e support does not exist\n\n"
.align 4
- /* The Sparc trap table, bootloader gives us control at _start. */
- __HEAD
- .globl _stext, _start, __stext
- .globl trapbase
-_start: /* danger danger */
-__stext:
-_stext:
-trapbase:
-#ifdef CONFIG_SMP
-trapbase_cpu0:
-#endif
-/* We get control passed to us here at t_zero. */
-t_zero: b gokernel; nop; nop; nop;
-t_tflt: SPARC_TFAULT /* Inst. Access Exception */
-t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */
-t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */
-t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */
-t_wovf: WINDOW_SPILL /* Window Overflow */
-t_wunf: WINDOW_FILL /* Window Underflow */
-t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */
-t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */
-t_dflt: SPARC_DFAULT /* Data Miss Exception */
-t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */
-t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */
-t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
-t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */
-t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */
-t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */
-t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */
-t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */
-t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */
-t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */
-t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */
-t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */
-t_irq10:TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) */
-t_irq11:TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */
-t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */
-t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */
-t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */
- .globl t_nmi
-#ifndef CONFIG_SMP
-t_nmi: NMI_TRAP /* Level 15 (NMI) */
-#else
-t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
-#endif
-t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */
-t_iacce:BAD_TRAP(0x21) /* Instr Access Error */
-t_bad22:BAD_TRAP(0x22) BAD_TRAP(0x23)
-t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */
-t_uflsh:SKIP_TRAP(0x25, unimp_flush) /* Unimplemented FLUSH inst. */
-t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27)
-t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */
-t_dacce:SPARC_DFAULT /* Data Access Error */
-t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */
-t_dserr:BAD_TRAP(0x2b) /* Data Store Error */
-t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */
-t_bad2d:BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
-t_bad32:BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
-t_bad37:BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
-t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */
-t_bad3d:BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41)
-t_bad42:BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46)
-t_bad47:BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b)
-t_bad4c:BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) BAD_TRAP(0x50)
-t_bad51:BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
-t_bad56:BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
-t_bad5b:BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
-t_bad60:BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
-t_bad65:BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
-t_bad6a:BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
-t_bad6f:BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
-t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
-t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
-t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f)
-t_bad80:BAD_TRAP(0x80) /* SunOS System Call */
-t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */
-t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */
-t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */
-t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */
-t_rchk: BAD_TRAP(0x85) /* Range Check */
-t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */
-t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */
-t_bad88:BAD_TRAP(0x88) /* Slowaris System Call */
-t_bad89:BAD_TRAP(0x89) /* Net-B.S. System Call */
-t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e)
-t_bad8f:BAD_TRAP(0x8f)
-t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */
-t_bad91:BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95)
-t_bad96:BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a)
-t_bad9b:BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f)
-t_getcc:GETCC_TRAP /* Get Condition Codes */
-t_setcc:SETCC_TRAP /* Set Condition Codes */
-t_getpsr:GETPSR_TRAP /* Get PSR Register */
-t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
-t_bada7:BAD_TRAP(0xa7)
-t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
-t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
-t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
-t_badb6:BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
-t_badbb:BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
-t_badc0:BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
-t_badc5:BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
-t_badca:BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
-t_badcf:BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
-t_badd4:BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
-t_badd9:BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
-t_badde:BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
-t_bade3:BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
-t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
-t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
-t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
-t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
-t_badfc:BAD_TRAP(0xfc)
-t_kgdb: KGDB_TRAP(0xfd)
-dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */
-dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */
-
- .globl end_traptable
-end_traptable:
-
-#ifdef CONFIG_SMP
- /* Trap tables for the other cpus. */
- .globl trapbase_cpu1, trapbase_cpu2, trapbase_cpu3
-trapbase_cpu1:
- BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction)
- TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler)
- WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler)
- TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT
- TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint)
- BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
- TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2)
- TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4)
- TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6)
- TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8)
- TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10)
- TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12)
- TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14)
- TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
- TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22)
- BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush)
- BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception)
- SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c)
- BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
- BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
- BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
- BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40)
- BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45)
- BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a)
- BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f)
- BAD_TRAP(0x50)
- BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
- BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
- BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
- BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
- BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
- BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
- BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
- BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
- BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
- BAD_TRAP(0x7e) BAD_TRAP(0x7f)
- BAD_TRAP(0x80)
- BREAKPOINT_TRAP
- TRAP_ENTRY(0x82, do_hw_divzero)
- TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
- BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
- BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
- BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
- LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
- BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
- BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
- BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP
- BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
- BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
- BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
- BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
- BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
- BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
- BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
- BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
- BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
- BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
- BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
- BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
- BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
- BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
- BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
- BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
- BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
- BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
- BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
-
-trapbase_cpu2:
- BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction)
- TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler)
- WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler)
- TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT
- TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint)
- BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
- TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2)
- TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4)
- TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6)
- TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8)
- TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10)
- TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12)
- TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14)
- TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
- TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22)
- BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush)
- BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception)
- SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c)
- BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
- BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
- BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
- BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40)
- BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45)
- BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a)
- BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f)
- BAD_TRAP(0x50)
- BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
- BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
- BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
- BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
- BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
- BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
- BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
- BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
- BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
- BAD_TRAP(0x7e) BAD_TRAP(0x7f)
- BAD_TRAP(0x80)
- BREAKPOINT_TRAP
- TRAP_ENTRY(0x82, do_hw_divzero)
- TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
- BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
- BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
- BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
- LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
- BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
- BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
- BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP
- BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
- BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
- BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
- BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
- BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
- BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
- BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
- BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
- BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
- BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
- BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
- BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
- BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
- BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
- BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
- BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
- BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
- BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
- BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
-
-trapbase_cpu3:
- BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction)
- TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler)
- WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler)
- TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT
- TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint)
- BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
- TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2)
- TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4)
- TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6)
- TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8)
- TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10)
- TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12)
- TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14)
- TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
- TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22)
- BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush)
- BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception)
- SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c)
- BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
- BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
- BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
- BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40)
- BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45)
- BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a)
- BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f)
- BAD_TRAP(0x50)
- BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
- BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
- BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
- BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
- BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
- BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
- BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
- BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
- BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
- BAD_TRAP(0x7e) BAD_TRAP(0x7f)
- BAD_TRAP(0x80)
- BREAKPOINT_TRAP
- TRAP_ENTRY(0x82, do_hw_divzero)
- TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
- BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
- BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
- BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
- LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
- BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
- BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
- BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP
- BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
- BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
- BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
- BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
- BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
- BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
- BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
- BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
- BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
- BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
- BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
- BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
- BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
- BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
- BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
- BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
- BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
- BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
- BAD_TRAP(0xfc) KGDB_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)
+/* The trap-table - located in the __HEAD section */
+#include "ttable_32.S"
-#endif
.align PAGE_SIZE
/* This was the only reasonable way I could think of to properly align
* these page-table data structures.
*/
- .globl pg0, pg1, pg2, pg3
- .globl empty_bad_page
- .globl empty_bad_page_table
- .globl empty_zero_page
.globl swapper_pg_dir
swapper_pg_dir: .skip PAGE_SIZE
-pg0: .skip PAGE_SIZE
-pg1: .skip PAGE_SIZE
-pg2: .skip PAGE_SIZE
-pg3: .skip PAGE_SIZE
-empty_bad_page: .skip PAGE_SIZE
-empty_bad_page_table: .skip PAGE_SIZE
+ .globl empty_zero_page
empty_zero_page: .skip PAGE_SIZE
.global root_flags
@@ -474,7 +119,7 @@ current_pc:
tst %o0
be no_sun4u_here
mov %g4, %o7 /* Previous %o7. */
-
+
mov %o0, %l0 ! stash away romvec
mov %o0, %g7 ! put it here too
mov %o1, %l1 ! stash away debug_vec too
@@ -483,7 +128,7 @@ current_pc:
set current_pc, %g5
cmp %g3, %g5
be already_mapped
- nop
+ nop
/* %l6 will hold the offset we have to subtract
* from absolute symbols in order to access areas
@@ -523,10 +168,10 @@ copy_prom_lvl14:
ldd [%g2 + 0x8], %g4
std %g4, [%g3 + 0x8] ! Copy proms handler
-/* Must determine whether we are on a sun4c MMU, SRMMU, or SUN4/400 MUTANT
- * MMU so we can remap ourselves properly. DON'T TOUCH %l0 thru %l5 in these
- * remapping routines, we need their values afterwards!
+/* DON'T TOUCH %l0 thru %l5 in these remapping routines,
+ * we need their values afterwards!
*/
+
/* Now check whether we are already mapped, if we
* are we can skip all this garbage coming up.
*/
@@ -535,33 +180,49 @@ copy_prom_done:
be go_to_highmem ! this will be a nop then
nop
- set LOAD_ADDR, %g6
+ /* Validate that we are in fact running on an
+ * SRMMU based cpu.
+ */
+ set 0x4000, %g6
cmp %g7, %g6
- bne remap_not_a_sun4 ! This is not a Sun4
+ bne not_a_sun4
nop
- or %g0, 0x1, %g1
- lduba [%g1] ASI_CONTROL, %g1 ! Only safe to try on Sun4.
- subcc %g1, 0x24, %g0 ! Is this a mutant Sun4/400???
- be sun4_mutant_remap ! Ugh, it is...
+halt_notsup:
+ ld [%g7 + 0x68], %o1
+ set notsup, %o0
+ sub %o0, %l6, %o0
+ call %o1
nop
+ ba halt_me
+ nop
+
+not_a_sun4:
+ /* It looks like this is a machine we support.
+ * Now find out what MMU we are dealing with
+ * LEON - identified by the psr.impl field
+ * Viking - identified by the psr.impl field
+ * In all other cases a sun4m srmmu.
+ * We check that the MMU is enabled in all cases.
+ */
- b sun4_normal_remap ! regular sun4, 2 level mmu
+ /* Check if this is a LEON CPU */
+ rd %psr, %g3
+ srl %g3, PSR_IMPL_SHIFT, %g3
+ and %g3, PSR_IMPL_SHIFTED_MASK, %g3
+ cmp %g3, PSR_IMPL_LEON
+ be leon_remap /* It is a LEON - jump */
nop
-remap_not_a_sun4:
- lda [%g0] ASI_M_MMUREGS, %g1 ! same as ASI_PTE on sun4c
- and %g1, 0x1, %g1 ! Test SRMMU Enable bit ;-)
- cmp %g1, 0x0
- be sun4c_remap ! A sun4c MMU or normal Sun4
+ /* Sanity-check, is MMU enabled */
+ lda [%g0] ASI_M_MMUREGS, %g1
+ andcc %g1, 1, %g0
+ be halt_notsup
nop
-srmmu_remap:
- /* First, check for a viking (TI) module. */
- set 0x40000000, %g2
- rd %psr, %g3
- and %g2, %g3, %g3
- subcc %g3, 0x0, %g0
- bz srmmu_nviking
+
+ /* Check for a viking (TI) module. */
+ cmp %g3, PSR_IMPL_TI
+ bne srmmu_not_viking
nop
/* Figure out what kind of viking we are on.
@@ -576,14 +237,14 @@ srmmu_remap:
lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg
and %g2, %g3, %g3
subcc %g3, 0x0, %g0
- bnz srmmu_nviking ! is in mbus mode
+ bnz srmmu_not_viking ! is in mbus mode
nop
-
+
rd %psr, %g3 ! DO NOT TOUCH %g3
andn %g3, PSR_ET, %g2
wr %g2, 0x0, %psr
WRITE_PAUSE
-
+
/* Get context table pointer, then convert to
* a physical address, which is 36 bits.
*/
@@ -606,12 +267,12 @@ srmmu_remap:
lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr
srl %o1, 0x4, %o1 ! Clear low 4 bits
sll %o1, 0x8, %o1 ! Make physical
-
+
/* Ok, pull in the PTD. */
lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd
/* Calculate to KERNBASE entry. */
- add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3
+ add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3
/* Poke the entry into the calculated address. */
sta %o2, [%o3] ASI_M_BYPASS
@@ -641,12 +302,12 @@ srmmu_remap:
b go_to_highmem
nop
+srmmu_not_viking:
/* This works on viking's in Mbus mode and all
* other MBUS modules. It is virtually the same as
* the above madness sans turning traps off and flipping
* the AC bit.
*/
-srmmu_nviking:
set AC_M_CTPR, %g1
lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr
sll %g1, 0x4, %g1 ! make physical addr
@@ -660,72 +321,29 @@ srmmu_nviking:
b go_to_highmem
nop ! wheee....
- /* This remaps the kernel on Sun4/4xx machines
- * that have the Sun Mutant Three Level MMU.
- * It's like a platypus, Sun didn't have the
- * SRMMU in conception so they kludged the three
- * level logic in the regular Sun4 MMU probably.
- *
- * Basically, you take each entry in the top level
- * directory that maps the low 3MB starting at
- * address zero and put the mapping in the KERNBASE
- * slots. These top level pgd's are called regmaps.
- */
-sun4_mutant_remap:
- or %g0, %g0, %g3 ! source base
- sethi %hi(KERNBASE), %g4 ! destination base
- or %g4, %lo(KERNBASE), %g4
- sethi %hi(0x300000), %g5
- or %g5, %lo(0x300000), %g5 ! upper bound 3MB
- or %g0, 0x1, %l6
- sll %l6, 24, %l6 ! Regmap mapping size
- add %g3, 0x2, %g3 ! Base magic
- add %g4, 0x2, %g4 ! Base magic
-
- /* Main remapping loop on Sun4-Mutant-MMU.
- * "I am not an animal..." -Famous Mutant Person
- */
-sun4_mutant_loop:
- lduha [%g3] ASI_REGMAP, %g2 ! Get lower entry
- stha %g2, [%g4] ASI_REGMAP ! Store in high entry
- add %g4, %l6, %g4 ! Move up high memory ptr
- subcc %g3, %g5, %g0 ! Reached our limit?
- blu sun4_mutant_loop ! Nope, loop again
- add %g3, %l6, %g3 ! delay, Move up low ptr
- b go_to_highmem ! Jump to high memory.
- nop
- /* The following is for non-4/4xx sun4 MMU's. */
-sun4_normal_remap:
- mov 0, %g3 ! source base
- set KERNBASE, %g4 ! destination base
- set 0x300000, %g5 ! upper bound 3MB
- mov 1, %l6
- sll %l6, 18, %l6 ! sun4 mmu segmap size
-sun4_normal_loop:
- lduha [%g3] ASI_SEGMAP, %g6 ! load phys_seg
- stha %g6, [%g4] ASI_SEGMAP ! stort new virt mapping
- add %g3, %l6, %g3 ! increment source pointer
- subcc %g3, %g5, %g0 ! reached limit?
- blu sun4_normal_loop ! nope, loop again
- add %g4, %l6, %g4 ! delay, increment dest ptr
- b go_to_highmem
+leon_remap:
+ /* Sanity-check, is MMU enabled */
+ lda [%g0] ASI_LEON_MMUREGS, %g1
+ andcc %g1, 1, %g0
+ be halt_notsup
nop
- /* The following works for Sun4c MMU's */
-sun4c_remap:
- mov 0, %g3 ! source base
- set KERNBASE, %g4 ! destination base
- set 0x300000, %g5 ! upper bound 3MB
- mov 1, %l6
- sll %l6, 18, %l6 ! sun4c mmu segmap size
-sun4c_remap_loop:
- lda [%g3] ASI_SEGMAP, %g6 ! load phys_seg
- sta %g6, [%g4] ASI_SEGMAP ! store new virt mapping
- add %g3, %l6, %g3 ! Increment source ptr
- subcc %g3, %g5, %g0 ! Reached limit?
- bl sun4c_remap_loop ! Nope, loop again
- add %g4, %l6, %g4 ! delay, Increment dest ptr
+ /* Same code as in the srmmu_not_viking case,
+ * with the LEON ASI for mmuregs
+ */
+ set AC_M_CTPR, %g1
+ lda [%g1] ASI_LEON_MMUREGS, %g1 ! get ctx table ptr
+ sll %g1, 0x4, %g1 ! make physical addr
+ lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table
+ srl %g1, 0x4, %g1
+ sll %g1, 0x8, %g1 ! make phys addr for l1 tbl
+
+ lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0
+ add %g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3
+ sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry
+ b go_to_highmem
+ nop ! wheee....
/* Now do a non-relative jump so that PC is in high-memory */
go_to_highmem:
@@ -750,35 +368,13 @@ execute_in_high_mem:
sethi %hi(linux_dbvec), %g1
st %o1, [%g1 + %lo(linux_dbvec)]
- ld [%o0 + 0x4], %o3
- and %o3, 0x3, %o5 ! get the version
-
- cmp %o3, 0x2 ! a v2 prom?
- be found_version
- nop
-
- /* paul@sfe.com.au */
- cmp %o3, 0x3 ! a v3 prom?
- be found_version
- nop
-
-/* Old sun4's pass our load address into %o0 instead of the prom
- * pointer. On sun4's you have to hard code the romvec pointer into
- * your code. Sun probably still does that because they don't even
- * trust their own "OpenBoot" specifications.
- */
- set LOAD_ADDR, %g6
- cmp %o0, %g6 ! an old sun4?
- be sun4_init
- nop
-
-found_version:
-/* Get the machine type via the mysterious romvec node operations. */
-
- add %g7, 0x1c, %l1
+ /* Get the machine type via the romvec
+ * getprops node operation
+ */
+ add %g7, 0x1c, %l1
ld [%l1], %l0
ld [%l0], %l0
- call %l0
+ call %l0
or %g0, %g0, %o0 ! next_node(0) = first_node
or %o0, %g0, %g6
@@ -786,31 +382,49 @@ found_version:
or %o1, %lo(cputypvar), %o1
sethi %hi(cputypval), %o2 ! information, the string
or %o2, %lo(cputypval), %o2
- ld [%l1], %l0 ! 'compatibility' tells
+ ld [%l1], %l0 ! 'compatible' tells
ld [%l0 + 0xc], %l0 ! that we want 'sun4x' where
- call %l0 ! x is one of '', 'c', 'm',
- nop ! 'd' or 'e'. %o2 holds pointer
+ call %l0 ! x is one of 'm', 'd' or 'e'.
+ nop ! %o2 holds pointer
! to a buf where above string
! will get stored by the prom.
- subcc %o0, %g0, %g0
- bpos got_prop ! Got the property
- nop
- or %g6, %g0, %o0
- sethi %hi(cputypvar_sun4m), %o1
- or %o1, %lo(cputypvar_sun4m), %o1
- sethi %hi(cputypval), %o2
- or %o2, %lo(cputypval), %o2
- ld [%l1], %l0
- ld [%l0 + 0xc], %l0
- call %l0
+ /* Check value of "compatible" property.
+ * "value" => "model"
+ * leon => sparc_leon
+ * sun4m => sun4m
+ * sun4s => sun4m
+ * sun4d => sun4d
+ * sun4e => "no_sun4e_here"
+ * '*' => "no_sun4u_here"
+ * Check single letters only
+ */
+
+ set cputypval, %o2
+ /* If cputypval[0] == 'l' (lower case letter L) this is leon */
+ ldub [%o2], %l1
+ cmp %l1, 'l'
+ be leon_init
nop
-got_prop:
-#ifdef CONFIG_SPARC_LEON
- /* no cpu-type check is needed, it is a SPARC-LEON */
+ /* Check cputypval[4] to find the sun model */
+ ldub [%o2 + 0x4], %l1
+
+ cmp %l1, 'm'
+ be sun4m_init
+ cmp %l1, 's'
+ be sun4m_init
+ cmp %l1, 'd'
+ be sun4d_init
+ cmp %l1, 'e'
+ be no_sun4e_here ! Could be a sun4e.
+ nop
+ b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
+ nop
+leon_init:
+ /* LEON CPU - set boot_cpu_id */
sethi %hi(boot_cpu_id), %g2 ! boot-cpu index
#ifdef CONFIG_SMP
@@ -826,43 +440,7 @@ got_prop:
/* Update boot_cpu_id only on boot cpu */
stub %g1, [%g2 + %lo(boot_cpu_id)]
- ba sun4c_continue_boot
- nop
-#endif
- set cputypval, %o2
- ldub [%o2 + 0x4], %l1
-
- cmp %l1, ' '
- be 1f
- cmp %l1, 'c'
- be 1f
- cmp %l1, 'm'
- be 1f
- cmp %l1, 's'
- be 1f
- cmp %l1, 'd'
- be 1f
- cmp %l1, 'e'
- be no_sun4e_here ! Could be a sun4e.
- nop
- b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
- nop
-
-1: set cputypval, %l1
- ldub [%l1 + 0x4], %l1
- cmp %l1, 'm' ! Test for sun4d, sun4e ?
- be sun4m_init
- cmp %l1, 's' ! Treat sun4s as sun4m
- be sun4m_init
- cmp %l1, 'd' ! Let us see how the beast will die
- be sun4d_init
- nop
-
- /* Jump into mmu context zero. */
- set AC_CONTEXT, %g1
- stba %g0, [%g1] ASI_CONTROL
-
- b sun4c_continue_boot
+ ba continue_boot
nop
/* CPUID in bootbus can be found at PA 0xff0140000 */
@@ -892,66 +470,6 @@ sun4d_init:
/* Fall through to sun4m_init */
sun4m_init:
- /* XXX Fucking Cypress... */
- lda [%g0] ASI_M_MMUREGS, %g5
- srl %g5, 28, %g4
-
- cmp %g4, 1
- bne 1f
- srl %g5, 24, %g4
-
- and %g4, 0xf, %g4
- cmp %g4, 7 /* This would be a HyperSparc. */
-
- bne 2f
- nop
-
-1:
-
-#define PATCH_IT(dst, src) \
- set (dst), %g5; \
- set (src), %g4; \
- ld [%g4], %g3; \
- st %g3, [%g5]; \
- ld [%g4+0x4], %g3; \
- st %g3, [%g5+0x4];
-
- /* Signed multiply. */
- PATCH_IT(.mul, .mul_patch)
- PATCH_IT(.mul+0x08, .mul_patch+0x08)
-
- /* Signed remainder. */
- PATCH_IT(.rem, .rem_patch)
- PATCH_IT(.rem+0x08, .rem_patch+0x08)
- PATCH_IT(.rem+0x10, .rem_patch+0x10)
- PATCH_IT(.rem+0x18, .rem_patch+0x18)
- PATCH_IT(.rem+0x20, .rem_patch+0x20)
- PATCH_IT(.rem+0x28, .rem_patch+0x28)
-
- /* Signed division. */
- PATCH_IT(.div, .div_patch)
- PATCH_IT(.div+0x08, .div_patch+0x08)
- PATCH_IT(.div+0x10, .div_patch+0x10)
- PATCH_IT(.div+0x18, .div_patch+0x18)
- PATCH_IT(.div+0x20, .div_patch+0x20)
-
- /* Unsigned multiply. */
- PATCH_IT(.umul, .umul_patch)
- PATCH_IT(.umul+0x08, .umul_patch+0x08)
-
- /* Unsigned remainder. */
- PATCH_IT(.urem, .urem_patch)
- PATCH_IT(.urem+0x08, .urem_patch+0x08)
- PATCH_IT(.urem+0x10, .urem_patch+0x10)
- PATCH_IT(.urem+0x18, .urem_patch+0x18)
-
- /* Unsigned division. */
- PATCH_IT(.udiv, .udiv_patch)
- PATCH_IT(.udiv+0x08, .udiv_patch+0x08)
- PATCH_IT(.udiv+0x10, .udiv_patch+0x10)
-
-#undef PATCH_IT
-
/* Ok, the PROM could have done funny things and apple cider could still
* be sitting in the fault status/address registers. Read them all to
* clear them so we don't get magic faults later on.
@@ -959,10 +477,10 @@ sun4m_init:
/* This sucks, apparently this makes Vikings call prom panic, will fix later */
2:
rd %psr, %o1
- srl %o1, 28, %o1 ! Get a type of the CPU
+ srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU
- subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC
- be sun4c_continue_boot
+ subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC
+ be continue_boot
nop
set AC_M_SFSR, %o0
@@ -972,7 +490,7 @@ sun4m_init:
/* Fujitsu MicroSPARC-II has no asynchronous flavors of FARs */
subcc %o1, 0, %g0
- be sun4c_continue_boot
+ be continue_boot
nop
set AC_M_AFSR, %o0
@@ -982,16 +500,11 @@ sun4m_init:
nop
-sun4c_continue_boot:
-
+continue_boot:
/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
* show-time!
*/
-
- sethi %hi(cputyp), %o0
- st %g4, [%o0 + %lo(cputyp)]
-
/* Turn on Supervisor, EnableFloating, and all the PIL bits.
* Also puts us in register window zero with traps off.
*/
@@ -1009,7 +522,7 @@ sun4c_continue_boot:
set __bss_start , %o0 ! First address of BSS
set _end , %o1 ! Last address of BSS
add %o0, 0x1, %o0
-1:
+1:
stb %g0, [%o0]
subcc %o0, %o1, %g0
bl 1b
@@ -1026,10 +539,7 @@ sun4c_continue_boot:
mov %g0, %g3
stub %g3, [%g2 + %lo(boot_cpu_id)]
-1: /* boot_cpu_id set. calculate boot_cpu_id4 = boot_cpu_id*4 */
- sll %g3, 2, %g3
- sethi %hi(boot_cpu_id4), %g2
- stub %g3, [%g2 + %lo(boot_cpu_id4)]
+1: sll %g3, 2, %g3
/* Initialize the uwinmask value for init task just in case.
* But first make current_set[boot_cpu_id] point to something useful.
@@ -1078,7 +588,7 @@ sun4c_continue_boot:
set dest, %g2; \
ld [%g5], %g4; \
st %g4, [%g2];
-
+
/* Patch for window spills... */
PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
@@ -1129,7 +639,7 @@ sun4c_continue_boot:
st %g4, [%g5 + 0x18]
st %g4, [%g5 + 0x1c]
-2:
+2:
sethi %hi(nwindows), %g4
st %g3, [%g4 + %lo(nwindows)] ! store final value
sub %g3, 0x1, %g3
@@ -1149,35 +659,16 @@ sun4c_continue_boot:
wr %g3, PSR_ET, %psr
WRITE_PAUSE
- /* First we call prom_init() to set up PROMLIB, then
- * off to start_kernel().
- */
-
+ /* Call sparc32_start_kernel(struct linux_romvec *rp) */
sethi %hi(prom_vector_p), %g5
ld [%g5 + %lo(prom_vector_p)], %o0
- call prom_init
+ call sparc32_start_kernel
nop
- call start_kernel
- nop
-
/* We should not get here. */
call halt_me
nop
-sun4_init:
- sethi %hi(SUN4_PROM_VECTOR+0x84), %o1
- ld [%o1 + %lo(SUN4_PROM_VECTOR+0x84)], %o1
- set sun4_notsup, %o0
- call %o1 /* printf */
- nop
- sethi %hi(SUN4_PROM_VECTOR+0xc4), %o1
- ld [%o1 + %lo(SUN4_PROM_VECTOR+0xc4)], %o1
- call %o1 /* exittomon */
- nop
-1: ba 1b ! Cannot exit into KMON
- nop
-
no_sun4e_here:
ld [%g7 + 0x68], %o1
set sun4e_notsup, %o0
@@ -1204,7 +695,7 @@ sun4u_5:
.asciz "write"
.align 4
sun4u_6:
- .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r"
+ .asciz "\n\rOn sun4u you have to use sparc64 kernel\n\rand not a sparc32 version\n\r\n\r"
sun4u_6e:
.align 4
sun4u_7:
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index 0d810c2f1d0..b42ddbf9651 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -906,7 +906,7 @@ swapper_4m_tsb:
* error and will instead write junk into the relocation and
* you'll have an unbootable kernel.
*/
-#include "ttable.S"
+#include "ttable_64.S"
! 0x0000000000428000
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c
index 9167db40720..6bd75012109 100644
--- a/arch/sparc/kernel/idprom.c
+++ b/arch/sparc/kernel/idprom.c
@@ -25,22 +25,9 @@ static struct idprom idprom_buffer;
* of the Sparc CPU and have a meaningful IDPROM machtype value that we
* know about. See asm-sparc/machines.h for empirical constants.
*/
-static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
-/* First, Sun4's */
-{ .name = "Sun 4/100 Series", .id_machtype = (SM_SUN4 | SM_4_110) },
-{ .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) },
-{ .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) },
-{ .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) },
-/* Now Leon */
+static struct Sun_Machine_Models Sun_Machines[] = {
+/* First, Leon */
{ .name = "Leon3 System-on-a-Chip", .id_machtype = (M_LEON | M_LEON3_SOC) },
-/* Now, Sun4c's */
-{ .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) },
-{ .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) },
-{ .name = "Sun4c SparcStation 1+", .id_machtype = (SM_SUN4C | SM_4C_SS1PLUS) },
-{ .name = "Sun4c SparcStation SLC", .id_machtype = (SM_SUN4C | SM_4C_SLC) },
-{ .name = "Sun4c SparcStation 2", .id_machtype = (SM_SUN4C | SM_4C_SS2) },
-{ .name = "Sun4c SparcStation ELC", .id_machtype = (SM_SUN4C | SM_4C_ELC) },
-{ .name = "Sun4c SparcStation IPX", .id_machtype = (SM_SUN4C | SM_4C_IPX) },
/* Finally, early Sun4m's */
{ .name = "Sun4m SparcSystem600", .id_machtype = (SM_SUN4M | SM_4M_SS60) },
{ .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) },
@@ -53,7 +40,7 @@ static void __init display_system_type(unsigned char machtype)
char sysname[128];
register int i;
- for (i = 0; i < NUM_SUN_MACHINES; i++) {
+ for (i = 0; i < ARRAY_SIZE(Sun_Machines); i++) {
if (Sun_Machines[i].id_machtype == machtype) {
if (machtype != (SM_SUN4M_OBP | 0x00) ||
prom_getproperty(prom_root_node, "banner-name",
diff --git a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c
deleted file mode 100644
index 35f141a9f50..00000000000
--- a/arch/sparc/kernel/init_task.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init_task.h>
-#include <linux/mqueue.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct task_struct init_task = INIT_TASK(init_task);
-EXPORT_SYMBOL(init_task);
-
-/* .text section in head.S is aligned at 8k boundary and this gets linked
- * right after that so that the init_thread_union is aligned properly as well.
- * If this is not aligned on a 8k boundary, then you should change code
- * in etrap.S which assumes it.
- */
-union thread_union init_thread_union __init_task_data =
- { INIT_THREAD_INFO(init_task) };
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 21bd73943f7..0f094db918c 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -50,20 +50,18 @@
#include <asm/io-unit.h>
#include <asm/leon.h>
+const struct sparc32_dma_ops *sparc32_dma_ops;
+
/* This function must make sure that caches and memory are coherent after DMA
* On LEON systems without cache snooping it flushes the entire D-CACHE.
*/
-#ifndef CONFIG_SPARC_LEON
-static inline void dma_make_coherent(unsigned long pa, unsigned long len)
-{
-}
-#else
static inline void dma_make_coherent(unsigned long pa, unsigned long len)
{
- if (!sparc_leon3_snooping_enabled())
- leon_flush_dcache_all();
+ if (sparc_cpu_model == sparc_leon) {
+ if (!sparc_leon3_snooping_enabled())
+ leon_flush_dcache_all();
+ }
}
-#endif
static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz);
static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys,
@@ -229,7 +227,7 @@ _sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz)
}
pa &= PAGE_MASK;
- sparc_mapiorange(bus, pa, res->start, resource_size(res));
+ srmmu_mapiorange(bus, pa, res->start, resource_size(res));
return (void __iomem *)(unsigned long)(res->start + offset);
}
@@ -243,7 +241,7 @@ static void _sparc_free_io(struct resource *res)
plen = resource_size(res);
BUG_ON((plen & (PAGE_SIZE-1)) != 0);
- sparc_unmapiorange(res->start, plen);
+ srmmu_unmapiorange(res->start, plen);
release_resource(res);
}
@@ -292,13 +290,13 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len,
goto err_nova;
}
- // XXX The mmu_map_dma_area does this for us below, see comments.
- // sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
+ // XXX The sbus_map_dma_area does this for us below, see comments.
+ // srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total);
/*
* XXX That's where sdev would be used. Currently we load
* all iommu tables with the same translations.
*/
- if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
+ if (sbus_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
goto err_noiommu;
res->name = op->dev.of_node->name;
@@ -343,7 +341,7 @@ static void sbus_free_coherent(struct device *dev, size_t n, void *p,
kfree(res);
pgv = virt_to_page(p);
- mmu_unmap_dma_area(dev, ba, n);
+ sbus_unmap_dma_area(dev, ba, n);
__free_pages(pgv, get_order(n));
}
@@ -381,11 +379,6 @@ static int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n,
enum dma_data_direction dir, struct dma_attrs *attrs)
{
mmu_get_scsi_sgl(dev, sg, n);
-
- /*
- * XXX sparc64 can return a partial length here. sun4c should do this
- * but it currently panics if it can't fulfill the request - Anton
- */
return n;
}
@@ -430,9 +423,6 @@ arch_initcall(sparc_register_ioport);
#endif /* CONFIG_SBUS */
-/* LEON reuses PCI DMA ops */
-#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON)
-
/* Allocate and map kernel buffer using consistent mode DMA for a device.
* hwdev should be valid struct pci_dev pointer for PCI devices.
*/
@@ -469,7 +459,7 @@ static void *pci32_alloc_coherent(struct device *dev, size_t len,
printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total);
goto err_nova;
}
- sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
+ srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total);
*pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
return (void *) res->start;
@@ -514,7 +504,7 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p,
}
dma_make_coherent(ba, n);
- sparc_unmapiorange((unsigned long)p, n);
+ srmmu_unmapiorange((unsigned long)p, n);
release_resource(res);
kfree(res);
@@ -660,14 +650,11 @@ struct dma_map_ops pci32_dma_ops = {
};
EXPORT_SYMBOL(pci32_dma_ops);
-#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */
+/* leon re-uses pci32_dma_ops */
+struct dma_map_ops *leon_dma_ops = &pci32_dma_ops;
+EXPORT_SYMBOL(leon_dma_ops);
-#ifdef CONFIG_SPARC_LEON
-struct dma_map_ops *dma_ops = &pci32_dma_ops;
-#elif defined(CONFIG_SBUS)
struct dma_map_ops *dma_ops = &sbus_dma_ops;
-#endif
-
EXPORT_SYMBOL(dma_ops);
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index 5a021dd2f85..b66b6aad1d6 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -1,6 +1,5 @@
#include <linux/platform_device.h>
-#include <asm/btfixup.h>
#include <asm/cpu_type.h>
struct irq_bucket {
@@ -10,6 +9,9 @@ struct irq_bucket {
unsigned int pil;
};
+#define SUN4M_HARD_INT(x) (0x000000001 << (x))
+#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
+
#define SUN4D_MAX_BOARD 10
#define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5)
@@ -41,52 +43,46 @@ struct sun4m_irq_global {
extern struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
extern struct sun4m_irq_global __iomem *sun4m_irq_global;
+/* The following definitions describe the individual platform features: */
+#define FEAT_L10_CLOCKSOURCE (1 << 0) /* L10 timer is used as a clocksource */
+#define FEAT_L10_CLOCKEVENT (1 << 1) /* L10 timer is used as a clockevent */
+#define FEAT_L14_ONESHOT (1 << 2) /* L14 timer clockevent can oneshot */
+
/*
- * Platform specific irq configuration
+ * Platform specific configuration
* The individual platforms assign their platform
* specifics in their init functions.
*/
-struct sparc_irq_config {
- void (*init_timers)(irq_handler_t);
+struct sparc_config {
+ void (*init_timers)(void);
unsigned int (*build_device_irq)(struct platform_device *op,
unsigned int real_irq);
+
+ /* generic clockevent features - see FEAT_* above */
+ int features;
+
+ /* clock rate used for clock event timer */
+ int clock_rate;
+
+ /* one period for clock source timer */
+ unsigned int cs_period;
+
+ /* function to obtain offsett for cs period */
+ unsigned int (*get_cycles_offset)(void);
+
+ void (*clear_clock_irq)(void);
+ void (*load_profile_irq)(int cpu, unsigned int limit);
};
-extern struct sparc_irq_config sparc_irq_config;
+extern struct sparc_config sparc_config;
unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
void irq_link(unsigned int irq);
void irq_unlink(unsigned int irq);
void handler_irq(unsigned int pil, struct pt_regs *regs);
-/* Dave Redman (djhr@tadpole.co.uk)
- * changed these to function pointers.. it saves cycles and will allow
- * the irq dependencies to be split into different files at a later date
- * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size.
- * Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Changed these to btfixup entities... It saves cycles :)
- */
-
-BTFIXUPDEF_CALL(void, clear_clock_irq, void)
-BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
-
-static inline void clear_clock_irq(void)
-{
- BTFIXUP_CALL(clear_clock_irq)();
-}
-
-static inline void load_profile_irq(int cpu, int limit)
-{
- BTFIXUP_CALL(load_profile_irq)(cpu, limit);
-}
+unsigned long leon_get_irqmask(unsigned int irq);
#ifdef CONFIG_SMP
-BTFIXUPDEF_CALL(void, set_cpu_int, int, int)
-BTFIXUPDEF_CALL(void, clear_cpu_int, int, int)
-BTFIXUPDEF_CALL(void, set_irq_udt, int)
-
-#define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level)
-#define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level)
-#define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu)
/* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
#define SUN4D_IPI_IRQ 13
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index b2668afd1c3..c145f6fd123 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -23,16 +23,8 @@
#include "kernel.h"
#include "irq.h"
-#ifdef CONFIG_SMP
-#define SMP_NOP2 "nop; nop;\n\t"
-#define SMP_NOP3 "nop; nop; nop;\n\t"
-#else
-#define SMP_NOP2
-#define SMP_NOP3
-#endif /* SMP */
-
/* platform specific irq setup */
-struct sparc_irq_config sparc_irq_config;
+struct sparc_config sparc_config;
unsigned long arch_local_irq_save(void)
{
@@ -41,7 +33,6 @@ unsigned long arch_local_irq_save(void)
__asm__ __volatile__(
"rd %%psr, %0\n\t"
- SMP_NOP3 /* Sun4m + Cypress + SMP bug */
"or %0, %2, %1\n\t"
"wr %1, 0, %%psr\n\t"
"nop; nop; nop\n"
@@ -59,7 +50,6 @@ void arch_local_irq_enable(void)
__asm__ __volatile__(
"rd %%psr, %0\n\t"
- SMP_NOP3 /* Sun4m + Cypress + SMP bug */
"andn %0, %1, %0\n\t"
"wr %0, 0, %%psr\n\t"
"nop; nop; nop\n"
@@ -76,7 +66,6 @@ void arch_local_irq_restore(unsigned long old_psr)
__asm__ __volatile__(
"rd %%psr, %0\n\t"
"and %2, %1, %2\n\t"
- SMP_NOP2 /* Sun4m + Cypress + SMP bug */
"andn %0, %1, %0\n\t"
"wr %0, %2, %%psr\n\t"
"nop; nop; nop\n"
@@ -252,9 +241,6 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
unsigned int cpu_irq;
int err;
-#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
- struct tt_entry *trap_table;
-#endif
err = request_irq(irq, irq_handler, 0, "floppy", NULL);
if (err)
@@ -275,13 +261,18 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
INSTANTIATE(sparc_ttable)
-#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
- trap_table = &trapbase_cpu1;
- INSTANTIATE(trap_table)
- trap_table = &trapbase_cpu2;
- INSTANTIATE(trap_table)
- trap_table = &trapbase_cpu3;
- INSTANTIATE(trap_table)
+
+#if defined CONFIG_SMP
+ if (sparc_cpu_model != sparc_leon) {
+ struct tt_entry *trap_table;
+
+ trap_table = &trapbase_cpu1;
+ INSTANTIATE(trap_table)
+ trap_table = &trapbase_cpu2;
+ INSTANTIATE(trap_table)
+ trap_table = &trapbase_cpu3;
+ INSTANTIATE(trap_table)
+ }
#endif
#undef INSTANTIATE
/*
@@ -346,11 +337,6 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
void __init init_IRQ(void)
{
switch (sparc_cpu_model) {
- case sun4c:
- case sun4:
- sun4c_init_IRQ();
- break;
-
case sun4m:
pcic_probe();
if (pcic_present())
@@ -371,6 +357,5 @@ void __init init_IRQ(void)
prom_printf("Cannot initialize IRQs on this Sun machine...");
break;
}
- btfixup();
}
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index dff2c3d7d37..9bcbbe2c4e7 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -799,7 +799,7 @@ static void kill_prom_timer(void)
prom_limit0 = prom_timers->limit0;
prom_limit1 = prom_timers->limit1;
- /* Just as in sun4c/sun4m PROM uses timer which ticks at IRQ 14.
+ /* Just as in sun4c PROM uses timer which ticks at IRQ 14.
* We turn both off here just to be paranoid.
*/
prom_timers->limit0 = 0;
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index fd6c36b1df7..291bb5de9ce 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -26,15 +26,15 @@ static inline unsigned long kimage_addr_to_ra(const char *p)
#endif
#ifdef CONFIG_SPARC32
+/* setup_32.c */
+void sparc32_start_kernel(struct linux_romvec *rp);
+
/* cpu.c */
extern void cpu_probe(void);
/* traps_32.c */
extern void handle_hw_divzero(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
-/* muldiv.c */
-extern int do_user_muldiv (struct pt_regs *, unsigned long);
-
/* irq_32.c */
extern struct irqaction static_irqaction[];
extern int static_irq_count;
@@ -43,12 +43,7 @@ extern spinlock_t irq_action_lock;
extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs);
extern void init_IRQ(void);
-/* sun4c_irq.c */
-extern void sun4c_init_IRQ(void);
-
/* sun4m_irq.c */
-extern unsigned int lvl14_resolution;
-
extern void sun4m_init_IRQ(void);
extern void sun4m_unmask_profile_irq(void);
extern void sun4m_clear_profile_irq(int cpu);
@@ -85,8 +80,6 @@ extern unsigned int patchme_maybe_smp_msg[];
extern void floppy_hardint(void);
/* trampoline_32.S */
-extern int __smp4m_processor_id(void);
-extern int __smp4d_processor_id(void);
extern unsigned long sun4m_cpu_startup;
extern unsigned long sun4d_cpu_startup;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 35e43673c45..e34e2c40c06 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -10,6 +10,8 @@
#include <linux/of_platform.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <asm/oplib.h>
#include <asm/timer.h>
@@ -21,6 +23,7 @@
#include <asm/smp.h>
#include <asm/setup.h>
+#include "kernel.h"
#include "prom.h"
#include "irq.h"
@@ -84,7 +87,7 @@ void leon_eirq_setup(unsigned int eirq)
sparc_leon_eirq = eirq;
}
-static inline unsigned long get_irqmask(unsigned int irq)
+unsigned long leon_get_irqmask(unsigned int irq)
{
unsigned long mask;
@@ -210,7 +213,7 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
unsigned long mask;
irq = 0;
- mask = get_irqmask(real_irq);
+ mask = leon_get_irqmask(real_irq);
if (mask == 0)
goto out;
@@ -250,7 +253,38 @@ void leon_update_virq_handling(unsigned int virq,
irq_set_chip_data(virq, (void *)mask);
}
-void __init leon_init_timers(irq_handler_t counter_fn)
+static u32 leon_cycles_offset(void)
+{
+ u32 rld, val, off;
+ rld = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld);
+ val = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val);
+ off = rld - val;
+ return rld - val;
+}
+
+#ifdef CONFIG_SMP
+
+/* smp clockevent irq */
+irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused)
+{
+ struct clock_event_device *ce;
+ int cpu = smp_processor_id();
+
+ leon_clear_profile_irq(cpu);
+
+ ce = &per_cpu(sparc32_clockevent, cpu);
+
+ irq_enter();
+ if (ce->event_handler)
+ ce->event_handler(ce);
+ irq_exit();
+
+ return IRQ_HANDLED;
+}
+
+#endif /* CONFIG_SMP */
+
+void __init leon_init_timers(void)
{
int irq, eirq;
struct device_node *rootnp, *np, *nnp;
@@ -260,6 +294,14 @@ void __init leon_init_timers(irq_handler_t counter_fn)
int ampopts;
int err;
+ sparc_config.get_cycles_offset = leon_cycles_offset;
+ sparc_config.cs_period = 1000000 / HZ;
+ sparc_config.features |= FEAT_L10_CLOCKSOURCE;
+
+#ifndef CONFIG_SMP
+ sparc_config.features |= FEAT_L10_CLOCKEVENT;
+#endif
+
leondebug_irq_disable = 0;
leon_debug_irqout = 0;
master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
@@ -369,7 +411,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
leon_eirq_setup(eirq);
irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx);
- err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
+ err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
if (err) {
printk(KERN_ERR "unable to attach timer IRQ%d\n", irq);
prom_halt();
@@ -386,7 +428,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
*/
local_irq_save(flags);
patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
- local_flush_cache_all();
+ local_ops->cache_all();
local_irq_restore(flags);
}
#endif
@@ -401,7 +443,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
/* Install per-cpu IRQ handler for broadcasted ticker */
irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq,
"per-cpu", 0);
- err = request_irq(irq, leon_percpu_timer_interrupt,
+ err = request_irq(irq, leon_percpu_timer_ce_interrupt,
IRQF_PERCPU | IRQF_TIMER, "ticker",
NULL);
if (err) {
@@ -422,13 +464,12 @@ bad:
return;
}
-void leon_clear_clock_irq(void)
+static void leon_clear_clock_irq(void)
{
}
-void leon_load_profile_irq(int cpu, unsigned int limit)
+static void leon_load_profile_irq(int cpu, unsigned int limit)
{
- BUG();
}
void __init leon_trans_init(struct device_node *dp)
@@ -457,25 +498,6 @@ 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)
{
}
@@ -483,7 +505,7 @@ 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);
+ mask = leon_get_irqmask(irq_nr);
spin_lock_irqsave(&leon_irq_lock, flags);
addr = (unsigned long *)LEON_IMASK(cpu);
LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask));
@@ -494,20 +516,11 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu)
void __init leon_init_IRQ(void)
{
- sparc_irq_config.init_timers = leon_init_timers;
- sparc_irq_config.build_device_irq = _leon_build_device_irq;
-
- BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq,
- BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq,
- BTFIXUPCALL_NOP);
-
-#ifdef CONFIG_SMP
- BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(clear_cpu_int, leon_clear_ipi, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(set_irq_udt, leon_set_udt, BTFIXUPCALL_NORM);
-#endif
-
+ sparc_config.init_timers = leon_init_timers;
+ sparc_config.build_device_irq = _leon_build_device_irq;
+ sparc_config.clock_rate = 1000000;
+ sparc_config.clear_clock_irq = leon_clear_clock_irq;
+ sparc_config.load_profile_irq = leon_load_profile_irq;
}
void __init leon_init(void)
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c
index 519ca923f59..4e174321097 100644
--- a/arch/sparc/kernel/leon_pmc.c
+++ b/arch/sparc/kernel/leon_pmc.c
@@ -7,6 +7,7 @@
#include <linux/pm.h>
#include <asm/leon_amba.h>
+#include <asm/cpu_type.h>
#include <asm/leon.h>
/* List of Systems that need fixup instructions around power-down instruction */
@@ -65,13 +66,15 @@ void pmc_leon_idle(void)
/* Install LEON Power Down function */
static int __init leon_pmc_install(void)
{
- /* Assign power management IDLE handler */
- if (pmc_leon_need_fixup())
- pm_idle = pmc_leon_idle_fixup;
- else
- pm_idle = pmc_leon_idle;
+ if (sparc_cpu_model == sparc_leon) {
+ /* Assign power management IDLE handler */
+ if (pmc_leon_need_fixup())
+ pm_idle = pmc_leon_idle_fixup;
+ else
+ pm_idle = pmc_leon_idle;
- printk(KERN_INFO "leon: power management initialized\n");
+ printk(KERN_INFO "leon: power management initialized\n");
+ }
return 0;
}
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 160cac9c403..0f3fb6d9c8e 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/cpu.h>
+#include <linux/clockchips.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
@@ -43,18 +44,17 @@
#include <asm/asi.h>
#include <asm/leon.h>
#include <asm/leon_amba.h>
+#include <asm/timer.h>
#include "kernel.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 cpumask_t smp_commenced_mask;
-void __init leon_configure_cache_smp(void);
+void __cpuinit leon_configure_cache_smp(void);
static void leon_ipi_init(void);
/* IRQ number of LEON IPIs */
@@ -69,26 +69,24 @@ static inline unsigned long do_swap(volatile unsigned long *ptr,
return val;
}
-static void smp_setup_percpu_timer(void);
-
void __cpuinit leon_callin(void)
{
- int cpuid = hard_smpleon_processor_id();
+ int cpuid = hard_smp_processor_id();
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
leon_configure_cache_smp();
notify_cpu_starting(cpuid);
/* Get our local ticker going. */
- smp_setup_percpu_timer();
+ register_percpu_ce(cpuid);
calibrate_delay();
smp_store_cpu_info(cpuid);
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
/*
* Unblock the master CPU _only_ when the scheduler state
@@ -99,8 +97,8 @@ void __cpuinit leon_callin(void)
*/
do_swap(&cpu_callin_map[cpuid], 1);
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
/* Fix idle thread fields. */
__asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(&current_set[cpuid])
@@ -123,7 +121,7 @@ void __cpuinit leon_callin(void)
extern struct linux_prom_registers smp_penguin_ctable;
-void __init leon_configure_cache_smp(void)
+void __cpuinit leon_configure_cache_smp(void)
{
unsigned long cfg = sparc_leon3_get_dcachecfg();
int me = smp_processor_id();
@@ -143,8 +141,8 @@ void __init leon_configure_cache_smp(void)
}
}
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
}
void leon_smp_setbroadcast(unsigned int mask)
@@ -199,21 +197,15 @@ void __init leon_boot_cpus(void)
leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER);
leon_configure_cache_smp();
- smp_setup_percpu_timer();
- local_flush_cache_all();
+ local_ops->cache_all();
}
-int __cpuinit leon_boot_one_cpu(int i)
+int __cpuinit leon_boot_one_cpu(int i, struct task_struct *idle)
{
-
- struct task_struct *p;
int timeout;
- /* Cook up an idler for this guy. */
- p = fork_idle(i);
-
- current_set[i] = task_thread_info(p);
+ current_set[i] = task_thread_info(idle);
/* See trampoline.S:leon_smp_cpu_startup for details...
* Initialize the contexts table
@@ -227,7 +219,7 @@ int __cpuinit leon_boot_one_cpu(int i)
/* 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();
+ local_ops->cache_all();
/* Make sure all IRQs are of from the start for this new CPU */
LEON_BYPASS_STORE_PA(&leon3_irqctrl_regs->mask[i], 0);
@@ -252,7 +244,7 @@ int __cpuinit leon_boot_one_cpu(int i)
leon_enable_irq_cpu(leon_ipi_irq, i);
}
- local_flush_cache_all();
+ local_ops->cache_all();
return 0;
}
@@ -272,7 +264,7 @@ void __init leon_smp_done(void)
}
}
*prev = first;
- local_flush_cache_all();
+ local_ops->cache_all();
/* Free unneeded trap tables */
if (!cpu_present(1)) {
@@ -338,7 +330,7 @@ static void __init leon_ipi_init(void)
local_irq_save(flags);
trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_ipi_irq - 1)];
trap_table->inst_three += smpleon_ipi - real_irq_entry;
- local_flush_cache_all();
+ local_ops->cache_all();
local_irq_restore(flags);
for_each_possible_cpu(cpu) {
@@ -347,6 +339,13 @@ static void __init leon_ipi_init(void)
}
}
+static void leon_send_ipi(int cpu, int level)
+{
+ unsigned long mask;
+ mask = leon_get_irqmask(level);
+ LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask);
+}
+
static void leon_ipi_single(int cpu)
{
struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu);
@@ -355,7 +354,7 @@ static void leon_ipi_single(int cpu)
work->single = 1;
/* Generate IRQ on the CPU */
- set_cpu_int(cpu, leon_ipi_irq);
+ leon_send_ipi(cpu, leon_ipi_irq);
}
static void leon_ipi_mask_one(int cpu)
@@ -366,7 +365,7 @@ static void leon_ipi_mask_one(int cpu)
work->msk = 1;
/* Generate IRQ on the CPU */
- set_cpu_int(cpu, leon_ipi_irq);
+ leon_send_ipi(cpu, leon_ipi_irq);
}
static void leon_ipi_resched(int cpu)
@@ -377,7 +376,7 @@ static void leon_ipi_resched(int cpu)
work->resched = 1;
/* Generate IRQ on the CPU (any IRQ will cause resched) */
- set_cpu_int(cpu, leon_ipi_irq);
+ leon_send_ipi(cpu, leon_ipi_irq);
}
void leonsmp_ipi_interrupt(void)
@@ -449,7 +448,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
if (cpumask_test_cpu(i, &mask)) {
ccall_info.processors_in[i] = 0;
ccall_info.processors_out[i] = 0;
- set_cpu_int(i, LEON3_IRQ_CROSS_CALL);
+ leon_send_ipi(i, LEON3_IRQ_CROSS_CALL);
}
}
@@ -492,68 +491,17 @@ void leon_cross_call_irq(void)
ccall_info.processors_out[i] = 1;
}
-irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused)
-{
- int cpu = smp_processor_id();
-
- leon_clear_profile_irq(cpu);
-
- profile_tick(CPU_PROFILING);
-
- if (!--prof_counter(cpu)) {
- int user = user_mode(get_irq_regs());
-
- update_process_times(user);
-
- prof_counter(cpu) = prof_multiplier(cpu);
- }
-
- return IRQ_HANDLED;
-}
-
-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 */
-
-}
+static const struct sparc32_ipi_ops leon_ipi_ops = {
+ .cross_call = leon_cross_call,
+ .resched = leon_ipi_resched,
+ .single = leon_ipi_single,
+ .mask_one = leon_ipi_mask_one,
+};
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);
- BTFIXUPSET_CALL(smp_ipi_resched, leon_ipi_resched, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_single, leon_ipi_single, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_mask_one, leon_ipi_mask_one, BTFIXUPCALL_NORM);
+ sparc32_ipi_ops = &leon_ipi_ops;
}
-
-#endif /* CONFIG_SPARC_LEON */
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 276359e1ff5..15e0a169397 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -32,26 +32,11 @@ static void *module_map(unsigned long size)
GFP_KERNEL, PAGE_KERNEL, -1,
__builtin_return_address(0));
}
-
-static char *dot2underscore(char *name)
-{
- return name;
-}
#else
static void *module_map(unsigned long size)
{
return vmalloc(size);
}
-
-/* Replace references to .func with _Func */
-static char *dot2underscore(char *name)
-{
- if (name[0] == '.') {
- name[0] = '_';
- name[1] = toupper(name[1]);
- }
- return name;
-}
#endif /* CONFIG_SPARC64 */
void *module_alloc(unsigned long size)
@@ -93,12 +78,8 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) {
if (sym[i].st_shndx == SHN_UNDEF) {
- if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER) {
+ if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER)
sym[i].st_shndx = SHN_ABS;
- } else {
- char *name = strtab + sym[i].st_name;
- dot2underscore(name);
- }
}
}
return 0;
diff --git a/arch/sparc/kernel/muldiv.c b/arch/sparc/kernel/muldiv.c
deleted file mode 100644
index f7db516b07d..00000000000
--- a/arch/sparc/kernel/muldiv.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * muldiv.c: Hardware multiply/division illegal instruction trap
- * for sun4c/sun4 (which do not have those instructions)
- *
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- *
- * 2004-12-25 Krzysztof Helt (krzysztof.h1@wp.pl)
- * - fixed registers constrains in inline assembly declarations
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-#include "kernel.h"
-
-/* #define DEBUG_MULDIV */
-
-static inline int has_imm13(int insn)
-{
- return (insn & 0x2000);
-}
-
-static inline int is_foocc(int insn)
-{
- return (insn & 0x800000);
-}
-
-static inline int sign_extend_imm13(int imm)
-{
- return imm << 19 >> 19;
-}
-
-static inline void advance(struct pt_regs *regs)
-{
- regs->pc = regs->npc;
- regs->npc += 4;
-}
-
-static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2,
- unsigned int rd)
-{
- if(rs2 >= 16 || rs1 >= 16 || rd >= 16) {
- /* Wheee... */
- __asm__ __volatile__("save %sp, -0x40, %sp\n\t"
- "save %sp, -0x40, %sp\n\t"
- "save %sp, -0x40, %sp\n\t"
- "save %sp, -0x40, %sp\n\t"
- "save %sp, -0x40, %sp\n\t"
- "save %sp, -0x40, %sp\n\t"
- "save %sp, -0x40, %sp\n\t"
- "restore; restore; restore; restore;\n\t"
- "restore; restore; restore;\n\t");
- }
-}
-
-#define fetch_reg(reg, regs) ({ \
- struct reg_window32 __user *win; \
- register unsigned long ret; \
- \
- if (!(reg)) ret = 0; \
- else if ((reg) < 16) { \
- ret = regs->u_regs[(reg)]; \
- } else { \
- /* Ho hum, the slightly complicated case. */ \
- win = (struct reg_window32 __user *)regs->u_regs[UREG_FP];\
- if (get_user (ret, &win->locals[(reg) - 16])) return -1;\
- } \
- ret; \
-})
-
-static inline int
-store_reg(unsigned int result, unsigned int reg, struct pt_regs *regs)
-{
- struct reg_window32 __user *win;
-
- if (!reg)
- return 0;
- if (reg < 16) {
- regs->u_regs[reg] = result;
- return 0;
- } else {
- /* need to use put_user() in this case: */
- win = (struct reg_window32 __user *) regs->u_regs[UREG_FP];
- return (put_user(result, &win->locals[reg - 16]));
- }
-}
-
-/* Should return 0 if mul/div emulation succeeded and SIGILL should
- * not be issued.
- */
-int do_user_muldiv(struct pt_regs *regs, unsigned long pc)
-{
- unsigned int insn;
- int inst;
- unsigned int rs1, rs2, rdv;
-
- if (!pc)
- return -1; /* This happens to often, I think */
- if (get_user (insn, (unsigned int __user *)pc))
- return -1;
- if ((insn & 0xc1400000) != 0x80400000)
- return -1;
- inst = ((insn >> 19) & 0xf);
- if ((inst & 0xe) != 10 && (inst & 0xe) != 14)
- return -1;
-
- /* Now we know we have to do something with umul, smul, udiv or sdiv */
- rs1 = (insn >> 14) & 0x1f;
- rs2 = insn & 0x1f;
- rdv = (insn >> 25) & 0x1f;
- if (has_imm13(insn)) {
- maybe_flush_windows(rs1, 0, rdv);
- rs2 = sign_extend_imm13(insn);
- } else {
- maybe_flush_windows(rs1, rs2, rdv);
- rs2 = fetch_reg(rs2, regs);
- }
- rs1 = fetch_reg(rs1, regs);
- switch (inst) {
- case 10: /* umul */
-#ifdef DEBUG_MULDIV
- printk ("unsigned muldiv: 0x%x * 0x%x = ", rs1, rs2);
-#endif
- __asm__ __volatile__ ("\n\t"
- "mov %0, %%o0\n\t"
- "call .umul\n\t"
- " mov %1, %%o1\n\t"
- "mov %%o0, %0\n\t"
- "mov %%o1, %1\n\t"
- : "=r" (rs1), "=r" (rs2)
- : "0" (rs1), "1" (rs2)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc");
-#ifdef DEBUG_MULDIV
- printk ("0x%x%08x\n", rs2, rs1);
-#endif
- if (store_reg(rs1, rdv, regs))
- return -1;
- regs->y = rs2;
- break;
- case 11: /* smul */
-#ifdef DEBUG_MULDIV
- printk ("signed muldiv: 0x%x * 0x%x = ", rs1, rs2);
-#endif
- __asm__ __volatile__ ("\n\t"
- "mov %0, %%o0\n\t"
- "call .mul\n\t"
- " mov %1, %%o1\n\t"
- "mov %%o0, %0\n\t"
- "mov %%o1, %1\n\t"
- : "=r" (rs1), "=r" (rs2)
- : "0" (rs1), "1" (rs2)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7", "cc");
-#ifdef DEBUG_MULDIV
- printk ("0x%x%08x\n", rs2, rs1);
-#endif
- if (store_reg(rs1, rdv, regs))
- return -1;
- regs->y = rs2;
- break;
- case 14: /* udiv */
-#ifdef DEBUG_MULDIV
- printk ("unsigned muldiv: 0x%x%08x / 0x%x = ", regs->y, rs1, rs2);
-#endif
- if (!rs2) {
-#ifdef DEBUG_MULDIV
- printk ("DIVISION BY ZERO\n");
-#endif
- handle_hw_divzero (regs, pc, regs->npc, regs->psr);
- return 0;
- }
- __asm__ __volatile__ ("\n\t"
- "mov %2, %%o0\n\t"
- "mov %0, %%o1\n\t"
- "mov %%g0, %%o2\n\t"
- "call __udivdi3\n\t"
- " mov %1, %%o3\n\t"
- "mov %%o1, %0\n\t"
- "mov %%o0, %1\n\t"
- : "=r" (rs1), "=r" (rs2)
- : "r" (regs->y), "0" (rs1), "1" (rs2)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
- "g1", "g2", "g3", "cc");
-#ifdef DEBUG_MULDIV
- printk ("0x%x\n", rs1);
-#endif
- if (store_reg(rs1, rdv, regs))
- return -1;
- break;
- case 15: /* sdiv */
-#ifdef DEBUG_MULDIV
- printk ("signed muldiv: 0x%x%08x / 0x%x = ", regs->y, rs1, rs2);
-#endif
- if (!rs2) {
-#ifdef DEBUG_MULDIV
- printk ("DIVISION BY ZERO\n");
-#endif
- handle_hw_divzero (regs, pc, regs->npc, regs->psr);
- return 0;
- }
- __asm__ __volatile__ ("\n\t"
- "mov %2, %%o0\n\t"
- "mov %0, %%o1\n\t"
- "mov %%g0, %%o2\n\t"
- "call __divdi3\n\t"
- " mov %1, %%o3\n\t"
- "mov %%o1, %0\n\t"
- "mov %%o0, %1\n\t"
- : "=r" (rs1), "=r" (rs2)
- : "r" (regs->y), "0" (rs1), "1" (rs2)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
- "g1", "g2", "g3", "cc");
-#ifdef DEBUG_MULDIV
- printk ("0x%x\n", rs1);
-#endif
- if (store_reg(rs1, rdv, regs))
- return -1;
- break;
- }
- if (is_foocc (insn)) {
- regs->psr &= ~PSR_ICC;
- if ((inst & 0xe) == 14) {
- /* ?div */
- if (rs2) regs->psr |= PSR_V;
- }
- if (!rs1) regs->psr |= PSR_Z;
- if (((int)rs1) < 0) regs->psr |= PSR_N;
-#ifdef DEBUG_MULDIV
- printk ("psr muldiv: %08x\n", regs->psr);
-#endif
- }
- advance(regs);
- return 0;
-}
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 4ee8ce0d5d8..185aa96fa5b 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -356,7 +356,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
for (i = 0; i < op->archdata.num_irqs; i++)
op->archdata.irqs[i] =
- sparc_irq_config.build_device_irq(op, intr[i].pri);
+ sparc_config.build_device_irq(op, intr[i].pri);
} else {
const unsigned int *irq =
of_get_property(dp, "interrupts", &len);
@@ -365,7 +365,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
op->archdata.num_irqs = len / sizeof(unsigned int);
for (i = 0; i < op->archdata.num_irqs; i++)
op->archdata.irqs[i] =
- sparc_irq_config.build_device_irq(op, irq[i]);
+ sparc_config.build_device_irq(op, irq[i]);
} else {
op->archdata.num_irqs = 0;
}
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index fcc148effaa..ded3f6090c3 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -703,31 +703,28 @@ static void pcic_clear_clock_irq(void)
pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT);
}
-static irqreturn_t pcic_timer_handler (int irq, void *h)
+/* CPU frequency is 100 MHz, timer increments every 4 CPU clocks */
+#define USECS_PER_JIFFY (1000000 / HZ)
+#define TICK_TIMER_LIMIT ((100 * 1000000 / 4) / HZ)
+
+static unsigned int pcic_cycles_offset(void)
{
- pcic_clear_clock_irq();
- xtime_update(1);
-#ifndef CONFIG_SMP
- update_process_times(user_mode(get_irq_regs()));
-#endif
- return IRQ_HANDLED;
-}
+ u32 value, count;
-#define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */
-#define TICK_TIMER_LIMIT ((100*1000000/4)/100)
+ value = readl(pcic0.pcic_regs + PCI_SYS_COUNTER);
+ count = value & ~PCI_SYS_COUNTER_OVERFLOW;
-u32 pci_gettimeoffset(void)
-{
+ if (value & PCI_SYS_COUNTER_OVERFLOW)
+ count += TICK_TIMER_LIMIT;
/*
- * We divide all by 100
+ * We divide all by HZ
* 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;
-}
+ count = ((count / HZ) * USECS_PER_JIFFY) / (TICK_TIMER_LIMIT / HZ);
+ /* Coordinate with the sparc_config.clock_rate setting */
+ return count * 2;
+}
void __init pci_time_init(void)
{
@@ -736,9 +733,16 @@ void __init pci_time_init(void)
int timer_irq, irq;
int err;
- do_arch_gettimeoffset = pci_gettimeoffset;
-
- btfixup();
+#ifndef CONFIG_SMP
+ /*
+ * The clock_rate is in SBUS dimension.
+ * We take into account this in pcic_cycles_offset()
+ */
+ sparc_config.clock_rate = SBUS_CLOCK_RATE / HZ;
+ sparc_config.features |= FEAT_L10_CLOCKEVENT;
+#endif
+ sparc_config.features |= FEAT_L10_CLOCKSOURCE;
+ sparc_config.get_cycles_offset = pcic_cycles_offset;
writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT);
/* PROM should set appropriate irq */
@@ -747,7 +751,7 @@ void __init pci_time_init(void)
writel (PCI_COUNTER_IRQ_SET(timer_irq, 0),
pcic->pcic_regs+PCI_COUNTER_IRQ);
irq = pcic_build_device_irq(NULL, timer_irq);
- err = request_irq(irq, pcic_timer_handler,
+ err = request_irq(irq, timer_interrupt,
IRQF_TIMER, "timer", NULL);
if (err) {
prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);
@@ -875,10 +879,9 @@ static void pcic_load_profile_irq(int cpu, unsigned int limit)
void __init sun4m_pci_init_IRQ(void)
{
- sparc_irq_config.build_device_irq = pcic_build_device_irq;
-
- BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM);
+ sparc_config.build_device_irq = pcic_build_device_irq;
+ sparc_config.clear_clock_irq = pcic_clear_clock_irq;
+ sparc_config.load_profile_irq = pcic_load_profile_irq;
}
int pcibios_assign_resource(struct pci_dev *pdev, int resource)
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 28559ce5eeb..5713957dcb8 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1296,8 +1296,6 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
regs = args->regs;
- perf_sample_data_init(&data, 0);
-
cpuc = &__get_cpu_var(cpu_hw_events);
/* If the PMU has the TOE IRQ enable bits, we need to do a
@@ -1321,7 +1319,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
if (val & (1ULL << 31))
continue;
- data.period = event->hw.last_period;
+ perf_sample_data_init(&data, 0, hwc->last_period);
if (!sparc_perf_event_set_period(event, hwc, idx))
continue;
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index efa07542e85..cb36e82dcd5 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -65,84 +65,25 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
struct task_struct *last_task_used_math = NULL;
struct thread_info *current_set[NR_CPUS];
-#ifndef CONFIG_SMP
-
-#define SUN4C_FAULT_HIGH 100
-
/*
* the idle loop on a Sparc... ;)
*/
void cpu_idle(void)
{
- /* endless idle loop with no priority at all */
- for (;;) {
- if (ARCH_SUN4C) {
- static int count = HZ;
- static unsigned long last_jiffies;
- static unsigned long last_faults;
- static unsigned long fps;
- unsigned long now;
- unsigned long faults;
-
- extern unsigned long sun4c_kernel_faults;
- extern void sun4c_grow_kernel_ring(void);
-
- local_irq_disable();
- now = jiffies;
- count -= (now - last_jiffies);
- last_jiffies = now;
- if (count < 0) {
- count += HZ;
- faults = sun4c_kernel_faults;
- fps = (fps + (faults - last_faults)) >> 1;
- last_faults = faults;
-#if 0
- printk("kernel faults / second = %ld\n", fps);
-#endif
- if (fps >= SUN4C_FAULT_HIGH) {
- sun4c_grow_kernel_ring();
- }
- }
- local_irq_enable();
- }
-
- if (pm_idle) {
- while (!need_resched())
- (*pm_idle)();
- } else {
- while (!need_resched())
- cpu_relax();
- }
- schedule_preempt_disabled();
- check_pgt_cache();
- }
-}
+ set_thread_flag(TIF_POLLING_NRFLAG);
-#else
-
-/* This is being executed in task 0 'user space'. */
-void cpu_idle(void)
-{
- set_thread_flag(TIF_POLLING_NRFLAG);
/* endless idle loop with no priority at all */
- while(1) {
-#ifdef CONFIG_SPARC_LEON
- if (pm_idle) {
- while (!need_resched())
+ for (;;) {
+ while (!need_resched()) {
+ if (pm_idle)
(*pm_idle)();
- } else
-#endif
- {
- while (!need_resched())
+ else
cpu_relax();
}
schedule_preempt_disabled();
- check_pgt_cache();
}
}
-#endif
-
/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
void machine_halt(void)
{
@@ -179,88 +120,6 @@ void machine_power_off(void)
machine_halt();
}
-#if 0
-
-static DEFINE_SPINLOCK(sparc_backtrace_lock);
-
-void __show_backtrace(unsigned long fp)
-{
- struct reg_window32 *rw;
- unsigned long flags;
- int cpu = smp_processor_id();
-
- spin_lock_irqsave(&sparc_backtrace_lock, flags);
-
- rw = (struct reg_window32 *)fp;
- while(rw && (((unsigned long) rw) >= PAGE_OFFSET) &&
- !(((unsigned long) rw) & 0x7)) {
- printk("CPU[%d]: ARGS[%08lx,%08lx,%08lx,%08lx,%08lx,%08lx] "
- "FP[%08lx] CALLER[%08lx]: ", cpu,
- rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3],
- rw->ins[4], rw->ins[5],
- rw->ins[6],
- rw->ins[7]);
- printk("%pS\n", (void *) rw->ins[7]);
- rw = (struct reg_window32 *) rw->ins[6];
- }
- spin_unlock_irqrestore(&sparc_backtrace_lock, flags);
-}
-
-#define __SAVE __asm__ __volatile__("save %sp, -0x40, %sp\n\t")
-#define __RESTORE __asm__ __volatile__("restore %g0, %g0, %g0\n\t")
-#define __GET_FP(fp) __asm__ __volatile__("mov %%i6, %0" : "=r" (fp))
-
-void show_backtrace(void)
-{
- unsigned long fp;
-
- __SAVE; __SAVE; __SAVE; __SAVE;
- __SAVE; __SAVE; __SAVE; __SAVE;
- __RESTORE; __RESTORE; __RESTORE; __RESTORE;
- __RESTORE; __RESTORE; __RESTORE; __RESTORE;
-
- __GET_FP(fp);
-
- __show_backtrace(fp);
-}
-
-#ifdef CONFIG_SMP
-void smp_show_backtrace_all_cpus(void)
-{
- xc0((smpfunc_t) show_backtrace);
- show_backtrace();
-}
-#endif
-
-void show_stackframe(struct sparc_stackf *sf)
-{
- unsigned long size;
- unsigned long *stk;
- int i;
-
- printk("l0: %08lx l1: %08lx l2: %08lx l3: %08lx "
- "l4: %08lx l5: %08lx l6: %08lx l7: %08lx\n",
- sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
- sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
- printk("i0: %08lx i1: %08lx i2: %08lx i3: %08lx "
- "i4: %08lx i5: %08lx fp: %08lx i7: %08lx\n",
- sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
- sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
- printk("sp: %08lx x0: %08lx x1: %08lx x2: %08lx "
- "x3: %08lx x4: %08lx x5: %08lx xx: %08lx\n",
- (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
- sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
- sf->xxargs[0]);
- size = ((unsigned long)sf->fp) - ((unsigned long)sf);
- size -= STACKFRAME_SZ;
- stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
- i = 0;
- do {
- printk("s%d: %08lx\n", i++, *stk++);
- } while ((size -= sizeof(unsigned long)));
-}
-#endif
-
void show_regs(struct pt_regs *r)
{
struct reg_window32 *rw = (struct reg_window32 *) r->u_regs[14];
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 741df916c12..1303021748c 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -23,7 +23,6 @@
#include <linux/of_pdt.h>
#include <asm/prom.h>
#include <asm/oplib.h>
-#include <asm/leon.h>
#include "prom.h"
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index 6f97c076799..484dabac704 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -1062,7 +1062,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
int ret = 0;
/* do the secure computing check first */
- secure_computing(regs->u_regs[UREG_G1]);
+ secure_computing_strict(regs->u_regs[UREG_G1]);
if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = tracehook_report_syscall_entry(regs);
diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S
index 5f5f74c2c2c..6c34de0c2ab 100644
--- a/arch/sparc/kernel/rtrap_32.S
+++ b/arch/sparc/kernel/rtrap_32.S
@@ -128,13 +128,12 @@ rtrap_patch2: and %glob_tmp, 0xff, %glob_tmp
wr %glob_tmp, 0x0, %wim
- /* Here comes the architecture specific
- * branch to the user stack checking routine
- * for return from traps.
- */
- .globl rtrap_mmu_patchme
-rtrap_mmu_patchme: b sun4c_rett_stackchk
- andcc %fp, 0x7, %g0
+ /* Here comes the architecture specific
+ * branch to the user stack checking routine
+ * for return from traps.
+ */
+ b srmmu_rett_stackchk
+ andcc %fp, 0x7, %g0
ret_trap_userwins_ok:
LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
@@ -225,69 +224,6 @@ ret_trap_user_stack_is_bolixed:
b signal_p
ld [%curptr + TI_FLAGS], %g2
-sun4c_rett_stackchk:
- be 1f
- and %fp, 0xfff, %g1 ! delay slot
-
- b ret_trap_user_stack_is_bolixed + 0x4
- wr %t_wim, 0x0, %wim
-
- /* See if we have to check the sanity of one page or two */
-1:
- add %g1, 0x38, %g1
- sra %fp, 29, %g2
- add %g2, 0x1, %g2
- andncc %g2, 0x1, %g0
- be 1f
- andncc %g1, 0xff8, %g0
-
- /* %sp is in vma hole, yuck */
- b ret_trap_user_stack_is_bolixed + 0x4
- wr %t_wim, 0x0, %wim
-
-1:
- be sun4c_rett_onepage /* Only one page to check */
- lda [%fp] ASI_PTE, %g2
-
-sun4c_rett_twopages:
- add %fp, 0x38, %g1
- sra %g1, 29, %g2
- add %g2, 0x1, %g2
- andncc %g2, 0x1, %g0
- be 1f
- lda [%g1] ASI_PTE, %g2
-
- /* Second page is in vma hole */
- b ret_trap_user_stack_is_bolixed + 0x4
- wr %t_wim, 0x0, %wim
-
-1:
- srl %g2, 29, %g2
- andcc %g2, 0x4, %g0
- bne sun4c_rett_onepage
- lda [%fp] ASI_PTE, %g2
-
- /* Second page has bad perms */
- b ret_trap_user_stack_is_bolixed + 0x4
- wr %t_wim, 0x0, %wim
-
-sun4c_rett_onepage:
- srl %g2, 29, %g2
- andcc %g2, 0x4, %g0
- bne,a 1f
- restore %g0, %g0, %g0
-
- /* A page had bad page permissions, losing... */
- b ret_trap_user_stack_is_bolixed + 0x4
- wr %t_wim, 0x0, %wim
-
- /* Whee, things are ok, load the window and continue. */
-1:
- LOAD_WINDOW(sp)
-
- b ret_trap_userwins_ok
- save %g0, %g0, %g0
-
.globl srmmu_rett_stackchk
srmmu_rett_stackchk:
bne ret_trap_user_stack_is_bolixed
@@ -295,11 +231,14 @@ srmmu_rett_stackchk:
cmp %g1, %fp
bleu ret_trap_user_stack_is_bolixed
mov AC_M_SFSR, %g1
- lda [%g1] ASI_M_MMUREGS, %g0
+LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g0)
+SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g0)
- lda [%g0] ASI_M_MMUREGS, %g1
+LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %g1)
+SUN_PI_(lda [%g0] ASI_M_MMUREGS, %g1)
or %g1, 0x2, %g1
- sta %g1, [%g0] ASI_M_MMUREGS
+LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS)
+SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS)
restore %g0, %g0, %g0
@@ -308,13 +247,16 @@ srmmu_rett_stackchk:
save %g0, %g0, %g0
andn %g1, 0x2, %g1
- sta %g1, [%g0] ASI_M_MMUREGS
+LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS)
+SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS)
mov AC_M_SFAR, %g2
- lda [%g2] ASI_M_MMUREGS, %g2
+LEON_PI(lda [%g2] ASI_LEON_MMUREGS, %g2)
+SUN_PI_(lda [%g2] ASI_M_MMUREGS, %g2)
mov AC_M_SFSR, %g1
- lda [%g1] ASI_M_MMUREGS, %g1
+LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g1)
+SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g1)
andcc %g1, 0x2, %g0
be ret_trap_userwins_ok
nop
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
index 9171fc238de..afa2a9e3d0a 100644
--- a/arch/sparc/kernel/rtrap_64.S
+++ b/arch/sparc/kernel/rtrap_64.S
@@ -73,18 +73,8 @@ rtrap_nmi: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
.globl rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall
rtrap_irq:
rtrap:
-#ifndef CONFIG_SMP
- sethi %hi(__cpu_data), %l0
- lduw [%l0 + %lo(__cpu_data)], %l1
-#else
- sethi %hi(__cpu_data), %l0
- or %l0, %lo(__cpu_data), %l0
- lduw [%l0 + %g5], %l1
-#endif
- cmp %l1, 0
-
/* mm/ultra.S:xcall_report_regs KNOWS about this load. */
- ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+ ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
rtrap_xcall:
sethi %hi(0xf << 20), %l4
and %l1, %l4, %l4
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index d444468b27f..efe3e64bba3 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -32,6 +32,7 @@
#include <linux/cpu.h>
#include <linux/kdebug.h>
#include <linux/export.h>
+#include <linux/start_kernel.h>
#include <asm/io.h>
#include <asm/processor.h>
@@ -42,10 +43,10 @@
#include <asm/vaddrs.h>
#include <asm/mbus.h>
#include <asm/idprom.h>
-#include <asm/machines.h>
#include <asm/cpudata.h>
#include <asm/setup.h>
#include <asm/cacheflush.h>
+#include <asm/sections.h>
#include "kernel.h"
@@ -106,7 +107,6 @@ unsigned long cmdline_memory_size __initdata = 0;
/* which CPU booted us (0xff = not set) */
unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */
-unsigned char boot_cpu_id4; /* boot_cpu_id << 2 */
static void
prom_console_write(struct console *con, const char *s, unsigned n)
@@ -182,13 +182,6 @@ static void __init boot_flags_init(char *commands)
}
}
-/* This routine will in the future do all the nasty prom stuff
- * to probe for the mmu type and its parameters, etc. This will
- * also be where SMP things happen.
- */
-
-extern void sun4c_probe_vac(void);
-
extern unsigned short root_flags;
extern unsigned short root_dev;
extern unsigned short ram_flags;
@@ -200,35 +193,91 @@ extern int root_mountflags;
char reboot_command[COMMAND_LINE_SIZE];
+struct cpuid_patch_entry {
+ unsigned int addr;
+ unsigned int sun4d[3];
+ unsigned int leon[3];
+};
+extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
+
+static void __init per_cpu_patch(void)
+{
+ struct cpuid_patch_entry *p;
+
+ if (sparc_cpu_model == sun4m) {
+ /* Nothing to do, this is what the unpatched code
+ * targets.
+ */
+ return;
+ }
+
+ p = &__cpuid_patch;
+ while (p < &__cpuid_patch_end) {
+ unsigned long addr = p->addr;
+ unsigned int *insns;
+
+ switch (sparc_cpu_model) {
+ case sun4d:
+ insns = &p->sun4d[0];
+ break;
+
+ case sparc_leon:
+ insns = &p->leon[0];
+ break;
+ default:
+ prom_printf("Unknown cpu type, halting.\n");
+ prom_halt();
+ }
+ *(unsigned int *) (addr + 0) = insns[0];
+ flushi(addr + 0);
+ *(unsigned int *) (addr + 4) = insns[1];
+ flushi(addr + 4);
+ *(unsigned int *) (addr + 8) = insns[2];
+ flushi(addr + 8);
+
+ p++;
+ }
+}
+
+struct leon_1insn_patch_entry {
+ unsigned int addr;
+ unsigned int insn;
+};
+
enum sparc_cpu sparc_cpu_model;
EXPORT_SYMBOL(sparc_cpu_model);
-struct tt_entry *sparc_ttable;
+static __init void leon_patch(void)
+{
+ struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch;
+ struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end;
-struct pt_regs fake_swapper_regs;
+ /* Default instruction is leon - no patching */
+ if (sparc_cpu_model == sparc_leon)
+ return;
-void __init setup_arch(char **cmdline_p)
-{
- int i;
- unsigned long highest_paddr;
+ while (start < end) {
+ unsigned long addr = start->addr;
- sparc_ttable = (struct tt_entry *) &trapbase;
+ *(unsigned int *)(addr) = start->insn;
+ flushi(addr);
- /* Initialize PROM console and command line. */
- *cmdline_p = prom_getbootargs();
- strcpy(boot_command_line, *cmdline_p);
- parse_early_param();
+ start++;
+ }
+}
- boot_flags_init(*cmdline_p);
+struct tt_entry *sparc_ttable;
+struct pt_regs fake_swapper_regs;
- register_console(&prom_early_console);
+/* Called from head_32.S - before we have setup anything
+ * in the kernel. Be very careful with what you do here.
+ */
+void __init sparc32_start_kernel(struct linux_romvec *rp)
+{
+ prom_init(rp);
/* Set sparc_cpu_model */
sparc_cpu_model = sun_unknown;
- if (!strcmp(&cputypval[0], "sun4 "))
- sparc_cpu_model = sun4;
- if (!strcmp(&cputypval[0], "sun4c"))
- sparc_cpu_model = sun4c;
if (!strcmp(&cputypval[0], "sun4m"))
sparc_cpu_model = sun4m;
if (!strcmp(&cputypval[0], "sun4s"))
@@ -242,14 +291,28 @@ void __init setup_arch(char **cmdline_p)
if (!strncmp(&cputypval[0], "leon" , 4))
sparc_cpu_model = sparc_leon;
+ leon_patch();
+ start_kernel();
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+ int i;
+ unsigned long highest_paddr;
+
+ sparc_ttable = (struct tt_entry *) &trapbase;
+
+ /* Initialize PROM console and command line. */
+ *cmdline_p = prom_getbootargs();
+ strcpy(boot_command_line, *cmdline_p);
+ parse_early_param();
+
+ boot_flags_init(*cmdline_p);
+
+ register_console(&prom_early_console);
+
printk("ARCH: ");
switch(sparc_cpu_model) {
- case sun4:
- printk("SUN4\n");
- break;
- case sun4c:
- printk("SUN4C\n");
- break;
case sun4m:
printk("SUN4M\n");
break;
@@ -275,8 +338,6 @@ void __init setup_arch(char **cmdline_p)
#endif
idprom_init();
- if (ARCH_SUN4C)
- sun4c_probe_vac();
load_mmu();
phys_base = 0xffffffffUL;
@@ -313,6 +374,9 @@ void __init setup_arch(char **cmdline_p)
init_mm.context = (unsigned long) NO_CONTEXT;
init_task.thread.kregs = &fake_swapper_regs;
+ /* Run-time patch instructions to match the cpu model */
+ per_cpu_patch();
+
paging_init();
smp_setup_cpu_possible_map();
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 948700fb903..a53e0a5fd3a 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -32,8 +32,6 @@
#include "sigutil.h"
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
/* This magic should be in g_upper[0] for all upper parts
* to be valid.
*/
@@ -215,8 +213,9 @@ void do_sigreturn32(struct pt_regs *regs)
(((unsigned long) sf) & 3))
goto segv;
- get_user(pc, &sf->info.si_regs.pc);
- __get_user(npc, &sf->info.si_regs.npc);
+ if (get_user(pc, &sf->info.si_regs.pc) ||
+ __get_user(npc, &sf->info.si_regs.npc))
+ goto segv;
if ((pc | npc) & 3)
goto segv;
@@ -273,7 +272,6 @@ void do_sigreturn32(struct pt_regs *regs)
case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
}
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
return;
@@ -305,8 +303,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
(((unsigned long) sf) & 3))
goto segv;
- get_user(pc, &sf->regs.pc);
- __get_user(npc, &sf->regs.npc);
+ if (get_user(pc, &sf->regs.pc) ||
+ __get_user(npc, &sf->regs.npc))
+ goto segv;
if ((pc | npc) & 3)
goto segv;
@@ -374,7 +373,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
}
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
return;
segv:
@@ -773,7 +771,7 @@ sigsegv:
return -EFAULT;
}
-static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
+static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
@@ -785,12 +783,9 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
err = setup_frame32(ka, regs, signr, oldset);
if (err)
- return err;
-
- block_sigmask(ka, signr);
- tracehook_signal_handler(signr, info, ka, regs, 0);
+ return;
- return 0;
+ signal_delivered(signr, info, ka, regs, 0);
}
static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -839,14 +834,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs)
if (signr > 0) {
if (restart_syscall)
syscall_restart32(orig_i0, regs, &ka.sa);
- if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) {
- /* A signal was successfully delivered; the saved
- * sigmask will have been stored in the signal frame,
- * and will be restored by sigreturn, so we can simply
- * clear the TS_RESTORE_SIGMASK flag.
- */
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- }
+ handle_signal32(signr, &ka, &info, oldset, regs);
return;
}
if (restart_syscall &&
@@ -870,10 +858,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs)
/* If there's no signal to deliver, we just put the saved sigmask
* back
*/
- if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- set_current_blocked(&current->saved_sigmask);
- }
+ restore_saved_sigmask();
}
struct sigstack32 {
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 1e750e415d7..68f9c8650af 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -29,8 +29,6 @@
#include "sigutil.h"
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
void *fpqueue, unsigned long *fpqdepth);
extern void fpload(unsigned long *fpregs, unsigned long *fsr);
@@ -64,18 +62,8 @@ struct rt_signal_frame {
static int _sigpause_common(old_sigset_t set)
{
sigset_t blocked;
-
- current->saved_sigmask = current->blocked;
-
- set &= _BLOCKABLE;
siginitset(&blocked, set);
- set_current_blocked(&blocked);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- set_thread_flag(TIF_RESTORE_SIGMASK);
-
- return -ERESTARTNOHAND;
+ return sigsuspend(&blocked);
}
asmlinkage int sys_sigsuspend(old_sigset_t set)
@@ -140,7 +128,6 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
if (err)
goto segv_and_exit;
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
return;
@@ -207,7 +194,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
goto segv;
}
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
return;
segv:
@@ -217,12 +203,9 @@ segv:
/* Checks if the fp is valid */
static inline int invalid_frame_pointer(void __user *fp, int fplen)
{
- if ((((unsigned long) fp) & 7) ||
- !__access_ok((unsigned long)fp, fplen) ||
- ((sparc_cpu_model == sun4 || sparc_cpu_model == sun4c) &&
- ((unsigned long) fp < 0xe0000000 && (unsigned long) fp >= 0x20000000)))
+ if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
return 1;
-
+
return 0;
}
@@ -462,10 +445,11 @@ sigsegv:
return -EFAULT;
}
-static inline int
+static inline void
handle_signal(unsigned long signr, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+ siginfo_t *info, struct pt_regs *regs)
{
+ sigset_t *oldset = sigmask_to_save();
int err;
if (ka->sa.sa_flags & SA_SIGINFO)
@@ -474,12 +458,9 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
err = setup_frame(ka, regs, signr, oldset);
if (err)
- return err;
-
- block_sigmask(ka, signr);
- tracehook_signal_handler(signr, info, ka, regs, 0);
+ return;
- return 0;
+ signal_delivered(signr, info, ka, regs, 0);
}
static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -511,7 +492,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
{
struct k_sigaction ka;
int restart_syscall;
- sigset_t *oldset;
siginfo_t info;
int signr;
@@ -536,11 +516,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
regs->u_regs[UREG_G6] = orig_i0;
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- oldset = &current->saved_sigmask;
- else
- oldset = &current->blocked;
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
/* If the debugger messes with the program counter, it clears
@@ -557,15 +532,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if (signr > 0) {
if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa);
- if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
- /* a signal was successfully delivered; the saved
- * sigmask will have been stored in the signal frame,
- * and will be restored by sigreturn, so we can simply
- * clear the TIF_RESTORE_SIGMASK flag.
- */
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- }
+ handle_signal(signr, &ka, &info, regs);
return;
}
if (restart_syscall &&
@@ -589,22 +556,17 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
/* if there's no signal to deliver, we just put the saved sigmask
* back
*/
- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- set_current_blocked(&current->saved_sigmask);
- }
+ restore_saved_sigmask();
}
void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
unsigned long thread_info_flags)
{
- if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+ if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs, orig_i0);
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
- if (current->replacement_session_keyring)
- key_replace_session_keyring();
}
}
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 48b0f57b65f..867de2f8189 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -38,8 +38,6 @@
#include "systbls.h"
#include "sigutil.h"
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
/* {set, get}context() needed for 64-bit SparcLinux userland. */
asmlinkage void sparc64_set_context(struct pt_regs *regs)
{
@@ -71,7 +69,6 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t)))
goto do_sigsegv;
}
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
}
if (test_thread_flag(TIF_32BIT)) {
@@ -242,19 +239,8 @@ struct rt_signal_frame {
static long _sigpause_common(old_sigset_t set)
{
sigset_t blocked;
-
- current->saved_sigmask = current->blocked;
-
- set &= _BLOCKABLE;
siginitset(&blocked, set);
- set_current_blocked(&blocked);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule();
-
- set_restore_sigmask();
-
- return -ERESTARTNOHAND;
+ return sigsuspend(&blocked);
}
asmlinkage long sys_sigpause(unsigned int set)
@@ -326,7 +312,6 @@ void do_rt_sigreturn(struct pt_regs *regs)
/* Prevent syscall restart. */
pt_regs_clear_syscall(regs);
- sigdelsetmask(&set, ~_BLOCKABLE);
set_current_blocked(&set);
return;
segv:
@@ -477,7 +462,7 @@ sigsegv:
return -EFAULT;
}
-static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
+static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
@@ -486,12 +471,9 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
err = setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
if (err)
- return err;
-
- block_sigmask(ka, signr);
- tracehook_signal_handler(signr, info, ka, regs, 0);
+ return;
- return 0;
+ signal_delivered(signr, info, ka, regs, 0);
}
static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -523,7 +505,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
{
struct k_sigaction ka;
int restart_syscall;
- sigset_t *oldset;
+ sigset_t *oldset = sigmask_to_save();
siginfo_t info;
int signr;
@@ -549,11 +531,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
regs->u_regs[UREG_G6] = orig_i0;
- if (current_thread_info()->status & TS_RESTORE_SIGMASK)
- oldset = &current->saved_sigmask;
- else
- oldset = &current->blocked;
-
#ifdef CONFIG_COMPAT
if (test_thread_flag(TIF_32BIT)) {
extern void do_signal32(sigset_t *, struct pt_regs *);
@@ -574,14 +551,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if (signr > 0) {
if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa);
- if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
- /* A signal was successfully delivered; the saved
- * sigmask will have been stored in the signal frame,
- * and will be restored by sigreturn, so we can simply
- * clear the TS_RESTORE_SIGMASK flag.
- */
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- }
+ handle_signal(signr, &ka, &info, oldset, regs);
return;
}
if (restart_syscall &&
@@ -605,10 +575,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
/* If there's no signal to deliver, we just put the saved sigmask
* back
*/
- if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- set_current_blocked(&current->saved_sigmask);
- }
+ restore_saved_sigmask();
}
void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
@@ -618,8 +585,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
- if (current->replacement_session_keyring)
- key_replace_session_keyring();
}
}
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index f671e7fd6dd..79db45e5134 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -40,6 +40,8 @@ volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,};
cpumask_t smp_commenced_mask = CPU_MASK_NONE;
+const struct sparc32_ipi_ops *sparc32_ipi_ops;
+
/* The only guaranteed locking primitive available on all Sparc
* processors is 'ldstub [%reg + immediate], %dest_reg' which atomically
* places the current byte at the effective address into dest_reg and
@@ -85,14 +87,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
(bogosum/(5000/HZ))%100);
switch(sparc_cpu_model) {
- case sun4:
- printk("SUN4\n");
- BUG();
- break;
- case sun4c:
- printk("SUN4C\n");
- BUG();
- break;
case sun4m:
smp4m_smp_done();
break;
@@ -132,7 +126,7 @@ void smp_send_reschedule(int cpu)
* a single CPU. The trap handler needs only to do trap entry/return
* to call schedule.
*/
- BTFIXUP_CALL(smp_ipi_resched)(cpu);
+ sparc32_ipi_ops->resched(cpu);
}
void smp_send_stop(void)
@@ -142,7 +136,7 @@ void smp_send_stop(void)
void arch_send_call_function_single_ipi(int cpu)
{
/* trigger one IPI single call on one CPU */
- BTFIXUP_CALL(smp_ipi_single)(cpu);
+ sparc32_ipi_ops->single(cpu);
}
void arch_send_call_function_ipi_mask(const struct cpumask *mask)
@@ -151,7 +145,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
/* trigger IPI mask call on each CPU */
for_each_cpu(cpu, mask)
- BTFIXUP_CALL(smp_ipi_mask_one)(cpu);
+ sparc32_ipi_ops->mask_one(cpu);
}
void smp_resched_interrupt(void)
@@ -179,150 +173,9 @@ void smp_call_function_interrupt(void)
irq_exit();
}
-void smp_flush_cache_all(void)
-{
- xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all));
- local_flush_cache_all();
-}
-
-void smp_flush_tlb_all(void)
-{
- xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all));
- local_flush_tlb_all();
-}
-
-void smp_flush_cache_mm(struct mm_struct *mm)
-{
- if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
- xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm);
- local_flush_cache_mm(mm);
- }
-}
-
-void smp_flush_tlb_mm(struct mm_struct *mm)
-{
- if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask)) {
- xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm);
- if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
- cpumask_copy(mm_cpumask(mm),
- cpumask_of(smp_processor_id()));
- }
- local_flush_tlb_mm(mm);
- }
-}
-
-void smp_flush_cache_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
-
- if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
- xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end);
- local_flush_cache_range(vma, start, end);
- }
-}
-
-void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
-
- if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
- xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end);
- local_flush_tlb_range(vma, start, end);
- }
-}
-
-void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
-{
- struct mm_struct *mm = vma->vm_mm;
-
- if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
- xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page);
- local_flush_cache_page(vma, page);
- }
-}
-
-void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
- struct mm_struct *mm = vma->vm_mm;
-
- if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
- xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page);
- local_flush_tlb_page(vma, page);
- }
-}
-
-void smp_flush_page_to_ram(unsigned long page)
-{
- /* Current theory is that those who call this are the one's
- * who have just dirtied their cache with the pages contents
- * in kernel space, therefore we only run this on local cpu.
- *
- * XXX This experiment failed, research further... -DaveM
- */
-#if 1
- xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page);
-#endif
- local_flush_page_to_ram(page);
-}
-
-void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
-{
- cpumask_t cpu_mask;
- cpumask_copy(&cpu_mask, mm_cpumask(mm));
- cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
- if (!cpumask_empty(&cpu_mask))
- xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr);
- local_flush_sig_insns(mm, insn_addr);
-}
-
-extern unsigned int lvl14_resolution;
-
-/* /proc/profile writes can call this, don't __init it please. */
-static DEFINE_SPINLOCK(prof_setup_lock);
-
int setup_profiling_timer(unsigned int multiplier)
{
- int i;
- unsigned long flags;
-
- /* Prevent level14 ticker IRQ flooding. */
- if((!multiplier) || (lvl14_resolution / multiplier) < 500)
- return -EINVAL;
-
- spin_lock_irqsave(&prof_setup_lock, flags);
- for_each_possible_cpu(i) {
- load_profile_irq(i, lvl14_resolution / multiplier);
- prof_multiplier(i) = multiplier;
- }
- spin_unlock_irqrestore(&prof_setup_lock, flags);
-
- return 0;
+ return -EINVAL;
}
void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -345,14 +198,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(boot_cpu_id);
switch(sparc_cpu_model) {
- case sun4:
- printk("SUN4\n");
- BUG();
- break;
- case sun4c:
- printk("SUN4C\n");
- BUG();
- break;
case sun4m:
smp4m_boot_cpus();
break;
@@ -411,29 +256,21 @@ void __init smp_prepare_boot_cpu(void)
set_cpu_possible(cpuid, true);
}
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
- extern int __cpuinit smp4m_boot_one_cpu(int);
- extern int __cpuinit smp4d_boot_one_cpu(int);
+ extern int __cpuinit smp4m_boot_one_cpu(int, struct task_struct *);
+ extern int __cpuinit smp4d_boot_one_cpu(int, struct task_struct *);
int ret=0;
switch(sparc_cpu_model) {
- case sun4:
- printk("SUN4\n");
- BUG();
- break;
- case sun4c:
- printk("SUN4C\n");
- BUG();
- break;
case sun4m:
- ret = smp4m_boot_one_cpu(cpu);
+ ret = smp4m_boot_one_cpu(cpu, tidle);
break;
case sun4d:
- ret = smp4d_boot_one_cpu(cpu);
+ ret = smp4d_boot_one_cpu(cpu, tidle);
break;
case sparc_leon:
- ret = leon_boot_one_cpu(cpu);
+ ret = leon_boot_one_cpu(cpu, tidle);
break;
case sun4e:
printk("SUN4E\n");
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 3b1bd7c5016..f591598d92f 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -343,21 +343,17 @@ extern unsigned long sparc64_cpu_startup;
*/
static struct thread_info *cpu_new_thread = NULL;
-static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
+static int __cpuinit smp_boot_one_cpu(unsigned int cpu, struct task_struct *idle)
{
unsigned long entry =
(unsigned long)(&sparc64_cpu_startup);
unsigned long cookie =
(unsigned long)(&cpu_new_thread);
- struct task_struct *p;
void *descr = NULL;
int timeout, ret;
- p = fork_idle(cpu);
- if (IS_ERR(p))
- return PTR_ERR(p);
callin_flag = 0;
- cpu_new_thread = task_thread_info(p);
+ cpu_new_thread = task_thread_info(idle);
if (tlb_type == hypervisor) {
#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
@@ -1227,9 +1223,9 @@ void __devinit smp_fill_in_sib_core_maps(void)
}
}
-int __cpuinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
- int ret = smp_boot_one_cpu(cpu);
+ int ret = smp_boot_one_cpu(cpu, tidle);
if (!ret) {
cpumask_set_cpu(cpu, &smp_commenced_mask);
diff --git a/arch/sparc/kernel/sparc_ksyms_32.c b/arch/sparc/kernel/sparc_ksyms_32.c
index baeab872023..e521c54560f 100644
--- a/arch/sparc/kernel/sparc_ksyms_32.c
+++ b/arch/sparc/kernel/sparc_ksyms_32.c
@@ -28,19 +28,5 @@ EXPORT_SYMBOL(__ndelay);
EXPORT_SYMBOL(__ret_efault);
EXPORT_SYMBOL(empty_zero_page);
-/* Defined using magic */
-#ifndef CONFIG_SMP
-EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32));
-#else
-EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id));
-#endif
-EXPORT_SYMBOL(BTFIXUP_CALL(mmu_unlockarea));
-EXPORT_SYMBOL(BTFIXUP_CALL(mmu_lockarea));
-EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl));
-EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_one));
-EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_sgl));
-EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one));
-EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached));
-
/* Exporting a symbol from /init/main.c */
EXPORT_SYMBOL(saved_command_line);
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c
deleted file mode 100644
index f6bf25a2ff8..00000000000
--- a/arch/sparc/kernel/sun4c_irq.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * sun4c irq support
- *
- * djhr: Hacked out of irq.c into a CPU dependent version.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1995 Pete A. Zaitcev (zaitcev@yahoo.com)
- * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
- */
-
-#include <linux/init.h>
-
-#include <asm/oplib.h>
-#include <asm/timer.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include "irq.h"
-
-/* Sun4c interrupts are typically laid out as follows:
- *
- * 1 - Software interrupt, SBUS level 1
- * 2 - SBUS level 2
- * 3 - ESP SCSI, SBUS level 3
- * 4 - Software interrupt
- * 5 - Lance ethernet, SBUS level 4
- * 6 - Software interrupt
- * 7 - Graphics card, SBUS level 5
- * 8 - SBUS level 6
- * 9 - SBUS level 7
- * 10 - Counter timer
- * 11 - Floppy
- * 12 - Zilog uart
- * 13 - CS4231 audio
- * 14 - Profiling timer
- * 15 - NMI
- *
- * The interrupt enable bits in the interrupt mask register are
- * really only used to enable/disable the timer interrupts, and
- * for signalling software interrupts. There is also a master
- * interrupt enable bit in this register.
- *
- * Interrupts are enabled by setting the SUN4C_INT_* bits, they
- * are disabled by clearing those bits.
- */
-
-/*
- * Bit field defines for the interrupt registers on various
- * Sparc machines.
- */
-
-/* The sun4c interrupt register. */
-#define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */
-#define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */
-#define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */
-#define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */
-#define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */
-#define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */
-#define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */
-
-/*
- * Pointer to the interrupt enable byte
- * Used by entry.S
- */
-unsigned char __iomem *interrupt_enable;
-
-static void sun4c_mask_irq(struct irq_data *data)
-{
- unsigned long mask = (unsigned long)data->chip_data;
-
- if (mask) {
- unsigned long flags;
-
- local_irq_save(flags);
- mask = sbus_readb(interrupt_enable) & ~mask;
- sbus_writeb(mask, interrupt_enable);
- local_irq_restore(flags);
- }
-}
-
-static void sun4c_unmask_irq(struct irq_data *data)
-{
- unsigned long mask = (unsigned long)data->chip_data;
-
- if (mask) {
- unsigned long flags;
-
- local_irq_save(flags);
- mask = sbus_readb(interrupt_enable) | mask;
- sbus_writeb(mask, interrupt_enable);
- local_irq_restore(flags);
- }
-}
-
-static unsigned int sun4c_startup_irq(struct irq_data *data)
-{
- irq_link(data->irq);
- sun4c_unmask_irq(data);
-
- return 0;
-}
-
-static void sun4c_shutdown_irq(struct irq_data *data)
-{
- sun4c_mask_irq(data);
- irq_unlink(data->irq);
-}
-
-static struct irq_chip sun4c_irq = {
- .name = "sun4c",
- .irq_startup = sun4c_startup_irq,
- .irq_shutdown = sun4c_shutdown_irq,
- .irq_mask = sun4c_mask_irq,
- .irq_unmask = sun4c_unmask_irq,
-};
-
-static unsigned int sun4c_build_device_irq(struct platform_device *op,
- unsigned int real_irq)
-{
- unsigned int irq;
-
- if (real_irq >= 16) {
- prom_printf("Bogus sun4c IRQ %u\n", real_irq);
- prom_halt();
- }
-
- irq = irq_alloc(real_irq, real_irq);
- if (irq) {
- unsigned long mask = 0UL;
-
- switch (real_irq) {
- case 1:
- mask = SUN4C_INT_E1;
- break;
- case 8:
- mask = SUN4C_INT_E8;
- break;
- case 10:
- mask = SUN4C_INT_E10;
- break;
- case 14:
- mask = SUN4C_INT_E14;
- break;
- default:
- /* All the rest are either always enabled,
- * or are for signalling software interrupts.
- */
- break;
- }
- irq_set_chip_and_handler_name(irq, &sun4c_irq,
- handle_level_irq, "level");
- irq_set_chip_data(irq, (void *)mask);
- }
- return irq;
-}
-
-struct sun4c_timer_info {
- u32 l10_count;
- u32 l10_limit;
- u32 l14_count;
- u32 l14_limit;
-};
-
-static struct sun4c_timer_info __iomem *sun4c_timers;
-
-static void sun4c_clear_clock_irq(void)
-{
- sbus_readl(&sun4c_timers->l10_limit);
-}
-
-static void sun4c_load_profile_irq(int cpu, unsigned int limit)
-{
- /* Errm.. not sure how to do this.. */
-}
-
-static void __init sun4c_init_timers(irq_handler_t counter_fn)
-{
- const struct linux_prom_irqs *prom_irqs;
- struct device_node *dp;
- unsigned int irq;
- const u32 *addr;
- int err;
-
- dp = of_find_node_by_name(NULL, "counter-timer");
- if (!dp) {
- prom_printf("sun4c_init_timers: Unable to find counter-timer\n");
- prom_halt();
- }
-
- addr = of_get_property(dp, "address", NULL);
- if (!addr) {
- prom_printf("sun4c_init_timers: No address property\n");
- prom_halt();
- }
-
- sun4c_timers = (void __iomem *) (unsigned long) addr[0];
-
- prom_irqs = of_get_property(dp, "intr", NULL);
- of_node_put(dp);
- if (!prom_irqs) {
- prom_printf("sun4c_init_timers: No intr property\n");
- prom_halt();
- }
-
- /* Have the level 10 timer tick at 100HZ. We don't touch the
- * level 14 timer limit since we are letting the prom handle
- * them until we have a real console driver so L1-A works.
- */
- sbus_writel((((1000000/HZ) + 1) << 10), &sun4c_timers->l10_limit);
-
- master_l10_counter = &sun4c_timers->l10_count;
-
- irq = sun4c_build_device_irq(NULL, prom_irqs[0].pri);
- err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
- if (err) {
- prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err);
- prom_halt();
- }
-
- /* disable timer interrupt */
- sun4c_mask_irq(irq_get_irq_data(irq));
-}
-
-#ifdef CONFIG_SMP
-static void sun4c_nop(void)
-{
-}
-#endif
-
-void __init sun4c_init_IRQ(void)
-{
- struct device_node *dp;
- const u32 *addr;
-
- dp = of_find_node_by_name(NULL, "interrupt-enable");
- if (!dp) {
- prom_printf("sun4c_init_IRQ: Unable to find interrupt-enable\n");
- prom_halt();
- }
-
- addr = of_get_property(dp, "address", NULL);
- of_node_put(dp);
- if (!addr) {
- prom_printf("sun4c_init_IRQ: No address property\n");
- prom_halt();
- }
-
- interrupt_enable = (void __iomem *) (unsigned long) addr[0];
-
- BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP);
-
- sparc_irq_config.init_timers = sun4c_init_timers;
- sparc_irq_config.build_device_irq = sun4c_build_device_irq;
-
-#ifdef CONFIG_SMP
- BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP);
-#endif
- sbus_writeb(SUN4C_INT_ENABLE, interrupt_enable);
- /* Cannot enable interrupts until OBP ticker is disabled. */
-}
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 1d13c5bda0b..e490ac9327c 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -15,6 +15,7 @@
#include <asm/sbi.h>
#include <asm/cacheflush.h>
#include <asm/setup.h>
+#include <asm/oplib.h>
#include "kernel.h"
#include "irq.h"
@@ -243,19 +244,6 @@ struct irq_chip sun4d_irq = {
};
#ifdef CONFIG_SMP
-static void sun4d_set_cpu_int(int cpu, int level)
-{
- sun4d_send_ipi(cpu, level);
-}
-
-static void sun4d_clear_ipi(int cpu, int level)
-{
-}
-
-static void sun4d_set_udt(int cpu)
-{
-}
-
/* Setup IRQ distribution scheme. */
void __init sun4d_distribute_irqs(void)
{
@@ -282,7 +270,8 @@ static void sun4d_clear_clock_irq(void)
static void sun4d_load_profile_irq(int cpu, unsigned int limit)
{
- bw_set_prof_limit(cpu, limit);
+ unsigned int value = limit ? timer_value(limit) : 0;
+ bw_set_prof_limit(cpu, value);
}
static void __init sun4d_load_profile_irqs(void)
@@ -418,12 +407,12 @@ static void __init sun4d_fixup_trap_table(void)
trap_table->inst_two = lvl14_save[1];
trap_table->inst_three = lvl14_save[2];
trap_table->inst_four = lvl14_save[3];
- local_flush_cache_all();
+ local_ops->cache_all();
local_irq_restore(flags);
#endif
}
-static void __init sun4d_init_timers(irq_handler_t counter_fn)
+static void __init sun4d_init_timers(void)
{
struct device_node *dp;
struct resource res;
@@ -466,12 +455,20 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
prom_halt();
}
- sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit);
+#ifdef CONFIG_SMP
+ sparc_config.cs_period = SBUS_CLOCK_RATE * 2; /* 2 seconds */
+#else
+ sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; /* 1/HZ sec */
+ sparc_config.features |= FEAT_L10_CLOCKEVENT;
+#endif
+ sparc_config.features |= FEAT_L10_CLOCKSOURCE;
+ sbus_writel(timer_value(sparc_config.cs_period),
+ &sun4d_timers->l10_timer_limit);
master_l10_counter = &sun4d_timers->l10_cur_count;
irq = sun4d_build_timer_irq(board, SUN4D_TIMER_IRQ);
- err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
+ err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
if (err) {
prom_printf("sun4d_init_timers: request_irq() failed with %d\n",
err);
@@ -509,16 +506,11 @@ void __init sun4d_init_IRQ(void)
{
local_irq_disable();
- BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM);
+ sparc_config.init_timers = sun4d_init_timers;
+ sparc_config.build_device_irq = sun4d_build_device_irq;
+ sparc_config.clock_rate = SBUS_CLOCK_RATE;
+ sparc_config.clear_clock_irq = sun4d_clear_clock_irq;
+ sparc_config.load_profile_irq = sun4d_load_profile_irq;
- sparc_irq_config.init_timers = sun4d_init_timers;
- sparc_irq_config.build_device_irq = sun4d_build_device_irq;
-
-#ifdef CONFIG_SMP
- BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(clear_cpu_int, sun4d_clear_ipi, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(set_irq_udt, sun4d_set_udt, BTFIXUPCALL_NOP);
-#endif
/* Cannot enable interrupts until OBP ticker is disabled. */
}
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 540b2fec09f..ddaea31de58 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -6,16 +6,20 @@
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/profile.h>
#include <linux/delay.h>
+#include <linux/sched.h>
#include <linux/cpu.h>
+#include <asm/cacheflush.h>
+#include <asm/switch_to.h>
+#include <asm/tlbflush.h>
+#include <asm/timer.h>
+#include <asm/oplib.h>
#include <asm/sbi.h>
#include <asm/mmu.h>
-#include <asm/tlbflush.h>
-#include <asm/switch_to.h>
-#include <asm/cacheflush.h>
#include "kernel.h"
#include "irq.h"
@@ -34,7 +38,6 @@ static inline unsigned long sun4d_swap(volatile unsigned long *ptr, unsigned lon
}
static void smp4d_ipi_init(void);
-static void smp_setup_percpu_timer(void);
static unsigned char cpu_leds[32];
@@ -49,7 +52,7 @@ static inline void show_leds(int cpuid)
void __cpuinit smp4d_callin(void)
{
- int cpuid = hard_smp4d_processor_id();
+ int cpuid = hard_smp_processor_id();
unsigned long flags;
/* Show we are alive */
@@ -59,8 +62,8 @@ void __cpuinit smp4d_callin(void)
/* Enable level15 interrupt, disable level14 interrupt for now */
cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000);
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
notify_cpu_starting(cpuid);
/*
@@ -70,17 +73,17 @@ void __cpuinit smp4d_callin(void)
* to call the scheduler code.
*/
/* Get our local ticker going. */
- smp_setup_percpu_timer();
+ register_percpu_ce(cpuid);
calibrate_delay();
smp_store_cpu_info(cpuid);
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
/* Allow master to continue. */
sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1);
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
while ((unsigned long)current_set[cpuid] < PAGE_OFFSET)
barrier();
@@ -100,8 +103,8 @@ void __cpuinit smp4d_callin(void)
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
local_irq_enable(); /* We don't allow PIL 14 yet */
@@ -123,22 +126,17 @@ void __init smp4d_boot_cpus(void)
smp4d_ipi_init();
if (boot_cpu_id)
current_set[0] = NULL;
- smp_setup_percpu_timer();
- local_flush_cache_all();
+ local_ops->cache_all();
}
-int __cpuinit smp4d_boot_one_cpu(int i)
+int __cpuinit smp4d_boot_one_cpu(int i, struct task_struct *idle)
{
unsigned long *entry = &sun4d_cpu_startup;
- struct task_struct *p;
int timeout;
int cpu_node;
cpu_find_by_instance(i, &cpu_node, NULL);
- /* Cook up an idler for this guy. */
- p = fork_idle(i);
- current_set[i] = task_thread_info(p);
-
+ current_set[i] = task_thread_info(idle);
/*
* Initialize the contexts table
* Since the call to prom_startcpu() trashes the structure,
@@ -150,7 +148,7 @@ int __cpuinit smp4d_boot_one_cpu(int i)
/* whirrr, whirrr, whirrrrrrrrr... */
printk(KERN_INFO "Starting CPU %d at %p\n", i, entry);
- local_flush_cache_all();
+ local_ops->cache_all();
prom_startcpu(cpu_node,
&smp_penguin_ctable, 0, (char *)entry);
@@ -168,7 +166,7 @@ int __cpuinit smp4d_boot_one_cpu(int i)
return -ENODEV;
}
- local_flush_cache_all();
+ local_ops->cache_all();
return 0;
}
@@ -185,7 +183,7 @@ void __init smp4d_smp_done(void)
prev = &cpu_data(i).next;
}
*prev = first;
- local_flush_cache_all();
+ local_ops->cache_all();
/* Ok, they are spinning and ready to go. */
smp_processors_ready = 1;
@@ -233,7 +231,20 @@ void sun4d_ipi_interrupt(void)
}
}
-static void smp4d_ipi_single(int cpu)
+/* +-------+-------------+-----------+------------------------------------+
+ * | bcast | devid | sid | levels mask |
+ * +-------+-------------+-----------+------------------------------------+
+ * 31 30 23 22 15 14 0
+ */
+#define IGEN_MESSAGE(bcast, devid, sid, levels) \
+ (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels))
+
+static void sun4d_send_ipi(int cpu, int level)
+{
+ cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1)));
+}
+
+static void sun4d_ipi_single(int cpu)
{
struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
@@ -244,7 +255,7 @@ static void smp4d_ipi_single(int cpu)
sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
}
-static void smp4d_ipi_mask_one(int cpu)
+static void sun4d_ipi_mask_one(int cpu)
{
struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
@@ -255,7 +266,7 @@ static void smp4d_ipi_mask_one(int cpu)
sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
}
-static void smp4d_ipi_resched(int cpu)
+static void sun4d_ipi_resched(int cpu)
{
struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
@@ -280,7 +291,7 @@ static struct smp_funcall {
static DEFINE_SPINLOCK(cross_call_lock);
/* Cross calls must be serialized, at least currently. */
-static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
unsigned long arg2, unsigned long arg3,
unsigned long arg4)
{
@@ -352,7 +363,7 @@ static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
/* Running cross calls. */
void smp4d_cross_call_irq(void)
{
- int i = hard_smp4d_processor_id();
+ int i = hard_smp_processor_id();
ccall_info.processors_in[i] = 1;
ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
@@ -363,7 +374,8 @@ void smp4d_cross_call_irq(void)
void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
{
struct pt_regs *old_regs;
- int cpu = hard_smp4d_processor_id();
+ int cpu = hard_smp_processor_id();
+ struct clock_event_device *ce;
static int cpu_tick[NR_CPUS];
static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd };
@@ -379,45 +391,21 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
show_leds(cpu);
}
- profile_tick(CPU_PROFILING);
-
- if (!--prof_counter(cpu)) {
- int user = user_mode(regs);
+ ce = &per_cpu(sparc32_clockevent, cpu);
- irq_enter();
- update_process_times(user);
- irq_exit();
+ irq_enter();
+ ce->event_handler(ce);
+ irq_exit();
- prof_counter(cpu) = prof_multiplier(cpu);
- }
set_irq_regs(old_regs);
}
-static void __cpuinit smp_setup_percpu_timer(void)
-{
- int cpu = hard_smp4d_processor_id();
-
- prof_counter(cpu) = prof_multiplier(cpu) = 1;
- load_profile_irq(cpu, lvl14_resolution);
-}
-
-void __init smp4d_blackbox_id(unsigned *addr)
-{
- int rd = *addr & 0x3e000000;
-
- addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */
- addr[1] = 0x01000000; /* nop */
- addr[2] = 0x01000000; /* nop */
-}
-
-void __init smp4d_blackbox_current(unsigned *addr)
-{
- int rd = *addr & 0x3e000000;
-
- addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */
- addr[2] = 0x81282002 | rd | (rd >> 11); /* sll reg, 2, reg */
- addr[4] = 0x01000000; /* nop */
-}
+static const struct sparc32_ipi_ops sun4d_ipi_ops = {
+ .cross_call = sun4d_cross_call,
+ .resched = sun4d_ipi_resched,
+ .single = sun4d_ipi_single,
+ .mask_one = sun4d_ipi_mask_one,
+};
void __init sun4d_init_smp(void)
{
@@ -426,14 +414,7 @@ void __init sun4d_init_smp(void)
/* Patch ipi15 trap table */
t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m);
- /* And set btfixup... */
- BTFIXUPSET_BLACKBOX(hard_smp_processor_id, smp4d_blackbox_id);
- BTFIXUPSET_BLACKBOX(load_current, smp4d_blackbox_current);
- BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4d_processor_id, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_resched, smp4d_ipi_resched, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_single, smp4d_ipi_single, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_mask_one, smp4d_ipi_mask_one, BTFIXUPCALL_NORM);
+ sparc32_ipi_ops = &sun4d_ipi_ops;
for (i = 0; i < NR_CPUS; i++) {
ccall_info.processors_in[i] = 1;
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index e61165161dd..c5ade9d27a1 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -112,9 +112,6 @@ struct sun4m_handler_data {
#define SUN4M_INT_E14 0x00000080
#define SUN4M_INT_E10 0x00080000
-#define SUN4M_HARD_INT(x) (0x000000001 << (x))
-#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
-
#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
#define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */
@@ -282,23 +279,6 @@ out:
return irq;
}
-#ifdef CONFIG_SMP
-static void sun4m_send_ipi(int cpu, int level)
-{
- sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
-}
-
-static void sun4m_clear_ipi(int cpu, int level)
-{
- sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->clear);
-}
-
-static void sun4m_set_udt(int cpu)
-{
- sbus_writel(cpu, &sun4m_irq_global->interrupt_target);
-}
-#endif
-
struct sun4m_timer_percpu {
u32 l14_limit;
u32 l14_count;
@@ -318,9 +298,6 @@ struct sun4m_timer_global {
static struct sun4m_timer_global __iomem *timers_global;
-
-unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);
-
static void sun4m_clear_clock_irq(void)
{
sbus_readl(&timers_global->l10_limit);
@@ -369,10 +346,11 @@ void sun4m_clear_profile_irq(int cpu)
static void sun4m_load_profile_irq(int cpu, unsigned int limit)
{
- sbus_writel(limit, &timers_percpu[cpu]->l14_limit);
+ unsigned int value = limit ? timer_value(limit) : 0;
+ sbus_writel(value, &timers_percpu[cpu]->l14_limit);
}
-static void __init sun4m_init_timers(irq_handler_t counter_fn)
+static void __init sun4m_init_timers(void)
{
struct device_node *dp = of_find_node_by_name(NULL, "counter");
int i, err, len, num_cpu_timers;
@@ -402,13 +380,22 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
/* Every per-cpu timer works in timer mode */
sbus_writel(0x00000000, &timers_global->timer_config);
- sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit);
+#ifdef CONFIG_SMP
+ sparc_config.cs_period = SBUS_CLOCK_RATE * 2; /* 2 seconds */
+ sparc_config.features |= FEAT_L14_ONESHOT;
+#else
+ sparc_config.cs_period = SBUS_CLOCK_RATE / HZ; /* 1/HZ sec */
+ sparc_config.features |= FEAT_L10_CLOCKEVENT;
+#endif
+ sparc_config.features |= FEAT_L10_CLOCKSOURCE;
+ sbus_writel(timer_value(sparc_config.cs_period),
+ &timers_global->l10_limit);
master_l10_counter = &timers_global->l10_count;
irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
- err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
+ err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
if (err) {
printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
err);
@@ -434,7 +421,7 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
trap_table->inst_two = lvl14_save[1];
trap_table->inst_three = lvl14_save[2];
trap_table->inst_four = lvl14_save[3];
- local_flush_cache_all();
+ local_ops->cache_all();
local_irq_restore(flags);
}
#endif
@@ -475,17 +462,12 @@ void __init sun4m_init_IRQ(void)
if (num_cpu_iregs == 4)
sbus_writel(0, &sun4m_irq_global->interrupt_target);
- BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);
-
- sparc_irq_config.init_timers = sun4m_init_timers;
- sparc_irq_config.build_device_irq = sun4m_build_device_irq;
+ sparc_config.init_timers = sun4m_init_timers;
+ sparc_config.build_device_irq = sun4m_build_device_irq;
+ sparc_config.clock_rate = SBUS_CLOCK_RATE;
+ sparc_config.clear_clock_irq = sun4m_clear_clock_irq;
+ sparc_config.load_profile_irq = sun4m_load_profile_irq;
-#ifdef CONFIG_SMP
- BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM);
-#endif
/* Cannot enable interrupts until OBP ticker is disabled. */
}
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 02db9a0412c..128af730428 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -4,14 +4,18 @@
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/profile.h>
#include <linux/delay.h>
+#include <linux/sched.h>
#include <linux/cpu.h>
#include <asm/cacheflush.h>
#include <asm/switch_to.h>
#include <asm/tlbflush.h>
+#include <asm/timer.h>
+#include <asm/oplib.h>
#include "irq.h"
#include "kernel.h"
@@ -30,26 +34,22 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val)
return val;
}
-static void smp4m_ipi_init(void);
-static void smp_setup_percpu_timer(void);
-
void __cpuinit smp4m_callin(void)
{
int cpuid = hard_smp_processor_id();
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
notify_cpu_starting(cpuid);
- /* Get our local ticker going. */
- smp_setup_percpu_timer();
+ register_percpu_ce(cpuid);
calibrate_delay();
smp_store_cpu_info(cpuid);
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
/*
* Unblock the master CPU _only_ when the scheduler state
@@ -61,8 +61,8 @@ void __cpuinit smp4m_callin(void)
swap_ulong(&cpu_callin_map[cpuid], 1);
/* XXX: What's up with all the flushes? */
- local_flush_cache_all();
- local_flush_tlb_all();
+ local_ops->cache_all();
+ local_ops->tlb_all();
/* Fix idle thread fields. */
__asm__ __volatile__("ld [%0], %%g6\n\t"
@@ -86,23 +86,19 @@ void __cpuinit smp4m_callin(void)
*/
void __init smp4m_boot_cpus(void)
{
- smp4m_ipi_init();
- smp_setup_percpu_timer();
- local_flush_cache_all();
+ sun4m_unmask_profile_irq();
+ local_ops->cache_all();
}
-int __cpuinit smp4m_boot_one_cpu(int i)
+int __cpuinit smp4m_boot_one_cpu(int i, struct task_struct *idle)
{
unsigned long *entry = &sun4m_cpu_startup;
- struct task_struct *p;
int timeout;
int cpu_node;
cpu_find_by_mid(i, &cpu_node);
+ current_set[i] = task_thread_info(idle);
- /* Cook up an idler for this guy. */
- p = fork_idle(i);
- current_set[i] = task_thread_info(p);
/* See trampoline.S for details... */
entry += ((i - 1) * 3);
@@ -117,7 +113,7 @@ int __cpuinit smp4m_boot_one_cpu(int i)
/* whirrr, whirrr, whirrrrrrrrr... */
printk(KERN_INFO "Starting CPU %d at %p\n", i, entry);
- local_flush_cache_all();
+ local_ops->cache_all();
prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry);
/* wheee... it's going... */
@@ -132,7 +128,7 @@ int __cpuinit smp4m_boot_one_cpu(int i)
return -ENODEV;
}
- local_flush_cache_all();
+ local_ops->cache_all();
return 0;
}
@@ -149,30 +145,29 @@ void __init smp4m_smp_done(void)
prev = &cpu_data(i).next;
}
*prev = first;
- local_flush_cache_all();
+ local_ops->cache_all();
/* Ok, they are spinning and ready to go. */
}
-
-/* Initialize IPIs on the SUN4M SMP machine */
-static void __init smp4m_ipi_init(void)
+static void sun4m_send_ipi(int cpu, int level)
{
+ sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
}
-static void smp4m_ipi_resched(int cpu)
+static void sun4m_ipi_resched(int cpu)
{
- set_cpu_int(cpu, IRQ_IPI_RESCHED);
+ sun4m_send_ipi(cpu, IRQ_IPI_RESCHED);
}
-static void smp4m_ipi_single(int cpu)
+static void sun4m_ipi_single(int cpu)
{
- set_cpu_int(cpu, IRQ_IPI_SINGLE);
+ sun4m_send_ipi(cpu, IRQ_IPI_SINGLE);
}
-static void smp4m_ipi_mask_one(int cpu)
+static void sun4m_ipi_mask_one(int cpu)
{
- set_cpu_int(cpu, IRQ_IPI_MASK);
+ sun4m_send_ipi(cpu, IRQ_IPI_MASK);
}
static struct smp_funcall {
@@ -189,7 +184,7 @@ static struct smp_funcall {
static DEFINE_SPINLOCK(cross_call_lock);
/* Cross calls must be serialized, at least currently. */
-static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
unsigned long arg2, unsigned long arg3,
unsigned long arg4)
{
@@ -216,7 +211,7 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
if (cpumask_test_cpu(i, &mask)) {
ccall_info.processors_in[i] = 0;
ccall_info.processors_out[i] = 0;
- set_cpu_int(i, IRQ_CROSS_CALL);
+ sun4m_send_ipi(i, IRQ_CROSS_CALL);
} else {
ccall_info.processors_in[i] = 1;
ccall_info.processors_out[i] = 1;
@@ -260,64 +255,33 @@ void smp4m_cross_call_irq(void)
void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
{
struct pt_regs *old_regs;
+ struct clock_event_device *ce;
int cpu = smp_processor_id();
old_regs = set_irq_regs(regs);
- sun4m_clear_profile_irq(cpu);
-
- profile_tick(CPU_PROFILING);
+ ce = &per_cpu(sparc32_clockevent, cpu);
- if (!--prof_counter(cpu)) {
- int user = user_mode(regs);
+ if (ce->mode & CLOCK_EVT_MODE_PERIODIC)
+ sun4m_clear_profile_irq(cpu);
+ else
+ sparc_config.load_profile_irq(cpu, 0); /* Is this needless? */
- irq_enter();
- update_process_times(user);
- irq_exit();
+ irq_enter();
+ ce->event_handler(ce);
+ irq_exit();
- prof_counter(cpu) = prof_multiplier(cpu);
- }
set_irq_regs(old_regs);
}
-static void __cpuinit smp_setup_percpu_timer(void)
-{
- int cpu = smp_processor_id();
-
- prof_counter(cpu) = prof_multiplier(cpu) = 1;
- load_profile_irq(cpu, lvl14_resolution);
-
- if (cpu == boot_cpu_id)
- sun4m_unmask_profile_irq();
-}
-
-static void __init smp4m_blackbox_id(unsigned *addr)
-{
- int rd = *addr & 0x3e000000;
- int rs1 = rd >> 11;
-
- addr[0] = 0x81580000 | rd; /* rd %tbr, reg */
- addr[1] = 0x8130200c | rd | rs1; /* srl reg, 0xc, reg */
- addr[2] = 0x80082003 | rd | rs1; /* and reg, 3, reg */
-}
-
-static void __init smp4m_blackbox_current(unsigned *addr)
-{
- int rd = *addr & 0x3e000000;
- int rs1 = rd >> 11;
-
- addr[0] = 0x81580000 | rd; /* rd %tbr, reg */
- addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */
- addr[4] = 0x8008200c | rd | rs1; /* and reg, 0xc, reg */
-}
+static const struct sparc32_ipi_ops sun4m_ipi_ops = {
+ .cross_call = sun4m_cross_call,
+ .resched = sun4m_ipi_resched,
+ .single = sun4m_ipi_single,
+ .mask_one = sun4m_ipi_mask_one,
+};
void __init sun4m_init_smp(void)
{
- BTFIXUPSET_BLACKBOX(hard_smp_processor_id, smp4m_blackbox_id);
- BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current);
- BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM);
+ sparc32_ipi_ops = &sun4m_ipi_ops;
}
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index 29c478ffed9..f7392336961 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -139,8 +139,8 @@ static int cp_compat_stat64(struct kstat *stat,
err |= put_user(stat->ino, &statbuf->st_ino);
err |= put_user(stat->mode, &statbuf->st_mode);
err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(stat->uid, &statbuf->st_uid);
- err |= put_user(stat->gid, &statbuf->st_gid);
+ err |= put_user(from_kuid_munged(current_user_ns(), stat->uid), &statbuf->st_uid);
+ err |= put_user(from_kgid_munged(current_user_ns(), stat->gid), &statbuf->st_gid);
err |= put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
err |= put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
err |= put_user(stat->size, &statbuf->st_size);
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 42b282fa611..0c9b31b22e0 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -53,8 +53,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
/* See asm-sparc/uaccess.h */
if (len > TASK_SIZE - PAGE_SIZE)
return -ENOMEM;
- if (ARCH_SUN4C && len > 0x20000000)
- return -ENOMEM;
if (!addr)
addr = TASK_UNMAPPED_BASE;
@@ -65,10 +63,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
/* At this point: (!vmm || addr < vmm->vm_end). */
- if (ARCH_SUN4C && addr < 0xe0000000 && 0x20000000 - len < addr) {
- addr = PAGE_OFFSET;
- vmm = find_vma(current->mm, PAGE_OFFSET);
- }
if (TASK_SIZE - PAGE_SIZE - len < addr)
return -ENOMEM;
if (!vmm || addr + len <= vmm->vm_start)
@@ -99,11 +93,6 @@ out:
int sparc_mmap_check(unsigned long addr, unsigned long len)
{
- if (ARCH_SUN4C &&
- (len > 0x20000000 ||
- (addr < 0xe0000000 && addr + len > 0x20000000)))
- return -EINVAL;
-
/* See asm-sparc/uaccess.h */
if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
return -EINVAL;
@@ -195,10 +184,10 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+ __get_user(mask, &act->sa_mask))
return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
new_ka.ka_restorer = NULL;
}
@@ -206,17 +195,12 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
- /* In the clone() case we could copy half consistent
- * state to the user, however this could sleep and
- * deadlock us if we held the signal lock on SMP. So for
- * now I take the easy way out and do no locking.
- */
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 3ee51f189a5..275f74fd6f6 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -580,16 +580,9 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len,
unsigned long, new_len, unsigned long, flags,
unsigned long, new_addr)
{
- unsigned long ret = -EINVAL;
-
if (test_thread_flag(TIF_32BIT))
- 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;
+ return -EINVAL;
+ return sys_mremap(addr, old_len, new_len, flags, new_addr);
}
/* we come to here via sys_nis_syscall so it can setup the regs argument */
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 7d0c088e8ab..953641549e8 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -26,6 +26,8 @@
#include <linux/rtc.h>
#include <linux/rtc/m48t59.h>
#include <linux/timex.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ioport.h>
@@ -40,13 +42,24 @@
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/idprom.h>
-#include <asm/machines.h>
#include <asm/page.h>
#include <asm/pcic.h>
#include <asm/irq_regs.h>
+#include <asm/setup.h>
#include "irq.h"
+static __cacheline_aligned_in_smp DEFINE_SEQLOCK(timer_cs_lock);
+static __volatile__ u64 timer_cs_internal_counter = 0;
+static char timer_cs_enabled = 0;
+
+static struct clock_event_device timer_ce;
+static char timer_ce_enabled = 0;
+
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(struct clock_event_device, sparc32_clockevent);
+#endif
+
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
@@ -55,7 +68,6 @@ static int set_rtc_mmss(unsigned long);
unsigned long profile_pc(struct pt_regs *regs)
{
extern char __copy_user_begin[], __copy_user_end[];
- extern char __atomic_begin[], __atomic_end[];
extern char __bzero_begin[], __bzero_end[];
unsigned long pc = regs->pc;
@@ -63,8 +75,6 @@ unsigned long profile_pc(struct pt_regs *regs)
if (in_lock_functions(pc) ||
(pc >= (unsigned long) __copy_user_begin &&
pc < (unsigned long) __copy_user_end) ||
- (pc >= (unsigned long) __atomic_begin &&
- pc < (unsigned long) __atomic_end) ||
(pc >= (unsigned long) __bzero_begin &&
pc < (unsigned long) __bzero_end))
pc = regs->u_regs[UREG_RETPC];
@@ -75,36 +85,168 @@ EXPORT_SYMBOL(profile_pc);
__volatile__ unsigned int *master_l10_counter;
-u32 (*do_arch_gettimeoffset)(void);
-
int update_persistent_clock(struct timespec now)
{
return set_rtc_mmss(now.tv_sec);
}
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "xtime_update()" routine every clocktick
- */
+irqreturn_t notrace timer_interrupt(int dummy, void *dev_id)
+{
+ if (timer_cs_enabled) {
+ write_seqlock(&timer_cs_lock);
+ timer_cs_internal_counter++;
+ sparc_config.clear_clock_irq();
+ write_sequnlock(&timer_cs_lock);
+ } else {
+ sparc_config.clear_clock_irq();
+ }
-#define TICK_SIZE (tick_nsec / 1000)
+ if (timer_ce_enabled)
+ timer_ce.event_handler(&timer_ce);
-static irqreturn_t timer_interrupt(int dummy, void *dev_id)
+ return IRQ_HANDLED;
+}
+
+static void timer_ce_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
{
-#ifndef CONFIG_SMP
- profile_tick(CPU_PROFILING);
-#endif
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_RESUME:
+ timer_ce_enabled = 1;
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ timer_ce_enabled = 0;
+ break;
+ default:
+ break;
+ }
+ smp_mb();
+}
- clear_clock_irq();
+static __init void setup_timer_ce(void)
+{
+ struct clock_event_device *ce = &timer_ce;
+
+ BUG_ON(smp_processor_id() != boot_cpu_id);
+
+ ce->name = "timer_ce";
+ ce->rating = 100;
+ ce->features = CLOCK_EVT_FEAT_PERIODIC;
+ ce->set_mode = timer_ce_set_mode;
+ ce->cpumask = cpu_possible_mask;
+ ce->shift = 32;
+ ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
+ ce->shift);
+ clockevents_register_device(ce);
+}
- xtime_update(1);
+static unsigned int sbus_cycles_offset(void)
+{
+ unsigned int val, offset;
-#ifndef CONFIG_SMP
- update_process_times(user_mode(get_irq_regs()));
-#endif
- return IRQ_HANDLED;
+ val = *master_l10_counter;
+ offset = (val >> TIMER_VALUE_SHIFT) & TIMER_VALUE_MASK;
+
+ /* Limit hit? */
+ if (val & TIMER_LIMIT_BIT)
+ offset += sparc_config.cs_period;
+
+ return offset;
+}
+
+static cycle_t timer_cs_read(struct clocksource *cs)
+{
+ unsigned int seq, offset;
+ u64 cycles;
+
+ do {
+ seq = read_seqbegin(&timer_cs_lock);
+
+ cycles = timer_cs_internal_counter;
+ offset = sparc_config.get_cycles_offset();
+ } while (read_seqretry(&timer_cs_lock, seq));
+
+ /* Count absolute cycles */
+ cycles *= sparc_config.cs_period;
+ cycles += offset;
+
+ return cycles;
+}
+
+static struct clocksource timer_cs = {
+ .name = "timer_cs",
+ .rating = 100,
+ .read = timer_cs_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .shift = 2,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static __init int setup_timer_cs(void)
+{
+ timer_cs_enabled = 1;
+ timer_cs.mult = clocksource_hz2mult(sparc_config.clock_rate,
+ timer_cs.shift);
+
+ return clocksource_register(&timer_cs);
}
+#ifdef CONFIG_SMP
+static void percpu_ce_setup(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ int cpu = __first_cpu(evt->cpumask);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ sparc_config.load_profile_irq(cpu,
+ SBUS_CLOCK_RATE / HZ);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ sparc_config.load_profile_irq(cpu, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+static int percpu_ce_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ int cpu = __first_cpu(evt->cpumask);
+ unsigned int next = (unsigned int)delta;
+
+ sparc_config.load_profile_irq(cpu, next);
+ return 0;
+}
+
+void register_percpu_ce(int cpu)
+{
+ struct clock_event_device *ce = &per_cpu(sparc32_clockevent, cpu);
+ unsigned int features = CLOCK_EVT_FEAT_PERIODIC;
+
+ if (sparc_config.features & FEAT_L14_ONESHOT)
+ features |= CLOCK_EVT_FEAT_ONESHOT;
+
+ ce->name = "percpu_ce";
+ ce->rating = 200;
+ ce->features = features;
+ ce->set_mode = percpu_ce_setup;
+ ce->set_next_event = percpu_ce_set_next_event;
+ ce->cpumask = cpumask_of(cpu);
+ ce->shift = 32;
+ ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
+ ce->shift);
+ ce->max_delta_ns = clockevent_delta2ns(sparc_config.clock_rate, ce);
+ ce->min_delta_ns = clockevent_delta2ns(100, ce);
+
+ clockevents_register_device(ce);
+}
+#endif
+
static unsigned char mostek_read_byte(struct device *dev, u32 ofs)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -195,38 +337,28 @@ static int __init clock_init(void)
*/
fs_initcall(clock_init);
-
-u32 sbus_do_gettimeoffset(void)
-{
- unsigned long val = *master_l10_counter;
- unsigned long usec = (val >> 10) & 0x1fffff;
-
- /* Limit hit? */
- if (val & 0x80000000)
- usec += 1000000 / HZ;
-
- return usec * 1000;
-}
-
-
-u32 arch_gettimeoffset(void)
+static void __init sparc32_late_time_init(void)
{
- if (unlikely(!do_arch_gettimeoffset))
- return 0;
- return do_arch_gettimeoffset();
+ if (sparc_config.features & FEAT_L10_CLOCKEVENT)
+ setup_timer_ce();
+ if (sparc_config.features & FEAT_L10_CLOCKSOURCE)
+ setup_timer_cs();
+#ifdef CONFIG_SMP
+ register_percpu_ce(smp_processor_id());
+#endif
}
static void __init sbus_time_init(void)
{
- do_arch_gettimeoffset = sbus_do_gettimeoffset;
-
- btfixup();
-
- sparc_irq_config.init_timers(timer_interrupt);
+ sparc_config.get_cycles_offset = sbus_cycles_offset;
+ sparc_config.init_timers();
}
void __init time_init(void)
{
+ sparc_config.features = 0;
+ late_time_init = sparc32_late_time_init;
+
if (pcic_present())
pci_time_init();
else
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S
index 691f484e03b..af27acab448 100644
--- a/arch/sparc/kernel/trampoline_32.S
+++ b/arch/sparc/kernel/trampoline_32.S
@@ -15,8 +15,8 @@
#include <asm/contregs.h>
#include <asm/thread_info.h>
- .globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id
- .globl sun4d_cpu_startup, __smp4d_processor_id
+ .globl sun4m_cpu_startup
+ .globl sun4d_cpu_startup
__CPUINIT
.align 4
@@ -94,24 +94,6 @@ smp_do_cpu_idle:
call cpu_panic
nop
-__smp4m_processor_id:
- rd %tbr, %g2
- srl %g2, 12, %g2
- and %g2, 3, %g2
- retl
- mov %g1, %o7
-
-__smp4d_processor_id:
- lda [%g0] ASI_M_VIKING_TMP1, %g2
- 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
@@ -167,8 +149,6 @@ sun4d_cpu_startup:
b,a smp_do_cpu_idle
-#ifdef CONFIG_SPARC_LEON
-
__CPUINIT
.align 4
.global leon_smp_cpu_startup, smp_penguin_ctable
@@ -179,7 +159,7 @@ leon_smp_cpu_startup:
ld [%g1+4],%g1
srl %g1,4,%g1
set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */
- sta %g1, [%g5] ASI_M_MMUREGS
+ sta %g1, [%g5] ASI_LEON_MMUREGS
/* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */
set (PSR_PIL | PSR_S | PSR_PS), %g1
@@ -225,5 +205,3 @@ leon_smp_cpu_startup:
nop
b,a smp_do_cpu_idle
-
-#endif
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index d2de2133314..a5785ea2a85 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -120,8 +120,6 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon
printk("Ill instr. at pc=%08lx instruction is %08lx\n",
regs->pc, *(unsigned long *)regs->pc);
#endif
- if (!do_user_muldiv (regs, pc))
- return;
info.si_signo = SIGILL;
info.si_errno = 0;
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index c72fdf55e1c..3b05e669771 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2054,7 +2054,7 @@ void do_fpieee(struct pt_regs *regs)
do_fpe_common(regs);
}
-extern int do_mathemu(struct pt_regs *, struct fpustate *);
+extern int do_mathemu(struct pt_regs *, struct fpustate *, bool);
void do_fpother(struct pt_regs *regs)
{
@@ -2068,7 +2068,7 @@ void do_fpother(struct pt_regs *regs)
switch ((current_thread_info()->xfsr[0] & 0x1c000)) {
case (2 << 14): /* unfinished_FPop */
case (3 << 14): /* unimplemented_FPop */
- ret = do_mathemu(regs, f);
+ ret = do_mathemu(regs, f, false);
break;
}
if (ret)
@@ -2308,10 +2308,12 @@ void do_illegal_instruction(struct pt_regs *regs)
} else {
struct fpustate *f = FPUSTATE;
- /* XXX maybe verify XFSR bits like
- * XXX do_fpother() does?
+ /* On UltraSPARC T2 and later, FPU insns which
+ * are not implemented in HW signal an illegal
+ * instruction trap and do not set the FP Trap
+ * Trap in the %fsr to unimplemented_FPop.
*/
- if (do_mathemu(regs, f))
+ if (do_mathemu(regs, f, true))
return;
}
}
diff --git a/arch/sparc/kernel/ttable_32.S b/arch/sparc/kernel/ttable_32.S
new file mode 100644
index 00000000000..8a7a96ca676
--- /dev/null
+++ b/arch/sparc/kernel/ttable_32.S
@@ -0,0 +1,417 @@
+/* The Sparc trap table, bootloader gives us control at _start. */
+ __HEAD
+
+ .globl _start
+_start:
+
+ .globl _stext
+_stext:
+
+ .globl trapbase
+trapbase:
+
+#ifdef CONFIG_SMP
+trapbase_cpu0:
+#endif
+/* We get control passed to us here at t_zero. */
+t_zero: b gokernel; nop; nop; nop;
+t_tflt: SRMMU_TFAULT /* Inst. Access Exception */
+t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */
+t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */
+t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */
+t_wovf: WINDOW_SPILL /* Window Overflow */
+t_wunf: WINDOW_FILL /* Window Underflow */
+t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */
+t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */
+t_dflt: SRMMU_DFAULT /* Data Miss Exception */
+t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */
+t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */
+t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
+t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */
+t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */
+t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */
+t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */
+t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */
+t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */
+t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */
+t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */
+t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */
+t_irq10:TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) */
+t_irq11:TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */
+t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */
+t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */
+t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */
+
+ .globl t_nmi
+t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+
+t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */
+t_iacce:BAD_TRAP(0x21) /* Instr Access Error */
+t_bad22:BAD_TRAP(0x22)
+ BAD_TRAP(0x23)
+t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */
+t_uflsh:SKIP_TRAP(0x25, unimp_flush) /* Unimplemented FLUSH inst. */
+t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27)
+t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */
+t_dacce:SRMMU_DFAULT /* Data Access Error */
+t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */
+t_dserr:BAD_TRAP(0x2b) /* Data Store Error */
+t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */
+t_bad2d:BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
+t_bad32:BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
+t_bad37:BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
+t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */
+t_bad3d:BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41)
+t_bad42:BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46)
+t_bad47:BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b)
+t_bad4c:BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) BAD_TRAP(0x50)
+t_bad51:BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
+t_bad56:BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
+t_bad5b:BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
+t_bad60:BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
+t_bad65:BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
+t_bad6a:BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
+t_bad6f:BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
+t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
+t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
+t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f)
+t_bad80:BAD_TRAP(0x80) /* SunOS System Call */
+t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */
+t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */
+t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */
+t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */
+t_rchk: BAD_TRAP(0x85) /* Range Check */
+t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */
+t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */
+t_bad88:BAD_TRAP(0x88) /* Slowaris System Call */
+t_bad89:BAD_TRAP(0x89) /* Net-B.S. System Call */
+t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e)
+t_bad8f:BAD_TRAP(0x8f)
+t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */
+t_bad91:BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95)
+t_bad96:BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a)
+t_bad9b:BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f)
+t_getcc:GETCC_TRAP /* Get Condition Codes */
+t_setcc:SETCC_TRAP /* Set Condition Codes */
+t_getpsr:GETPSR_TRAP /* Get PSR Register */
+t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
+t_bada7:BAD_TRAP(0xa7)
+t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
+t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
+t_badb6:BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
+t_badbb:BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
+t_badc0:BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
+t_badc5:BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
+t_badca:BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
+t_badcf:BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
+t_badd4:BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
+t_badd9:BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
+t_badde:BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
+t_bade3:BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
+t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
+t_baded:BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
+t_badf2:BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
+t_badf7:BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
+t_badfc:BAD_TRAP(0xfc)
+t_kgdb: KGDB_TRAP(0xfd)
+dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */
+dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */
+
+ .globl end_traptable
+end_traptable:
+
+#ifdef CONFIG_SMP
+ /* Trap tables for the other cpus. */
+ .globl trapbase_cpu1, trapbase_cpu2, trapbase_cpu3
+trapbase_cpu1:
+ BAD_TRAP(0x0)
+ SRMMU_TFAULT
+ TRAP_ENTRY(0x2, bad_instruction)
+ TRAP_ENTRY(0x3, priv_instruction)
+ TRAP_ENTRY(0x4, fpd_trap_handler)
+ WINDOW_SPILL
+ WINDOW_FILL
+ TRAP_ENTRY(0x7, mna_handler)
+ TRAP_ENTRY(0x8, fpe_trap_handler)
+ SRMMU_DFAULT
+ TRAP_ENTRY(0xa, do_tag_overflow)
+ TRAP_ENTRY(0xb, do_watchpoint)
+ BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
+ TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2)
+ TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4)
+ TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6)
+ TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8)
+ TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10)
+ TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12)
+ TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14)
+ TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+ TRAP_ENTRY(0x20, do_reg_access)
+ BAD_TRAP(0x21)
+ BAD_TRAP(0x22)
+ BAD_TRAP(0x23)
+ TRAP_ENTRY(0x24, do_cp_disabled)
+ SKIP_TRAP(0x25, unimp_flush)
+ BAD_TRAP(0x26)
+ BAD_TRAP(0x27)
+ TRAP_ENTRY(0x28, do_cp_exception)
+ SRMMU_DFAULT
+ TRAP_ENTRY(0x2a, do_hw_divzero)
+ BAD_TRAP(0x2b)
+ BAD_TRAP(0x2c)
+ BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
+ BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
+ BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
+ BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40)
+ BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45)
+ BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a)
+ BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f)
+ BAD_TRAP(0x50)
+ BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
+ BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
+ BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
+ BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
+ BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
+ BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
+ BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
+ BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
+ BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
+ BAD_TRAP(0x7e) BAD_TRAP(0x7f)
+ BAD_TRAP(0x80)
+ BREAKPOINT_TRAP
+ TRAP_ENTRY(0x82, do_hw_divzero)
+ TRAP_ENTRY(0x83, do_flush_windows)
+ BAD_TRAP(0x84) BAD_TRAP(0x85) BAD_TRAP(0x86)
+ BAD_TRAP(0x87) BAD_TRAP(0x88) BAD_TRAP(0x89)
+ BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
+ BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
+ LINUX_SYSCALL_TRAP BAD_TRAP(0x91)
+ BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
+ BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
+ BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
+ BAD_TRAP(0x9f)
+ GETCC_TRAP
+ SETCC_TRAP
+ GETPSR_TRAP
+ BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
+ BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+ BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
+ BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
+ BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
+ BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
+ BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
+ BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
+ BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
+ BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
+ BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
+ BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
+ BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
+ BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
+ BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
+ BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
+ BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
+ BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
+ BAD_TRAP(0xfc)
+ KGDB_TRAP(0xfd)
+ BAD_TRAP(0xfe)
+ BAD_TRAP(0xff)
+
+trapbase_cpu2:
+ BAD_TRAP(0x0)
+ SRMMU_TFAULT
+ TRAP_ENTRY(0x2, bad_instruction)
+ TRAP_ENTRY(0x3, priv_instruction)
+ TRAP_ENTRY(0x4, fpd_trap_handler)
+ WINDOW_SPILL
+ WINDOW_FILL
+ TRAP_ENTRY(0x7, mna_handler)
+ TRAP_ENTRY(0x8, fpe_trap_handler)
+ SRMMU_DFAULT
+ TRAP_ENTRY(0xa, do_tag_overflow)
+ TRAP_ENTRY(0xb, do_watchpoint)
+ BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
+ TRAP_ENTRY_INTERRUPT(1)
+ TRAP_ENTRY_INTERRUPT(2)
+ TRAP_ENTRY_INTERRUPT(3)
+ TRAP_ENTRY_INTERRUPT(4)
+ TRAP_ENTRY_INTERRUPT(5)
+ TRAP_ENTRY_INTERRUPT(6)
+ TRAP_ENTRY_INTERRUPT(7)
+ TRAP_ENTRY_INTERRUPT(8)
+ TRAP_ENTRY_INTERRUPT(9)
+ TRAP_ENTRY_INTERRUPT(10)
+ TRAP_ENTRY_INTERRUPT(11)
+ TRAP_ENTRY_INTERRUPT(12)
+ TRAP_ENTRY_INTERRUPT(13)
+ TRAP_ENTRY_INTERRUPT(14)
+ TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+ TRAP_ENTRY(0x20, do_reg_access)
+ BAD_TRAP(0x21)
+ BAD_TRAP(0x22)
+ BAD_TRAP(0x23)
+ TRAP_ENTRY(0x24, do_cp_disabled)
+ SKIP_TRAP(0x25, unimp_flush)
+ BAD_TRAP(0x26)
+ BAD_TRAP(0x27)
+ TRAP_ENTRY(0x28, do_cp_exception)
+ SRMMU_DFAULT
+ TRAP_ENTRY(0x2a, do_hw_divzero)
+ BAD_TRAP(0x2b)
+ BAD_TRAP(0x2c)
+ BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
+ BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
+ BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
+ BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40)
+ BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45)
+ BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a)
+ BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f)
+ BAD_TRAP(0x50)
+ BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
+ BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
+ BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
+ BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
+ BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
+ BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
+ BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
+ BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
+ BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
+ BAD_TRAP(0x7e) BAD_TRAP(0x7f)
+ BAD_TRAP(0x80)
+ BREAKPOINT_TRAP
+ TRAP_ENTRY(0x82, do_hw_divzero)
+ TRAP_ENTRY(0x83, do_flush_windows)
+ BAD_TRAP(0x84)
+ BAD_TRAP(0x85)
+ BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
+ BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
+ BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
+ LINUX_SYSCALL_TRAP BAD_TRAP(0x91)
+ BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
+ BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
+ BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
+ BAD_TRAP(0x9f)
+ GETCC_TRAP
+ SETCC_TRAP
+ GETPSR_TRAP
+ BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
+ BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+ BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
+ BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
+ BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
+ BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
+ BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
+ BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
+ BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
+ BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
+ BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
+ BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
+ BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
+ BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
+ BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
+ BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
+ BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
+ BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
+ BAD_TRAP(0xfc)
+ KGDB_TRAP(0xfd)
+ BAD_TRAP(0xfe)
+ BAD_TRAP(0xff)
+
+trapbase_cpu3:
+ BAD_TRAP(0x0)
+ SRMMU_TFAULT
+ TRAP_ENTRY(0x2, bad_instruction)
+ TRAP_ENTRY(0x3, priv_instruction)
+ TRAP_ENTRY(0x4, fpd_trap_handler)
+ WINDOW_SPILL
+ WINDOW_FILL
+ TRAP_ENTRY(0x7, mna_handler)
+ TRAP_ENTRY(0x8, fpe_trap_handler)
+ SRMMU_DFAULT
+ TRAP_ENTRY(0xa, do_tag_overflow)
+ TRAP_ENTRY(0xb, do_watchpoint)
+ BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
+ TRAP_ENTRY_INTERRUPT(1)
+ TRAP_ENTRY_INTERRUPT(2)
+ TRAP_ENTRY_INTERRUPT(3)
+ TRAP_ENTRY_INTERRUPT(4)
+ TRAP_ENTRY_INTERRUPT(5)
+ TRAP_ENTRY_INTERRUPT(6)
+ TRAP_ENTRY_INTERRUPT(7)
+ TRAP_ENTRY_INTERRUPT(8)
+ TRAP_ENTRY_INTERRUPT(9)
+ TRAP_ENTRY_INTERRUPT(10)
+ TRAP_ENTRY_INTERRUPT(11)
+ TRAP_ENTRY_INTERRUPT(12)
+ TRAP_ENTRY_INTERRUPT(13)
+ TRAP_ENTRY_INTERRUPT(14)
+ TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+ TRAP_ENTRY(0x20, do_reg_access)
+ BAD_TRAP(0x21)
+ BAD_TRAP(0x22)
+ BAD_TRAP(0x23)
+ TRAP_ENTRY(0x24, do_cp_disabled)
+ SKIP_TRAP(0x25, unimp_flush)
+ BAD_TRAP(0x26)
+ BAD_TRAP(0x27)
+ TRAP_ENTRY(0x28, do_cp_exception)
+ SRMMU_DFAULT
+ TRAP_ENTRY(0x2a, do_hw_divzero)
+ BAD_TRAP(0x2b) BAD_TRAP(0x2c)
+ BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
+ BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
+ BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
+ BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40)
+ BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45)
+ BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a)
+ BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f)
+ BAD_TRAP(0x50)
+ BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55)
+ BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a)
+ BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
+ BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64)
+ BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69)
+ BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e)
+ BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
+ BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
+ BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
+ BAD_TRAP(0x7e) BAD_TRAP(0x7f)
+ BAD_TRAP(0x80)
+ BREAKPOINT_TRAP
+ TRAP_ENTRY(0x82, do_hw_divzero)
+ TRAP_ENTRY(0x83, do_flush_windows)
+ BAD_TRAP(0x84) BAD_TRAP(0x85)
+ BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
+ BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
+ BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
+ LINUX_SYSCALL_TRAP
+ BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
+ BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
+ BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
+ BAD_TRAP(0x9f)
+ GETCC_TRAP
+ SETCC_TRAP
+ GETPSR_TRAP
+ BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
+ BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
+ BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
+ BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
+ BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
+ BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
+ BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4)
+ BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9)
+ BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce)
+ BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
+ BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8)
+ BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd)
+ BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2)
+ BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
+ BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec)
+ BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1)
+ BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6)
+ BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
+ BAD_TRAP(0xfc)
+ KGDB_TRAP(0xfd)
+ BAD_TRAP(0xfe)
+ BAD_TRAP(0xff)
+
+#endif
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable_64.S
index c6dfdaa29e2..c6dfdaa29e2 100644
--- a/arch/sparc/kernel/ttable.S
+++ b/arch/sparc/kernel/ttable_64.S
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index dae85bc2eda..f81d038f734 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -21,7 +21,6 @@
#include <linux/bitops.h>
#include <linux/perf_event.h>
#include <linux/ratelimit.h>
-#include <linux/bitops.h>
#include <asm/fpumacro.h>
#include <asm/cacheflush.h>
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c
index 5cffdc55f07..3e244f31e56 100644
--- a/arch/sparc/kernel/vio.c
+++ b/arch/sparc/kernel/vio.c
@@ -443,7 +443,7 @@ static int __init vio_init(void)
root_vdev = vio_create_one(hp, root, NULL);
err = -ENODEV;
if (!root_vdev) {
- printk(KERN_ERR "VIO: Coult not create root device.\n");
+ printk(KERN_ERR "VIO: Could not create root device.\n");
goto out_release;
}
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 0e1605697b4..89c2c29f154 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -107,6 +107,11 @@ SECTIONS
*(.sun4v_2insn_patch)
__sun4v_2insn_patch_end = .;
}
+ .leon_1insn_patch : {
+ __leon_1insn_patch = .;
+ *(.leon_1insn_patch)
+ __leon_1insn_patch_end = .;
+ }
.swapper_tsb_phys_patch : {
__swapper_tsb_phys_patch = .;
*(.swapper_tsb_phys_patch)
diff --git a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S
index 3bbcd8dc9ab..28a7bc69f82 100644
--- a/arch/sparc/kernel/wof.S
+++ b/arch/sparc/kernel/wof.S
@@ -163,9 +163,8 @@ spwin_fromuser:
* the label 'spwin_user_stack_is_bolixed' which will take
* care of things at that point.
*/
- .globl spwin_mmu_patchme
-spwin_mmu_patchme: b spwin_sun4c_stackchk
- andcc %sp, 0x7, %g0
+ b spwin_srmmu_stackchk
+ andcc %sp, 0x7, %g0
spwin_good_ustack:
/* LOCATION: Window to be saved */
@@ -306,73 +305,6 @@ spwin_bad_ustack_from_kernel:
* As noted above %curptr cannot be touched by this routine at all.
*/
-spwin_sun4c_stackchk:
- /* LOCATION: Window to be saved on the stack */
-
- /* See if the stack is in the address space hole but first,
- * check results of callers andcc %sp, 0x7, %g0
- */
- be 1f
- sra %sp, 29, %glob_tmp
-
- rd %psr, %glob_tmp
- b spwin_user_stack_is_bolixed + 0x4
- nop
-
-1:
- add %glob_tmp, 0x1, %glob_tmp
- andncc %glob_tmp, 0x1, %g0
- be 1f
- and %sp, 0xfff, %glob_tmp ! delay slot
-
- rd %psr, %glob_tmp
- b spwin_user_stack_is_bolixed + 0x4
- nop
-
- /* See if our dump area will be on more than one
- * page.
- */
-1:
- add %glob_tmp, 0x38, %glob_tmp
- andncc %glob_tmp, 0xff8, %g0
- be spwin_sun4c_onepage ! only one page to check
- lda [%sp] ASI_PTE, %glob_tmp ! have to check first page anyways
-
-spwin_sun4c_twopages:
- /* Is first page ok permission wise? */
- srl %glob_tmp, 29, %glob_tmp
- cmp %glob_tmp, 0x6
- be 1f
- add %sp, 0x38, %glob_tmp /* Is second page in vma hole? */
-
- rd %psr, %glob_tmp
- b spwin_user_stack_is_bolixed + 0x4
- nop
-
-1:
- sra %glob_tmp, 29, %glob_tmp
- add %glob_tmp, 0x1, %glob_tmp
- andncc %glob_tmp, 0x1, %g0
- be 1f
- add %sp, 0x38, %glob_tmp
-
- rd %psr, %glob_tmp
- b spwin_user_stack_is_bolixed + 0x4
- nop
-
-1:
- lda [%glob_tmp] ASI_PTE, %glob_tmp
-
-spwin_sun4c_onepage:
- srl %glob_tmp, 29, %glob_tmp
- cmp %glob_tmp, 0x6 ! can user write to it?
- be spwin_good_ustack ! success
- nop
-
- rd %psr, %glob_tmp
- b spwin_user_stack_is_bolixed + 0x4
- nop
-
/* This is a generic SRMMU routine. As far as I know this
* works for all current v8/srmmu implementations, we'll
* see...
@@ -400,24 +332,30 @@ spwin_srmmu_stackchk:
mov AC_M_SFSR, %glob_tmp
/* Clear the fault status and turn on the no_fault bit. */
- lda [%glob_tmp] ASI_M_MMUREGS, %g0 ! eat SFSR
+LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) ! eat SFSR
+SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) ! eat SFSR
- lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control
+LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
+SUN_PI_(lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
- sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it
+LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
+SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
/* Dump the registers and cross fingers. */
STORE_WINDOW(sp)
/* Clear the no_fault bit and check the status. */
andn %glob_tmp, 0x2, %glob_tmp
- sta %glob_tmp, [%g0] ASI_M_MMUREGS
+LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
+SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
mov AC_M_SFAR, %glob_tmp
- lda [%glob_tmp] ASI_M_MMUREGS, %g0
+LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
+SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
mov AC_M_SFSR, %glob_tmp
- lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp
+LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)
+SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp)
andcc %glob_tmp, 0x2, %g0 ! did we fault?
be,a spwin_finish_up + 0x4 ! cool beans, success
restore %g0, %g0, %g0
diff --git a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S
index 779ff750603..2c21cc59683 100644
--- a/arch/sparc/kernel/wuf.S
+++ b/arch/sparc/kernel/wuf.S
@@ -131,12 +131,9 @@ fwin_from_user:
/* LOCATION: Window 'W' */
- /* Branch to the architecture specific stack validation
- * routine. They can be found below...
- */
- .globl fwin_mmu_patchme
-fwin_mmu_patchme: b sun4c_fwin_stackchk
- andcc %sp, 0x7, %g0
+ /* Branch to the stack validation routine */
+ b srmmu_fwin_stackchk
+ andcc %sp, 0x7, %g0
#define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - STACKFRAME_SZ)
@@ -242,57 +239,6 @@ fwin_user_finish_up:
* 'someone elses' window possibly.
*/
- .align 4
-sun4c_fwin_stackchk:
- /* LOCATION: Window 'W' */
-
- /* Caller did 'andcc %sp, 0x7, %g0' */
- be 1f
- and %sp, 0xfff, %l0 ! delay slot
-
- b,a fwin_user_stack_is_bolixed
-
- /* See if we have to check the sanity of one page or two */
-1:
- add %l0, 0x38, %l0
- sra %sp, 29, %l5
- add %l5, 0x1, %l5
- andncc %l5, 0x1, %g0
- be 1f
- andncc %l0, 0xff8, %g0
-
- b,a fwin_user_stack_is_bolixed /* %sp is in vma hole, yuck */
-
-1:
- be sun4c_fwin_onepage /* Only one page to check */
- lda [%sp] ASI_PTE, %l1
-sun4c_fwin_twopages:
- add %sp, 0x38, %l0
- sra %l0, 29, %l5
- add %l5, 0x1, %l5
- andncc %l5, 0x1, %g0
- be 1f
- lda [%l0] ASI_PTE, %l1
-
- b,a fwin_user_stack_is_bolixed /* Second page in vma hole */
-
-1:
- srl %l1, 29, %l1
- andcc %l1, 0x4, %g0
- bne sun4c_fwin_onepage
- lda [%sp] ASI_PTE, %l1
-
- b,a fwin_user_stack_is_bolixed /* Second page has bad perms */
-
-sun4c_fwin_onepage:
- srl %l1, 29, %l1
- andcc %l1, 0x4, %g0
- bne fwin_user_stack_is_ok
- nop
-
- /* A page had bad page permissions, losing... */
- b,a fwin_user_stack_is_bolixed
-
.globl srmmu_fwin_stackchk
srmmu_fwin_stackchk:
/* LOCATION: Window 'W' */
@@ -308,16 +254,19 @@ srmmu_fwin_stackchk:
mov AC_M_SFSR, %l4
cmp %l5, %sp
bleu fwin_user_stack_is_bolixed
- lda [%l4] ASI_M_MMUREGS, %g0 ! clear fault status
+LEON_PI( lda [%l4] ASI_LEON_MMUREGS, %g0) ! clear fault status
+SUN_PI_( lda [%l4] ASI_M_MMUREGS, %g0) ! clear fault status
/* The technique is, turn off faults on this processor,
* just let the load rip, then check the sfsr to see if
* a fault did occur. Then we turn on fault traps again
* and branch conditionally based upon what happened.
*/
- lda [%g0] ASI_M_MMUREGS, %l5 ! read mmu-ctrl reg
+LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %l5) ! read mmu-ctrl reg
+SUN_PI_(lda [%g0] ASI_M_MMUREGS, %l5) ! read mmu-ctrl reg
or %l5, 0x2, %l5 ! turn on no-fault bit
- sta %l5, [%g0] ASI_M_MMUREGS ! store it
+LEON_PI(sta %l5, [%g0] ASI_LEON_MMUREGS) ! store it
+SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it
/* Cross fingers and go for it. */
LOAD_WINDOW(sp)
@@ -329,18 +278,22 @@ srmmu_fwin_stackchk:
/* LOCATION: Window 'T' */
- lda [%g0] ASI_M_MMUREGS, %twin_tmp1 ! load mmu-ctrl again
- andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit
- sta %twin_tmp1, [%g0] ASI_M_MMUREGS ! store it
+LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
+SUN_PI_(lda [%g0] ASI_M_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
+ andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit
+LEON_PI(sta %twin_tmp1, [%g0] ASI_LEON_MMUREGS) ! store it
+SUN_PI_(sta %twin_tmp1, [%g0] ASI_M_MMUREGS) ! store it
mov AC_M_SFAR, %twin_tmp2
- lda [%twin_tmp2] ASI_M_MMUREGS, %g0 ! read fault address
+LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %g0) ! read fault address
+SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %g0) ! read fault address
mov AC_M_SFSR, %twin_tmp2
- lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2 ! read fault status
- andcc %twin_tmp2, 0x2, %g0 ! did fault occur?
+LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %twin_tmp2) ! read fault status
+SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2) ! read fault status
+ andcc %twin_tmp2, 0x2, %g0 ! did fault occur?
- bne 1f ! yep, cleanup
+ bne 1f ! yep, cleanup
nop
wr %t_psr, 0x0, %psr
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index a3fc4375a15..dff4096f3de 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -4,16 +4,15 @@
asflags-y := -ansi -DST_DIV0=0x02
ccflags-y := -Werror
-lib-$(CONFIG_SPARC32) += mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o
+lib-$(CONFIG_SPARC32) += ashrdi3.o
lib-$(CONFIG_SPARC32) += memcpy.o memset.o
lib-y += strlen.o
lib-y += checksum_$(BITS).o
lib-$(CONFIG_SPARC32) += blockops.o
lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o
-lib-y += strncpy_from_user_$(BITS).o strlen_user_$(BITS).o
lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
lib-$(CONFIG_SPARC32) += copy_user.o locks.o
-lib-y += atomic_$(BITS).o
+lib-$(CONFIG_SPARC64) += atomic_64.o
lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
@@ -40,7 +39,7 @@ lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o
lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
obj-y += iomap.o
-obj-$(CONFIG_SPARC32) += atomic32.o
+obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o
obj-y += ksyms.o
obj-$(CONFIG_SPARC64) += PeeCeeI.o
obj-y += usercopy.o
diff --git a/arch/sparc/lib/ashldi3.S b/arch/sparc/lib/ashldi3.S
index 17912e60871..86f60de07b0 100644
--- a/arch/sparc/lib/ashldi3.S
+++ b/arch/sparc/lib/ashldi3.S
@@ -5,10 +5,10 @@
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
*/
+#include <linux/linkage.h>
+
.text
- .align 4
- .globl __ashldi3
-__ashldi3:
+ENTRY(__ashldi3)
cmp %o2, 0
be 9f
mov 0x20, %g2
@@ -32,3 +32,4 @@ __ashldi3:
9:
retl
nop
+ENDPROC(__ashldi3)
diff --git a/arch/sparc/lib/ashrdi3.S b/arch/sparc/lib/ashrdi3.S
index 85398fd6dcc..6eb8ba2dd50 100644
--- a/arch/sparc/lib/ashrdi3.S
+++ b/arch/sparc/lib/ashrdi3.S
@@ -5,10 +5,10 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/linkage.h>
+
.text
- .align 4
- .globl __ashrdi3
-__ashrdi3:
+ENTRY(__ashrdi3)
tst %o2
be 3f
or %g0, 32, %g2
@@ -34,3 +34,4 @@ __ashrdi3:
3:
jmpl %o7 + 8, %g0
nop
+ENDPROC(__ashrdi3)
diff --git a/arch/sparc/lib/atomic_32.S b/arch/sparc/lib/atomic_32.S
deleted file mode 100644
index eb6c7359cbd..00000000000
--- a/arch/sparc/lib/atomic_32.S
+++ /dev/null
@@ -1,44 +0,0 @@
-/* atomic.S: Move this stuff here for better ICACHE hit rates.
- *
- * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
- */
-
-#include <asm/ptrace.h>
-#include <asm/psr.h>
-
- .text
- .align 4
-
- .globl __atomic_begin
-__atomic_begin:
-
-#ifndef CONFIG_SMP
- .globl ___xchg32_sun4c
-___xchg32_sun4c:
- rd %psr, %g3
- andcc %g3, PSR_PIL, %g0
- bne 1f
- nop
- wr %g3, PSR_PIL, %psr
- nop; nop; nop
-1:
- andcc %g3, PSR_PIL, %g0
- ld [%g1], %g7
- bne 1f
- st %g2, [%g1]
- wr %g3, 0x0, %psr
- nop; nop; nop
-1:
- mov %g7, %g2
- jmpl %o7 + 8, %g0
- mov %g4, %o7
-
- .globl ___xchg32_sun4md
-___xchg32_sun4md:
- swap [%g1], %g2
- jmpl %o7 + 8, %g0
- mov %g4, %o7
-#endif
-
- .globl __atomic_end
-__atomic_end:
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S
index 59186e0fcf3..4d502da3de7 100644
--- a/arch/sparc/lib/atomic_64.S
+++ b/arch/sparc/lib/atomic_64.S
@@ -3,6 +3,7 @@
* Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
*/
+#include <linux/linkage.h>
#include <asm/asi.h>
#include <asm/backoff.h>
@@ -13,9 +14,7 @@
* memory barriers, and a second which returns
* a value and does the barriers.
*/
- .globl atomic_add
- .type atomic_add,#function
-atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
+ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: lduw [%o1], %g1
add %g1, %o0, %g7
@@ -26,11 +25,9 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
retl
nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic_add, .-atomic_add
+ENDPROC(atomic_add)
- .globl atomic_sub
- .type atomic_sub,#function
-atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: lduw [%o1], %g1
sub %g1, %o0, %g7
@@ -41,11 +38,9 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
retl
nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic_sub, .-atomic_sub
+ENDPROC(atomic_sub)
- .globl atomic_add_ret
- .type atomic_add_ret,#function
-atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: lduw [%o1], %g1
add %g1, %o0, %g7
@@ -56,11 +51,9 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
retl
sra %g1, 0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic_add_ret, .-atomic_add_ret
+ENDPROC(atomic_add_ret)
- .globl atomic_sub_ret
- .type atomic_sub_ret,#function
-atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+ENTRY(atomic_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: lduw [%o1], %g1
sub %g1, %o0, %g7
@@ -71,11 +64,9 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
retl
sra %g1, 0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic_sub_ret, .-atomic_sub_ret
+ENDPROC(atomic_sub_ret)
- .globl atomic64_add
- .type atomic64_add,#function
-atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
+ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: ldx [%o1], %g1
add %g1, %o0, %g7
@@ -86,11 +77,9 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
retl
nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic64_add, .-atomic64_add
+ENDPROC(atomic64_add)
- .globl atomic64_sub
- .type atomic64_sub,#function
-atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: ldx [%o1], %g1
sub %g1, %o0, %g7
@@ -101,11 +90,9 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
retl
nop
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic64_sub, .-atomic64_sub
+ENDPROC(atomic64_sub)
- .globl atomic64_add_ret
- .type atomic64_add_ret,#function
-atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: ldx [%o1], %g1
add %g1, %o0, %g7
@@ -116,11 +103,9 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
retl
add %g1, %o0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic64_add_ret, .-atomic64_add_ret
+ENDPROC(atomic64_add_ret)
- .globl atomic64_sub_ret
- .type atomic64_sub_ret,#function
-atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: ldx [%o1], %g1
sub %g1, %o0, %g7
@@ -131,4 +116,4 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
retl
sub %g1, %o0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
- .size atomic64_sub_ret, .-atomic64_sub_ret
+ENDPROC(atomic64_sub_ret)
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S
index 3dc61d5537c..36f72cc0e67 100644
--- a/arch/sparc/lib/bitops.S
+++ b/arch/sparc/lib/bitops.S
@@ -3,14 +3,13 @@
* Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
*/
+#include <linux/linkage.h>
#include <asm/asi.h>
#include <asm/backoff.h>
.text
- .globl test_and_set_bit
- .type test_and_set_bit,#function
-test_and_set_bit: /* %o0=nr, %o1=addr */
+ENTRY(test_and_set_bit) /* %o0=nr, %o1=addr */
BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
@@ -29,11 +28,9 @@ test_and_set_bit: /* %o0=nr, %o1=addr */
retl
nop
2: BACKOFF_SPIN(%o3, %o4, 1b)
- .size test_and_set_bit, .-test_and_set_bit
+ENDPROC(test_and_set_bit)
- .globl test_and_clear_bit
- .type test_and_clear_bit,#function
-test_and_clear_bit: /* %o0=nr, %o1=addr */
+ENTRY(test_and_clear_bit) /* %o0=nr, %o1=addr */
BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
@@ -52,11 +49,9 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */
retl
nop
2: BACKOFF_SPIN(%o3, %o4, 1b)
- .size test_and_clear_bit, .-test_and_clear_bit
+ENDPROC(test_and_clear_bit)
- .globl test_and_change_bit
- .type test_and_change_bit,#function
-test_and_change_bit: /* %o0=nr, %o1=addr */
+ENTRY(test_and_change_bit) /* %o0=nr, %o1=addr */
BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
@@ -75,11 +70,9 @@ test_and_change_bit: /* %o0=nr, %o1=addr */
retl
nop
2: BACKOFF_SPIN(%o3, %o4, 1b)
- .size test_and_change_bit, .-test_and_change_bit
+ENDPROC(test_and_change_bit)
- .globl set_bit
- .type set_bit,#function
-set_bit: /* %o0=nr, %o1=addr */
+ENTRY(set_bit) /* %o0=nr, %o1=addr */
BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
@@ -96,11 +89,9 @@ set_bit: /* %o0=nr, %o1=addr */
retl
nop
2: BACKOFF_SPIN(%o3, %o4, 1b)
- .size set_bit, .-set_bit
+ENDPROC(set_bit)
- .globl clear_bit
- .type clear_bit,#function
-clear_bit: /* %o0=nr, %o1=addr */
+ENTRY(clear_bit) /* %o0=nr, %o1=addr */
BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
@@ -117,11 +108,9 @@ clear_bit: /* %o0=nr, %o1=addr */
retl
nop
2: BACKOFF_SPIN(%o3, %o4, 1b)
- .size clear_bit, .-clear_bit
+ENDPROC(clear_bit)
- .globl change_bit
- .type change_bit,#function
-change_bit: /* %o0=nr, %o1=addr */
+ENTRY(change_bit) /* %o0=nr, %o1=addr */
BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
@@ -138,4 +127,4 @@ change_bit: /* %o0=nr, %o1=addr */
retl
nop
2: BACKOFF_SPIN(%o3, %o4, 1b)
- .size change_bit, .-change_bit
+ENDPROC(change_bit)
diff --git a/arch/sparc/lib/blockops.S b/arch/sparc/lib/blockops.S
index 804be87f9a4..3c771011ff4 100644
--- a/arch/sparc/lib/blockops.S
+++ b/arch/sparc/lib/blockops.S
@@ -4,6 +4,7 @@
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/linkage.h>
#include <asm/page.h>
/* Zero out 64 bytes of memory at (buf + offset).
@@ -44,10 +45,7 @@
*/
.text
- .align 4
- .globl bzero_1page, __copy_1page
-
-bzero_1page:
+ENTRY(bzero_1page)
/* NOTE: If you change the number of insns of this routine, please check
* arch/sparc/mm/hypersparc.S */
/* %o0 = buf */
@@ -65,8 +63,9 @@ bzero_1page:
retl
nop
+ENDPROC(bzero_1page)
-__copy_1page:
+ENTRY(__copy_1page)
/* NOTE: If you change the number of insns of this routine, please check
* arch/sparc/mm/hypersparc.S */
/* %o0 = dst, %o1 = src */
@@ -87,3 +86,4 @@ __copy_1page:
retl
nop
+ENDPROC(__copy_1page)
diff --git a/arch/sparc/lib/bzero.S b/arch/sparc/lib/bzero.S
index 615f401edf6..8c058114b64 100644
--- a/arch/sparc/lib/bzero.S
+++ b/arch/sparc/lib/bzero.S
@@ -4,11 +4,11 @@
* Copyright (C) 2005 David S. Miller <davem@davemloft.net>
*/
+#include <linux/linkage.h>
+
.text
- .globl memset
- .type memset, #function
-memset: /* %o0=buf, %o1=pat, %o2=len */
+ENTRY(memset) /* %o0=buf, %o1=pat, %o2=len */
and %o1, 0xff, %o3
mov %o2, %o1
sllx %o3, 8, %g1
@@ -19,9 +19,7 @@ memset: /* %o0=buf, %o1=pat, %o2=len */
ba,pt %xcc, 1f
or %g1, %o2, %o2
- .globl __bzero
- .type __bzero, #function
-__bzero: /* %o0=buf, %o1=len */
+ENTRY(__bzero) /* %o0=buf, %o1=len */
clr %o2
1: mov %o0, %o3
brz,pn %o1, __bzero_done
@@ -78,8 +76,8 @@ __bzero_tiny:
__bzero_done:
retl
mov %o3, %o0
- .size __bzero, .-__bzero
- .size memset, .-memset
+ENDPROC(__bzero)
+ENDPROC(memset)
#define EX_ST(x,y) \
98: x,y; \
@@ -89,9 +87,7 @@ __bzero_done:
.text; \
.align 4;
- .globl __clear_user
- .type __clear_user, #function
-__clear_user: /* %o0=buf, %o1=len */
+ENTRY(__clear_user) /* %o0=buf, %o1=len */
brz,pn %o1, __clear_user_done
cmp %o1, 16
bl,pn %icc, __clear_user_tiny
@@ -146,4 +142,4 @@ __clear_user_tiny:
__clear_user_done:
retl
clr %o0
- .size __clear_user, .-__clear_user
+ENDPROC(__clear_user)
diff --git a/arch/sparc/lib/divdi3.S b/arch/sparc/lib/divdi3.S
index d74bc0925f2..9614b48b6ef 100644
--- a/arch/sparc/lib/divdi3.S
+++ b/arch/sparc/lib/divdi3.S
@@ -19,7 +19,6 @@ Boston, MA 02111-1307, USA. */
.text
.align 4
- .global .udiv
.globl __divdi3
__divdi3:
save %sp,-104,%sp
@@ -83,8 +82,9 @@ __divdi3:
bne .LL85
mov %i0,%o2
mov 1,%o0
- call .udiv,0
mov 0,%o1
+ wr %g0, 0, %y
+ udiv %o0, %o1, %o0
mov %o0,%o4
mov %i0,%o2
.LL85:
diff --git a/arch/sparc/lib/ipcsum.S b/arch/sparc/lib/ipcsum.S
index 58ca5b9a877..4742d59029e 100644
--- a/arch/sparc/lib/ipcsum.S
+++ b/arch/sparc/lib/ipcsum.S
@@ -1,8 +1,7 @@
+#include <linux/linkage.h>
+
.text
- .align 32
- .globl ip_fast_csum
- .type ip_fast_csum,#function
-ip_fast_csum: /* %o0 = iph, %o1 = ihl */
+ENTRY(ip_fast_csum) /* %o0 = iph, %o1 = ihl */
sub %o1, 4, %g7
lduw [%o0 + 0x00], %o2
lduw [%o0 + 0x04], %g2
@@ -31,4 +30,4 @@ ip_fast_csum: /* %o0 = iph, %o1 = ihl */
set 0xffff, %o1
retl
and %o2, %o1, %o0
- .size ip_fast_csum, .-ip_fast_csum
+ENDPROC(ip_fast_csum)
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index f73c2240fe6..3b31218cafc 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -15,8 +15,6 @@
/* string functions */
EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(__strlen_user);
-EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(strncmp);
/* mem* functions */
@@ -33,9 +31,6 @@ EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__bzero);
-/* Moving data to/from/in userspace. */
-EXPORT_SYMBOL(__strncpy_from_user);
-
/* Networking helper routines. */
EXPORT_SYMBOL(csum_partial);
@@ -56,23 +51,11 @@ extern int __divdi3(int, int);
extern void (*__copy_1page)(void *, const void *);
extern void (*bzero_1page)(void *);
-extern int __strncmp(const char *, const char *, __kernel_size_t);
-
extern void ___rw_read_enter(void);
extern void ___rw_read_try(void);
extern void ___rw_read_exit(void);
extern void ___rw_write_enter(void);
-/* Alias functions whose names begin with "." and export the aliases.
- * The module references will be fixed up by module_frob_arch_sections.
- */
-extern int _Div(int, int);
-extern int _Mul(int, int);
-extern int _Rem(int, int);
-extern unsigned _Udiv(unsigned, unsigned);
-extern unsigned _Umul(unsigned, unsigned);
-extern unsigned _Urem(unsigned, unsigned);
-
/* Networking helper routines. */
EXPORT_SYMBOL(__csum_partial_copy_sparc_generic);
@@ -81,9 +64,6 @@ EXPORT_SYMBOL(__copy_1page);
EXPORT_SYMBOL(__memmove);
EXPORT_SYMBOL(bzero_1page);
-/* string functions */
-EXPORT_SYMBOL(__strncmp);
-
/* Moving data to/from/in userspace. */
EXPORT_SYMBOL(__copy_user);
@@ -100,13 +80,6 @@ EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__lshrdi3);
EXPORT_SYMBOL(__muldi3);
EXPORT_SYMBOL(__divdi3);
-
-EXPORT_SYMBOL(_Rem);
-EXPORT_SYMBOL(_Urem);
-EXPORT_SYMBOL(_Mul);
-EXPORT_SYMBOL(_Umul);
-EXPORT_SYMBOL(_Div);
-EXPORT_SYMBOL(_Udiv);
#endif
/*
diff --git a/arch/sparc/lib/lshrdi3.S b/arch/sparc/lib/lshrdi3.S
index 47a1354c160..60ebc7cdbee 100644
--- a/arch/sparc/lib/lshrdi3.S
+++ b/arch/sparc/lib/lshrdi3.S
@@ -1,6 +1,6 @@
+#include <linux/linkage.h>
- .globl __lshrdi3
-__lshrdi3:
+ENTRY(__lshrdi3)
cmp %o2, 0
be 3f
mov 0x20, %g2
@@ -24,3 +24,4 @@ __lshrdi3:
3:
retl
nop
+ENDPROC(__lshrdi3)
diff --git a/arch/sparc/lib/memmove.S b/arch/sparc/lib/memmove.S
index 97395802c23..b7f6334e159 100644
--- a/arch/sparc/lib/memmove.S
+++ b/arch/sparc/lib/memmove.S
@@ -4,11 +4,10 @@
* Copyright (C) 1996, 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz)
*/
+#include <linux/linkage.h>
+
.text
- .align 32
- .globl memmove
- .type memmove,#function
-memmove: /* o0=dst o1=src o2=len */
+ENTRY(memmove) /* o0=dst o1=src o2=len */
mov %o0, %g1
cmp %o0, %o1
bleu,pt %xcc, memcpy
@@ -28,4 +27,4 @@ memmove: /* o0=dst o1=src o2=len */
retl
mov %g1, %o0
- .size memmove, .-memmove
+ENDPROC(memmove)
diff --git a/arch/sparc/lib/mul.S b/arch/sparc/lib/mul.S
deleted file mode 100644
index c45470d0b0c..00000000000
--- a/arch/sparc/lib/mul.S
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * mul.S: This routine was taken from glibc-1.09 and is covered
- * by the GNU Library General Public License Version 2.
- */
-
-/*
- * Signed multiply, from Appendix E of the Sparc Version 8
- * Architecture Manual.
- */
-
-/*
- * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of
- * the 64-bit product).
- *
- * This code optimizes short (less than 13-bit) multiplies.
- */
-
- .globl .mul
- .globl _Mul
-.mul:
-_Mul: /* needed for export */
- mov %o0, %y ! multiplier -> Y
- andncc %o0, 0xfff, %g0 ! test bits 12..31
- be Lmul_shortway ! if zero, can do it the short way
- andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
-
- /*
- * Long multiply. 32 steps, followed by a final shift step.
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %o1, %o4 ! 13
- mulscc %o4, %o1, %o4 ! 14
- mulscc %o4, %o1, %o4 ! 15
- mulscc %o4, %o1, %o4 ! 16
- mulscc %o4, %o1, %o4 ! 17
- mulscc %o4, %o1, %o4 ! 18
- mulscc %o4, %o1, %o4 ! 19
- mulscc %o4, %o1, %o4 ! 20
- mulscc %o4, %o1, %o4 ! 21
- mulscc %o4, %o1, %o4 ! 22
- mulscc %o4, %o1, %o4 ! 23
- mulscc %o4, %o1, %o4 ! 24
- mulscc %o4, %o1, %o4 ! 25
- mulscc %o4, %o1, %o4 ! 26
- mulscc %o4, %o1, %o4 ! 27
- mulscc %o4, %o1, %o4 ! 28
- mulscc %o4, %o1, %o4 ! 29
- mulscc %o4, %o1, %o4 ! 30
- mulscc %o4, %o1, %o4 ! 31
- mulscc %o4, %o1, %o4 ! 32
- mulscc %o4, %g0, %o4 ! final shift
-
- ! If %o0 was negative, the result is
- ! (%o0 * %o1) + (%o1 << 32))
- ! We fix that here.
-
-#if 0
- tst %o0
- bge 1f
- rd %y, %o0
-
- ! %o0 was indeed negative; fix upper 32 bits of result by subtracting
- ! %o1 (i.e., return %o4 - %o1 in %o1).
- retl
- sub %o4, %o1, %o1
-
-1:
- retl
- mov %o4, %o1
-#else
- /* Faster code adapted from tege@sics.se's code for umul.S. */
- sra %o0, 31, %o2 ! make mask from sign bit
- and %o1, %o2, %o2 ! %o2 = 0 or %o1, depending on sign of %o0
- rd %y, %o0 ! get lower half of product
- retl
- sub %o4, %o2, %o1 ! subtract compensation
- ! and put upper half in place
-#endif
-
-Lmul_shortway:
- /*
- * Short multiply. 12 steps, followed by a final shift step.
- * The resulting bits are off by 12 and (32-12) = 20 bit positions,
- * but there is no problem with %o0 being negative (unlike above).
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %g0, %o4 ! final shift
-
- /*
- * %o4 has 20 of the bits that should be in the low part of the
- * result; %y has the bottom 12 (as %y's top 12). That is:
- *
- * %o4 %y
- * +----------------+----------------+
- * | -12- | -20- | -12- | -20- |
- * +------(---------+------)---------+
- * --hi-- ----low-part----
- *
- * The upper 12 bits of %o4 should be sign-extended to form the
- * high part of the product (i.e., highpart = %o4 >> 20).
- */
-
- rd %y, %o5
- sll %o4, 12, %o0 ! shift middle bits left 12
- srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left
- or %o5, %o0, %o0 ! construct low part of result
- retl
- sra %o4, 20, %o1 ! ... and extract high part of result
-
- .globl .mul_patch
-.mul_patch:
- smul %o0, %o1, %o0
- retl
- rd %y, %o1
- nop
diff --git a/arch/sparc/lib/muldi3.S b/arch/sparc/lib/muldi3.S
index 7f17872d060..9794939d1c1 100644
--- a/arch/sparc/lib/muldi3.S
+++ b/arch/sparc/lib/muldi3.S
@@ -63,12 +63,12 @@ __muldi3:
rd %y, %o1
mov %o1, %l3
mov %i1, %o0
- call .umul
mov %i2, %o1
+ umul %o0, %o1, %o0
mov %o0, %l0
mov %i0, %o0
- call .umul
mov %i3, %o1
+ umul %o0, %o1, %o0
add %l0, %o0, %l0
mov %l2, %i0
add %l2, %l0, %i0
diff --git a/arch/sparc/lib/rem.S b/arch/sparc/lib/rem.S
deleted file mode 100644
index 42fb8625281..00000000000
--- a/arch/sparc/lib/rem.S
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * rem.S: This routine was taken from glibc-1.09 and is covered
- * by the GNU Library General Public License Version 2.
- */
-
-
-/* This file is generated from divrem.m4; DO NOT EDIT! */
-/*
- * Division and remainder, from Appendix E of the Sparc Version 8
- * Architecture Manual, with fixes from Gordon Irlam.
- */
-
-/*
- * Input: dividend and divisor in %o0 and %o1 respectively.
- *
- * m4 parameters:
- * .rem name of function to generate
- * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1
- * true true=true => signed; true=false => unsigned
- *
- * Algorithm parameters:
- * N how many bits per iteration we try to get (4)
- * WORDSIZE total number of bits (32)
- *
- * Derived constants:
- * TOPBITS number of bits in the top decade of a number
- *
- * Important variables:
- * Q the partial quotient under development (initially 0)
- * R the remainder so far, initially the dividend
- * ITER number of main division loop iterations required;
- * equal to ceil(log2(quotient) / N). Note that this
- * is the log base (2^N) of the quotient.
- * V the current comparand, initially divisor*2^(ITER*N-1)
- *
- * Cost:
- * Current estimate for non-large dividend is
- * ceil(log2(quotient) / N) * (10 + 7N/2) + C
- * A large dividend is one greater than 2^(31-TOPBITS) and takes a
- * different path, as the upper bits of the quotient must be developed
- * one bit at a time.
- */
-
-
- .globl .rem
- .globl _Rem
-.rem:
-_Rem: /* needed for export */
- ! compute sign of result; if neither is negative, no problem
- orcc %o1, %o0, %g0 ! either negative?
- bge 2f ! no, go do the divide
- mov %o0, %g2 ! compute sign in any case
-
- tst %o1
- bge 1f
- tst %o0
- ! %o1 is definitely negative; %o0 might also be negative
- bge 2f ! if %o0 not negative...
- sub %g0, %o1, %o1 ! in any case, make %o1 nonneg
-1: ! %o0 is negative, %o1 is nonnegative
- sub %g0, %o0, %o0 ! make %o0 nonnegative
-2:
-
- ! Ready to divide. Compute size of quotient; scale comparand.
- orcc %o1, %g0, %o5
- bne 1f
- mov %o0, %o3
-
- ! Divide by zero trap. If it returns, return 0 (about as
- ! wrong as possible, but that is what SunOS does...).
- ta ST_DIV0
- retl
- clr %o0
-
-1:
- cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
- clr %o2
-
- sethi %hi(1 << (32 - 4 - 1)), %g1
-
- cmp %o3, %g1
- blu Lnot_really_big
- clr %o4
-
- ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
- ! as our usual N-at-a-shot divide step will cause overflow and havoc.
- ! The number of bits in the result here is N*ITER+SC, where SC <= N.
- ! Compute ITER in an unorthodox manner: know we need to shift V into
- ! the top decade: so do not even bother to compare to R.
- 1:
- cmp %o5, %g1
- bgeu 3f
- mov 1, %g7
-
- sll %o5, 4, %o5
-
- b 1b
- add %o4, 1, %o4
-
- ! Now compute %g7.
- 2:
- addcc %o5, %o5, %o5
-
- bcc Lnot_too_big
- add %g7, 1, %g7
-
- ! We get here if the %o1 overflowed while shifting.
- ! This means that %o3 has the high-order bit set.
- ! Restore %o5 and subtract from %o3.
- sll %g1, 4, %g1 ! high order bit
- srl %o5, 1, %o5 ! rest of %o5
- add %o5, %g1, %o5
-
- b Ldo_single_div
- sub %g7, 1, %g7
-
- Lnot_too_big:
- 3:
- cmp %o5, %o3
- blu 2b
- nop
-
- be Ldo_single_div
- nop
- /* NB: these are commented out in the V8-Sparc manual as well */
- /* (I do not understand this) */
- ! %o5 > %o3: went too far: back up 1 step
- ! srl %o5, 1, %o5
- ! dec %g7
- ! do single-bit divide steps
- !
- ! We have to be careful here. We know that %o3 >= %o5, so we can do the
- ! first divide step without thinking. BUT, the others are conditional,
- ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
- ! order bit set in the first step, just falling into the regular
- ! division loop will mess up the first time around.
- ! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
- nop
-
- sub %o3, %o5, %o3
- mov 1, %o2
-
- b Lend_single_divloop
- nop
- Lsingle_divloop:
- sll %o2, 1, %o2
-
- bl 1f
- srl %o5, 1, %o5
- ! %o3 >= 0
- sub %o3, %o5, %o3
-
- b 2f
- add %o2, 1, %o2
- 1: ! %o3 < 0
- add %o3, %o5, %o3
- sub %o2, 1, %o2
- 2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
- tst %o3
-
- b,a Lend_regular_divide
-
-Lnot_really_big:
-1:
- sll %o5, 4, %o5
- cmp %o5, %o3
- bleu 1b
- addcc %o4, 1, %o4
- be Lgot_result
- sub %o4, 1, %o4
-
- tst %o3 ! set up for initial iteration
-Ldivloop:
- sll %o2, 4, %o2
- ! depth 1, accumulated bits 0
- bl L.1.16
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 2, accumulated bits 1
- bl L.2.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits 3
- bl L.3.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 7
- bl L.4.23
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
-
- b 9f
- add %o2, (7*2+1), %o2
-
-L.4.23:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (7*2-1), %o2
-
-L.3.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 5
- bl L.4.21
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2+1), %o2
-
-L.4.21:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2-1), %o2
-
-L.2.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits 1
- bl L.3.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 3
- bl L.4.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2+1), %o2
-
-L.4.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2-1), %o2
-
-L.3.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 1
- bl L.4.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2+1), %o2
-
-L.4.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2-1), %o2
-
-L.1.16:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 2, accumulated bits -1
- bl L.2.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits -1
- bl L.3.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -1
- bl L.4.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2+1), %o2
-
-L.4.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2-1), %o2
-
-L.3.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -3
- bl L.4.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2+1), %o2
-
-L.4.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2-1), %o2
-
-L.2.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits -3
- bl L.3.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -5
- bl L.4.11
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2+1), %o2
-
-L.4.11:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2-1), %o2
-
-
-L.3.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -7
- bl L.4.9
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2+1), %o2
-
-L.4.9:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2-1), %o2
-
- 9:
-Lend_regular_divide:
- subcc %o4, 1, %o4
- bge Ldivloop
- tst %o3
-
- bl,a Lgot_result
- ! non-restoring fixup here (one instruction only!)
- add %o3, %o1, %o3
-
-Lgot_result:
- ! check to see if answer should be < 0
- tst %g2
- bl,a 1f
- sub %g0, %o3, %o3
-1:
- retl
- mov %o3, %o0
-
- .globl .rem_patch
-.rem_patch:
- sra %o0, 0x1f, %o4
- wr %o4, 0x0, %y
- nop
- nop
- nop
- sdivcc %o0, %o1, %o2
- bvs,a 1f
- xnor %o2, %g0, %o2
-1: smul %o2, %o1, %o2
- retl
- sub %o0, %o2, %o0
- nop
diff --git a/arch/sparc/lib/sdiv.S b/arch/sparc/lib/sdiv.S
deleted file mode 100644
index f0a0d4e4db7..00000000000
--- a/arch/sparc/lib/sdiv.S
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * sdiv.S: This routine was taken from glibc-1.09 and is covered
- * by the GNU Library General Public License Version 2.
- */
-
-
-/* This file is generated from divrem.m4; DO NOT EDIT! */
-/*
- * Division and remainder, from Appendix E of the Sparc Version 8
- * Architecture Manual, with fixes from Gordon Irlam.
- */
-
-/*
- * Input: dividend and divisor in %o0 and %o1 respectively.
- *
- * m4 parameters:
- * .div name of function to generate
- * div div=div => %o0 / %o1; div=rem => %o0 % %o1
- * true true=true => signed; true=false => unsigned
- *
- * Algorithm parameters:
- * N how many bits per iteration we try to get (4)
- * WORDSIZE total number of bits (32)
- *
- * Derived constants:
- * TOPBITS number of bits in the top decade of a number
- *
- * Important variables:
- * Q the partial quotient under development (initially 0)
- * R the remainder so far, initially the dividend
- * ITER number of main division loop iterations required;
- * equal to ceil(log2(quotient) / N). Note that this
- * is the log base (2^N) of the quotient.
- * V the current comparand, initially divisor*2^(ITER*N-1)
- *
- * Cost:
- * Current estimate for non-large dividend is
- * ceil(log2(quotient) / N) * (10 + 7N/2) + C
- * A large dividend is one greater than 2^(31-TOPBITS) and takes a
- * different path, as the upper bits of the quotient must be developed
- * one bit at a time.
- */
-
-
- .globl .div
- .globl _Div
-.div:
-_Div: /* needed for export */
- ! compute sign of result; if neither is negative, no problem
- orcc %o1, %o0, %g0 ! either negative?
- bge 2f ! no, go do the divide
- xor %o1, %o0, %g2 ! compute sign in any case
-
- tst %o1
- bge 1f
- tst %o0
- ! %o1 is definitely negative; %o0 might also be negative
- bge 2f ! if %o0 not negative...
- sub %g0, %o1, %o1 ! in any case, make %o1 nonneg
-1: ! %o0 is negative, %o1 is nonnegative
- sub %g0, %o0, %o0 ! make %o0 nonnegative
-2:
-
- ! Ready to divide. Compute size of quotient; scale comparand.
- orcc %o1, %g0, %o5
- bne 1f
- mov %o0, %o3
-
- ! Divide by zero trap. If it returns, return 0 (about as
- ! wrong as possible, but that is what SunOS does...).
- ta ST_DIV0
- retl
- clr %o0
-
-1:
- cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
- clr %o2
-
- sethi %hi(1 << (32 - 4 - 1)), %g1
-
- cmp %o3, %g1
- blu Lnot_really_big
- clr %o4
-
- ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
- ! as our usual N-at-a-shot divide step will cause overflow and havoc.
- ! The number of bits in the result here is N*ITER+SC, where SC <= N.
- ! Compute ITER in an unorthodox manner: know we need to shift V into
- ! the top decade: so do not even bother to compare to R.
- 1:
- cmp %o5, %g1
- bgeu 3f
- mov 1, %g7
-
- sll %o5, 4, %o5
-
- b 1b
- add %o4, 1, %o4
-
- ! Now compute %g7.
- 2:
- addcc %o5, %o5, %o5
- bcc Lnot_too_big
- add %g7, 1, %g7
-
- ! We get here if the %o1 overflowed while shifting.
- ! This means that %o3 has the high-order bit set.
- ! Restore %o5 and subtract from %o3.
- sll %g1, 4, %g1 ! high order bit
- srl %o5, 1, %o5 ! rest of %o5
- add %o5, %g1, %o5
-
- b Ldo_single_div
- sub %g7, 1, %g7
-
- Lnot_too_big:
- 3:
- cmp %o5, %o3
- blu 2b
- nop
-
- be Ldo_single_div
- nop
- /* NB: these are commented out in the V8-Sparc manual as well */
- /* (I do not understand this) */
- ! %o5 > %o3: went too far: back up 1 step
- ! srl %o5, 1, %o5
- ! dec %g7
- ! do single-bit divide steps
- !
- ! We have to be careful here. We know that %o3 >= %o5, so we can do the
- ! first divide step without thinking. BUT, the others are conditional,
- ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
- ! order bit set in the first step, just falling into the regular
- ! division loop will mess up the first time around.
- ! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
- nop
-
- sub %o3, %o5, %o3
- mov 1, %o2
-
- b Lend_single_divloop
- nop
- Lsingle_divloop:
- sll %o2, 1, %o2
-
- bl 1f
- srl %o5, 1, %o5
- ! %o3 >= 0
- sub %o3, %o5, %o3
-
- b 2f
- add %o2, 1, %o2
- 1: ! %o3 < 0
- add %o3, %o5, %o3
- sub %o2, 1, %o2
- 2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
- tst %o3
-
- b,a Lend_regular_divide
-
-Lnot_really_big:
-1:
- sll %o5, 4, %o5
- cmp %o5, %o3
- bleu 1b
- addcc %o4, 1, %o4
-
- be Lgot_result
- sub %o4, 1, %o4
-
- tst %o3 ! set up for initial iteration
-Ldivloop:
- sll %o2, 4, %o2
- ! depth 1, accumulated bits 0
- bl L.1.16
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 2, accumulated bits 1
- bl L.2.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits 3
- bl L.3.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 7
- bl L.4.23
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (7*2+1), %o2
-
-L.4.23:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (7*2-1), %o2
-
-L.3.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 5
- bl L.4.21
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2+1), %o2
-
-L.4.21:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2-1), %o2
-
-L.2.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits 1
- bl L.3.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 3
- bl L.4.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2+1), %o2
-
-L.4.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2-1), %o2
-
-
-L.3.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 1
- bl L.4.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2+1), %o2
-
-L.4.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2-1), %o2
-
-L.1.16:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 2, accumulated bits -1
- bl L.2.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits -1
- bl L.3.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -1
- bl L.4.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2+1), %o2
-
-L.4.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2-1), %o2
-
-L.3.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -3
- bl L.4.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2+1), %o2
-
-L.4.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2-1), %o2
-
-L.2.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits -3
- bl L.3.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -5
- bl L.4.11
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2+1), %o2
-
-L.4.11:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2-1), %o2
-
-L.3.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -7
- bl L.4.9
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2+1), %o2
-
-L.4.9:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2-1), %o2
-
- 9:
-Lend_regular_divide:
- subcc %o4, 1, %o4
- bge Ldivloop
- tst %o3
-
- bl,a Lgot_result
- ! non-restoring fixup here (one instruction only!)
- sub %o2, 1, %o2
-
-Lgot_result:
- ! check to see if answer should be < 0
- tst %g2
- bl,a 1f
- sub %g0, %o2, %o2
-1:
- retl
- mov %o2, %o0
-
- .globl .div_patch
-.div_patch:
- sra %o0, 0x1f, %o2
- wr %o2, 0x0, %y
- nop
- nop
- nop
- sdivcc %o0, %o1, %o0
- bvs,a 1f
- xnor %o0, %g0, %o0
-1: retl
- nop
diff --git a/arch/sparc/lib/strlen_user_32.S b/arch/sparc/lib/strlen_user_32.S
deleted file mode 100644
index 8c8a371df3c..00000000000
--- a/arch/sparc/lib/strlen_user_32.S
+++ /dev/null
@@ -1,109 +0,0 @@
-/* strlen_user.S: Sparc optimized strlen_user code
- *
- * Return length of string in userspace including terminating 0
- * or 0 for error
- *
- * Copyright (C) 1991,1996 Free Software Foundation
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#define LO_MAGIC 0x01010101
-#define HI_MAGIC 0x80808080
-
-10:
- ldub [%o0], %o5
- cmp %o5, 0
- be 1f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be 4f
- or %o4, %lo(HI_MAGIC), %o3
-11:
- ldub [%o0], %o5
- cmp %o5, 0
- be 2f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be 5f
- sethi %hi(LO_MAGIC), %o4
-12:
- ldub [%o0], %o5
- cmp %o5, 0
- be 3f
- add %o0, 1, %o0
- b 13f
- or %o4, %lo(LO_MAGIC), %o2
-1:
- retl
- mov 1, %o0
-2:
- retl
- mov 2, %o0
-3:
- retl
- mov 3, %o0
-
- .align 4
- .global __strlen_user, __strnlen_user
-__strlen_user:
- sethi %hi(32768), %o1
-__strnlen_user:
- mov %o1, %g1
- mov %o0, %o1
- andcc %o0, 3, %g0
- bne 10b
- sethi %hi(HI_MAGIC), %o4
- or %o4, %lo(HI_MAGIC), %o3
-4:
- sethi %hi(LO_MAGIC), %o4
-5:
- or %o4, %lo(LO_MAGIC), %o2
-13:
- ld [%o0], %o5
-2:
- sub %o5, %o2, %o4
- andcc %o4, %o3, %g0
- bne 82f
- add %o0, 4, %o0
- sub %o0, %o1, %g2
-81: cmp %g2, %g1
- blu 13b
- mov %o0, %o4
- ba,a 1f
-
- /* Check every byte. */
-82: srl %o5, 24, %g5
- andcc %g5, 0xff, %g0
- be 1f
- add %o0, -3, %o4
- srl %o5, 16, %g5
- andcc %g5, 0xff, %g0
- be 1f
- add %o4, 1, %o4
- srl %o5, 8, %g5
- andcc %g5, 0xff, %g0
- be 1f
- add %o4, 1, %o4
- andcc %o5, 0xff, %g0
- bne 81b
- sub %o0, %o1, %g2
-
- add %o4, 1, %o4
-1:
- retl
- sub %o4, %o1, %o0
-
- .section .fixup,#alloc,#execinstr
- .align 4
-9:
- retl
- clr %o0
-
- .section __ex_table,#alloc
- .align 4
-
- .word 10b, 9b
- .word 11b, 9b
- .word 12b, 9b
- .word 13b, 9b
diff --git a/arch/sparc/lib/strlen_user_64.S b/arch/sparc/lib/strlen_user_64.S
deleted file mode 100644
index 114ed111e25..00000000000
--- a/arch/sparc/lib/strlen_user_64.S
+++ /dev/null
@@ -1,95 +0,0 @@
-/* strlen_user.S: Sparc64 optimized strlen_user code
- *
- * Return length of string in userspace including terminating 0
- * or 0 for error
- *
- * Copyright (C) 1991,1996 Free Software Foundation
- * Copyright (C) 1996,1999 David S. Miller (davem@redhat.com)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <asm/asi.h>
-
-#define LO_MAGIC 0x01010101
-#define HI_MAGIC 0x80808080
-
- .align 4
- .global __strlen_user, __strnlen_user
-__strlen_user:
- sethi %hi(32768), %o1
-__strnlen_user:
- mov %o1, %g1
- mov %o0, %o1
- andcc %o0, 3, %g0
- be,pt %icc, 9f
- sethi %hi(HI_MAGIC), %o4
-10: lduba [%o0] %asi, %o5
- brz,pn %o5, 21f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be,pn %icc, 4f
- or %o4, %lo(HI_MAGIC), %o3
-11: lduba [%o0] %asi, %o5
- brz,pn %o5, 22f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be,pt %icc, 13f
- srl %o3, 7, %o2
-12: lduba [%o0] %asi, %o5
- brz,pn %o5, 23f
- add %o0, 1, %o0
- ba,pt %icc, 2f
-15: lda [%o0] %asi, %o5
-9: or %o4, %lo(HI_MAGIC), %o3
-4: srl %o3, 7, %o2
-13: lda [%o0] %asi, %o5
-2: sub %o5, %o2, %o4
- andcc %o4, %o3, %g0
- bne,pn %icc, 82f
- add %o0, 4, %o0
- sub %o0, %o1, %g2
-81: cmp %g2, %g1
- blu,pt %icc, 13b
- mov %o0, %o4
- ba,a,pt %xcc, 1f
-
- /* Check every byte. */
-82: srl %o5, 24, %g7
- andcc %g7, 0xff, %g0
- be,pn %icc, 1f
- add %o0, -3, %o4
- srl %o5, 16, %g7
- andcc %g7, 0xff, %g0
- be,pn %icc, 1f
- add %o4, 1, %o4
- srl %o5, 8, %g7
- andcc %g7, 0xff, %g0
- be,pn %icc, 1f
- add %o4, 1, %o4
- andcc %o5, 0xff, %g0
- bne,pt %icc, 81b
- sub %o0, %o1, %g2
- add %o4, 1, %o4
-1: retl
- sub %o4, %o1, %o0
-21: retl
- mov 1, %o0
-22: retl
- mov 2, %o0
-23: retl
- mov 3, %o0
-
- .section .fixup,#alloc,#execinstr
- .align 4
-30:
- retl
- clr %o0
-
- .section __ex_table,"a"
- .align 4
-
- .word 10b, 30b
- .word 11b, 30b
- .word 12b, 30b
- .word 15b, 30b
- .word 13b, 30b
diff --git a/arch/sparc/lib/strncmp_32.S b/arch/sparc/lib/strncmp_32.S
index 494ec664537..c0d1b568c1c 100644
--- a/arch/sparc/lib/strncmp_32.S
+++ b/arch/sparc/lib/strncmp_32.S
@@ -3,11 +3,10 @@
* generic strncmp routine.
*/
+#include <linux/linkage.h>
+
.text
- .align 4
- .global __strncmp, strncmp
-__strncmp:
-strncmp:
+ENTRY(strncmp)
mov %o0, %g3
mov 0, %o3
@@ -116,3 +115,4 @@ strncmp:
and %g2, 0xff, %o0
retl
sub %o3, %o0, %o0
+ENDPROC(strncmp)
diff --git a/arch/sparc/lib/strncmp_64.S b/arch/sparc/lib/strncmp_64.S
index 980e8375155..0656627166f 100644
--- a/arch/sparc/lib/strncmp_64.S
+++ b/arch/sparc/lib/strncmp_64.S
@@ -4,13 +4,11 @@
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
+#include <linux/linkage.h>
#include <asm/asi.h>
.text
- .align 32
- .globl strncmp
- .type strncmp,#function
-strncmp:
+ENTRY(strncmp)
brlez,pn %o2, 3f
lduba [%o0] (ASI_PNF), %o3
1:
@@ -29,4 +27,4 @@ strncmp:
3:
retl
clr %o0
- .size strncmp, .-strncmp
+ENDPROC(strncmp)
diff --git a/arch/sparc/lib/strncpy_from_user_32.S b/arch/sparc/lib/strncpy_from_user_32.S
deleted file mode 100644
index d77198976a6..00000000000
--- a/arch/sparc/lib/strncpy_from_user_32.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/* strncpy_from_user.S: Sparc strncpy from userspace.
- *
- * Copyright(C) 1996 David S. Miller
- */
-
-#include <asm/ptrace.h>
-#include <asm/errno.h>
-
- .text
- .align 4
-
- /* Must return:
- *
- * -EFAULT for an exception
- * count if we hit the buffer limit
- * bytes copied if we hit a null byte
- */
-
- .globl __strncpy_from_user
-__strncpy_from_user:
- /* %o0=dest, %o1=src, %o2=count */
- mov %o2, %o3
-1:
- subcc %o2, 1, %o2
- bneg 2f
- nop
-10:
- ldub [%o1], %o4
- add %o0, 1, %o0
- cmp %o4, 0
- add %o1, 1, %o1
- bne 1b
- stb %o4, [%o0 - 1]
-2:
- add %o2, 1, %o0
- retl
- sub %o3, %o0, %o0
-
- .section .fixup,#alloc,#execinstr
- .align 4
-4:
- retl
- mov -EFAULT, %o0
-
- .section __ex_table,#alloc
- .align 4
- .word 10b, 4b
diff --git a/arch/sparc/lib/strncpy_from_user_64.S b/arch/sparc/lib/strncpy_from_user_64.S
deleted file mode 100644
index 511c8f136f9..00000000000
--- a/arch/sparc/lib/strncpy_from_user_64.S
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * strncpy_from_user.S: Sparc64 strncpy from userspace.
- *
- * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
- */
-
-#include <asm/asi.h>
-#include <asm/errno.h>
-
- .data
- .align 8
-0: .xword 0x0101010101010101
-
- .text
- .align 32
-
- /* Must return:
- *
- * -EFAULT for an exception
- * count if we hit the buffer limit
- * bytes copied if we hit a null byte
- * (without the null byte)
- *
- * This implementation assumes:
- * %o1 is 8 aligned => !(%o2 & 7)
- * %o0 is 8 aligned (if not, it will be slooooow, but will work)
- *
- * This is optimized for the common case:
- * in my stats, 90% of src are 8 aligned (even on sparc32)
- * and average length is 18 or so.
- */
-
- .globl __strncpy_from_user
- .type __strncpy_from_user,#function
-__strncpy_from_user:
- /* %o0=dest, %o1=src, %o2=count */
- andcc %o1, 7, %g0 ! IEU1 Group
- bne,pn %icc, 30f ! CTI
- add %o0, %o2, %g3 ! IEU0
-60: ldxa [%o1] %asi, %g1 ! Load Group
- brlez,pn %o2, 10f ! CTI
- mov %o0, %o3 ! IEU0
-50: sethi %hi(0b), %o4 ! IEU0 Group
- ldx [%o4 + %lo(0b)], %o4 ! Load
- sllx %o4, 7, %o5 ! IEU1 Group
-1: sub %g1, %o4, %g2 ! IEU0 Group
- stx %g1, [%o0] ! Store
- add %o0, 8, %o0 ! IEU1
- andcc %g2, %o5, %g0 ! IEU1 Group
- bne,pn %xcc, 5f ! CTI
- add %o1, 8, %o1 ! IEU0
- cmp %o0, %g3 ! IEU1 Group
- bl,a,pt %xcc, 1b ! CTI
-61: ldxa [%o1] %asi, %g1 ! Load
-10: retl ! CTI Group
- mov %o2, %o0 ! IEU0
-5: srlx %g2, 32, %g7 ! IEU0 Group
- sethi %hi(0xff00), %o4 ! IEU1
- andcc %g7, %o5, %g0 ! IEU1 Group
- be,pn %icc, 2f ! CTI
- or %o4, %lo(0xff00), %o4 ! IEU0
- srlx %g1, 48, %g7 ! IEU0 Group
- andcc %g7, %o4, %g0 ! IEU1 Group
- be,pn %icc, 50f ! CTI
- andcc %g7, 0xff, %g0 ! IEU1 Group
- be,pn %icc, 51f ! CTI
- srlx %g1, 32, %g7 ! IEU0
- andcc %g7, %o4, %g0 ! IEU1 Group
- be,pn %icc, 52f ! CTI
- andcc %g7, 0xff, %g0 ! IEU1 Group
- be,pn %icc, 53f ! CTI
-2: andcc %g2, %o5, %g0 ! IEU1 Group
- be,pn %icc, 2f ! CTI
- srl %g1, 16, %g7 ! IEU0
- andcc %g7, %o4, %g0 ! IEU1 Group
- be,pn %icc, 54f ! CTI
- andcc %g7, 0xff, %g0 ! IEU1 Group
- be,pn %icc, 55f ! CTI
- andcc %g1, %o4, %g0 ! IEU1 Group
- be,pn %icc, 56f ! CTI
- andcc %g1, 0xff, %g0 ! IEU1 Group
- be,a,pn %icc, 57f ! CTI
- sub %o0, %o3, %o0 ! IEU0
-2: cmp %o0, %g3 ! IEU1 Group
- bl,a,pt %xcc, 50b ! CTI
-62: ldxa [%o1] %asi, %g1 ! Load
- retl ! CTI Group
- mov %o2, %o0 ! IEU0
-50: sub %o0, %o3, %o0
- retl
- sub %o0, 8, %o0
-51: sub %o0, %o3, %o0
- retl
- sub %o0, 7, %o0
-52: sub %o0, %o3, %o0
- retl
- sub %o0, 6, %o0
-53: sub %o0, %o3, %o0
- retl
- sub %o0, 5, %o0
-54: sub %o0, %o3, %o0
- retl
- sub %o0, 4, %o0
-55: sub %o0, %o3, %o0
- retl
- sub %o0, 3, %o0
-56: sub %o0, %o3, %o0
- retl
- sub %o0, 2, %o0
-57: retl
- sub %o0, 1, %o0
-30: brlez,pn %o2, 3f
- sub %g0, %o2, %o3
- add %o0, %o2, %o0
-63: lduba [%o1] %asi, %o4
-1: add %o1, 1, %o1
- brz,pn %o4, 2f
- stb %o4, [%o0 + %o3]
- addcc %o3, 1, %o3
- bne,pt %xcc, 1b
-64: lduba [%o1] %asi, %o4
-3: retl
- mov %o2, %o0
-2: retl
- add %o2, %o3, %o0
- .size __strncpy_from_user, .-__strncpy_from_user
-
- .section __ex_table,"a"
- .align 4
- .word 60b, __retl_efault
- .word 61b, __retl_efault
- .word 62b, __retl_efault
- .word 63b, __retl_efault
- .word 64b, __retl_efault
- .previous
diff --git a/arch/sparc/lib/ucmpdi2.c b/arch/sparc/lib/ucmpdi2.c
new file mode 100644
index 00000000000..1e06ed50068
--- /dev/null
+++ b/arch/sparc/lib/ucmpdi2.c
@@ -0,0 +1,19 @@
+#include <linux/module.h>
+#include "libgcc.h"
+
+word_type __ucmpdi2(unsigned long long a, unsigned long long b)
+{
+ const DWunion au = {.ll = a};
+ const DWunion bu = {.ll = b};
+
+ if ((unsigned int) au.s.high < (unsigned int) bu.s.high)
+ return 0;
+ else if ((unsigned int) au.s.high > (unsigned int) bu.s.high)
+ return 2;
+ if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
+ return 0;
+ else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
+ return 2;
+ return 1;
+}
+EXPORT_SYMBOL(__ucmpdi2);
diff --git a/arch/sparc/lib/udiv.S b/arch/sparc/lib/udiv.S
deleted file mode 100644
index 2101405bdfc..00000000000
--- a/arch/sparc/lib/udiv.S
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * udiv.S: This routine was taken from glibc-1.09 and is covered
- * by the GNU Library General Public License Version 2.
- */
-
-
-/* This file is generated from divrem.m4; DO NOT EDIT! */
-/*
- * Division and remainder, from Appendix E of the Sparc Version 8
- * Architecture Manual, with fixes from Gordon Irlam.
- */
-
-/*
- * Input: dividend and divisor in %o0 and %o1 respectively.
- *
- * m4 parameters:
- * .udiv name of function to generate
- * div div=div => %o0 / %o1; div=rem => %o0 % %o1
- * false false=true => signed; false=false => unsigned
- *
- * Algorithm parameters:
- * N how many bits per iteration we try to get (4)
- * WORDSIZE total number of bits (32)
- *
- * Derived constants:
- * TOPBITS number of bits in the top decade of a number
- *
- * Important variables:
- * Q the partial quotient under development (initially 0)
- * R the remainder so far, initially the dividend
- * ITER number of main division loop iterations required;
- * equal to ceil(log2(quotient) / N). Note that this
- * is the log base (2^N) of the quotient.
- * V the current comparand, initially divisor*2^(ITER*N-1)
- *
- * Cost:
- * Current estimate for non-large dividend is
- * ceil(log2(quotient) / N) * (10 + 7N/2) + C
- * A large dividend is one greater than 2^(31-TOPBITS) and takes a
- * different path, as the upper bits of the quotient must be developed
- * one bit at a time.
- */
-
-
- .globl .udiv
- .globl _Udiv
-.udiv:
-_Udiv: /* needed for export */
-
- ! Ready to divide. Compute size of quotient; scale comparand.
- orcc %o1, %g0, %o5
- bne 1f
- mov %o0, %o3
-
- ! Divide by zero trap. If it returns, return 0 (about as
- ! wrong as possible, but that is what SunOS does...).
- ta ST_DIV0
- retl
- clr %o0
-
-1:
- cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
- clr %o2
-
- sethi %hi(1 << (32 - 4 - 1)), %g1
-
- cmp %o3, %g1
- blu Lnot_really_big
- clr %o4
-
- ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
- ! as our usual N-at-a-shot divide step will cause overflow and havoc.
- ! The number of bits in the result here is N*ITER+SC, where SC <= N.
- ! Compute ITER in an unorthodox manner: know we need to shift V into
- ! the top decade: so do not even bother to compare to R.
- 1:
- cmp %o5, %g1
- bgeu 3f
- mov 1, %g7
-
- sll %o5, 4, %o5
-
- b 1b
- add %o4, 1, %o4
-
- ! Now compute %g7.
- 2:
- addcc %o5, %o5, %o5
- bcc Lnot_too_big
- add %g7, 1, %g7
-
- ! We get here if the %o1 overflowed while shifting.
- ! This means that %o3 has the high-order bit set.
- ! Restore %o5 and subtract from %o3.
- sll %g1, 4, %g1 ! high order bit
- srl %o5, 1, %o5 ! rest of %o5
- add %o5, %g1, %o5
-
- b Ldo_single_div
- sub %g7, 1, %g7
-
- Lnot_too_big:
- 3:
- cmp %o5, %o3
- blu 2b
- nop
-
- be Ldo_single_div
- nop
- /* NB: these are commented out in the V8-Sparc manual as well */
- /* (I do not understand this) */
- ! %o5 > %o3: went too far: back up 1 step
- ! srl %o5, 1, %o5
- ! dec %g7
- ! do single-bit divide steps
- !
- ! We have to be careful here. We know that %o3 >= %o5, so we can do the
- ! first divide step without thinking. BUT, the others are conditional,
- ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
- ! order bit set in the first step, just falling into the regular
- ! division loop will mess up the first time around.
- ! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
- nop
-
- sub %o3, %o5, %o3
- mov 1, %o2
-
- b Lend_single_divloop
- nop
- Lsingle_divloop:
- sll %o2, 1, %o2
- bl 1f
- srl %o5, 1, %o5
- ! %o3 >= 0
- sub %o3, %o5, %o3
- b 2f
- add %o2, 1, %o2
- 1: ! %o3 < 0
- add %o3, %o5, %o3
- sub %o2, 1, %o2
- 2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
- tst %o3
-
- b,a Lend_regular_divide
-
-Lnot_really_big:
-1:
- sll %o5, 4, %o5
-
- cmp %o5, %o3
- bleu 1b
- addcc %o4, 1, %o4
-
- be Lgot_result
- sub %o4, 1, %o4
-
- tst %o3 ! set up for initial iteration
-Ldivloop:
- sll %o2, 4, %o2
- ! depth 1, accumulated bits 0
- bl L.1.16
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 2, accumulated bits 1
- bl L.2.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits 3
- bl L.3.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 7
- bl L.4.23
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (7*2+1), %o2
-
-L.4.23:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (7*2-1), %o2
-
-L.3.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 5
- bl L.4.21
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2+1), %o2
-
-L.4.21:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2-1), %o2
-
-L.2.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits 1
- bl L.3.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 3
- bl L.4.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2+1), %o2
-
-L.4.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2-1), %o2
-
-L.3.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 1
- bl L.4.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2+1), %o2
-
-L.4.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2-1), %o2
-
-L.1.16:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 2, accumulated bits -1
- bl L.2.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits -1
- bl L.3.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -1
- bl L.4.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2+1), %o2
-
-L.4.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2-1), %o2
-
-L.3.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -3
- bl L.4.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2+1), %o2
-
-L.4.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2-1), %o2
-
-L.2.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits -3
- bl L.3.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -5
- bl L.4.11
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2+1), %o2
-
-L.4.11:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2-1), %o2
-
-L.3.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -7
- bl L.4.9
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2+1), %o2
-
-L.4.9:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2-1), %o2
-
- 9:
-Lend_regular_divide:
- subcc %o4, 1, %o4
- bge Ldivloop
- tst %o3
-
- bl,a Lgot_result
- ! non-restoring fixup here (one instruction only!)
- sub %o2, 1, %o2
-
-Lgot_result:
-
- retl
- mov %o2, %o0
-
- .globl .udiv_patch
-.udiv_patch:
- wr %g0, 0x0, %y
- nop
- nop
- retl
- udiv %o0, %o1, %o0
- nop
diff --git a/arch/sparc/lib/udivdi3.S b/arch/sparc/lib/udivdi3.S
index b430f1f0ef6..24e0a355e2e 100644
--- a/arch/sparc/lib/udivdi3.S
+++ b/arch/sparc/lib/udivdi3.S
@@ -60,8 +60,9 @@ __udivdi3:
bne .LL77
mov %i0,%o2
mov 1,%o0
- call .udiv,0
mov 0,%o1
+ wr %g0, 0, %y
+ udiv %o0, %o1, %o0
mov %o0,%o3
mov %i0,%o2
.LL77:
diff --git a/arch/sparc/lib/umul.S b/arch/sparc/lib/umul.S
deleted file mode 100644
index 1f36ae68252..00000000000
--- a/arch/sparc/lib/umul.S
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * umul.S: This routine was taken from glibc-1.09 and is covered
- * by the GNU Library General Public License Version 2.
- */
-
-
-/*
- * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the
- * upper 32 bits of the 64-bit product).
- *
- * This code optimizes short (less than 13-bit) multiplies. Short
- * multiplies require 25 instruction cycles, and long ones require
- * 45 instruction cycles.
- *
- * On return, overflow has occurred (%o1 is not zero) if and only if
- * the Z condition code is clear, allowing, e.g., the following:
- *
- * call .umul
- * nop
- * bnz overflow (or tnz)
- */
-
- .globl .umul
- .globl _Umul
-.umul:
-_Umul: /* needed for export */
- or %o0, %o1, %o4
- mov %o0, %y ! multiplier -> Y
-
- andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args
- be Lmul_shortway ! if zero, can do it the short way
- andcc %g0, %g0, %o4 ! zero the partial product and clear N and V
-
- /*
- * Long multiply. 32 steps, followed by a final shift step.
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %o1, %o4 ! 13
- mulscc %o4, %o1, %o4 ! 14
- mulscc %o4, %o1, %o4 ! 15
- mulscc %o4, %o1, %o4 ! 16
- mulscc %o4, %o1, %o4 ! 17
- mulscc %o4, %o1, %o4 ! 18
- mulscc %o4, %o1, %o4 ! 19
- mulscc %o4, %o1, %o4 ! 20
- mulscc %o4, %o1, %o4 ! 21
- mulscc %o4, %o1, %o4 ! 22
- mulscc %o4, %o1, %o4 ! 23
- mulscc %o4, %o1, %o4 ! 24
- mulscc %o4, %o1, %o4 ! 25
- mulscc %o4, %o1, %o4 ! 26
- mulscc %o4, %o1, %o4 ! 27
- mulscc %o4, %o1, %o4 ! 28
- mulscc %o4, %o1, %o4 ! 29
- mulscc %o4, %o1, %o4 ! 30
- mulscc %o4, %o1, %o4 ! 31
- mulscc %o4, %o1, %o4 ! 32
- mulscc %o4, %g0, %o4 ! final shift
-
-
- /*
- * Normally, with the shift-and-add approach, if both numbers are
- * positive you get the correct result. With 32-bit two's-complement
- * numbers, -x is represented as
- *
- * x 32
- * ( 2 - ------ ) mod 2 * 2
- * 32
- * 2
- *
- * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s,
- * we can treat this as if the radix point were just to the left
- * of the sign bit (multiply by 2^32), and get
- *
- * -x = (2 - x) mod 2
- *
- * Then, ignoring the `mod 2's for convenience:
- *
- * x * y = xy
- * -x * y = 2y - xy
- * x * -y = 2x - xy
- * -x * -y = 4 - 2x - 2y + xy
- *
- * For signed multiplies, we subtract (x << 32) from the partial
- * product to fix this problem for negative multipliers (see mul.s).
- * Because of the way the shift into the partial product is calculated
- * (N xor V), this term is automatically removed for the multiplicand,
- * so we don't have to adjust.
- *
- * But for unsigned multiplies, the high order bit wasn't a sign bit,
- * and the correction is wrong. So for unsigned multiplies where the
- * high order bit is one, we end up with xy - (y << 32). To fix it
- * we add y << 32.
- */
-#if 0
- tst %o1
- bl,a 1f ! if %o1 < 0 (high order bit = 1),
- add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half)
-
-1:
- rd %y, %o0 ! get lower half of product
- retl
- addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0
-#else
- /* Faster code from tege@sics.se. */
- sra %o1, 31, %o2 ! make mask from sign bit
- and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1
- rd %y, %o0 ! get lower half of product
- retl
- addcc %o4, %o2, %o1 ! add compensation and put upper half in place
-#endif
-
-Lmul_shortway:
- /*
- * Short multiply. 12 steps, followed by a final shift step.
- * The resulting bits are off by 12 and (32-12) = 20 bit positions,
- * but there is no problem with %o0 being negative (unlike above),
- * and overflow is impossible (the answer is at most 24 bits long).
- */
- mulscc %o4, %o1, %o4 ! 1
- mulscc %o4, %o1, %o4 ! 2
- mulscc %o4, %o1, %o4 ! 3
- mulscc %o4, %o1, %o4 ! 4
- mulscc %o4, %o1, %o4 ! 5
- mulscc %o4, %o1, %o4 ! 6
- mulscc %o4, %o1, %o4 ! 7
- mulscc %o4, %o1, %o4 ! 8
- mulscc %o4, %o1, %o4 ! 9
- mulscc %o4, %o1, %o4 ! 10
- mulscc %o4, %o1, %o4 ! 11
- mulscc %o4, %o1, %o4 ! 12
- mulscc %o4, %g0, %o4 ! final shift
-
- /*
- * %o4 has 20 of the bits that should be in the result; %y has
- * the bottom 12 (as %y's top 12). That is:
- *
- * %o4 %y
- * +----------------+----------------+
- * | -12- | -20- | -12- | -20- |
- * +------(---------+------)---------+
- * -----result-----
- *
- * The 12 bits of %o4 left of the `result' area are all zero;
- * in fact, all top 20 bits of %o4 are zero.
- */
-
- rd %y, %o5
- sll %o4, 12, %o0 ! shift middle bits left 12
- srl %o5, 20, %o5 ! shift low bits right 20
- or %o5, %o0, %o0
- retl
- addcc %g0, %g0, %o1 ! %o1 = zero, and set Z
-
- .globl .umul_patch
-.umul_patch:
- umul %o0, %o1, %o0
- retl
- rd %y, %o1
- nop
diff --git a/arch/sparc/lib/urem.S b/arch/sparc/lib/urem.S
deleted file mode 100644
index 77123eb83c4..00000000000
--- a/arch/sparc/lib/urem.S
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * urem.S: This routine was taken from glibc-1.09 and is covered
- * by the GNU Library General Public License Version 2.
- */
-
-/* This file is generated from divrem.m4; DO NOT EDIT! */
-/*
- * Division and remainder, from Appendix E of the Sparc Version 8
- * Architecture Manual, with fixes from Gordon Irlam.
- */
-
-/*
- * Input: dividend and divisor in %o0 and %o1 respectively.
- *
- * m4 parameters:
- * .urem name of function to generate
- * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1
- * false false=true => signed; false=false => unsigned
- *
- * Algorithm parameters:
- * N how many bits per iteration we try to get (4)
- * WORDSIZE total number of bits (32)
- *
- * Derived constants:
- * TOPBITS number of bits in the top decade of a number
- *
- * Important variables:
- * Q the partial quotient under development (initially 0)
- * R the remainder so far, initially the dividend
- * ITER number of main division loop iterations required;
- * equal to ceil(log2(quotient) / N). Note that this
- * is the log base (2^N) of the quotient.
- * V the current comparand, initially divisor*2^(ITER*N-1)
- *
- * Cost:
- * Current estimate for non-large dividend is
- * ceil(log2(quotient) / N) * (10 + 7N/2) + C
- * A large dividend is one greater than 2^(31-TOPBITS) and takes a
- * different path, as the upper bits of the quotient must be developed
- * one bit at a time.
- */
-
- .globl .urem
- .globl _Urem
-.urem:
-_Urem: /* needed for export */
-
- ! Ready to divide. Compute size of quotient; scale comparand.
- orcc %o1, %g0, %o5
- bne 1f
- mov %o0, %o3
-
- ! Divide by zero trap. If it returns, return 0 (about as
- ! wrong as possible, but that is what SunOS does...).
- ta ST_DIV0
- retl
- clr %o0
-
-1:
- cmp %o3, %o5 ! if %o1 exceeds %o0, done
- blu Lgot_result ! (and algorithm fails otherwise)
- clr %o2
-
- sethi %hi(1 << (32 - 4 - 1)), %g1
-
- cmp %o3, %g1
- blu Lnot_really_big
- clr %o4
-
- ! Here the dividend is >= 2**(31-N) or so. We must be careful here,
- ! as our usual N-at-a-shot divide step will cause overflow and havoc.
- ! The number of bits in the result here is N*ITER+SC, where SC <= N.
- ! Compute ITER in an unorthodox manner: know we need to shift V into
- ! the top decade: so do not even bother to compare to R.
- 1:
- cmp %o5, %g1
- bgeu 3f
- mov 1, %g7
-
- sll %o5, 4, %o5
-
- b 1b
- add %o4, 1, %o4
-
- ! Now compute %g7.
- 2:
- addcc %o5, %o5, %o5
- bcc Lnot_too_big
- add %g7, 1, %g7
-
- ! We get here if the %o1 overflowed while shifting.
- ! This means that %o3 has the high-order bit set.
- ! Restore %o5 and subtract from %o3.
- sll %g1, 4, %g1 ! high order bit
- srl %o5, 1, %o5 ! rest of %o5
- add %o5, %g1, %o5
-
- b Ldo_single_div
- sub %g7, 1, %g7
-
- Lnot_too_big:
- 3:
- cmp %o5, %o3
- blu 2b
- nop
-
- be Ldo_single_div
- nop
- /* NB: these are commented out in the V8-Sparc manual as well */
- /* (I do not understand this) */
- ! %o5 > %o3: went too far: back up 1 step
- ! srl %o5, 1, %o5
- ! dec %g7
- ! do single-bit divide steps
- !
- ! We have to be careful here. We know that %o3 >= %o5, so we can do the
- ! first divide step without thinking. BUT, the others are conditional,
- ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
- ! order bit set in the first step, just falling into the regular
- ! division loop will mess up the first time around.
- ! So we unroll slightly...
- Ldo_single_div:
- subcc %g7, 1, %g7
- bl Lend_regular_divide
- nop
-
- sub %o3, %o5, %o3
- mov 1, %o2
-
- b Lend_single_divloop
- nop
- Lsingle_divloop:
- sll %o2, 1, %o2
- bl 1f
- srl %o5, 1, %o5
- ! %o3 >= 0
- sub %o3, %o5, %o3
- b 2f
- add %o2, 1, %o2
- 1: ! %o3 < 0
- add %o3, %o5, %o3
- sub %o2, 1, %o2
- 2:
- Lend_single_divloop:
- subcc %g7, 1, %g7
- bge Lsingle_divloop
- tst %o3
-
- b,a Lend_regular_divide
-
-Lnot_really_big:
-1:
- sll %o5, 4, %o5
-
- cmp %o5, %o3
- bleu 1b
- addcc %o4, 1, %o4
-
- be Lgot_result
- sub %o4, 1, %o4
-
- tst %o3 ! set up for initial iteration
-Ldivloop:
- sll %o2, 4, %o2
- ! depth 1, accumulated bits 0
- bl L.1.16
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 2, accumulated bits 1
- bl L.2.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits 3
- bl L.3.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 7
- bl L.4.23
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (7*2+1), %o2
-
-L.4.23:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (7*2-1), %o2
-
-L.3.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 5
- bl L.4.21
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2+1), %o2
-
-L.4.21:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (5*2-1), %o2
-
-L.2.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits 1
- bl L.3.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits 3
- bl L.4.19
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2+1), %o2
-
-L.4.19:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (3*2-1), %o2
-
-L.3.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits 1
- bl L.4.17
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2+1), %o2
-
-L.4.17:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (1*2-1), %o2
-
-L.1.16:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 2, accumulated bits -1
- bl L.2.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 3, accumulated bits -1
- bl L.3.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -1
- bl L.4.15
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2+1), %o2
-
-L.4.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-1*2-1), %o2
-
-L.3.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -3
- bl L.4.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2+1), %o2
-
-L.4.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-3*2-1), %o2
-
-L.2.15:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 3, accumulated bits -3
- bl L.3.13
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- ! depth 4, accumulated bits -5
- bl L.4.11
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2+1), %o2
-
-L.4.11:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-5*2-1), %o2
-
-L.3.13:
- ! remainder is negative
- addcc %o3,%o5,%o3
- ! depth 4, accumulated bits -7
- bl L.4.9
- srl %o5,1,%o5
- ! remainder is positive
- subcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2+1), %o2
-
-L.4.9:
- ! remainder is negative
- addcc %o3,%o5,%o3
- b 9f
- add %o2, (-7*2-1), %o2
-
- 9:
-Lend_regular_divide:
- subcc %o4, 1, %o4
- bge Ldivloop
- tst %o3
-
- bl,a Lgot_result
- ! non-restoring fixup here (one instruction only!)
- add %o3, %o1, %o3
-
-Lgot_result:
-
- retl
- mov %o3, %o0
-
- .globl .urem_patch
-.urem_patch:
- wr %g0, 0x0, %y
- nop
- nop
- nop
- udiv %o0, %o1, %o2
- umul %o2, %o1, %o2
- retl
- sub %o0, %o2, %o0
diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
index 14b363fec8a..5c4284ce1c0 100644
--- a/arch/sparc/lib/usercopy.c
+++ b/arch/sparc/lib/usercopy.c
@@ -1,4 +1,5 @@
#include <linux/module.h>
+#include <linux/kernel.h>
#include <linux/bug.h>
void copy_from_user_overflow(void)
diff --git a/arch/sparc/lib/xor.S b/arch/sparc/lib/xor.S
index f44f58f4023..2c05641c326 100644
--- a/arch/sparc/lib/xor.S
+++ b/arch/sparc/lib/xor.S
@@ -8,6 +8,7 @@
* Copyright (C) 2006 David S. Miller <davem@davemloft.net>
*/
+#include <linux/linkage.h>
#include <asm/visasm.h>
#include <asm/asi.h>
#include <asm/dcu.h>
@@ -19,12 +20,9 @@
* !(len & 127) && len >= 256
*/
.text
- .align 32
/* VIS versions. */
- .globl xor_vis_2
- .type xor_vis_2,#function
-xor_vis_2:
+ENTRY(xor_vis_2)
rd %fprs, %o5
andcc %o5, FPRS_FEF|FPRS_DU, %g0
be,pt %icc, 0f
@@ -91,11 +89,9 @@ xor_vis_2:
wr %g1, %g0, %asi
retl
wr %g0, 0, %fprs
- .size xor_vis_2, .-xor_vis_2
+ENDPROC(xor_vis_2)
- .globl xor_vis_3
- .type xor_vis_3,#function
-xor_vis_3:
+ENTRY(xor_vis_3)
rd %fprs, %o5
andcc %o5, FPRS_FEF|FPRS_DU, %g0
be,pt %icc, 0f
@@ -159,11 +155,9 @@ xor_vis_3:
wr %g1, %g0, %asi
retl
wr %g0, 0, %fprs
- .size xor_vis_3, .-xor_vis_3
+ENDPROC(xor_vis_3)
- .globl xor_vis_4
- .type xor_vis_4,#function
-xor_vis_4:
+ENTRY(xor_vis_4)
rd %fprs, %o5
andcc %o5, FPRS_FEF|FPRS_DU, %g0
be,pt %icc, 0f
@@ -246,11 +240,9 @@ xor_vis_4:
wr %g1, %g0, %asi
retl
wr %g0, 0, %fprs
- .size xor_vis_4, .-xor_vis_4
+ENDPROC(xor_vis_4)
- .globl xor_vis_5
- .type xor_vis_5,#function
-xor_vis_5:
+ENTRY(xor_vis_5)
save %sp, -192, %sp
rd %fprs, %o5
andcc %o5, FPRS_FEF|FPRS_DU, %g0
@@ -354,12 +346,10 @@ xor_vis_5:
wr %g0, 0, %fprs
ret
restore
- .size xor_vis_5, .-xor_vis_5
+ENDPROC(xor_vis_5)
/* Niagara versions. */
- .globl xor_niagara_2
- .type xor_niagara_2,#function
-xor_niagara_2: /* %o0=bytes, %o1=dest, %o2=src */
+ENTRY(xor_niagara_2) /* %o0=bytes, %o1=dest, %o2=src */
save %sp, -192, %sp
prefetch [%i1], #n_writes
prefetch [%i2], #one_read
@@ -402,11 +392,9 @@ xor_niagara_2: /* %o0=bytes, %o1=dest, %o2=src */
wr %g7, 0x0, %asi
ret
restore
- .size xor_niagara_2, .-xor_niagara_2
+ENDPROC(xor_niagara_2)
- .globl xor_niagara_3
- .type xor_niagara_3,#function
-xor_niagara_3: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */
+ENTRY(xor_niagara_3) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */
save %sp, -192, %sp
prefetch [%i1], #n_writes
prefetch [%i2], #one_read
@@ -465,11 +453,9 @@ xor_niagara_3: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */
wr %g7, 0x0, %asi
ret
restore
- .size xor_niagara_3, .-xor_niagara_3
+ENDPROC(xor_niagara_3)
- .globl xor_niagara_4
- .type xor_niagara_4,#function
-xor_niagara_4: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */
+ENTRY(xor_niagara_4) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */
save %sp, -192, %sp
prefetch [%i1], #n_writes
prefetch [%i2], #one_read
@@ -549,11 +535,9 @@ xor_niagara_4: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */
wr %g7, 0x0, %asi
ret
restore
- .size xor_niagara_4, .-xor_niagara_4
+ENDPROC(xor_niagara_4)
- .globl xor_niagara_5
- .type xor_niagara_5,#function
-xor_niagara_5: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 */
+ENTRY(xor_niagara_5) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 */
save %sp, -192, %sp
prefetch [%i1], #n_writes
prefetch [%i2], #one_read
@@ -649,4 +633,4 @@ xor_niagara_5: /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 *
wr %g7, 0x0, %asi
ret
restore
- .size xor_niagara_5, .-xor_niagara_5
+ENDPROC(xor_niagara_5)
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c
index 2bbe2f28ad2..1704068da92 100644
--- a/arch/sparc/math-emu/math_64.c
+++ b/arch/sparc/math-emu/math_64.c
@@ -163,7 +163,7 @@ typedef union {
u64 q[2];
} *argp;
-int do_mathemu(struct pt_regs *regs, struct fpustate *f)
+int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap)
{
unsigned long pc = regs->tpc;
unsigned long tstate = regs->tstate;
@@ -218,7 +218,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f)
case FSQRTS: {
unsigned long x = current_thread_info()->xfsr[0];
- x = (x >> 14) & 0xf;
+ x = (x >> 14) & 0x7;
TYPE(x,1,1,1,1,0,0);
break;
}
@@ -226,7 +226,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f)
case FSQRTD: {
unsigned long x = current_thread_info()->xfsr[0];
- x = (x >> 14) & 0xf;
+ x = (x >> 14) & 0x7;
TYPE(x,2,1,2,1,0,0);
break;
}
@@ -357,9 +357,17 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f)
if (type) {
argp rs1 = NULL, rs2 = NULL, rd = NULL;
- freg = (current_thread_info()->xfsr[0] >> 14) & 0xf;
- if (freg != (type >> 9))
- goto err;
+ /* Starting with UltraSPARC-T2, the cpu does not set the FP Trap
+ * Type field in the %fsr to unimplemented_FPop. Nor does it
+ * use the fp_exception_other trap. Instead it signals an
+ * illegal instruction and leaves the FP trap type field of
+ * the %fsr unchanged.
+ */
+ if (!illegal_insn_trap) {
+ int ftt = (current_thread_info()->xfsr[0] >> 14) & 0x7;
+ if (ftt != (type >> 9))
+ goto err;
+ }
current_thread_info()->xfsr[0] &= ~0x1c000;
freg = ((insn >> 14) & 0x1f);
switch (type & 0x3) {
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 301421c1129..30c3eccfdf5 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -7,19 +7,13 @@ ccflags-y := -Werror
obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o
obj-y += fault_$(BITS).o
obj-y += init_$(BITS).o
-obj-$(CONFIG_SPARC32) += loadmmu.o
-obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o
+obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o
+obj-$(CONFIG_SPARC32) += srmmu_access.o
obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o
-obj-$(CONFIG_SPARC_LEON)+= leon_mm.o
+obj-$(CONFIG_SPARC32) += leon_mm.o
# Only used by sparc64
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
# Only used by sparc32
obj-$(CONFIG_HIGHMEM) += highmem.o
-
-ifdef CONFIG_SMP
-obj-$(CONFIG_SPARC32) += nosun4c.o
-else
-obj-$(CONFIG_SPARC32) += sun4c.o
-endif
diff --git a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c
deleted file mode 100644
index 09d6af22db2..00000000000
--- a/arch/sparc/mm/btfixup.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* btfixup.c: Boot time code fixup and relocator, so that
- * we can get rid of most indirect calls to achieve single
- * image sun4c and srmmu kernel.
- *
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/btfixup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/oplib.h>
-#include <asm/cacheflush.h>
-
-#define BTFIXUP_OPTIMIZE_NOP
-#define BTFIXUP_OPTIMIZE_OTHER
-
-extern char *srmmu_name;
-static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for ";
-static char str_sun4c[] __initdata = "sun4c\n";
-static char str_srmmu[] __initdata = "srmmu[%s]/";
-static char str_iommu[] __initdata = "iommu\n";
-static char str_iounit[] __initdata = "io-unit\n";
-
-static int visited __initdata = 0;
-extern unsigned int ___btfixup_start[], ___btfixup_end[], __init_begin[], __init_end[], __init_text_end[];
-extern unsigned int _stext[], _end[], __start___ksymtab[], __stop___ksymtab[];
-static char wrong_f[] __initdata = "Trying to set f fixup %p to invalid function %08x\n";
-static char wrong_b[] __initdata = "Trying to set b fixup %p to invalid function %08x\n";
-static char wrong_s[] __initdata = "Trying to set s fixup %p to invalid value %08x\n";
-static char wrong_h[] __initdata = "Trying to set h fixup %p to invalid value %08x\n";
-static char wrong_a[] __initdata = "Trying to set a fixup %p to invalid value %08x\n";
-static char wrong[] __initdata = "Wrong address for %c fixup %p\n";
-static char insn_f[] __initdata = "Fixup f %p refers to weird instructions at %p[%08x,%08x]\n";
-static char insn_b[] __initdata = "Fixup b %p doesn't refer to a SETHI at %p[%08x]\n";
-static char insn_s[] __initdata = "Fixup s %p doesn't refer to an OR at %p[%08x]\n";
-static char insn_h[] __initdata = "Fixup h %p doesn't refer to a SETHI at %p[%08x]\n";
-static char insn_a[] __initdata = "Fixup a %p doesn't refer to a SETHI nor OR at %p[%08x]\n";
-static char insn_i[] __initdata = "Fixup i %p doesn't refer to a valid instruction at %p[%08x]\n";
-static char fca_und[] __initdata = "flush_cache_all undefined in btfixup()\n";
-static char wrong_setaddr[] __initdata = "Garbled CALL/INT patch at %p[%08x,%08x,%08x]=%08x\n";
-
-#ifdef BTFIXUP_OPTIMIZE_OTHER
-static void __init set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value)
-{
- if (!fmangled)
- *addr = value;
- else {
- unsigned int *q = (unsigned int *)q1;
- if (*addr == 0x01000000) {
- /* Noped */
- *q = value;
- } else if (addr[-1] == *q) {
- /* Moved */
- addr[-1] = value;
- *q = value;
- } else {
- prom_printf(wrong_setaddr, addr-1, addr[-1], *addr, *q, value);
- prom_halt();
- }
- }
-}
-#else
-static inline void set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value)
-{
- *addr = value;
-}
-#endif
-
-void __init btfixup(void)
-{
- unsigned int *p, *q;
- int type, count;
- unsigned insn;
- unsigned *addr;
- int fmangled = 0;
- void (*flush_cacheall)(void);
-
- if (!visited) {
- visited++;
- printk(version);
- if (ARCH_SUN4C)
- printk(str_sun4c);
- else {
- printk(str_srmmu, srmmu_name);
- if (sparc_cpu_model == sun4d)
- printk(str_iounit);
- else
- printk(str_iommu);
- }
- }
- for (p = ___btfixup_start; p < ___btfixup_end; ) {
- count = p[2];
- q = p + 3;
- switch (type = *(unsigned char *)p) {
- case 'f':
- count = p[3];
- q = p + 4;
- if (((p[0] & 1) || p[1])
- && ((p[1] & 3) || (unsigned *)(p[1]) < _stext || (unsigned *)(p[1]) >= _end)) {
- prom_printf(wrong_f, p, p[1]);
- prom_halt();
- }
- break;
- case 'b':
- if (p[1] < (unsigned long)__init_begin || p[1] >= (unsigned long)__init_text_end || (p[1] & 3)) {
- prom_printf(wrong_b, p, p[1]);
- prom_halt();
- }
- break;
- case 's':
- if (p[1] + 0x1000 >= 0x2000) {
- prom_printf(wrong_s, p, p[1]);
- prom_halt();
- }
- break;
- case 'h':
- if (p[1] & 0x3ff) {
- prom_printf(wrong_h, p, p[1]);
- prom_halt();
- }
- break;
- case 'a':
- if (p[1] + 0x1000 >= 0x2000 && (p[1] & 0x3ff)) {
- prom_printf(wrong_a, p, p[1]);
- prom_halt();
- }
- break;
- }
- if (p[0] & 1) {
- p[0] &= ~1;
- while (count) {
- fmangled = 0;
- addr = (unsigned *)*q;
- if (addr < _stext || addr >= _end) {
- prom_printf(wrong, type, p);
- prom_halt();
- }
- insn = *addr;
-#ifdef BTFIXUP_OPTIMIZE_OTHER
- if (type != 'f' && q[1]) {
- insn = *(unsigned int *)q[1];
- if (!insn || insn == 1)
- insn = *addr;
- else
- fmangled = 1;
- }
-#endif
- switch (type) {
- case 'f': /* CALL */
- if (addr >= __start___ksymtab && addr < __stop___ksymtab) {
- *addr = p[1];
- break;
- } else if (!q[1]) {
- if ((insn & 0xc1c00000) == 0x01000000) { /* SETHI */
- *addr = (insn & 0xffc00000) | (p[1] >> 10); break;
- } else if ((insn & 0xc1f82000) == 0x80102000) { /* OR X, %LO(i), Y */
- *addr = (insn & 0xffffe000) | (p[1] & 0x3ff); break;
- } else if ((insn & 0xc0000000) != 0x40000000) { /* !CALL */
- bad_f:
- prom_printf(insn_f, p, addr, insn, addr[1]);
- prom_halt();
- }
- } else if (q[1] != 1)
- addr[1] = q[1];
- if (p[2] == BTFIXUPCALL_NORM) {
- norm_f:
- *addr = 0x40000000 | ((p[1] - (unsigned)addr) >> 2);
- q[1] = 0;
- break;
- }
-#ifndef BTFIXUP_OPTIMIZE_NOP
- goto norm_f;
-#else
- if (!(addr[1] & 0x80000000)) {
- if ((addr[1] & 0xc1c00000) != 0x01000000) /* !SETHI */
- goto bad_f; /* CALL, Bicc, FBfcc, CBccc are weird in delay slot, aren't they? */
- } else {
- if ((addr[1] & 0x01800000) == 0x01800000) {
- if ((addr[1] & 0x01f80000) == 0x01e80000) {
- /* RESTORE */
- goto norm_f; /* It is dangerous to patch that */
- }
- goto bad_f;
- }
- if ((addr[1] & 0xffffe003) == 0x9e03e000) {
- /* ADD %O7, XX, %o7 */
- int displac = (addr[1] << 19);
-
- displac = (displac >> 21) + 2;
- *addr = (0x10800000) + (displac & 0x3fffff);
- q[1] = addr[1];
- addr[1] = p[2];
- break;
- }
- if ((addr[1] & 0x201f) == 0x200f || (addr[1] & 0x7c000) == 0x3c000)
- goto norm_f; /* Someone is playing bad tricks with us: rs1 or rs2 is o7 */
- if ((addr[1] & 0x3e000000) == 0x1e000000)
- goto norm_f; /* rd is %o7. We'd better take care. */
- }
- if (p[2] == BTFIXUPCALL_NOP) {
- *addr = 0x01000000;
- q[1] = 1;
- break;
- }
-#ifndef BTFIXUP_OPTIMIZE_OTHER
- goto norm_f;
-#else
- if (addr[1] == 0x01000000) { /* NOP in the delay slot */
- q[1] = addr[1];
- *addr = p[2];
- break;
- }
- if ((addr[1] & 0xc0000000) != 0xc0000000) {
- /* Not a memory operation */
- if ((addr[1] & 0x30000000) == 0x10000000) {
- /* Ok, non-memory op with rd %oX */
- if ((addr[1] & 0x3e000000) == 0x1c000000)
- goto bad_f; /* Aiee. Someone is playing strange %sp tricks */
- if ((addr[1] & 0x3e000000) > 0x12000000 ||
- ((addr[1] & 0x3e000000) == 0x12000000 &&
- p[2] != BTFIXUPCALL_STO1O0 && p[2] != BTFIXUPCALL_SWAPO0O1) ||
- ((p[2] & 0xffffe000) == BTFIXUPCALL_RETINT(0))) {
- /* Nobody uses the result. We can nop it out. */
- *addr = p[2];
- q[1] = addr[1];
- addr[1] = 0x01000000;
- break;
- }
- if ((addr[1] & 0xf1ffffe0) == 0x90100000) {
- /* MOV %reg, %Ox */
- if ((addr[1] & 0x3e000000) == 0x10000000 &&
- (p[2] & 0x7c000) == 0x20000) {
- /* Ok, it is call xx; mov reg, %o0 and call optimizes
- to doing something on %o0. Patch the patch. */
- *addr = (p[2] & ~0x7c000) | ((addr[1] & 0x1f) << 14);
- q[1] = addr[1];
- addr[1] = 0x01000000;
- break;
- }
- if ((addr[1] & 0x3e000000) == 0x12000000 &&
- p[2] == BTFIXUPCALL_STO1O0) {
- *addr = (p[2] & ~0x3e000000) | ((addr[1] & 0x1f) << 25);
- q[1] = addr[1];
- addr[1] = 0x01000000;
- break;
- }
- }
- }
- }
- *addr = addr[1];
- q[1] = addr[1];
- addr[1] = p[2];
- break;
-#endif /* BTFIXUP_OPTIMIZE_OTHER */
-#endif /* BTFIXUP_OPTIMIZE_NOP */
- case 'b': /* BLACKBOX */
- /* Has to be sethi i, xx */
- if ((insn & 0xc1c00000) != 0x01000000) {
- prom_printf(insn_b, p, addr, insn);
- prom_halt();
- } else {
- void (*do_fixup)(unsigned *);
-
- do_fixup = (void (*)(unsigned *))p[1];
- do_fixup(addr);
- }
- break;
- case 's': /* SIMM13 */
- /* Has to be or %g0, i, xx */
- if ((insn & 0xc1ffe000) != 0x80102000) {
- prom_printf(insn_s, p, addr, insn);
- prom_halt();
- }
- set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x1fff));
- break;
- case 'h': /* SETHI */
- /* Has to be sethi i, xx */
- if ((insn & 0xc1c00000) != 0x01000000) {
- prom_printf(insn_h, p, addr, insn);
- prom_halt();
- }
- set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10));
- break;
- case 'a': /* HALF */
- /* Has to be sethi i, xx or or %g0, i, xx */
- if ((insn & 0xc1c00000) != 0x01000000 &&
- (insn & 0xc1ffe000) != 0x80102000) {
- prom_printf(insn_a, p, addr, insn);
- prom_halt();
- }
- if (p[1] & 0x3ff)
- set_addr(addr, q[1], fmangled,
- (insn & 0x3e000000) | 0x80102000 | (p[1] & 0x1fff));
- else
- set_addr(addr, q[1], fmangled,
- (insn & 0x3e000000) | 0x01000000 | (p[1] >> 10));
- break;
- case 'i': /* INT */
- if ((insn & 0xc1c00000) == 0x01000000) /* %HI */
- set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10));
- else if ((insn & 0x80002000) == 0x80002000) /* %LO */
- set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x3ff));
- else {
- prom_printf(insn_i, p, addr, insn);
- prom_halt();
- }
- break;
- }
- count -= 2;
- q += 2;
- }
- } else
- p = q + count;
- }
-#ifdef CONFIG_SMP
- flush_cacheall = (void (*)(void))BTFIXUPVAL_CALL(local_flush_cache_all);
-#else
- flush_cacheall = (void (*)(void))BTFIXUPVAL_CALL(flush_cache_all);
-#endif
- if (!flush_cacheall) {
- prom_printf(fca_und);
- prom_halt();
- }
- (*flush_cacheall)();
-}
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index df3155a1799..f46cf6be337 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -24,29 +24,19 @@
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/memreg.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/smp.h>
#include <asm/traps.h>
#include <asm/uaccess.h>
-extern int prom_node_root;
-
int show_unhandled_signals = 1;
/* At boot time we determine these two values necessary for setting
* up the segment maps and page table entries (pte's).
*/
-int num_segmaps, num_contexts;
-int invalid_segment;
-
-/* various Virtual Address Cache parameters we find at boot time... */
-
-int vac_size, vac_linesize, vac_do_hw_vac_flushes;
-int vac_entries_per_context, vac_entries_per_segment;
-int vac_entries_per_page;
+int num_contexts;
/* Return how much physical memory we have. */
unsigned long probe_memory(void)
@@ -60,55 +50,36 @@ unsigned long probe_memory(void)
return total;
}
-extern void sun4c_complete_all_stores(void);
-
-/* Whee, a level 15 NMI interrupt memory error. Let's have fun... */
-asmlinkage void sparc_lvl15_nmi(struct pt_regs *regs, unsigned long serr,
- unsigned long svaddr, unsigned long aerr,
- unsigned long avaddr)
-{
- sun4c_complete_all_stores();
- printk("FAULT: NMI received\n");
- printk("SREGS: Synchronous Error %08lx\n", serr);
- printk(" Synchronous Vaddr %08lx\n", svaddr);
- printk(" Asynchronous Error %08lx\n", aerr);
- printk(" Asynchronous Vaddr %08lx\n", avaddr);
- if (sun4c_memerr_reg)
- printk(" Memory Parity Error %08lx\n", *sun4c_memerr_reg);
- printk("REGISTER DUMP:\n");
- show_regs(regs);
- prom_halt();
-}
-
static void unhandled_fault(unsigned long, struct task_struct *,
struct pt_regs *) __attribute__ ((noreturn));
-static void unhandled_fault(unsigned long address, struct task_struct *tsk,
- struct pt_regs *regs)
+static void __noreturn unhandled_fault(unsigned long address,
+ struct task_struct *tsk,
+ struct pt_regs *regs)
{
- if((unsigned long) address < PAGE_SIZE) {
+ if ((unsigned long) address < PAGE_SIZE) {
printk(KERN_ALERT
"Unable to handle kernel NULL pointer dereference\n");
} else {
- printk(KERN_ALERT "Unable to handle kernel paging request "
- "at virtual address %08lx\n", address);
+ printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %08lx\n",
+ address);
}
printk(KERN_ALERT "tsk->{mm,active_mm}->context = %08lx\n",
(tsk->mm ? tsk->mm->context : tsk->active_mm->context));
printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %08lx\n",
(tsk->mm ? (unsigned long) tsk->mm->pgd :
- (unsigned long) tsk->active_mm->pgd));
+ (unsigned long) tsk->active_mm->pgd));
die_if_kernel("Oops", regs);
}
-asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
+asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
unsigned long address)
{
struct pt_regs regs;
unsigned long g2;
unsigned int insn;
int i;
-
+
i = search_extables_range(ret_pc, &g2);
switch (i) {
case 3:
@@ -128,14 +99,14 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
/* for _from_ macros */
insn = *((unsigned int *) pc);
if (!((insn >> 21) & 1) || ((insn>>19)&0x3f) == 15)
- return 2;
- break;
+ return 2;
+ break;
default:
break;
}
- memset(&regs, 0, sizeof (regs));
+ memset(&regs, 0, sizeof(regs));
regs.pc = pc;
regs.npc = pc + 4;
__asm__ __volatile__(
@@ -198,11 +169,10 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
if (text_fault)
return regs->pc;
- if (regs->psr & PSR_PS) {
+ if (regs->psr & PSR_PS)
insn = *(unsigned int *) regs->pc;
- } else {
+ else
__get_user(insn, (unsigned int *) regs->pc);
- }
return safe_compute_effective_address(regs, insn);
}
@@ -228,7 +198,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
(write ? FAULT_FLAG_WRITE : 0));
- if(text_fault)
+ if (text_fault)
address = regs->pc;
/*
@@ -241,36 +211,32 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
* nothing more.
*/
code = SEGV_MAPERR;
- if (!ARCH_SUN4C && address >= TASK_SIZE)
+ if (address >= TASK_SIZE)
goto vmalloc_fault;
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_atomic() || !mm)
- goto no_context;
+ if (in_atomic() || !mm)
+ goto no_context;
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
retry:
down_read(&mm->mmap_sem);
- /*
- * The kernel referencing a bad kernel pointer can lock up
- * a sun4c machine completely, so we must attempt recovery.
- */
- if(!from_user && address >= PAGE_OFFSET)
+ if (!from_user && address >= PAGE_OFFSET)
goto bad_area;
vma = find_vma(mm, address);
- if(!vma)
+ if (!vma)
goto bad_area;
- if(vma->vm_start <= address)
+ if (vma->vm_start <= address)
goto good_area;
- if(!(vma->vm_flags & VM_GROWSDOWN))
+ if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if(expand_stack(vma, address))
+ if (expand_stack(vma, address))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
@@ -278,12 +244,12 @@ retry:
*/
good_area:
code = SEGV_ACCERR;
- if(write) {
- if(!(vma->vm_flags & VM_WRITE))
+ if (write) {
+ if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
} else {
/* Allow reads even for write-only mappings */
- if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
@@ -349,14 +315,16 @@ no_context:
g2 = regs->u_regs[UREG_G2];
if (!from_user) {
fixup = search_extables_range(regs->pc, &g2);
- if (fixup > 10) { /* Values below are reserved for other things */
+ /* Values below 10 are reserved for other things */
+ if (fixup > 10) {
extern const unsigned __memset_start[];
extern const unsigned __memset_end[];
extern const unsigned __csum_partial_copy_start[];
extern const unsigned __csum_partial_copy_end[];
#ifdef DEBUG_EXCEPTIONS
- printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address);
+ printk("Exception: PC<%08lx> faddr<%08lx>\n",
+ regs->pc, address);
printk("EX_TABLE: insn<%08lx> fixup<%08x> g2<%08lx>\n",
regs->pc, fixup, g2);
#endif
@@ -364,7 +332,7 @@ no_context:
regs->pc < (unsigned long)__memset_end) ||
(regs->pc >= (unsigned long)__csum_partial_copy_start &&
regs->pc < (unsigned long)__csum_partial_copy_end)) {
- regs->u_regs[UREG_I4] = address;
+ regs->u_regs[UREG_I4] = address;
regs->u_regs[UREG_I5] = regs->pc;
}
regs->u_regs[UREG_G2] = g2;
@@ -373,8 +341,8 @@ no_context:
return;
}
}
-
- unhandled_fault (address, tsk, regs);
+
+ unhandled_fault(address, tsk, regs);
do_exit(SIGKILL);
/*
@@ -420,97 +388,12 @@ vmalloc_fault:
if (pmd_present(*pmd) || !pmd_present(*pmd_k))
goto bad_area_nosemaphore;
+
*pmd = *pmd_k;
return;
}
}
-asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
- unsigned long address)
-{
- extern void sun4c_update_mmu_cache(struct vm_area_struct *,
- unsigned long,pte_t *);
- extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long);
- struct task_struct *tsk = current;
- struct mm_struct *mm = tsk->mm;
- pgd_t *pgdp;
- pte_t *ptep;
-
- if (text_fault) {
- address = regs->pc;
- } else if (!write &&
- !(regs->psr & PSR_PS)) {
- unsigned int insn, __user *ip;
-
- ip = (unsigned int __user *)regs->pc;
- if (!get_user(insn, ip)) {
- if ((insn & 0xc1680000) == 0xc0680000)
- write = 1;
- }
- }
-
- if (!mm) {
- /* We are oopsing. */
- do_sparc_fault(regs, text_fault, write, address);
- BUG(); /* P3 Oops already, you bitch */
- }
-
- pgdp = pgd_offset(mm, address);
- ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, address);
-
- if (pgd_val(*pgdp)) {
- if (write) {
- if ((pte_val(*ptep) & (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT))
- == (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT)) {
- unsigned long flags;
-
- *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED |
- _SUN4C_PAGE_MODIFIED |
- _SUN4C_PAGE_VALID |
- _SUN4C_PAGE_DIRTY);
-
- local_irq_save(flags);
- if (sun4c_get_segmap(address) != invalid_segment) {
- sun4c_put_pte(address, pte_val(*ptep));
- local_irq_restore(flags);
- return;
- }
- local_irq_restore(flags);
- }
- } else {
- if ((pte_val(*ptep) & (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT))
- == (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) {
- unsigned long flags;
-
- *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED |
- _SUN4C_PAGE_VALID);
-
- local_irq_save(flags);
- if (sun4c_get_segmap(address) != invalid_segment) {
- sun4c_put_pte(address, pte_val(*ptep));
- local_irq_restore(flags);
- return;
- }
- local_irq_restore(flags);
- }
- }
- }
-
- /* This conditional is 'interesting'. */
- if (pgd_val(*pgdp) && !(write && !(pte_val(*ptep) & _SUN4C_PAGE_WRITE))
- && (pte_val(*ptep) & _SUN4C_PAGE_VALID))
- /* Note: It is safe to not grab the MMAP semaphore here because
- * we know that update_mmu_cache() will not sleep for
- * any reason (at least not in the current implementation)
- * and therefore there is no danger of another thread getting
- * on the CPU and doing a shrink_mmap() on this vma.
- */
- sun4c_update_mmu_cache (find_vma(current->mm, address), address,
- ptep);
- else
- do_sparc_fault(regs, text_fault, write, address);
-}
-
/* This always deals with user addresses. */
static void force_user_fault(unsigned long address, int write)
{
@@ -523,21 +406,21 @@ static void force_user_fault(unsigned long address, int write)
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
- if(!vma)
+ if (!vma)
goto bad_area;
- if(vma->vm_start <= address)
+ if (vma->vm_start <= address)
goto good_area;
- if(!(vma->vm_flags & VM_GROWSDOWN))
+ if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if(expand_stack(vma, address))
+ if (expand_stack(vma, address))
goto bad_area;
good_area:
code = SEGV_ACCERR;
- if(write) {
- if(!(vma->vm_flags & VM_WRITE))
+ if (write) {
+ if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
} else {
- if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
switch (handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0)) {
@@ -568,7 +451,7 @@ void window_overflow_fault(void)
unsigned long sp;
sp = current_thread_info()->rwbuf_stkptrs[0];
- if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
+ if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
force_user_fault(sp + 0x38, 1);
force_user_fault(sp, 1);
@@ -577,7 +460,7 @@ void window_overflow_fault(void)
void window_underflow_fault(unsigned long sp)
{
- if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
+ if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
force_user_fault(sp + 0x38, 0);
force_user_fault(sp, 0);
@@ -589,7 +472,7 @@ void window_ret_fault(struct pt_regs *regs)
unsigned long sp;
sp = regs->u_regs[UREG_FP];
- if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
+ if (((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
force_user_fault(sp + 0x38, 0);
force_user_fault(sp, 0);
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index c5f9021b1a0..ef5c779ec85 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -27,7 +27,6 @@
#include <linux/gfp.h>
#include <asm/sections.h>
-#include <asm/vac-ops.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/vaddrs.h>
@@ -45,9 +44,6 @@ EXPORT_SYMBOL(phys_base);
unsigned long pfn_base;
EXPORT_SYMBOL(pfn_base);
-unsigned long page_kernel;
-EXPORT_SYMBOL(page_kernel);
-
struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
unsigned long sparc_unmapped_base;
@@ -287,44 +283,16 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
}
/*
- * check_pgt_cache
- *
- * This is called at the end of unmapping of VMA (zap_page_range),
- * to rescan the page cache for architecture specific things,
- * presumably something like sun4/sun4c PMEGs. Most architectures
- * define check_pgt_cache empty.
- *
- * We simply copy the 2.4 implementation for now.
- */
-static int pgt_cache_water[2] = { 25, 50 };
-
-void check_pgt_cache(void)
-{
- do_check_pgt_cache(pgt_cache_water[0], pgt_cache_water[1]);
-}
-
-/*
* paging_init() sets up the page tables: We call the MMU specific
* init routine based upon the Sun model type on the Sparc.
*
*/
-extern void sun4c_paging_init(void);
extern void srmmu_paging_init(void);
extern void device_scan(void);
-pgprot_t PAGE_SHARED __read_mostly;
-EXPORT_SYMBOL(PAGE_SHARED);
-
void __init paging_init(void)
{
switch(sparc_cpu_model) {
- case sun4c:
- case sun4e:
- case sun4:
- sun4c_paging_init();
- sparc_unmapped_base = 0xe0000000;
- BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000);
- break;
case sparc_leon:
leon_init();
/* fall through */
@@ -332,7 +300,6 @@ void __init paging_init(void)
case sun4d:
srmmu_paging_init();
sparc_unmapped_base = 0x50000000;
- BTFIXUPSET_SETHI(sparc_unmapped_base, 0x50000000);
break;
default:
prom_printf("paging_init: Cannot init paging on this Sparc\n");
@@ -341,24 +308,6 @@ void __init paging_init(void)
prom_halt();
}
- /* Initialize the protection map with non-constant, MMU dependent values. */
- protection_map[0] = PAGE_NONE;
- protection_map[1] = PAGE_READONLY;
- protection_map[2] = PAGE_COPY;
- protection_map[3] = PAGE_COPY;
- protection_map[4] = PAGE_READONLY;
- protection_map[5] = PAGE_READONLY;
- protection_map[6] = PAGE_COPY;
- protection_map[7] = PAGE_COPY;
- protection_map[8] = PAGE_NONE;
- protection_map[9] = PAGE_READONLY;
- protection_map[10] = PAGE_SHARED;
- protection_map[11] = PAGE_SHARED;
- protection_map[12] = PAGE_READONLY;
- protection_map[13] = PAGE_READONLY;
- protection_map[14] = PAGE_SHARED;
- protection_map[15] = PAGE_SHARED;
- btfixup();
prom_build_devicetree();
of_fill_in_cpu_data();
device_scan();
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 21faaeea85d..6026fdd1b2e 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -741,7 +741,6 @@ static void __init find_ramdisk(unsigned long phys_base)
struct node_mem_mask {
unsigned long mask;
unsigned long val;
- unsigned long bootmem_paddr;
};
static struct node_mem_mask node_masks[MAX_NUMNODES];
static int num_node_masks;
@@ -806,12 +805,6 @@ static u64 memblock_nid_range(u64 start, u64 end, int *nid)
return start;
}
-#else
-static u64 memblock_nid_range(u64 start, u64 end, int *nid)
-{
- *nid = 0;
- return end;
-}
#endif
/* This must be invoked after performing all of the necessary
@@ -820,10 +813,11 @@ static u64 memblock_nid_range(u64 start, u64 end, int *nid)
*/
static void __init allocate_node_data(int nid)
{
- unsigned long paddr, num_pages, start_pfn, end_pfn;
struct pglist_data *p;
-
+ unsigned long start_pfn, end_pfn;
#ifdef CONFIG_NEED_MULTIPLE_NODES
+ unsigned long paddr;
+
paddr = memblock_alloc_try_nid(sizeof(struct pglist_data), SMP_CACHE_BYTES, nid);
if (!paddr) {
prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid);
@@ -832,7 +826,7 @@ static void __init allocate_node_data(int nid)
NODE_DATA(nid) = __va(paddr);
memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
- NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
+ NODE_DATA(nid)->node_id = nid;
#endif
p = NODE_DATA(nid);
@@ -840,18 +834,6 @@ static void __init allocate_node_data(int nid)
get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
p->node_start_pfn = start_pfn;
p->node_spanned_pages = end_pfn - start_pfn;
-
- if (p->node_spanned_pages) {
- num_pages = bootmem_bootmap_pages(p->node_spanned_pages);
-
- paddr = memblock_alloc_try_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid);
- if (!paddr) {
- prom_printf("Cannot allocate bootmap for nid[%d]\n",
- nid);
- prom_halt();
- }
- node_masks[nid].bootmem_paddr = paddr;
- }
}
static void init_node_masks_nonnuma(void)
@@ -1292,75 +1274,9 @@ static void __init bootmem_init_nonnuma(void)
node_set_online(0);
}
-static void __init reserve_range_in_node(int nid, unsigned long start,
- unsigned long end)
-{
- numadbg(" reserve_range_in_node(nid[%d],start[%lx],end[%lx]\n",
- nid, start, end);
- while (start < end) {
- unsigned long this_end;
- int n;
-
- this_end = memblock_nid_range(start, end, &n);
- if (n == nid) {
- numadbg(" MATCH reserving range [%lx:%lx]\n",
- start, this_end);
- reserve_bootmem_node(NODE_DATA(nid), start,
- (this_end - start), BOOTMEM_DEFAULT);
- } else
- numadbg(" NO MATCH, advancing start to %lx\n",
- this_end);
-
- start = this_end;
- }
-}
-
-static void __init trim_reserved_in_node(int nid)
-{
- struct memblock_region *reg;
-
- numadbg(" trim_reserved_in_node(%d)\n", nid);
-
- for_each_memblock(reserved, reg)
- reserve_range_in_node(nid, reg->base, reg->base + reg->size);
-}
-
-static void __init bootmem_init_one_node(int nid)
-{
- struct pglist_data *p;
-
- numadbg("bootmem_init_one_node(%d)\n", nid);
-
- p = NODE_DATA(nid);
-
- if (p->node_spanned_pages) {
- unsigned long paddr = node_masks[nid].bootmem_paddr;
- unsigned long end_pfn;
-
- end_pfn = p->node_start_pfn + p->node_spanned_pages;
-
- numadbg(" init_bootmem_node(%d, %lx, %lx, %lx)\n",
- nid, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn);
-
- init_bootmem_node(p, paddr >> PAGE_SHIFT,
- p->node_start_pfn, end_pfn);
-
- numadbg(" free_bootmem_with_active_regions(%d, %lx)\n",
- nid, end_pfn);
- free_bootmem_with_active_regions(nid, end_pfn);
-
- trim_reserved_in_node(nid);
-
- numadbg(" sparse_memory_present_with_active_regions(%d)\n",
- nid);
- sparse_memory_present_with_active_regions(nid);
- }
-}
-
static unsigned long __init bootmem_init(unsigned long phys_base)
{
unsigned long end_pfn;
- int nid;
end_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
max_pfn = max_low_pfn = end_pfn;
@@ -1369,11 +1285,12 @@ static unsigned long __init bootmem_init(unsigned long phys_base)
if (bootmem_init_numa() < 0)
bootmem_init_nonnuma();
- /* XXX cpu notifier XXX */
+ /* Dump memblock with node info. */
+ memblock_dump_all();
- for_each_online_node(nid)
- bootmem_init_one_node(nid);
+ /* XXX cpu notifier XXX */
+ sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
return end_pfn;
@@ -1701,6 +1618,7 @@ void __init paging_init(void)
{
unsigned long end_pfn, shift, phys_base;
unsigned long real_end, i;
+ int node;
/* These build time checkes make sure that the dcache_dirty_cpu()
* page->flags usage will work.
@@ -1826,22 +1744,24 @@ void __init paging_init(void)
#endif
}
+ /* Setup bootmem... */
+ last_valid_pfn = end_pfn = bootmem_init(phys_base);
+
/* Once the OF device tree and MDESC have been setup, we know
* the list of possible cpus. Therefore we can allocate the
* IRQ stacks.
*/
for_each_possible_cpu(i) {
- /* XXX Use node local allocations... XXX */
- softirq_stack[i] = __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
- hardirq_stack[i] = __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
- }
+ node = cpu_to_node(i);
- /* Setup bootmem... */
- last_valid_pfn = end_pfn = bootmem_init(phys_base);
+ softirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
+ THREAD_SIZE,
+ THREAD_SIZE, 0);
+ hardirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
+ THREAD_SIZE,
+ THREAD_SIZE, 0);
+ }
-#ifndef CONFIG_NEED_MULTIPLE_NODES
- max_mapnr = last_valid_pfn;
-#endif
kernel_physical_mapping_init();
{
@@ -1973,6 +1893,7 @@ void __init mem_init(void)
free_all_bootmem_node(NODE_DATA(i));
}
}
+ totalram_pages += free_low_memory_core_early(MAX_NUMNODES);
}
#else
totalram_pages = free_all_bootmem();
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index fc58c3e917d..eb99862e965 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -197,7 +197,7 @@ static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg,
}
#ifdef CONFIG_SBUS
-static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len)
+static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, unsigned long addr, int len)
{
struct iounit_struct *iounit = dev->archdata.iommu;
unsigned long page, end;
@@ -242,29 +242,18 @@ static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int le
}
#endif
-static char *iounit_lockarea(char *vaddr, unsigned long len)
-{
-/* FIXME: Write this */
- return vaddr;
-}
-
-static void iounit_unlockarea(char *vaddr, unsigned long len)
-{
-/* FIXME: Write this */
-}
+static const struct sparc32_dma_ops iounit_dma_ops = {
+ .get_scsi_one = iounit_get_scsi_one,
+ .get_scsi_sgl = iounit_get_scsi_sgl,
+ .release_scsi_one = iounit_release_scsi_one,
+ .release_scsi_sgl = iounit_release_scsi_sgl,
+#ifdef CONFIG_SBUS
+ .map_dma_area = iounit_map_dma_area,
+ .unmap_dma_area = iounit_unmap_dma_area,
+#endif
+};
void __init ld_mmu_iounit(void)
{
- BTFIXUPSET_CALL(mmu_lockarea, iounit_lockarea, BTFIXUPCALL_RETO0);
- BTFIXUPSET_CALL(mmu_unlockarea, iounit_unlockarea, BTFIXUPCALL_NOP);
-
- BTFIXUPSET_CALL(mmu_get_scsi_one, iounit_get_scsi_one, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_get_scsi_sgl, iounit_get_scsi_sgl, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_release_scsi_one, iounit_release_scsi_one, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_release_scsi_sgl, iounit_release_scsi_sgl, BTFIXUPCALL_NORM);
-
-#ifdef CONFIG_SBUS
- BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM);
-#endif
+ sparc32_dma_ops = &iounit_dma_ops;
}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 07fc6a65d9b..a8a58cad9d2 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -39,8 +39,6 @@
/* srmmu.c */
extern int viking_mxcc_present;
-BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long)
-#define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page)
extern int flush_page_for_dma_global;
static int viking_flush;
/* viking.S */
@@ -143,7 +141,6 @@ static int __init iommu_init(void)
subsys_initcall(iommu_init);
-/* This begs to be btfixup-ed by srmmu. */
/* Flush the iotlb entries to ram. */
/* This could be better if we didn't have to flush whole pages. */
static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte)
@@ -216,11 +213,6 @@ static u32 iommu_get_scsi_one(struct device *dev, char *vaddr, unsigned int len)
return busa + off;
}
-static __u32 iommu_get_scsi_one_noflush(struct device *dev, char *vaddr, unsigned long len)
-{
- return iommu_get_scsi_one(dev, vaddr, len);
-}
-
static __u32 iommu_get_scsi_one_gflush(struct device *dev, char *vaddr, unsigned long len)
{
flush_page_for_dma(0);
@@ -238,19 +230,6 @@ static __u32 iommu_get_scsi_one_pflush(struct device *dev, char *vaddr, unsigned
return iommu_get_scsi_one(dev, vaddr, len);
}
-static void iommu_get_scsi_sgl_noflush(struct device *dev, struct scatterlist *sg, int sz)
-{
- int n;
-
- while (sz != 0) {
- --sz;
- n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
- sg->dma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
- sg->dma_length = sg->length;
- sg = sg_next(sg);
- }
-}
-
static void iommu_get_scsi_sgl_gflush(struct device *dev, struct scatterlist *sg, int sz)
{
int n;
@@ -426,40 +405,36 @@ static void iommu_unmap_dma_area(struct device *dev, unsigned long busa, int len
}
#endif
-static char *iommu_lockarea(char *vaddr, unsigned long len)
-{
- return vaddr;
-}
+static const struct sparc32_dma_ops iommu_dma_gflush_ops = {
+ .get_scsi_one = iommu_get_scsi_one_gflush,
+ .get_scsi_sgl = iommu_get_scsi_sgl_gflush,
+ .release_scsi_one = iommu_release_scsi_one,
+ .release_scsi_sgl = iommu_release_scsi_sgl,
+#ifdef CONFIG_SBUS
+ .map_dma_area = iommu_map_dma_area,
+ .unmap_dma_area = iommu_unmap_dma_area,
+#endif
+};
-static void iommu_unlockarea(char *vaddr, unsigned long len)
-{
-}
+static const struct sparc32_dma_ops iommu_dma_pflush_ops = {
+ .get_scsi_one = iommu_get_scsi_one_pflush,
+ .get_scsi_sgl = iommu_get_scsi_sgl_pflush,
+ .release_scsi_one = iommu_release_scsi_one,
+ .release_scsi_sgl = iommu_release_scsi_sgl,
+#ifdef CONFIG_SBUS
+ .map_dma_area = iommu_map_dma_area,
+ .unmap_dma_area = iommu_unmap_dma_area,
+#endif
+};
void __init ld_mmu_iommu(void)
{
- viking_flush = (BTFIXUPVAL_CALL(flush_page_for_dma) == (unsigned long)viking_flush_page);
- BTFIXUPSET_CALL(mmu_lockarea, iommu_lockarea, BTFIXUPCALL_RETO0);
- BTFIXUPSET_CALL(mmu_unlockarea, iommu_unlockarea, BTFIXUPCALL_NOP);
-
- if (!BTFIXUPVAL_CALL(flush_page_for_dma)) {
- /* IO coherent chip */
- BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_noflush, BTFIXUPCALL_RETO0);
- BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_noflush, BTFIXUPCALL_NORM);
- } else if (flush_page_for_dma_global) {
+ if (flush_page_for_dma_global) {
/* flush_page_for_dma flushes everything, no matter of what page is it */
- BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_gflush, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_gflush, BTFIXUPCALL_NORM);
+ sparc32_dma_ops = &iommu_dma_gflush_ops;
} else {
- BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_pflush, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_pflush, BTFIXUPCALL_NORM);
+ sparc32_dma_ops = &iommu_dma_pflush_ops;
}
- BTFIXUPSET_CALL(mmu_release_scsi_one, iommu_release_scsi_one, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_release_scsi_sgl, iommu_release_scsi_sgl, BTFIXUPCALL_NORM);
-
-#ifdef CONFIG_SBUS
- BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM);
-#endif
if (viking_mxcc_present || srmmu_modtype == HyperSparc) {
dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c
index 13c2169822a..5bed085a2c1 100644
--- a/arch/sparc/mm/leon_mm.c
+++ b/arch/sparc/mm/leon_mm.c
@@ -15,10 +15,24 @@
#include <asm/leon.h>
#include <asm/tlbflush.h>
+#include "srmmu.h"
+
int leon_flush_during_switch = 1;
int srmmu_swprobe_trace;
-unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr)
+static inline unsigned long leon_get_ctable_ptr(void)
+{
+ unsigned int retval;
+
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (SRMMU_CTXTBL_PTR),
+ "i" (ASI_LEON_MMUREGS));
+ return (retval & SRMMU_CTX_PMASK) << 4;
+}
+
+
+unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr)
{
unsigned int ctxtbl;
@@ -33,10 +47,10 @@ unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr)
if (srmmu_swprobe_trace)
printk(KERN_INFO "swprobe: trace on\n");
- ctxtbl = srmmu_get_ctable_ptr();
+ ctxtbl = leon_get_ctable_ptr();
if (!(ctxtbl)) {
if (srmmu_swprobe_trace)
- printk(KERN_INFO "swprobe: srmmu_get_ctable_ptr returned 0=>0\n");
+ printk(KERN_INFO "swprobe: leon_get_ctable_ptr returned 0=>0\n");
return 0;
}
if (!_pfn_valid(PFN(ctxtbl))) {
@@ -258,3 +272,80 @@ void leon_switch_mm(void)
if (leon_flush_during_switch)
leon_flush_cache_all();
}
+
+static void leon_flush_cache_mm(struct mm_struct *mm)
+{
+ leon_flush_cache_all();
+}
+
+static void leon_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
+{
+ leon_flush_pcache_all(vma, page);
+}
+
+static void leon_flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start,
+ unsigned long end)
+{
+ leon_flush_cache_all();
+}
+
+static void leon_flush_tlb_mm(struct mm_struct *mm)
+{
+ leon_flush_tlb_all();
+}
+
+static void leon_flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long page)
+{
+ leon_flush_tlb_all();
+}
+
+static void leon_flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start,
+ unsigned long end)
+{
+ leon_flush_tlb_all();
+}
+
+static void leon_flush_page_to_ram(unsigned long page)
+{
+ leon_flush_cache_all();
+}
+
+static void leon_flush_sig_insns(struct mm_struct *mm, unsigned long page)
+{
+ leon_flush_cache_all();
+}
+
+static void leon_flush_page_for_dma(unsigned long page)
+{
+ leon_flush_dcache_all();
+}
+
+void __init poke_leonsparc(void)
+{
+}
+
+static const struct sparc32_cachetlb_ops leon_ops = {
+ .cache_all = leon_flush_cache_all,
+ .cache_mm = leon_flush_cache_mm,
+ .cache_page = leon_flush_cache_page,
+ .cache_range = leon_flush_cache_range,
+ .tlb_all = leon_flush_tlb_all,
+ .tlb_mm = leon_flush_tlb_mm,
+ .tlb_page = leon_flush_tlb_page,
+ .tlb_range = leon_flush_tlb_range,
+ .page_to_ram = leon_flush_page_to_ram,
+ .sig_insns = leon_flush_sig_insns,
+ .page_for_dma = leon_flush_page_for_dma,
+};
+
+void __init init_leon(void)
+{
+ srmmu_name = "LEON";
+ sparc32_cachetlb_ops = &leon_ops;
+ poke_srmmu = poke_leonsparc;
+
+ leon_flush_during_switch = leon_flush_needed();
+}
diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c
deleted file mode 100644
index c5bf2a6c385..00000000000
--- a/arch/sparc/mm/loadmmu.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * loadmmu.c: This code loads up all the mm function pointers once the
- * machine type has been determined. It also sets the static
- * mmu values such as PAGE_NONE, etc.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/mmu_context.h>
-#include <asm/oplib.h>
-
-struct ctx_list *ctx_list_pool;
-struct ctx_list ctx_free;
-struct ctx_list ctx_used;
-
-extern void ld_mmu_sun4c(void);
-extern void ld_mmu_srmmu(void);
-
-void __init load_mmu(void)
-{
- switch(sparc_cpu_model) {
- case sun4c:
- case sun4:
- ld_mmu_sun4c();
- break;
- case sun4m:
- case sun4d:
- case sparc_leon:
- ld_mmu_srmmu();
- break;
- default:
- prom_printf("load_mmu: %d unsupported\n", (int)sparc_cpu_model);
- prom_halt();
- }
- btfixup();
-}
diff --git a/arch/sparc/mm/nosun4c.c b/arch/sparc/mm/nosun4c.c
deleted file mode 100644
index 4e62c27147c..00000000000
--- a/arch/sparc/mm/nosun4c.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * nosun4c.c: This file is a bunch of dummies for SMP compiles,
- * so that it does not need sun4c and avoid ifdefs.
- *
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <asm/pgtable.h>
-
-static char shouldnothappen[] __initdata = "32bit SMP kernel only supports sun4m and sun4d\n";
-
-/* Dummies */
-struct sun4c_mmu_ring {
- unsigned long xxx1[3];
- unsigned char xxx2[2];
- int xxx3;
-};
-struct sun4c_mmu_ring sun4c_kernel_ring;
-struct sun4c_mmu_ring sun4c_kfree_ring;
-unsigned long sun4c_kernel_faults;
-unsigned long *sun4c_memerr_reg;
-
-static void __init should_not_happen(void)
-{
- prom_printf(shouldnothappen);
- prom_halt();
-}
-
-unsigned long __init sun4c_paging_init(unsigned long start_mem, unsigned long end_mem)
-{
- should_not_happen();
- return 0;
-}
-
-void __init ld_mmu_sun4c(void)
-{
- should_not_happen();
-}
-
-void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly)
-{
-}
-
-void sun4c_unmapioaddr(unsigned long virt_addr)
-{
-}
-
-void sun4c_complete_all_stores(void)
-{
-}
-
-pte_t *sun4c_pte_offset(pmd_t * dir, unsigned long address)
-{
- return NULL;
-}
-
-pte_t *sun4c_pte_offset_kernel(pmd_t *dir, unsigned long address)
-{
- return NULL;
-}
-
-void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
-{
-}
-
-void __init sun4c_probe_vac(void)
-{
- should_not_happen();
-}
-
-void __init sun4c_probe_memerr_reg(void)
-{
- should_not_happen();
-}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index cbef74e793b..62e3f577330 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -48,39 +48,37 @@
#include <asm/turbosparc.h>
#include <asm/leon.h>
-#include <asm/btfixup.h>
+#include "srmmu.h"
enum mbus_module srmmu_modtype;
static unsigned int hwbug_bitmask;
int vac_cache_size;
int vac_line_size;
+struct ctx_list *ctx_list_pool;
+struct ctx_list ctx_free;
+struct ctx_list ctx_used;
+
extern struct resource sparc_iomap;
extern unsigned long last_valid_pfn;
-extern unsigned long page_kernel;
-
static pgd_t *srmmu_swapper_pg_dir;
+const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops;
+
#ifdef CONFIG_SMP
+const struct sparc32_cachetlb_ops *local_ops;
+
#define FLUSH_BEGIN(mm)
#define FLUSH_END
#else
-#define FLUSH_BEGIN(mm) if((mm)->context != NO_CONTEXT) {
+#define FLUSH_BEGIN(mm) if ((mm)->context != NO_CONTEXT) {
#define FLUSH_END }
#endif
-BTFIXUPDEF_CALL(void, flush_page_for_dma, unsigned long)
-#define flush_page_for_dma(page) BTFIXUP_CALL(flush_page_for_dma)(page)
-
int flush_page_for_dma_global = 1;
-#ifdef CONFIG_SMP
-BTFIXUPDEF_CALL(void, local_flush_page_for_dma, unsigned long)
-#define local_flush_page_for_dma(page) BTFIXUP_CALL(local_flush_page_for_dma)(page)
-#endif
-
char *srmmu_name;
ctxd_t *srmmu_ctx_table_phys;
@@ -91,28 +89,6 @@ static DEFINE_SPINLOCK(srmmu_context_spinlock);
static int is_hypersparc;
-/*
- * In general all page table modifications should use the V8 atomic
- * swap instruction. This insures the mmu and the cpu are in sync
- * with respect to ref/mod bits in the page tables.
- */
-static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value)
-{
- __asm__ __volatile__("swap [%2], %0" : "=&r" (value) : "0" (value), "r" (addr));
- return value;
-}
-
-static inline void srmmu_set_pte(pte_t *ptep, pte_t pteval)
-{
- srmmu_swap((unsigned long *)ptep, pte_val(pteval));
-}
-
-/* The very generic SRMMU page table operations. */
-static inline int srmmu_device_memory(unsigned long x)
-{
- return ((x & 0xF0000000) != 0);
-}
-
static int srmmu_cache_pagetables;
/* these will be initialized in srmmu_nocache_calcsize() */
@@ -129,145 +105,39 @@ void *srmmu_nocache_pool;
void *srmmu_nocache_bitmap;
static struct bit_map srmmu_nocache_map;
-static unsigned long srmmu_pte_pfn(pte_t pte)
-{
- if (srmmu_device_memory(pte_val(pte))) {
- /* Just return something that will cause
- * pfn_valid() to return false. This makes
- * copy_one_pte() to just directly copy to
- * PTE over.
- */
- return ~0UL;
- }
- return (pte_val(pte) & SRMMU_PTE_PMASK) >> (PAGE_SHIFT-4);
-}
-
-static struct page *srmmu_pmd_page(pmd_t pmd)
-{
-
- if (srmmu_device_memory(pmd_val(pmd)))
- BUG();
- return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4));
-}
-
-static inline unsigned long srmmu_pgd_page(pgd_t pgd)
-{ return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__nocache_va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); }
-
-
-static inline int srmmu_pte_none(pte_t pte)
-{ return !(pte_val(pte) & 0xFFFFFFF); }
-
-static inline int srmmu_pte_present(pte_t pte)
-{ return ((pte_val(pte) & SRMMU_ET_MASK) == SRMMU_ET_PTE); }
-
-static inline void srmmu_pte_clear(pte_t *ptep)
-{ srmmu_set_pte(ptep, __pte(0)); }
-
static inline int srmmu_pmd_none(pmd_t pmd)
{ return !(pmd_val(pmd) & 0xFFFFFFF); }
-static inline int srmmu_pmd_bad(pmd_t pmd)
-{ return (pmd_val(pmd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; }
-
-static inline int srmmu_pmd_present(pmd_t pmd)
-{ return ((pmd_val(pmd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); }
-
-static inline void srmmu_pmd_clear(pmd_t *pmdp) {
- int i;
- for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++)
- srmmu_set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
-}
-
-static inline int srmmu_pgd_none(pgd_t pgd)
-{ return !(pgd_val(pgd) & 0xFFFFFFF); }
-
-static inline int srmmu_pgd_bad(pgd_t pgd)
-{ return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD; }
-
-static inline int srmmu_pgd_present(pgd_t pgd)
-{ return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD); }
-
-static inline void srmmu_pgd_clear(pgd_t * pgdp)
-{ srmmu_set_pte((pte_t *)pgdp, __pte(0)); }
-
-static inline pte_t srmmu_pte_wrprotect(pte_t pte)
-{ return __pte(pte_val(pte) & ~SRMMU_WRITE);}
-
-static inline pte_t srmmu_pte_mkclean(pte_t pte)
-{ return __pte(pte_val(pte) & ~SRMMU_DIRTY);}
-
-static inline pte_t srmmu_pte_mkold(pte_t pte)
-{ return __pte(pte_val(pte) & ~SRMMU_REF);}
-
-static inline pte_t srmmu_pte_mkwrite(pte_t pte)
-{ return __pte(pte_val(pte) | SRMMU_WRITE);}
-
-static inline pte_t srmmu_pte_mkdirty(pte_t pte)
-{ return __pte(pte_val(pte) | SRMMU_DIRTY);}
-
-static inline pte_t srmmu_pte_mkyoung(pte_t pte)
-{ return __pte(pte_val(pte) | SRMMU_REF);}
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-static pte_t srmmu_mk_pte(struct page *page, pgprot_t pgprot)
-{ return __pte((page_to_pfn(page) << (PAGE_SHIFT-4)) | pgprot_val(pgprot)); }
-
-static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot)
-{ return __pte(((page) >> 4) | pgprot_val(pgprot)); }
-
-static pte_t srmmu_mk_pte_io(unsigned long page, pgprot_t pgprot, int space)
-{ return __pte(((page) >> 4) | (space << 28) | pgprot_val(pgprot)); }
-
/* XXX should we hyper_flush_whole_icache here - Anton */
static inline void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
-{ srmmu_set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); }
-
-static inline void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ srmmu_set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pmdp) >> 4))); }
+{ set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pgdp) >> 4))); }
-static void srmmu_pmd_set(pmd_t *pmdp, pte_t *ptep)
+void pmd_set(pmd_t *pmdp, pte_t *ptep)
{
unsigned long ptp; /* Physical address, shifted right by 4 */
int i;
ptp = __nocache_pa((unsigned long) ptep) >> 4;
for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
- srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
+ set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
}
}
-static void srmmu_pmd_populate(pmd_t *pmdp, struct page *ptep)
+void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep)
{
unsigned long ptp; /* Physical address, shifted right by 4 */
int i;
ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4); /* watch for overflow */
for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
- srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
+ set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
}
}
-static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot)
-{ return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); }
-
-/* to find an entry in a top-level page table... */
-static inline pgd_t *srmmu_pgd_offset(struct mm_struct * mm, unsigned long address)
-{ return mm->pgd + (address >> SRMMU_PGDIR_SHIFT); }
-
-/* Find an entry in the second-level page table.. */
-static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address)
-{
- return (pmd_t *) srmmu_pgd_page(*dir) +
- ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
-}
-
/* Find an entry in the third-level page table.. */
-static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address)
+pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address)
{
void *pte;
@@ -276,23 +146,6 @@ static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address)
((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
}
-static unsigned long srmmu_swp_type(swp_entry_t entry)
-{
- return (entry.val >> SRMMU_SWP_TYPE_SHIFT) & SRMMU_SWP_TYPE_MASK;
-}
-
-static unsigned long srmmu_swp_offset(swp_entry_t entry)
-{
- return (entry.val >> SRMMU_SWP_OFF_SHIFT) & SRMMU_SWP_OFF_MASK;
-}
-
-static swp_entry_t srmmu_swp_entry(unsigned long type, unsigned long offset)
-{
- return (swp_entry_t) {
- (type & SRMMU_SWP_TYPE_MASK) << SRMMU_SWP_TYPE_SHIFT
- | (offset & SRMMU_SWP_OFF_MASK) << SRMMU_SWP_OFF_SHIFT };
-}
-
/*
* size: bytes to allocate in the nocache area.
* align: bytes, number to align at.
@@ -325,7 +178,7 @@ static unsigned long __srmmu_get_nocache(int size, int align)
return (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT));
}
-static unsigned long srmmu_get_nocache(int size, int align)
+unsigned long srmmu_get_nocache(int size, int align)
{
unsigned long tmp;
@@ -337,7 +190,7 @@ static unsigned long srmmu_get_nocache(int size, int align)
return tmp;
}
-static void srmmu_free_nocache(unsigned long vaddr, int size)
+void srmmu_free_nocache(unsigned long vaddr, int size)
{
int offset;
@@ -429,15 +282,15 @@ static void __init srmmu_nocache_init(void)
while (vaddr < srmmu_nocache_end) {
pgd = pgd_offset_k(vaddr);
- pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr);
- pte = srmmu_pte_offset(__nocache_fix(pmd), vaddr);
+ pmd = pmd_offset(__nocache_fix(pgd), vaddr);
+ pte = pte_offset_kernel(__nocache_fix(pmd), vaddr);
pteval = ((paddr >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
if (srmmu_cache_pagetables)
pteval |= SRMMU_CACHE;
- srmmu_set_pte(__nocache_fix(pte), __pte(pteval));
+ set_pte(__nocache_fix(pte), __pte(pteval));
vaddr += PAGE_SIZE;
paddr += PAGE_SIZE;
@@ -447,7 +300,7 @@ static void __init srmmu_nocache_init(void)
flush_tlb_all();
}
-static inline pgd_t *srmmu_get_pgd_fast(void)
+pgd_t *get_pgd_fast(void)
{
pgd_t *pgd = NULL;
@@ -462,21 +315,6 @@ static inline pgd_t *srmmu_get_pgd_fast(void)
return pgd;
}
-static void srmmu_free_pgd_fast(pgd_t *pgd)
-{
- srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE);
-}
-
-static pmd_t *srmmu_pmd_alloc_one(struct mm_struct *mm, unsigned long address)
-{
- return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
-}
-
-static void srmmu_pmd_free(pmd_t * pmd)
-{
- srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE);
-}
-
/*
* Hardware needs alignment to 256 only, but we align to whole page size
* to reduce fragmentation problems due to the buddy principle.
@@ -485,31 +323,19 @@ static void srmmu_pmd_free(pmd_t * pmd)
* Alignments up to the page size are the same for physical and virtual
* addresses of the nocache area.
*/
-static pte_t *
-srmmu_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
-{
- return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
-}
-
-static pgtable_t
-srmmu_pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
unsigned long pte;
struct page *page;
- if ((pte = (unsigned long)srmmu_pte_alloc_one_kernel(mm, address)) == 0)
+ if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0)
return NULL;
page = pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT );
pgtable_page_ctor(page);
return page;
}
-static void srmmu_free_pte_fast(pte_t *pte)
-{
- srmmu_free_nocache((unsigned long)pte, PTE_SIZE);
-}
-
-static void srmmu_pte_free(pgtable_t pte)
+void pte_free(struct mm_struct *mm, pgtable_t pte)
{
unsigned long p;
@@ -560,8 +386,8 @@ static inline void free_context(int context)
}
-static void srmmu_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
- struct task_struct *tsk, int cpu)
+void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
+ struct task_struct *tsk)
{
if(mm->context == NO_CONTEXT) {
spin_lock(&srmmu_context_spinlock);
@@ -590,8 +416,8 @@ static inline void srmmu_mapioaddr(unsigned long physaddr,
physaddr &= PAGE_MASK;
pgdp = pgd_offset_k(virt_addr);
- pmdp = srmmu_pmd_offset(pgdp, virt_addr);
- ptep = srmmu_pte_offset(pmdp, virt_addr);
+ pmdp = pmd_offset(pgdp, virt_addr);
+ ptep = pte_offset_kernel(pmdp, virt_addr);
tmp = (physaddr >> 4) | SRMMU_ET_PTE;
/*
@@ -602,11 +428,11 @@ static inline void srmmu_mapioaddr(unsigned long physaddr,
tmp |= (bus_type << 28);
tmp |= SRMMU_PRIV;
__flush_page_to_ram(virt_addr);
- srmmu_set_pte(ptep, __pte(tmp));
+ set_pte(ptep, __pte(tmp));
}
-static void srmmu_mapiorange(unsigned int bus, unsigned long xpa,
- unsigned long xva, unsigned int len)
+void srmmu_mapiorange(unsigned int bus, unsigned long xpa,
+ unsigned long xva, unsigned int len)
{
while (len != 0) {
len -= PAGE_SIZE;
@@ -624,14 +450,14 @@ static inline void srmmu_unmapioaddr(unsigned long virt_addr)
pte_t *ptep;
pgdp = pgd_offset_k(virt_addr);
- pmdp = srmmu_pmd_offset(pgdp, virt_addr);
- ptep = srmmu_pte_offset(pmdp, virt_addr);
+ pmdp = pmd_offset(pgdp, virt_addr);
+ ptep = pte_offset_kernel(pmdp, virt_addr);
/* No need to flush uncacheable page. */
- srmmu_pte_clear(ptep);
+ __pte_clear(ptep);
}
-static void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len)
+void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len)
{
while (len != 0) {
len -= PAGE_SIZE;
@@ -641,34 +467,6 @@ static void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len)
flush_tlb_all();
}
-/*
- * On the SRMMU we do not have the problems with limited tlb entries
- * for mapping kernel pages, so we just take things from the free page
- * pool. As a side effect we are putting a little too much pressure
- * on the gfp() subsystem. This setup also makes the logic of the
- * iommu mapping code a lot easier as we can transparently handle
- * mappings on the kernel stack without any special code as we did
- * need on the sun4c.
- */
-static struct thread_info *srmmu_alloc_thread_info_node(int node)
-{
- struct thread_info *ret;
-
- ret = (struct thread_info *)__get_free_pages(GFP_KERNEL,
- THREAD_INFO_ORDER);
-#ifdef CONFIG_DEBUG_STACK_USAGE
- if (ret)
- memset(ret, 0, PAGE_SIZE << THREAD_INFO_ORDER);
-#endif /* DEBUG_STACK_USAGE */
-
- return ret;
-}
-
-static void srmmu_free_thread_info(struct thread_info *ti)
-{
- free_pages((unsigned long)ti, THREAD_INFO_ORDER);
-}
-
/* tsunami.S */
extern void tsunami_flush_cache_all(void);
extern void tsunami_flush_cache_mm(struct mm_struct *mm);
@@ -683,38 +481,6 @@ extern void tsunami_flush_tlb_range(struct vm_area_struct *vma, unsigned long st
extern void tsunami_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
extern void tsunami_setup_blockops(void);
-/*
- * Workaround, until we find what's going on with Swift. When low on memory,
- * it sometimes loops in fault/handle_mm_fault incl. flush_tlb_page to find
- * out it is already in page tables/ fault again on the same instruction.
- * I really don't understand it, have checked it and contexts
- * are right, flush_tlb_all is done as well, and it faults again...
- * Strange. -jj
- *
- * The following code is a deadwood that may be necessary when
- * we start to make precise page flushes again. --zaitcev
- */
-static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t *ptep)
-{
-#if 0
- static unsigned long last;
- unsigned int val;
- /* unsigned int n; */
-
- if (address == last) {
- val = srmmu_hwprobe(address);
- if (val != 0 && pte_val(*ptep) != val) {
- printk("swift_update_mmu_cache: "
- "addr %lx put %08x probed %08x from %p\n",
- address, pte_val(*ptep), val,
- __builtin_return_address(0));
- srmmu_flush_whole_tlb();
- }
- }
- last = address;
-#endif
-}
-
/* swift.S */
extern void swift_flush_cache_all(void);
extern void swift_flush_cache_mm(struct mm_struct *mm);
@@ -767,244 +533,6 @@ void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
* with respect to cache coherency.
*/
-/* Cypress flushes. */
-static void cypress_flush_cache_all(void)
-{
- volatile unsigned long cypress_sucks;
- unsigned long faddr, tagval;
-
- flush_user_windows();
- for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
- __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
- "=r" (tagval) :
- "r" (faddr), "r" (0x40000),
- "i" (ASI_M_DATAC_TAG));
-
- /* If modified and valid, kick it. */
- if((tagval & 0x60) == 0x60)
- cypress_sucks = *(unsigned long *)(0xf0020000 + faddr);
- }
-}
-
-static void cypress_flush_cache_mm(struct mm_struct *mm)
-{
- register unsigned long a, b, c, d, e, f, g;
- unsigned long flags, faddr;
- int octx;
-
- FLUSH_BEGIN(mm)
- flush_user_windows();
- local_irq_save(flags);
- octx = srmmu_get_context();
- srmmu_set_context(mm->context);
- a = 0x20; b = 0x40; c = 0x60;
- d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
-
- faddr = (0x10000 - 0x100);
- goto inside;
- do {
- faddr -= 0x100;
- inside:
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- "sta %%g0, [%0 + %2] %1\n\t"
- "sta %%g0, [%0 + %3] %1\n\t"
- "sta %%g0, [%0 + %4] %1\n\t"
- "sta %%g0, [%0 + %5] %1\n\t"
- "sta %%g0, [%0 + %6] %1\n\t"
- "sta %%g0, [%0 + %7] %1\n\t"
- "sta %%g0, [%0 + %8] %1\n\t" : :
- "r" (faddr), "i" (ASI_M_FLUSH_CTX),
- "r" (a), "r" (b), "r" (c), "r" (d),
- "r" (e), "r" (f), "r" (g));
- } while(faddr);
- srmmu_set_context(octx);
- local_irq_restore(flags);
- FLUSH_END
-}
-
-static void cypress_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- register unsigned long a, b, c, d, e, f, g;
- unsigned long flags, faddr;
- int octx;
-
- FLUSH_BEGIN(mm)
- flush_user_windows();
- local_irq_save(flags);
- octx = srmmu_get_context();
- srmmu_set_context(mm->context);
- a = 0x20; b = 0x40; c = 0x60;
- d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
-
- start &= SRMMU_REAL_PMD_MASK;
- while(start < end) {
- faddr = (start + (0x10000 - 0x100));
- goto inside;
- do {
- faddr -= 0x100;
- inside:
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- "sta %%g0, [%0 + %2] %1\n\t"
- "sta %%g0, [%0 + %3] %1\n\t"
- "sta %%g0, [%0 + %4] %1\n\t"
- "sta %%g0, [%0 + %5] %1\n\t"
- "sta %%g0, [%0 + %6] %1\n\t"
- "sta %%g0, [%0 + %7] %1\n\t"
- "sta %%g0, [%0 + %8] %1\n\t" : :
- "r" (faddr),
- "i" (ASI_M_FLUSH_SEG),
- "r" (a), "r" (b), "r" (c), "r" (d),
- "r" (e), "r" (f), "r" (g));
- } while (faddr != start);
- start += SRMMU_REAL_PMD_SIZE;
- }
- srmmu_set_context(octx);
- local_irq_restore(flags);
- FLUSH_END
-}
-
-static void cypress_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
-{
- register unsigned long a, b, c, d, e, f, g;
- struct mm_struct *mm = vma->vm_mm;
- unsigned long flags, line;
- int octx;
-
- FLUSH_BEGIN(mm)
- flush_user_windows();
- local_irq_save(flags);
- octx = srmmu_get_context();
- srmmu_set_context(mm->context);
- a = 0x20; b = 0x40; c = 0x60;
- d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
-
- page &= PAGE_MASK;
- line = (page + PAGE_SIZE) - 0x100;
- goto inside;
- do {
- line -= 0x100;
- inside:
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- "sta %%g0, [%0 + %2] %1\n\t"
- "sta %%g0, [%0 + %3] %1\n\t"
- "sta %%g0, [%0 + %4] %1\n\t"
- "sta %%g0, [%0 + %5] %1\n\t"
- "sta %%g0, [%0 + %6] %1\n\t"
- "sta %%g0, [%0 + %7] %1\n\t"
- "sta %%g0, [%0 + %8] %1\n\t" : :
- "r" (line),
- "i" (ASI_M_FLUSH_PAGE),
- "r" (a), "r" (b), "r" (c), "r" (d),
- "r" (e), "r" (f), "r" (g));
- } while(line != page);
- srmmu_set_context(octx);
- local_irq_restore(flags);
- FLUSH_END
-}
-
-/* Cypress is copy-back, at least that is how we configure it. */
-static void cypress_flush_page_to_ram(unsigned long page)
-{
- register unsigned long a, b, c, d, e, f, g;
- unsigned long line;
-
- a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
- page &= PAGE_MASK;
- line = (page + PAGE_SIZE) - 0x100;
- goto inside;
- do {
- line -= 0x100;
- inside:
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- "sta %%g0, [%0 + %2] %1\n\t"
- "sta %%g0, [%0 + %3] %1\n\t"
- "sta %%g0, [%0 + %4] %1\n\t"
- "sta %%g0, [%0 + %5] %1\n\t"
- "sta %%g0, [%0 + %6] %1\n\t"
- "sta %%g0, [%0 + %7] %1\n\t"
- "sta %%g0, [%0 + %8] %1\n\t" : :
- "r" (line),
- "i" (ASI_M_FLUSH_PAGE),
- "r" (a), "r" (b), "r" (c), "r" (d),
- "r" (e), "r" (f), "r" (g));
- } while(line != page);
-}
-
-/* Cypress is also IO cache coherent. */
-static void cypress_flush_page_for_dma(unsigned long page)
-{
-}
-
-/* Cypress has unified L2 VIPT, from which both instructions and data
- * are stored. It does not have an onboard icache of any sort, therefore
- * no flush is necessary.
- */
-static void cypress_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
-{
-}
-
-static void cypress_flush_tlb_all(void)
-{
- srmmu_flush_whole_tlb();
-}
-
-static void cypress_flush_tlb_mm(struct mm_struct *mm)
-{
- FLUSH_BEGIN(mm)
- __asm__ __volatile__(
- "lda [%0] %3, %%g5\n\t"
- "sta %2, [%0] %3\n\t"
- "sta %%g0, [%1] %4\n\t"
- "sta %%g5, [%0] %3\n"
- : /* no outputs */
- : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context),
- "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
- : "g5");
- FLUSH_END
-}
-
-static void cypress_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned long size;
-
- FLUSH_BEGIN(mm)
- start &= SRMMU_PGDIR_MASK;
- size = SRMMU_PGDIR_ALIGN(end) - start;
- __asm__ __volatile__(
- "lda [%0] %5, %%g5\n\t"
- "sta %1, [%0] %5\n"
- "1:\n\t"
- "subcc %3, %4, %3\n\t"
- "bne 1b\n\t"
- " sta %%g0, [%2 + %3] %6\n\t"
- "sta %%g5, [%0] %5\n"
- : /* no outputs */
- : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (start | 0x200),
- "r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS),
- "i" (ASI_M_FLUSH_PROBE)
- : "g5", "cc");
- FLUSH_END
-}
-
-static void cypress_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
- struct mm_struct *mm = vma->vm_mm;
-
- FLUSH_BEGIN(mm)
- __asm__ __volatile__(
- "lda [%0] %3, %%g5\n\t"
- "sta %1, [%0] %3\n\t"
- "sta %%g0, [%2] %4\n\t"
- "sta %%g5, [%0] %3\n"
- : /* no outputs */
- : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK),
- "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
- : "g5");
- FLUSH_END
-}
-
/* viking.S */
extern void viking_flush_cache_all(void);
extern void viking_flush_cache_mm(struct mm_struct *mm);
@@ -1065,21 +593,21 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
while(start < end) {
pgdp = pgd_offset_k(start);
- if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+ if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
pmdp = (pmd_t *) __srmmu_get_nocache(
SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
if (pmdp == NULL)
early_pgtable_allocfail("pmd");
memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
- srmmu_pgd_set(__nocache_fix(pgdp), pmdp);
+ pgd_set(__nocache_fix(pgdp), pmdp);
}
- pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start);
+ pmdp = pmd_offset(__nocache_fix(pgdp), start);
if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
memset(__nocache_fix(ptep), 0, PTE_SIZE);
- srmmu_pmd_set(__nocache_fix(pmdp), ptep);
+ pmd_set(__nocache_fix(pmdp), ptep);
}
if (start > (0xffffffffUL - PMD_SIZE))
break;
@@ -1096,21 +624,21 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
while(start < end) {
pgdp = pgd_offset_k(start);
- if(srmmu_pgd_none(*pgdp)) {
+ if (pgd_none(*pgdp)) {
pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
if (pmdp == NULL)
early_pgtable_allocfail("pmd");
memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE);
- srmmu_pgd_set(pgdp, pmdp);
+ pgd_set(pgdp, pmdp);
}
- pmdp = srmmu_pmd_offset(pgdp, start);
+ pmdp = pmd_offset(pgdp, start);
if(srmmu_pmd_none(*pmdp)) {
ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
memset(ptep, 0, PTE_SIZE);
- srmmu_pmd_set(pmdp, ptep);
+ pmd_set(pmdp, ptep);
}
if (start > (0xffffffffUL - PMD_SIZE))
break;
@@ -1118,6 +646,23 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
}
}
+/* These flush types are not available on all chips... */
+static inline unsigned long srmmu_probe(unsigned long vaddr)
+{
+ unsigned long retval;
+
+ if (sparc_cpu_model != sparc_leon) {
+
+ vaddr &= PAGE_MASK;
+ __asm__ __volatile__("lda [%1] %2, %0\n\t" :
+ "=r" (retval) :
+ "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
+ } else {
+ retval = leon_swprobe(vaddr, 0);
+ }
+ return retval;
+}
+
/*
* This is much cleaner than poking around physical address space
* looking at the prom's page table directly which is what most
@@ -1137,7 +682,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
break; /* probably wrap around */
if(start == 0xfef00000)
start = KADB_DEBUGGER_BEGVM;
- if(!(prompte = srmmu_hwprobe(start))) {
+ if(!(prompte = srmmu_probe(start))) {
start += PAGE_SIZE;
continue;
}
@@ -1146,12 +691,12 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
what = 0;
if(!(start & ~(SRMMU_REAL_PMD_MASK))) {
- if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte)
+ if(srmmu_probe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte)
what = 1;
}
if(!(start & ~(SRMMU_PGDIR_MASK))) {
- if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) ==
+ if(srmmu_probe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) ==
prompte)
what = 2;
}
@@ -1162,21 +707,21 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
start += SRMMU_PGDIR_SIZE;
continue;
}
- if(srmmu_pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+ if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
if (pmdp == NULL)
early_pgtable_allocfail("pmd");
memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
- srmmu_pgd_set(__nocache_fix(pgdp), pmdp);
+ pgd_set(__nocache_fix(pgdp), pmdp);
}
- pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start);
+ pmdp = pmd_offset(__nocache_fix(pgdp), start);
if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
memset(__nocache_fix(ptep), 0, PTE_SIZE);
- srmmu_pmd_set(__nocache_fix(pmdp), ptep);
+ pmd_set(__nocache_fix(pmdp), ptep);
}
if(what == 1) {
/*
@@ -1190,7 +735,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
start += SRMMU_REAL_PMD_SIZE;
continue;
}
- ptep = srmmu_pte_offset(__nocache_fix(pmdp), start);
+ ptep = pte_offset_kernel(__nocache_fix(pmdp), start);
*(pte_t *)__nocache_fix(ptep) = __pte(prompte);
start += PAGE_SIZE;
}
@@ -1231,13 +776,6 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry)
return vstart;
}
-static inline void memprobe_error(char *msg)
-{
- prom_printf(msg);
- prom_printf("Halting now...\n");
- prom_halt();
-}
-
static inline void map_kernel(void)
{
int i;
@@ -1249,8 +787,6 @@ static inline void map_kernel(void)
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
map_spbank((unsigned long)__va(sp_banks[i].base_addr), i);
}
-
- BTFIXUPSET_SIMM13(user_ptrs_per_pgd, PAGE_OFFSET / SRMMU_PGDIR_SIZE);
}
/* Paging initialization on the Sparc Reference MMU. */
@@ -1312,7 +848,7 @@ void __init srmmu_paging_init(void)
srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys);
#ifdef CONFIG_SMP
/* Stop from hanging here... */
- local_flush_tlb_all();
+ local_ops->tlb_all();
#else
flush_tlb_all();
#endif
@@ -1326,8 +862,8 @@ void __init srmmu_paging_init(void)
srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_END);
pgd = pgd_offset_k(PKMAP_BASE);
- pmd = srmmu_pmd_offset(pgd, PKMAP_BASE);
- pte = srmmu_pte_offset(pmd, PKMAP_BASE);
+ pmd = pmd_offset(pgd, PKMAP_BASE);
+ pte = pte_offset_kernel(pmd, PKMAP_BASE);
pkmap_page_table = pte;
flush_cache_all();
@@ -1359,7 +895,7 @@ void __init srmmu_paging_init(void)
}
}
-static void srmmu_mmu_info(struct seq_file *m)
+void mmu_info(struct seq_file *m)
{
seq_printf(m,
"MMU type\t: %s\n"
@@ -1372,11 +908,7 @@ static void srmmu_mmu_info(struct seq_file *m)
srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT);
}
-static void srmmu_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte)
-{
-}
-
-static void srmmu_destroy_context(struct mm_struct *mm)
+void destroy_context(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT) {
@@ -1474,6 +1006,20 @@ static void __cpuinit poke_hypersparc(void)
clear = srmmu_get_fstatus();
}
+static const struct sparc32_cachetlb_ops hypersparc_ops = {
+ .cache_all = hypersparc_flush_cache_all,
+ .cache_mm = hypersparc_flush_cache_mm,
+ .cache_page = hypersparc_flush_cache_page,
+ .cache_range = hypersparc_flush_cache_range,
+ .tlb_all = hypersparc_flush_tlb_all,
+ .tlb_mm = hypersparc_flush_tlb_mm,
+ .tlb_page = hypersparc_flush_tlb_page,
+ .tlb_range = hypersparc_flush_tlb_range,
+ .page_to_ram = hypersparc_flush_page_to_ram,
+ .sig_insns = hypersparc_flush_sig_insns,
+ .page_for_dma = hypersparc_flush_page_for_dma,
+};
+
static void __init init_hypersparc(void)
{
srmmu_name = "ROSS HyperSparc";
@@ -1482,118 +1028,13 @@ static void __init init_hypersparc(void)
init_vac_layout();
is_hypersparc = 1;
-
- BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_all, hypersparc_flush_cache_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_mm, hypersparc_flush_cache_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_range, hypersparc_flush_cache_range, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_page, hypersparc_flush_cache_page, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(flush_tlb_all, hypersparc_flush_tlb_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_mm, hypersparc_flush_tlb_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_range, hypersparc_flush_tlb_range, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_page, hypersparc_flush_tlb_page, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(__flush_page_to_ram, hypersparc_flush_page_to_ram, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_sig_insns, hypersparc_flush_sig_insns, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_page_for_dma, hypersparc_flush_page_for_dma, BTFIXUPCALL_NOP);
-
+ sparc32_cachetlb_ops = &hypersparc_ops;
poke_srmmu = poke_hypersparc;
hypersparc_setup_blockops();
}
-static void __cpuinit poke_cypress(void)
-{
- unsigned long mreg = srmmu_get_mmureg();
- unsigned long faddr, tagval;
- volatile unsigned long cypress_sucks;
- volatile unsigned long clear;
-
- clear = srmmu_get_faddr();
- clear = srmmu_get_fstatus();
-
- if (!(mreg & CYPRESS_CENABLE)) {
- for(faddr = 0x0; faddr < 0x10000; faddr += 20) {
- __asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t"
- "sta %%g0, [%0] %2\n\t" : :
- "r" (faddr), "r" (0x40000),
- "i" (ASI_M_DATAC_TAG));
- }
- } else {
- for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
- __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
- "=r" (tagval) :
- "r" (faddr), "r" (0x40000),
- "i" (ASI_M_DATAC_TAG));
-
- /* If modified and valid, kick it. */
- if((tagval & 0x60) == 0x60)
- cypress_sucks = *(unsigned long *)
- (0xf0020000 + faddr);
- }
- }
-
- /* And one more, for our good neighbor, Mr. Broken Cypress. */
- clear = srmmu_get_faddr();
- clear = srmmu_get_fstatus();
-
- mreg |= (CYPRESS_CENABLE | CYPRESS_CMODE);
- srmmu_set_mmureg(mreg);
-}
-
-static void __init init_cypress_common(void)
-{
- init_vac_layout();
-
- BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_all, cypress_flush_cache_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_mm, cypress_flush_cache_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_range, cypress_flush_cache_range, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_page, cypress_flush_cache_page, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(flush_tlb_all, cypress_flush_tlb_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_mm, cypress_flush_tlb_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_page, cypress_flush_tlb_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_range, cypress_flush_tlb_range, BTFIXUPCALL_NORM);
-
-
- BTFIXUPSET_CALL(__flush_page_to_ram, cypress_flush_page_to_ram, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_sig_insns, cypress_flush_sig_insns, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(flush_page_for_dma, cypress_flush_page_for_dma, BTFIXUPCALL_NOP);
-
- poke_srmmu = poke_cypress;
-}
-
-static void __init init_cypress_604(void)
-{
- srmmu_name = "ROSS Cypress-604(UP)";
- srmmu_modtype = Cypress;
- init_cypress_common();
-}
-
-static void __init init_cypress_605(unsigned long mrev)
-{
- srmmu_name = "ROSS Cypress-605(MP)";
- if(mrev == 0xe) {
- srmmu_modtype = Cypress_vE;
- hwbug_bitmask |= HWBUG_COPYBACK_BROKEN;
- } else {
- if(mrev == 0xd) {
- srmmu_modtype = Cypress_vD;
- hwbug_bitmask |= HWBUG_ASIFLUSH_BROKEN;
- } else {
- srmmu_modtype = Cypress;
- }
- }
- init_cypress_common();
-}
-
static void __cpuinit poke_swift(void)
{
unsigned long mreg;
@@ -1617,6 +1058,20 @@ static void __cpuinit poke_swift(void)
srmmu_set_mmureg(mreg);
}
+static const struct sparc32_cachetlb_ops swift_ops = {
+ .cache_all = swift_flush_cache_all,
+ .cache_mm = swift_flush_cache_mm,
+ .cache_page = swift_flush_cache_page,
+ .cache_range = swift_flush_cache_range,
+ .tlb_all = swift_flush_tlb_all,
+ .tlb_mm = swift_flush_tlb_mm,
+ .tlb_page = swift_flush_tlb_page,
+ .tlb_range = swift_flush_tlb_range,
+ .page_to_ram = swift_flush_page_to_ram,
+ .sig_insns = swift_flush_sig_insns,
+ .page_for_dma = swift_flush_page_for_dma,
+};
+
#define SWIFT_MASKID_ADDR 0x10003018
static void __init init_swift(void)
{
@@ -1667,23 +1122,7 @@ static void __init init_swift(void)
break;
}
- BTFIXUPSET_CALL(flush_cache_all, swift_flush_cache_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_mm, swift_flush_cache_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_page, swift_flush_cache_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_range, swift_flush_cache_range, BTFIXUPCALL_NORM);
-
-
- BTFIXUPSET_CALL(flush_tlb_all, swift_flush_tlb_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_mm, swift_flush_tlb_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_page, swift_flush_tlb_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_range, swift_flush_tlb_range, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(__flush_page_to_ram, swift_flush_page_to_ram, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_sig_insns, swift_flush_sig_insns, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_page_for_dma, swift_flush_page_for_dma, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(update_mmu_cache, swift_update_mmu_cache, BTFIXUPCALL_NORM);
-
+ sparc32_cachetlb_ops = &swift_ops;
flush_page_for_dma_global = 0;
/*
@@ -1734,7 +1173,7 @@ static void turbosparc_flush_page_to_ram(unsigned long page)
#ifdef TURBOSPARC_WRITEBACK
volatile unsigned long clear;
- if (srmmu_hwprobe(page))
+ if (srmmu_probe(page))
turbosparc_flush_page_cache(page);
clear = srmmu_get_fstatus();
#endif
@@ -1816,26 +1255,25 @@ static void __cpuinit poke_turbosparc(void)
srmmu_set_mmureg(mreg);
}
+static const struct sparc32_cachetlb_ops turbosparc_ops = {
+ .cache_all = turbosparc_flush_cache_all,
+ .cache_mm = turbosparc_flush_cache_mm,
+ .cache_page = turbosparc_flush_cache_page,
+ .cache_range = turbosparc_flush_cache_range,
+ .tlb_all = turbosparc_flush_tlb_all,
+ .tlb_mm = turbosparc_flush_tlb_mm,
+ .tlb_page = turbosparc_flush_tlb_page,
+ .tlb_range = turbosparc_flush_tlb_range,
+ .page_to_ram = turbosparc_flush_page_to_ram,
+ .sig_insns = turbosparc_flush_sig_insns,
+ .page_for_dma = turbosparc_flush_page_for_dma,
+};
+
static void __init init_turbosparc(void)
{
srmmu_name = "Fujitsu TurboSparc";
srmmu_modtype = TurboSparc;
-
- BTFIXUPSET_CALL(flush_cache_all, turbosparc_flush_cache_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_mm, turbosparc_flush_cache_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_page, turbosparc_flush_cache_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_range, turbosparc_flush_cache_range, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(flush_tlb_all, turbosparc_flush_tlb_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_mm, turbosparc_flush_tlb_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_page, turbosparc_flush_tlb_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_range, turbosparc_flush_tlb_range, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(__flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(flush_sig_insns, turbosparc_flush_sig_insns, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(flush_page_for_dma, turbosparc_flush_page_for_dma, BTFIXUPCALL_NORM);
-
+ sparc32_cachetlb_ops = &turbosparc_ops;
poke_srmmu = poke_turbosparc;
}
@@ -1850,6 +1288,20 @@ static void __cpuinit poke_tsunami(void)
srmmu_set_mmureg(mreg);
}
+static const struct sparc32_cachetlb_ops tsunami_ops = {
+ .cache_all = tsunami_flush_cache_all,
+ .cache_mm = tsunami_flush_cache_mm,
+ .cache_page = tsunami_flush_cache_page,
+ .cache_range = tsunami_flush_cache_range,
+ .tlb_all = tsunami_flush_tlb_all,
+ .tlb_mm = tsunami_flush_tlb_mm,
+ .tlb_page = tsunami_flush_tlb_page,
+ .tlb_range = tsunami_flush_tlb_range,
+ .page_to_ram = tsunami_flush_page_to_ram,
+ .sig_insns = tsunami_flush_sig_insns,
+ .page_for_dma = tsunami_flush_page_for_dma,
+};
+
static void __init init_tsunami(void)
{
/*
@@ -1860,22 +1312,7 @@ static void __init init_tsunami(void)
srmmu_name = "TI Tsunami";
srmmu_modtype = Tsunami;
-
- BTFIXUPSET_CALL(flush_cache_all, tsunami_flush_cache_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_mm, tsunami_flush_cache_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_page, tsunami_flush_cache_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_cache_range, tsunami_flush_cache_range, BTFIXUPCALL_NORM);
-
-
- BTFIXUPSET_CALL(flush_tlb_all, tsunami_flush_tlb_all, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_mm, tsunami_flush_tlb_mm, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_page, tsunami_flush_tlb_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_tlb_range, tsunami_flush_tlb_range, BTFIXUPCALL_NORM);
-
- BTFIXUPSET_CALL(__flush_page_to_ram, tsunami_flush_page_to_ram, BTFIXUPCALL_NOP);
- BTFIXUPSET_CALL(flush_sig_insns, tsunami_flush_sig_insns, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(flush_page_for_dma, tsunami_flush_page_for_dma, BTFIXUPCALL_NORM);
-
+ sparc32_cachetlb_ops = &tsunami_ops;
poke_srmmu = poke_tsunami;
tsunami_setup_blockops();
@@ -1886,7 +1323,7 @@ static void __cpuinit poke_viking(void)
unsigned long mreg = srmmu_get_mmureg();
static int smp_catch;
- if(viking_mxcc_present) {
+ if (viking_mxcc_present) {
unsigned long mxcc_control = mxcc_get_creg();
mxcc_control |= (MXCC_CTL_ECE | MXCC_CTL_PRE | MXCC_CTL_MCE);
@@ -1923,6 +1360,52 @@ static void __cpuinit poke_viking(void)
srmmu_set_mmureg(mreg);
}
+static struct sparc32_cachetlb_ops viking_ops = {
+ .cache_all = viking_flush_cache_all,
+ .cache_mm = viking_flush_cache_mm,
+ .cache_page = viking_flush_cache_page,
+ .cache_range = viking_flush_cache_range,
+ .tlb_all = viking_flush_tlb_all,
+ .tlb_mm = viking_flush_tlb_mm,
+ .tlb_page = viking_flush_tlb_page,
+ .tlb_range = viking_flush_tlb_range,
+ .page_to_ram = viking_flush_page_to_ram,
+ .sig_insns = viking_flush_sig_insns,
+ .page_for_dma = viking_flush_page_for_dma,
+};
+
+#ifdef CONFIG_SMP
+/* On sun4d the cpu broadcasts local TLB flushes, so we can just
+ * perform the local TLB flush and all the other cpus will see it.
+ * But, unfortunately, there is a bug in the sun4d XBUS backplane
+ * that requires that we add some synchronization to these flushes.
+ *
+ * The bug is that the fifo which keeps track of all the pending TLB
+ * broadcasts in the system is an entry or two too small, so if we
+ * have too many going at once we'll overflow that fifo and lose a TLB
+ * flush resulting in corruption.
+ *
+ * Our workaround is to take a global spinlock around the TLB flushes,
+ * which guarentees we won't ever have too many pending. It's a big
+ * hammer, but a semaphore like system to make sure we only have N TLB
+ * flushes going at once will require SMP locking anyways so there's
+ * no real value in trying any harder than this.
+ */
+static struct sparc32_cachetlb_ops viking_sun4d_smp_ops = {
+ .cache_all = viking_flush_cache_all,
+ .cache_mm = viking_flush_cache_mm,
+ .cache_page = viking_flush_cache_page,
+ .cache_range = viking_flush_cache_range,
+ .tlb_all = sun4dsmp_flush_tlb_all,
+ .tlb_mm = sun4dsmp_flush_tlb_mm,
+ .tlb_page = sun4dsmp_flush_tlb_page,
+ .tlb_range = sun4dsmp_flush_tlb_range,
+ .page_to_ram = viking_flush_page_to_ram,
+ .sig_insns = viking_flush_sig_insns,
+ .page_for_dma = viking_flush_page_for_dma,
+};
+#endif
+
static void __init init_viking(void)
{
unsigned long mreg = srmmu_get_mmureg();
@@ -1933,10 +1416,6 @@ static void __init init_viking(void)
viking_mxcc_present = 0;
msi_set_sync();
- BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(pmd_clear, srmmu_pmd_clear, BTFIXUPCALL_NORM);
- BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_NORM);
-
/*
* We need this to make sure old viking takes no hits
* on it's cache for dma snoops to workaround the
@@ -1944,84 +1423,28 @@ static void __init init_viking(void)
* This is only necessary because of the new way in
* which we use the IOMMU.
*/
- BTFIXUPSET_CALL(flush_page_for_dma, viking_flush_page, BTFIXUPCALL_NORM);
-
+ viking_ops.page_for_dma = viking_flush_page;
+#ifdef CONFIG_SMP
+ viking_sun4d_smp_ops.page_for_dma = viking_flush_page;
+#endif
flush_page_for_dma_global = 0;
} else {
srmmu_name = "TI Viking/MXCC";
viking_mxcc_present = 1;
-
srmmu_cache_pagetables = 1;
-
- /* MXCC vikings lack the DMA snooping bug. */
- BTFIXUPSET_CALL(flush_page_for_dma, vikin