Commit 6de71484 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6: (98 commits)
  sparc: move select of ARCH_SUPPORTS_MSI
  sparc: drop SUN_IO
  sparc: unify sections.h
  sparc: use .data.init_task section for init_thread_union
  sparc: fix array overrun check in of_device_64.c
  sparc: unify module.c
  sparc64: prepare module_64.c for unification
  sparc64: use bit neutral Elf symbols
  sparc: unify module.h
  sparc: introduce CONFIG_BITS
  sparc: fix hardirq.h removal fallout
  sparc64: do not export pus_fs_struct
  sparc: use sparc64 version of scatterlist.h
  sparc: Commonize memcmp assembler.
  sparc: Unify strlen assembler.
  sparc: Add asm/asm.h
  sparc: Kill memcmp_32.S code which has been ifdef'd out for centuries.
  sparc: replace for_each_cpu_mask_nr with for_each_cpu
  sparc: fix sparse warnings in irq_32.c
  sparc: add include guards to kernel.h
  ...
parents 1dff81f2 e3c6d4ee
...@@ -205,13 +205,14 @@ ifeq ($(ARCH),x86_64) ...@@ -205,13 +205,14 @@ ifeq ($(ARCH),x86_64)
SRCARCH := x86 SRCARCH := x86
endif endif
# Where to locate arch specific headers # Additional ARCH settings for sparc
ifeq ($(ARCH),sparc64) ifeq ($(ARCH),sparc64)
hdr-arch := sparc SRCARCH := sparc
else
hdr-arch := $(SRCARCH)
endif endif
# Where to locate arch specific headers
hdr-arch := $(SRCARCH)
KCONFIG_CONFIG ?= .config KCONFIG_CONFIG ?= .config
# SHELL used by kbuild # SHELL used by kbuild
......
This diff is collapsed.
...@@ -15,4 +15,30 @@ config DEBUG_STACK_USAGE ...@@ -15,4 +15,30 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat. This option will slow down process creation somewhat.
config DEBUG_DCFLUSH
bool "D-cache flush debugging"
depends on SPARC64 && DEBUG_KERNEL
config STACK_DEBUG
bool "Stack Overflow Detection Support"
config DEBUG_PAGEALLOC
bool "Debug page memory allocations"
depends on SPARC64 && DEBUG_KERNEL && !HIBERNATION
help
Unmap pages from the kernel linear mapping after free_pages().
This results in a large slowdown, but helps to find certain types
of memory corruptions.
config MCOUNT
bool
depends on SPARC64
depends on STACK_DEBUG || FUNCTION_TRACER
default y
config FRAME_POINTER
bool
depends on MCOUNT
default y
endmenu endmenu
...@@ -2,9 +2,21 @@ ...@@ -2,9 +2,21 @@
# sparc/Makefile # sparc/Makefile
# #
# Makefile for the architecture dependent flags and dependencies on the # Makefile for the architecture dependent flags and dependencies on the
# Sparc. # Sparc and sparc64.
# #
# Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) # Copyright (C) 1994,1996,1998 David S. Miller (davem@caip.rutgers.edu)
# Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
# We are not yet configured - so test on arch
ifeq ($(ARCH),sparc)
KBUILD_DEFCONFIG := sparc32_defconfig
else
KBUILD_DEFCONFIG := sparc64_defconfig
endif
ifeq ($(CONFIG_SPARC32),y)
#####
# sparc32
# #
# #
...@@ -14,6 +26,7 @@ ...@@ -14,6 +26,7 @@
AS := $(AS) -32 AS := $(AS) -32
LDFLAGS := -m elf32_sparc LDFLAGS := -m elf32_sparc
CHECKFLAGS += -D__sparc__ CHECKFLAGS += -D__sparc__
export BITS := 32
#KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
...@@ -25,38 +38,60 @@ CPPFLAGS_vmlinux.lds += -m32 ...@@ -25,38 +38,60 @@ CPPFLAGS_vmlinux.lds += -m32
# Actual linking is done with "make image". # Actual linking is done with "make image".
LDFLAGS_vmlinux = -r LDFLAGS_vmlinux = -r
head-y := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o # Default target
HEAD_Y := $(head-y) all: zImage
else
#####
# sparc64
#
core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64
libs-y += arch/sparc/prom/ arch/sparc/lib/
# Undefine sparc when processing vmlinux.lds - it is used
# And teach CPP we are doing 64 bit builds (for this case)
CPPFLAGS_vmlinux.lds += -m64 -Usparc
LDFLAGS := -m elf64_sparc
export BITS := 64
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 += $(call cc-option,-mtune=ultrasparc3)
KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs
ifeq ($(CONFIG_MCOUNT),y)
KBUILD_CFLAGS += -pg
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/
libs-y += arch/sparc/prom/
libs-y += arch/sparc/lib/
drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/
# Export what is needed by arch/sparc/boot/Makefile # Export what is needed by arch/sparc/boot/Makefile
# Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-) export VMLINUX_INIT VMLINUX_MAIN
INIT_Y := $(patsubst %/, %/built-in.o, $(init-y)) VMLINUX_INIT := $(head-y) $(init-y)
CORE_Y := $(core-y) VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/
CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y)) VMLINUX_MAIN += $(drivers-y) $(net-y)
DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
LIBS_Y1 := $(patsubst %/, %/lib.a, $(libs-y))
LIBS_Y2 := $(patsubst %/, %/built-in.o, $(libs-y))
LIBS_Y := $(LIBS_Y1) $(LIBS_Y2)
ifdef CONFIG_KALLSYMS ifdef CONFIG_KALLSYMS
kallsyms.o := .tmp_kallsyms2.o export kallsyms.o := .tmp_kallsyms2.o
endif endif
export INIT_Y CORE_Y DRIVERS_Y NET_Y LIBS_Y HEAD_Y kallsyms.o
# Default target
all: zImage
boot := arch/sparc/boot boot := arch/sparc/boot
image zImage tftpboot.img: vmlinux image zImage tftpboot.img vmlinux.aout: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
archclean: archclean:
...@@ -65,11 +100,17 @@ archclean: ...@@ -65,11 +100,17 @@ archclean:
# This is the image used for packaging # This is the image used for packaging
KBUILD_IMAGE := $(boot)/zImage KBUILD_IMAGE := $(boot)/zImage
CLEAN_FILES += arch/$(ARCH)/boot/System.map
# Don't use tabs in echo arguments. # Don't use tabs in echo arguments.
ifeq ($(ARCH),sparc)
define archhelp define archhelp
echo '* image - kernel image ($(boot)/image)' echo '* image - kernel image ($(boot)/image)'
echo '* zImage - stripped kernel image ($(boot)/zImage)' echo '* zImage - stripped kernel image ($(boot)/zImage)'
echo ' tftpboot.img - image prepared for tftp' echo ' tftpboot.img - image prepared for tftp'
endef endef
else
define archhelp
echo '* vmlinux - Standard sparc64 kernel'
echo ' vmlinux.aout - a.out kernel for sparc64'
echo ' tftpboot.img - image prepared for tftp'
endef
endif
btfix.S
btfixupprep
image image
zImage
tftpboot.img tftpboot.img
vmlinux.aout vmlinux.aout
piggyback piggyback
...@@ -6,13 +6,16 @@ ...@@ -6,13 +6,16 @@
ROOT_IMG := /usr/src/root.img ROOT_IMG := /usr/src/root.img
ELFTOAOUT := elftoaout ELFTOAOUT := elftoaout
hostprogs-y := piggyback btfixupprep hostprogs-y := piggyback_32 piggyback_64 btfixupprep
targets := tftpboot.img btfix.o btfix.S image targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout
clean-files := System.map
quiet_cmd_elftoaout = ELFTOAOUT $@ quiet_cmd_elftoaout = ELFTOAOUT $@
cmd_elftoaout = $(ELFTOAOUT) $(obj)/image -o $@ cmd_elftoaout = $(ELFTOAOUT) $(obj)/image -o $@
ifeq ($(CONFIG_SPARC32),y)
quiet_cmd_piggy = PIGGY $@ quiet_cmd_piggy = PIGGY $@
cmd_piggy = $(obj)/piggyback $@ $(obj)/System.map $(ROOT_IMG) cmd_piggy = $(obj)/piggyback_32 $@ $(obj)/System.map $(ROOT_IMG)
quiet_cmd_btfix = BTFIX $@ quiet_cmd_btfix = BTFIX $@
cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@
quiet_cmd_sysmap = SYSMAP $(obj)/System.map quiet_cmd_sysmap = SYSMAP $(obj)/System.map
...@@ -37,8 +40,8 @@ define rule_image ...@@ -37,8 +40,8 @@ define rule_image
echo 'cmd_$@ := $(cmd_image)' > $(@D)/.$(@F).cmd echo 'cmd_$@ := $(cmd_image)' > $(@D)/.$(@F).cmd
endef endef
BTOBJS := $(HEAD_Y) $(INIT_Y) BTOBJS := $(patsubst %/, %/built-in.o, $(VMLINUX_INIT))
BTLIBS := $(CORE_Y) $(LIBS_Y) $(DRIVERS_Y) $(NET_Y) BTLIBS := $(patsubst %/, %/built-in.o, $(VMLINUX_MAIN))
LDFLAGS_image := -T arch/sparc/kernel/vmlinux.lds $(BTOBJS) \ LDFLAGS_image := -T arch/sparc/kernel/vmlinux.lds $(BTOBJS) \
--start-group $(BTLIBS) --end-group \ --start-group $(BTLIBS) --end-group \
$(kallsyms.o) $(obj)/btfix.o $(kallsyms.o) $(obj)/btfix.o
...@@ -61,3 +64,28 @@ $(obj)/tftpboot.img: $(obj)/piggyback $(obj)/System.map $(obj)/image FORCE ...@@ -61,3 +64,28 @@ $(obj)/tftpboot.img: $(obj)/piggyback $(obj)/System.map $(obj)/image FORCE
$(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE $(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE
$(call if_changed,btfix) $(call if_changed,btfix)
endif
ifeq ($(CONFIG_SPARC64),y)
quiet_cmd_piggy = PIGGY $@
cmd_piggy = $(obj)/piggyback_64 $@ System.map $(ROOT_IMG)
quiet_cmd_strip = STRIP $@
cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start vmlinux -o $@
# Actual linking
$(obj)/image: vmlinux FORCE
$(call if_changed,strip)
@echo ' kernel: $@ is ready'
$(obj)/tftpboot.img: vmlinux $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE
$(call if_changed,elftoaout)
$(call if_changed,piggy)
@echo ' kernel: $@ is ready'
$(obj)/vmlinux.aout: vmlinux FORCE
$(call if_changed,elftoaout)
@echo ' kernel: $@ is ready'
endif
...@@ -15,8 +15,6 @@ header-y += signal_32.h ...@@ -15,8 +15,6 @@ header-y += signal_32.h
header-y += signal_64.h header-y += signal_64.h
header-y += stat_32.h header-y += stat_32.h
header-y += stat_64.h header-y += stat_64.h
header-y += unistd_32.h
header-y += unistd_64.h
header-y += apc.h header-y += apc.h
header-y += asi.h header-y += asi.h
......
#ifndef _SPARC_ASM_H
#define _SPARC_ASM_H
/* Macros to assist the sharing of assembler code between 32-bit and
* 64-bit sparc.
*/
#ifdef CONFIG_SPARC64
#define BRANCH32(TYPE, PREDICT, DEST) \
TYPE,PREDICT %icc, DEST
#define BRANCH32_ANNUL(TYPE, PREDICT, DEST) \
TYPE,a,PREDICT %icc, DEST
#define BRANCH_REG_ZERO(PREDICT, REG, DEST) \
brz,PREDICT REG, DEST
#define BRANCH_REG_ZERO_ANNUL(PREDICT, REG, DEST) \
brz,a,PREDICT REG, DEST
#define BRANCH_REG_NOT_ZERO(PREDICT, REG, DEST) \
brnz,PREDICT REG, DEST
#define BRANCH_REG_NOT_ZERO_ANNUL(PREDICT, REG, DEST) \
brnz,a,PREDICT REG, DEST
#else
#define BRANCH32(TYPE, PREDICT, DEST) \
TYPE DEST
#define BRANCH32_ANNUL(TYPE, PREDICT, DEST) \
TYPE,a DEST
#define BRANCH_REG_ZERO(PREDICT, REG, DEST) \
cmp REG, 0; \
be DEST
#define BRANCH_REG_ZERO_ANNUL(PREDICT, REG, DEST) \
cmp REG, 0; \
be,a DEST
#define BRANCH_REG_NOT_ZERO(PREDICT, REG, DEST) \
cmp REG, 0; \
bne DEST
#define BRANCH_REG_NOT_ZERO_ANNUL(PREDICT, REG, DEST) \
cmp REG, 0; \
bne,a DEST
#endif
#endif /* _SPARC_ASM_H */
...@@ -112,17 +112,10 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u) ...@@ -112,17 +112,10 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
/* Atomic operations are already serializing */ /* Atomic operations are already serializing */
#ifdef CONFIG_SMP
#define smp_mb__before_atomic_dec() membar_storeload_loadload();
#define smp_mb__after_atomic_dec() membar_storeload_storestore();
#define smp_mb__before_atomic_inc() membar_storeload_loadload();
#define smp_mb__after_atomic_inc() membar_storeload_storestore();
#else
#define smp_mb__before_atomic_dec() barrier() #define smp_mb__before_atomic_dec() barrier()
#define smp_mb__after_atomic_dec() barrier() #define smp_mb__after_atomic_dec() barrier()
#define smp_mb__before_atomic_inc() barrier() #define smp_mb__before_atomic_inc() barrier()
#define smp_mb__after_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier()
#endif
#include <asm-generic/atomic.h> #include <asm-generic/atomic.h>
#endif /* !(__ARCH_SPARC64_ATOMIC__) */ #endif /* !(__ARCH_SPARC64_ATOMIC__) */
...@@ -23,13 +23,8 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); ...@@ -23,13 +23,8 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr);
#include <asm-generic/bitops/non-atomic.h> #include <asm-generic/bitops/non-atomic.h>
#ifdef CONFIG_SMP
#define smp_mb__before_clear_bit() membar_storeload_loadload()
#define smp_mb__after_clear_bit() membar_storeload_storestore()
#else
#define smp_mb__before_clear_bit() barrier() #define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier()
#endif
#include <asm-generic/bitops/ffz.h> #include <asm-generic/bitops/ffz.h>
#include <asm-generic/bitops/__ffs.h> #include <asm-generic/bitops/__ffs.h>
......
...@@ -2713,6 +2713,30 @@ extern unsigned long sun4v_ldc_revoke(unsigned long channel, ...@@ -2713,6 +2713,30 @@ extern unsigned long sun4v_ldc_revoke(unsigned long channel,
*/ */
#define HV_FAST_SET_PERFREG 0x101 #define HV_FAST_SET_PERFREG 0x101
#define HV_N2_PERF_SPARC_CTL 0x0
#define HV_N2_PERF_DRAM_CTL0 0x1
#define HV_N2_PERF_DRAM_CNT0 0x2
#define HV_N2_PERF_DRAM_CTL1 0x3
#define HV_N2_PERF_DRAM_CNT1 0x4
#define HV_N2_PERF_DRAM_CTL2 0x5
#define HV_N2_PERF_DRAM_CNT2 0x6
#define HV_N2_PERF_DRAM_CTL3 0x7
#define HV_N2_PERF_DRAM_CNT3 0x8
#define HV_FAST_N2_GET_PERFREG 0x104
#define HV_FAST_N2_SET_PERFREG 0x105
#ifndef __ASSEMBLY__
extern unsigned long sun4v_niagara_getperf(unsigned long reg,
unsigned long *val);
extern unsigned long sun4v_niagara_setperf(unsigned long reg,
unsigned long val);
extern unsigned long sun4v_niagara2_getperf(unsigned long reg,
unsigned long *val);
extern unsigned long sun4v_niagara2_setperf(unsigned long reg,
unsigned long val);
#endif
/* MMU statistics services. /* MMU statistics services.
* *
* The hypervisor maintains MMU statistics and privileged code provides * The hypervisor maintains MMU statistics and privileged code provides
......
...@@ -12,4 +12,5 @@ ...@@ -12,4 +12,5 @@
#define irq_canonicalize(irq) (irq) #define irq_canonicalize(irq) (irq)
extern void __init init_IRQ(void);
#endif #endif
...@@ -66,6 +66,9 @@ extern void virt_irq_free(unsigned int virt_irq); ...@@ -66,6 +66,9 @@ extern void virt_irq_free(unsigned int virt_irq);
extern void __init init_IRQ(void); extern void __init init_IRQ(void);
extern void fixup_irqs(void); extern void fixup_irqs(void);
extern int register_perfctr_intr(void (*handler)(struct pt_regs *));
extern void release_perfctr_intr(void (*handler)(struct pt_regs *));
static inline void set_softint(unsigned long bits) static inline void set_softint(unsigned long bits)
{ {
__asm__ __volatile__("wr %0, 0x0, %%set_softint" __asm__ __volatile__("wr %0, 0x0, %%set_softint"
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#ifndef _ASM_IRQFLAGS_H #ifndef _ASM_IRQFLAGS_H
#define _ASM_IRQFLAGS_H #define _ASM_IRQFLAGS_H
#include <asm/pil.h>
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
static inline unsigned long __raw_local_save_flags(void) static inline unsigned long __raw_local_save_flags(void)
...@@ -40,9 +42,9 @@ static inline void raw_local_irq_restore(unsigned long flags) ...@@ -40,9 +42,9 @@ static inline void raw_local_irq_restore(unsigned long flags)
static inline void raw_local_irq_disable(void) static inline void raw_local_irq_disable(void)
{ {
__asm__ __volatile__( __asm__ __volatile__(
"wrpr 15, %%pil" "wrpr %0, %%pil"
: /* no outputs */ : /* no outputs */
: /* no inputs */ : "i" (PIL_NORMAL_MAX)
: "memory" : "memory"
); );
} }
......
#ifndef ___ASM_SPARC_MODULE_H #ifndef __SPARC_MODULE_H
#define ___ASM_SPARC_MODULE_H #define __SPARC_MODULE_H
#if defined(__sparc__) && defined(__arch64__) struct mod_arch_specific { };
#include <asm/module_64.h>
#else /*
#include <asm/module_32.h> * Use some preprocessor magic to define the correct symbol
#endif * for sparc32 and sparc64.
#endif * Elf_Addr becomes Elf32_Addr for sparc32 and Elf64_Addr for sparc64
*/
#define ___ELF(a, b, c) a##b##c
#define __ELF(a, b, c) ___ELF(a, b, c)
#define _Elf(t) __ELF(Elf, CONFIG_BITS, t)
#define _ELF(t) __ELF(ELF, CONFIG_BITS, t)
#define Elf_Shdr _Elf(_Shdr)
#define Elf_Sym _Elf(_Sym)
#define Elf_Ehdr _Elf(_Ehdr)
#define Elf_Rela _Elf(_Rela)
#define Elf_Addr _Elf(_Addr)
#define ELF_R_SYM _ELF(_R_SYM)
#define ELF_R_TYPE _ELF(_R_TYPE)
#endif /* __SPARC_MODULE_H */
#ifndef _ASM_SPARC_MODULE_H
#define _ASM_SPARC_MODULE_H
struct mod_arch_specific { };
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
#endif /* _ASM_SPARC_MODULE_H */
#ifndef _ASM_SPARC64_MODULE_H
#define _ASM_SPARC64_MODULE_H
struct mod_arch_specific { };
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
#endif /* _ASM_SPARC64_MODULE_H */
...@@ -170,9 +170,9 @@ struct linux_romvec { ...@@ -170,9 +170,9 @@ struct linux_romvec {
struct linux_nodeops { struct linux_nodeops {
int (*no_nextnode)(int node); int (*no_nextnode)(int node);
int (*no_child)(int node); int (*no_child)(int node);
int (*no_proplen)(int node, char *name); int (*no_proplen)(int node, const char *name);
int (*no_getprop)(int node, char *name, char *val); int (*no_getprop)(int node, const char *name, char *val);
int (*no_setprop)(int node, char *name, char *val, int len); int (*no_setprop)(int node, const char *name, char *val, int len);
char * (*no_nextprop)(int node, char *name); char * (*no_nextprop)(int node, char *name);
}; };
......
...@@ -136,7 +136,7 @@ extern char prom_getchar(void); ...@@ -136,7 +136,7 @@ extern char prom_getchar(void);
extern void prom_putchar(char character); extern void prom_putchar(char character);
/* Prom's internal routines, don't use in kernel/boot code. */ /* Prom's internal routines, don't use in kernel/boot code. */
extern void prom_printf(char *fmt, ...); extern void prom_printf(const char *fmt, ...);
extern void prom_write(const char *buf, unsigned int len); extern void prom_write(const char *buf, unsigned int len);
/* Multiprocessor operations... */ /* Multiprocessor operations... */
...@@ -199,12 +199,12 @@ extern int prom_getsibling(int node); ...@@ -199,12 +199,12 @@ extern int prom_getsibling(int node);
/* Get the length, at the passed node, of the given property type. /* Get the length, at the passed node, of the given property type.
* Returns -1 on error (ie. no such property at this node). * Returns -1 on error (ie. no such property at this node).
*/ */
extern int prom_getproplen(int thisnode, char *property); extern int prom_getproplen(int thisnode, const char *property);
/* Fetch the requested property using the given buffer. Returns /* Fetch the requested property using the given buffer. Returns
* the number of bytes the prom put into your buffer or -1 on error. * the number of bytes the prom put into your buffer or -1 on error.
*/ */
extern int __must_check prom_getproperty(int thisnode, char *property, extern int __must_check prom_getproperty(int thisnode, const char *property,
char *prop_buffer, int propbuf_size); char *prop_buffer, int propbuf_size);
/* Acquire an integer property. */ /* Acquire an integer property. */
...@@ -246,7 +246,7 @@ extern int prom_node_has_property(int node, char *property); ...@@ -246,7 +246,7 @@ extern int prom_node_has_property(int node, char *property);
/* Set the indicated property at the given node with the passed value. /* Set the indicated property at the given node with the passed value.
* Returns the number of bytes of your value that the prom took. * Returns the number of bytes of your value that the prom took.
*/ */
extern int prom_setprop(int node, char *prop_name, char *prop_value, extern int prom_setprop(int node, const char *prop_name, char *prop_value,
int value_size); int value_size);
extern int prom_pathtoinode(char *path); extern int prom_pathtoinode(char *path);
......
...@@ -10,7 +10,12 @@ ...@@ -10,7 +10,12 @@
* *
* In fact any XCALL which has to etrap/rtrap has a problem because * In fact any XCALL which has to etrap/rtrap has a problem because
* it is difficult to prevent rtrap from running BH's, and that would * it is difficult to prevent rtrap from running BH's, and that would
* need to be done if the XCALL arrived while %pil==15. * need to be done if the XCALL arrived while %pil==PIL_NORMAL_MAX.
*
* Finally, in order to handle profiling events even when a
* local_irq_disable() is in progress, we only disable up to level 14
* interrupts. Profile counter overflow interrupts arrive at level
* 15.
*/ */
#define PIL_SMP_CALL_FUNC 1 #define PIL_SMP_CALL_FUNC 1
#define PIL_SMP_RECEIVE_SIGNAL 2 #define PIL_SMP_RECEIVE_SIGNAL 2
...@@ -18,5 +23,7 @@ ...@@ -18,5 +23,7 @@
#define PIL_SMP_CTX_NEW_VERSION 4 #define PIL_SMP_CTX_NEW_VERSION 4
#define PIL_DEVICE_IRQ 5 #define PIL_DEVICE_IRQ 5
#define PIL_SMP_CALL_FUNC_SNGL 6 #define PIL_SMP_CALL_FUNC_SNGL 6
#define PIL_NORMAL_MAX 14
#define PIL_NMI 15
#endif /* !(_SPARC64_PIL_H) */ #endif /* !(_SPARC64_PIL_H) */
#ifndef ___ASM_SPARC_SCATTERLIST_H #ifndef _SPARC_SCATTERLIST_H
#define ___ASM_SPARC_SCATTERLIST_H #define _SPARC_SCATTERLIST_H
#if defined(__sparc__) && defined(__arch64__)
#include <asm/scatterlist_64.h> #include <asm/page.h>
#else #include <asm/types.h>
#include <asm/scatterlist_32.h>
#endif struct scatterlist {
#ifdef CONFIG_DEBUG_SG
unsigned long sg_magic;
#endif #endif
unsigned long page_link;
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
__u32 dma_length;
};
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->dma_length)
#define ISA_DMA_THRESHOLD (~0UL)
#define ARCH_HAS_SG_CHAIN
#endif /* !(_SPARC_SCATTERLIST_H) */
#ifndef _SPARC_SCATTERLIST_H
#define _SPARC_SCATTERLIST_H
#include <linux/types.h>
struct scatterlist {
#ifdef CONFIG_DEBUG_SG
unsigned long sg_magic;
#endif
unsigned long page_link;
unsigned int offset;
unsigned int length;
__u32 dvma_address; /* A place to hang host-specific addresses at. */
__u32 dvma_length;
};
#define sg_dma_address(sg) ((sg)->dvma_address)
#define sg_dma_len(sg) ((sg)->dvma_length)
#define ISA_DMA_THRESHOLD (~0UL)
#define ARCH_HAS_SG_CHAIN
#endif /* !(_SPARC_SCATTERLIST_H) */
#ifndef _SPARC64_SCATTERLIST_H
#define _SPARC64_SCATTERLIST_H
#include <asm/page.h>
#include <asm/types.h>
struct scatterlist {
#ifdef CONFIG_DEBUG_SG
unsigned long sg_magic;
#endif
unsigned long page_link;
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
__u32 dma_length;
};
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->dma_length)
#define ISA_DMA_THRESHOLD (~0UL)
#define ARCH_HAS_SG_CHAIN
#endif /* !(_SPARC64_SCATTERLIST_H) */
#ifndef ___ASM_SPARC_SECTIONS_H #ifndef __SPARC_SECTIONS_H
#define ___ASM_SPARC_SECTIONS_H #define __SPARC_SECTIONS_H
#if defined(__sparc__) && defined(__arch64__)
#include <asm/sections_64.h> /* nothing to see, move along */
#else #include <asm-generic/sections.h>
#include <asm/sections_32.h>
#endif /* sparc entry point */
extern char _start[];
#endif #endif
#ifndef _SPARC_SECTIONS_H
#define _SPARC_SECTIONS_H
#include <asm-generic/sections.h>
#endif
#ifndef _SPARC64_SECTIONS_H
#define _SPARC64_SECTIONS_H
/* nothing to see, move along */
#include <asm-generic/sections.h>
extern char _start[];
#endif
...@@ -13,17 +13,12 @@ ...@@ -13,17 +13,12 @@
* and rebuild your kernel. * and rebuild your kernel.
*/ */
/* All of these locking primitives are expected to work properly /* Because we play games to save cycles in the non-contention case, we
* even in an RMO memory model, which currently is what the kernel * need to be extra careful about branch targets into the "spinning"
* runs in. * code. They live in their own section, but the newer V9 branches
* * have a shorter range than the traditional 32-bit sparc branch
* There is another issue. Because we play games to save cycles * variants. The rule is that the branches that go into and out of
* in the non-contention case, we need to be extra careful about * the spinner sections must be pre-V9 branches.
* branch targets into the "spinning" code. They live in their
* own section, but the newer V9 branches have a shorter range
* than the traditional 32-bit sparc branch variants. The rule
* is that the branches that go into and out of the spinner sections
* must be pre-V9 branches.
*/ */
#define __raw_spin_is_locked(lp) ((lp)->lock != 0) #define __raw_spin_is_locked(lp) ((lp)->lock != 0)
...@@ -38,12 +33,10 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) ...@@ -38,12 +33,10 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
__asm__ __volatile__( __asm__ __volatile__(
"1: ldstub [%1], %0\n" "1: ldstub [%1], %0\n"
" membar #StoreLoad | #StoreStore\n"
" brnz,pn %0, 2f\n" " brnz,pn %0, 2f\n"
" nop\n" " nop\n"
" .subsection 2\n" " .subsection 2\n"
"2: ldub [%1], %0\n" "2: ldub [%1], %0\n"
" membar #LoadLoad\n"
" brnz,pt %0, 2b\n" " brnz,pt %0, 2b\n"
" nop\n" " nop\n"
" ba,a,pt %%xcc, 1b\n" " ba,a,pt %%xcc, 1b\n"
...@@ -59,7 +52,6 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) ...@@ -59,7 +52,6 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
__asm__ __volatile__( __asm__ __volatile__(
" ldstub [%1], %0\n" " ldstub [%1], %0\n"
" membar #StoreLoad | #StoreStore"
: "=r" (result) : "=r" (result)
: "r" (lock) : "r" (lock)
: "memory"); : "memory");
...@@ -70,7 +62,6 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) ...@@ -70,7 +62,6 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
static inline void __raw_spin_unlock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{ {
__asm__ __volatile__( __asm__ __volatile__(
" membar #StoreStore | #LoadStore\n"
" stb %%g0, [%0]" " stb %%g0, [%0]"
: /* No outputs */ : /* No outputs */
: "r" (lock) : "r" (lock)
...@@ -83,14 +74,12 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla ...@@ -83,14 +74,12 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla
__asm__ __volatile__( __asm__ __volatile__(
"1: ldstub [%2], %0\n" "1: ldstub [%2], %0\n"
" membar #StoreLoad | #StoreStore\n"
" brnz,pn %0, 2f\n" " brnz,pn %0, 2f\n"
" nop\n" " nop\n"
" .subsection 2\n" " .subsection 2\n"
"2: rdpr %%pil, %1\n" "2: rdpr %%pil, %1\n"
" wrpr %3, %%pil\n" " wrpr %3, %%pil\n"
"3: ldub [%2], %0\n" "3: ldub [%2], %0\n"
" membar #LoadLoad\n"
" brnz,pt %0, 3b\n" " brnz,pt %0, 3b\n"
" nop\n" " nop\n"
" ba,pt %%xcc, 1b\n" " ba,pt %%xcc, 1b\n"
...@@ -113,12 +102,10 @@ static void inline __read_lock(raw_rwlock_t *lock) ...@@ -113,12 +102,10 @@ static void inline __read_lock(raw_rwlock_t *lock)
"4: add %0, 1, %1\n" "4: add %0, 1, %1\n"
" cas [%2], %0, %1\n" " cas [%2], %0, %1\n"
" cmp %0, %1\n" " cmp %0, %1\n"
" membar #StoreLoad | #StoreStore\n"
" bne,pn %%icc, 1b\n" " bne,pn %%icc, 1b\n"
" nop\n" " nop\n"
" .subsection 2\n" " .subsection 2\n"
"2: ldsw [%2], %0\n" "2: ldsw [%2], %0\n"
" membar #LoadLoad\n"
" brlz,pt %0, 2b\n" " brlz,pt %0, 2b\n"
" nop\n" " nop\n"
" ba,a,pt %%xcc, 4b\n" " ba,a,pt %%xcc, 4b\n"
...@@ -139,7 +126,6 @@ static int inline __read_trylock(raw_rwlock_t *lock) ...@@ -139,7 +126,6 @@ static int inline __read_trylock(raw_rwlock_t *lock)
" add %0, 1, %1\n" " add %0, 1, %1\n"
" cas [%2], %0, %1\n" " cas [%2], %0, %1\n"
" cmp %0, %1\n" " cmp %0, %1\n"
" membar #StoreLoad | #StoreStore\n"
" bne,pn %%icc, 1b\n" " bne,pn %%icc, 1b\n"
" mov 1, %0\n" " mov 1, %0\n"
"2:" "2:"
...@@ -155,7 +141,6 @@ static void inline __read_unlock(raw_rwlock_t *lock) ...@@ -155,7 +141,6 @@ static void inline __read_unlock(raw_rwlock_t *lock)
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
__asm__ __volatile__( __asm__ __volatile__(
" membar #StoreLoad | #LoadLoad\n"
"1: lduw [%2], %0\n" "1: lduw [%2], %0\n"
" sub %0, 1, %1\n" " sub %0, 1, %1\n"
" cas [%2], %0, %1\n" " cas [%2], %0, %1\n"
...@@ -179,12 +164,10 @@ static void inline __write_lock(raw_rwlock_t *lock) ...@@ -179,12 +164,10 @@ static void inline __write_lock(raw_rwlock_t *lock)
"4: or %0, %3, %1\n" "4: or %0, %3, %1\n"
" cas [%2], %0, %1\n" " cas [%2], %0, %1\n"
" cmp %0, %1\n" " cmp %0, %1\n"
" membar #StoreLoad | #StoreStore\n"
" bne,pn %%icc, 1b\n" " bne,pn %%icc, 1b\n"
" nop\n" " nop\n"
" .subsection 2\n" " .subsection 2\n"
"2: lduw [%2], %0\n" "2: lduw [%2], %0\n"
" membar #LoadLoad\n"
" brnz,pt %0, 2b\n" " brnz,pt %0, 2b\n"
" nop\n" " nop\n"
" ba,a,pt %%xcc, 4b\n" " ba,a,pt %%xcc, 4b\n"
...@@ -197,7 +180,6 @@ static void inline __write_lock(raw_rwlock_t *lock) ...@@ -197,7 +180,6 @@ static void inline __write_lock(raw_rwlock_t *lock)
static void inline __write_unlock(raw_rwlock_t *lock) static void inline __write_unlock(raw_rwlock_t *lock)
{ {
__asm__ __volatile__( __asm__ __volatile__(
" membar #LoadStore | #StoreStore\n"
" stw %%g0, [%0]" " stw %%g0, [%0]"
: /* no outputs */ : /* no outputs */
: "r" (lock) : "r" (lock)
...@@ -217,7 +199,6 @@ static int inline __write_trylock(raw_rwlock_t *lock) ...@@ -217,7 +199,6 @@ static int inline __write_trylock(raw_rwlock_t *lock)
" or %0, %4, %1\n" " or %0, %4, %1\n"
" cas [%3], %0, %1\n" " cas [%3], %0, %1\n"
" cmp %0, %1\n" " cmp %0, %1\n"
" membar #StoreLoad | #StoreStore\n"
" bne,pn %%icc, 1b\n" " bne,pn %%icc, 1b\n"
" nop\n" " nop\n"
" mov 1, %2\n" " mov 1, %2\n"
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#ifndef _SPARC64_SPITFIRE_H #ifndef _SPARC64_SPITFIRE_H
#define _SPARC64_SPITFIRE_H #define _SPARC64_SPITFIRE_H
#ifdef CONFIG_SPARC64
#include <asm/asi.h> #include <asm/asi.h>
/* The following register addresses are accessible via ASI_DMMU /* The following register addresses are accessible via ASI_DMMU
...@@ -338,5 +340,5 @@ static inline void cheetah_put_itlb_data(int entry, unsigned long data) ...@@ -338,5 +340,5 @@ static inline void cheetah_put_itlb_data(int entry, unsigned long data)
} }
#endif /* !(__ASSEMBLY__) */ #endif /* !(__ASSEMBLY__) */
#endif /* CONFIG_SPARC64 */
#endif /* !(_SPARC64_SPITFIRE_H) */ #endif /* !(_SPARC64_SPITFIRE_H) */
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
#include <linux/irqflags.h> #include <linux/irqflags.h>
static inline unsigned int probe_irq_mask(unsigned long val)
{
return 0;
}
/* /*
* Sparc (general) CPU types * Sparc (general) CPU types
*/ */
......
...@@ -59,20 +59,9 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ ...@@ -59,20 +59,9 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
: : : "memory"); \ : : : "memory"); \
} while (0) } while (0)
#define mb() \ #define mb() membar_safe("#StoreLoad")
membar_safe("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad") #define rmb() __asm__ __volatile__("":::"memory")
#define rmb() \ #define wmb() __asm__ __volatile__("":::"memory")
membar_safe("#LoadLoad")
#define wmb() \
membar_safe("#StoreStore")
#define membar_storeload() \
membar_safe("#StoreLoad")
#define membar_storeload_storestore() \
membar_safe("#StoreLoad | #StoreStore")
#define membar_storeload_loadload() \
membar_safe("#StoreLoad | #LoadLoad")
#define membar_storestore_loadstore() \
membar_safe("#StoreStore | #LoadStore")
#endif #endif
...@@ -80,20 +69,20 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ ...@@ -80,20 +69,20 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
#define read_barrier_depends() do { } while(0) #define read_barrier_depends() do { } while(0)
#define set_mb(__var, __value) \ #define set_mb(__var, __value) \
do { __var = __value; membar_storeload_storestore(); } while(0) do { __var = __value; membar_safe("#StoreLoad"); } while(0)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define smp_mb() mb() #define smp_mb() mb()
#define smp_rmb() rmb() #define smp_rmb() rmb()
#define smp_wmb() wmb() #define smp_wmb() wmb()
#define smp_read_barrier_depends() read_barrier_depends()
#else #else
#define smp_mb() __asm__ __volatile__("":::"memory") #define smp_mb() __asm__ __volatile__("":::"memory")
#define smp_rmb() __asm__ __volatile__("":::"memory") #define smp_rmb() __asm__ __volatile__("":::"memory")
#define smp_wmb() __asm__ __volatile__("":::"memory") #define smp_wmb() __asm__ __volatile__("":::"memory")
#define smp_read_barrier_depends() do { } while(0)
#endif #endif
#define smp_read_barrier_depends() do { } while(0)
#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory") #define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
#define flushw_all() __asm__ __volatile__("flushw") #define flushw_all() __asm__ __volatile__("flushw")
...@@ -107,11 +96,12 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ ...@@ -107,11 +96,12 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
* arch/sparc64/kernel/smp.c:smp_percpu_timer_interrupt() * arch/sparc64/kernel/smp.c:smp_percpu_timer_interrupt()
* for more information. * for more information.
*/ */
#define reset_pic() \ #define write_pic(__p) \
__asm__ __volatile__("ba,pt %xcc, 99f\n\t" \ __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \
".align 64\n" \ ".align 64\n" \
"99:wr %g0, 0x0, %pic\n\t" \ "99:wr %0, 0x0, %%pic\n\t" \
"rd %pic, %g0") "rd %%pic, %%g0" : : "r" (__p))
#define reset_pic() write_pic(0)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
...@@ -170,6 +160,7 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ ...@@ -170,6 +160,7 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \
"stb %%o5, [%%g6 + %5]\n\t" \ "stb %%o5, [%%g6 + %5]\n\t" \
"rdpr %%cwp, %%o5\n\t" \ "rdpr %%cwp, %%o5\n\t" \
"stb %%o5, [%%g6 + %8]\n\t" \ "stb %%o5, [%%g6 + %8]\n\t" \
"wrpr %%g0, 15, %%pil\n\t" \
"mov %4, %%g6\n\t" \ "mov %4, %%g6\n\t" \
"ldub [%4 + %8], %%g1\n\t" \ "ldub [%4 + %8], %%g1\n\t" \
"wrpr %%g1, %%cwp\n\t" \ "wrpr %%g1, %%cwp\n\t" \
...@@ -180,6 +171,7 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ ...@@ -180,6 +171,7 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \
"ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \
"ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \
"ldx [%%g6 + %9], %%g4\n\t" \ "ldx [%%g6 + %9], %%g4\n\t" \
"wrpr %%g0, 14, %%pil\n\t" \
"brz,pt %%o7, switch_to_pc\n\t" \ "brz,pt %%o7, switch_to_pc\n\t" \
" mov %%g7, %0\n\t" \ " mov %%g7, %0\n\t" \
"sethi %%hi(ret_from_syscall), %%g1\n\t" \ "sethi %%hi(ret_from_syscall), %%g1\n\t" \
...@@ -209,14 +201,12 @@ static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int va ...@@ -209,14 +201,12 @@ static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int va
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
__asm__ __volatile__( __asm__ __volatile__(
" membar #StoreLoad | #LoadLoad\n"
" mov %0, %1\n" " mov %0, %1\n"
"1: lduw [%4], %2\n" "1: lduw [%4], %2\n"
" cas [%4], %2, %0\n" " cas [%4], %2, %0\n"
" cmp %2, %0\n" " cmp %2, %0\n"
" bne,a,pn %%icc, 1b\n" " bne,a,pn %%icc, 1b\n"
" mov %1, %0\n" " mov %1, %0\n"
" membar #StoreLoad | #StoreStore\n"
: "=&r" (val), "=&r" (tmp1), "=&r" (tmp2) : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
: "0" (val), "r" (m) : "0" (val), "r" (m)
: "cc", "memory"); : "cc", "memory");
...@@ -228,14 +218,12 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long ...@@ -228,14 +218,12 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
__asm__ __volatile__( __asm__ __volatile__(
" membar #StoreLoad | #LoadLoad\n"
" mov %0, %1\n" " mov %0, %1\n"
"1: ldx [%4], %2\n" "1: ldx [%4], %2\n"
" casx [%4], %2, %0\n" " casx [%4], %2, %0\n"
" cmp %2, %0\n" " cmp %2, %0\n"
" bne,a,pn %%xcc, 1b\n" " bne,a,pn %%xcc, 1b\n"
" mov %1, %0\n" " mov %1, %0\n"
" membar #StoreLoad | #StoreStore\n"
: "=&r" (val), "=&r" (tmp1), "=&r" (tmp2) : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
: "0" (val), "r" (m) : "0" (val), "r" (m)
: "cc", "memory"); : "cc", "memory");
...@@ -272,9 +260,7 @@ extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noret ...@@ -272,9 +260,7 @@ extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noret
static inline unsigned long static inline unsigned long
__cmpxchg_u32(volatile int *m, int old, int new) __cmpxchg_u32(volatile int *m, int old, int new)
{ {
__asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" __asm__ __volatile__("cas [%2], %3, %0"
"cas [%2], %3, %0\n\t"
"membar #StoreLoad | #StoreStore"
: "=&r" (new) : "=&r" (new)
: "0" (new), "r" (m), "r" (old) : "0" (new), "r" (m), "r" (old)
: "memory"); : "memory");
...@@ -285,9 +271,7 @@ __cmpxchg_u32(volatile int *m, int old, int new) ...@@ -285,9 +271,7 @@ __cmpxchg_u32(volatile int *m, int old, int new)
static inline unsigned long static inline unsigned long
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
{ {
__asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" __asm__ __volatile__("casx [%2], %3, %0"
"casx [%2], %3, %0\n\t"
"membar #StoreLoad | #StoreStore"
: "=&r" (new) : "=&r" (new)
: "0" (new), "r" (m), "r" (old) : "0" (new), "r" (m), "r" (old)
: "memory"); : "memory");
......
...@@ -50,8 +50,6 @@ ...@@ -50,8 +50,6 @@
#define TSB_TAG_INVALID_BIT 46 #define TSB_TAG_INVALID_BIT 46
#define TSB_TAG_INVALID_HIGH (1 << (TSB_TAG_INVALID_BIT - 32)) #define TSB_TAG_INVALID_HIGH (1 << (TSB_TAG_INVALID_BIT - 32))
#define TSB_MEMBAR membar #StoreStore
/* Some cpus support physical address quad loads. We want to use /* Some cpus support physical address quad loads. We want to use
* those if possible so we don't need to hard-lock the TSB mapping * those if possible so we don't need to hard-lock the TSB mapping
* into the TLB. We encode some instruction patching in order to * into the TLB. We encode some instruction patching in order to
...@@ -128,13 +126,11 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; ...@@ -128,13 +126,11 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
cmp REG1, REG2; \ cmp REG1, REG2; \
bne,pn %icc, 99b; \ bne,pn %icc, 99b; \
nop; \ nop; \
TSB_MEMBAR
#define TSB_WRITE(TSB, TTE, TAG) \ #define TSB_WRITE(TSB, TTE, TAG) \
add TSB, 0x8, TSB; \ add TSB, 0x8, TSB; \
TSB_STORE(TSB, TTE); \ TSB_STORE(TSB, TTE); \
sub TSB, 0x8, TSB; \ sub TSB, 0x8, TSB; \
TSB_MEMBAR; \
TSB_STORE(TSB, TAG); TSB_STORE(TSB, TAG);
#define KTSB_LOAD_QUAD(TSB, REG) \ #define KTSB_LOAD_QUAD(TSB, REG) \
...@@ -153,13 +149,11 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; ...@@ -153,13 +149,11 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
cmp REG1, REG2; \ cmp REG1, REG2; \
bne,pn %icc, 99b; \ bne,pn %icc, 99b; \
nop; \ nop; \
TSB_MEMBAR
#define KTSB_WRITE(TSB, TTE, TAG) \ #define KTSB_WRITE(TSB, TTE, TAG) \
add TSB, 0x8, TSB; \ add TSB, 0x8, TSB; \
stxa TTE, [TSB] ASI_N; \ stxa TTE, [TSB] ASI_N; \
sub TSB, 0x8, TSB; \ sub TSB, 0x8, TSB; \
TSB_MEMBAR; \
stxa TAG, [TSB] ASI_N; stxa TAG, [TSB] ASI_N;
/* Do a kernel page table walk. Leaves physical PTE pointer in /* Do a kernel page table walk. Leaves physical PTE pointer in
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define _SPARC64_TTABLE_H #define _SPARC64_TTABLE_H
#include <asm/utrap.h> #include <asm/utrap.h>
#include <asm/pil.h>
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
#include <asm/thread_info.h> #include <asm/thread_info.h>
...@@ -123,7 +124,7 @@ ...@@ -123,7 +124,7 @@
#define TRAP_IRQ(routine, level) \ #define TRAP_IRQ(routine, level) \
rdpr %pil, %g2; \ rdpr %pil, %g2; \
wrpr %g0, 15, %pil; \ wrpr %g0, PIL_NORMAL_MAX, %pil; \
sethi %hi(1f-4), %g7; \ sethi %hi(1f-4), %g7; \
ba,pt %xcc, etrap_irq; \ ba,pt %xcc, etrap_irq; \
or %g7, %lo(1f-4), %g7; \ or %g7, %lo(1f-4), %g7; \
...@@ -143,7 +144,7 @@ ...@@ -143,7 +144,7 @@
#define TRAP_IRQ(routine, level) \ #define TRAP_IRQ(routine, level) \
rdpr %pil, %g2; \ rdpr %pil, %g2; \
wrpr %g0, 15, %pil; \ wrpr %g0, PIL_NORMAL_MAX, %pil; \
ba,pt %xcc, etrap_irq; \ ba,pt %xcc, etrap_irq; \
rd %pc, %g7; \ rd %pc, %g7; \
mov level, %o0; \ mov level, %o0; \
...@@ -153,6 +154,16 @@ ...@@ -153,6 +154,16 @@
#endif #endif
#define TRAP_NMI_IRQ(routine, level) \
rdpr %pil, %g2; \
wrpr %g0, PIL_NMI, %pil; \
ba,pt %xcc, etrap_irq; \
rd %pc, %g7; \
mov level, %o0; \
call routine; \
add %sp, PTREGS_OFF, %o1; \
ba,a,pt %xcc, rtrap_nmi;
#define TRAP_IVEC TRAP_NOSAVE(do_ivec) #define TRAP_IVEC TRAP_NOSAVE(do_ivec)
#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl) #define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -2,25 +2,98 @@ ...@@ -2,25 +2,98 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
extra-y := head.o init_task.o vmlinux.lds asflags-y := -ansi
ccflags-y := -Werror
EXTRA_AFLAGS := -ansi extra-y := head_$(BITS).o
extra-y += init_task.o
extra-y += vmlinux.lds
IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o
obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ obj-$(CONFIG_SPARC32) += etrap_32.o
process.o signal.o ioport.o setup.o idprom.o \ obj-$(CONFIG_SPARC32) += rtrap_32.o
sys_sparc.o systbls.o \ obj-y += traps_$(BITS).o
time.o windows.o cpu.o devices.o \
tadpole.o tick14.o ptrace.o \
unaligned.o una_asm.o muldiv.o \
prom.o of_device.o devres.o dma.o
devres-y = ../../../kernel/irq/devres.o # IRQ
obj-y += irq_$(BITS).o
obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4c_irq.o sun4d_irq.o
obj-$(CONFIG_PCI) += pcic.o obj-y += process_$(BITS).o
obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o obj-y += signal_$(BITS).o
obj-$(CONFIG_SUN_AUXIO) += auxio.o obj-$(CONFIG_SPARC32) += ioport.o
obj-y += setup_$(BITS).o
obj-y += idprom.o
obj-y += sys_sparc_$(BITS).o
obj-$(CONFIG_SPARC32) += systbls_32.o
obj-y += time_$(BITS).o
obj-$(CONFIG_SPARC32) += windows.o
obj-y += cpu.o
obj-$(CONFIG_SPARC32) += devices.o
obj-$(CONFIG_SPARC32) += tadpole.o
obj-$(CONFIG_SPARC32) += tick14.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_$(BITS).o
obj-$(CONFIG_SPARC64) += prom_irqtrans.o
obj-$(CONFIG_SPARC64) += reboot.o
obj-$(CONFIG_SPARC64) += sysfs.o
obj-$(CONFIG_SPARC64) += iommu.o
obj-$(CONFIG_SPARC64) += central.o
obj-$(CONFIG_SPARC64) += starfire.o
obj-$(CONFIG_SPARC64) += power.o
obj-$(CONFIG_SPARC64) += sbus.o
obj-$(CONFIG_SPARC64) += ebus.o
obj-$(CONFIG_SPARC64) += visemul.o
obj-$(CONFIG_SPARC64) += hvapi.o
obj-$(CONFIG_SPARC64) += sstate.o
obj-$(CONFIG_SPARC64) += mdesc.o
# sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation
obj-$(CONFIG_SPARC32) += devres.o
devres-y := ../../../kernel/irq/devres.o
obj-$(CONFIG_SPARC32) += dma.o
obj-$(CONFIG_SPARC32_PCI) += pcic.o
obj-$(CONFIG_SMP) += trampoline_$(BITS).o smp_$(BITS).o
obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o
obj-$(CONFIG_SPARC64_SMP) += hvtramp.o
obj-y += auxio_$(BITS).o
obj-$(CONFIG_SUN_PM) += apc.o pmc.o obj-$(CONFIG_SUN_PM) += apc.o pmc.o
obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_MODULES) += sparc_ksyms_$(BITS).o
obj-$(CONFIG_SPARC_LED) += led.o obj-$(CONFIG_SPARC_LED) += led.o
obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB) += kgdb_$(BITS).o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
CFLAGS_REMOVE_ftrace.o := -pg
obj-$(CONFIG_STACKTRACE) += stacktrace.o
# sparc64 PCI
obj-$(CONFIG_SPARC64_PCI) += pci.o pci_common.o psycho_common.o
obj-$(CONFIG_SPARC64_PCI) += pci_psycho.o pci_sabre.o pci_schizo.o
obj-$(CONFIG_SPARC64_PCI) += pci_sun4v.o pci_sun4v_asm.o pci_fire.o
obj-$(CONFIG_PCI_MSI) += pci_msi.o
obj-$(CONFIG_COMPAT) += sys32.o sys_sparc32.o signal32.o
# sparc64 cpufreq
obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o
obj-$(CONFIG_US3_MC) += chmc.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
obj-$(CONFIG_AUDIT) += audit.o
audit--$(CONFIG_AUDIT) := compat_audit.o
obj-$(CONFIG_COMPAT) += $(audit--y)
...@@ -14,15 +14,28 @@ ...@@ -14,15 +14,28 @@
// #include <linux/mm.h> // #include <linux/mm.h>
#include <linux/kbuild.h> #include <linux/kbuild.h>
int foo(void) #ifdef CONFIG_SPARC32
int sparc32_foo(void)
{ {
DEFINE(AOFF_task_thread, offsetof(struct task_struct, thread));
BLANK();
DEFINE(AOFF_thread_fork_kpsr, DEFINE(AOFF_thread_fork_kpsr,
offsetof(struct thread_struct, fork_kpsr)); offsetof(struct thread_struct, fork_kpsr));
return 0;
}
#else
int sparc64_foo(void)
{
return 0;
}
#endif
int foo(void)
{
BLANK();
DEFINE(AOFF_task_thread, offsetof(struct task_struct, thread));
BLANK(); BLANK();
DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context)); DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context));
/* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */ /* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */
return 0; return 0;
} }
...@@ -27,73 +27,55 @@ enum auxio_type { ...@@ -27,73 +27,55 @@ enum auxio_type {
static enum auxio_type auxio_devtype = AUXIO_TYPE_NODEV; static enum auxio_type auxio_devtype = AUXIO_TYPE_NODEV;
static DEFINE_SPINLOCK(auxio_lock); static DEFINE_SPINLOCK(auxio_lock);
static void __auxio_sbus_set(u8 bits_on, u8 bits_off) static void __auxio_rmw(u8 bits_on, u8 bits_off, int ebus)
{ {
if (auxio_register) { if (auxio_register) {
unsigned char regval;
unsigned long flags; unsigned long flags;
unsigned char newval; u8 regval, newval;
spin_lock_irqsave(&auxio_lock, flags); spin_lock_irqsave(&auxio_lock, flags);
regval = sbus_readb(auxio_register); regval = (ebus ?
(u8) readl(auxio_register) :
sbus_readb(auxio_register));
newval = regval | bits_on; newval = regval | bits_on;
newval &= ~bits_off; newval &= ~bits_off;
if (!ebus)
newval &= ~AUXIO_AUX1_MASK; newval &= ~AUXIO_AUX1_MASK;
if (ebus)
writel((u32) newval, auxio_register);
else
sbus_writeb(newval, auxio_register); sbus_writeb(newval, auxio_register);
spin_unlock_irqrestore(&auxio_lock, flags); spin_unlock_irqrestore(&auxio_lock, flags);
} }
} }
static void __auxio_ebus_set(u8 bits_on, u8 bits_off) static void __auxio_set_bit(u8 bit, int on, int ebus)
{ {
if (auxio_register) { u8 bits_on = (ebus ? AUXIO_PCIO_LED : AUXIO_AUX1_LED);
unsigned char regval; u8 bits_off = 0;
unsigned long flags;
unsigned char newval;
spin_lock_irqsave(&auxio_lock, flags);
regval = (u8)readl(auxio_register);
newval = regval | bits_on;
newval &= ~bits_off;
writel((u32)newval, auxio_register);
spin_unlock_irqrestore(&auxio_lock, flags); if (!on) {
u8 tmp = bits_off;
bits_off = bits_on;
bits_on = tmp;
} }
} __auxio_rmw(bits_on, bits_off, ebus);
static inline void __auxio_ebus_set_led(int on)
{
(on) ? __auxio_ebus_set(AUXIO_PCIO_LED, 0) :
__auxio_ebus_set(0, AUXIO_PCIO_LED) ;
}
static inline void __auxio_sbus_set_led(int on)
{
(on) ? __auxio_sbus_set(AUXIO_AUX1_LED, 0) :
__auxio_sbus_set(0, AUXIO_AUX1_LED) ;
} }
void auxio_set_led(int on) void auxio_set_led(int on)
{ {
switch(auxio_devtype) { int ebus = auxio_devtype == AUXIO_TYPE_EBUS;
case AUXIO_TYPE_SBUS: u8 bit;
__auxio_sbus_set_led(on);
break; bit = (ebus ? AUXIO_PCIO_LED : AUXIO_AUX1_LED);
case AUXIO_TYPE_EBUS: __auxio_set_bit(bit, on, ebus);
__auxio_ebus_set_led(on);
break;
default:
break;
}
} }
static inline void __auxio_sbus_set_lte(int on) static void __auxio_sbus_set_lte(int on)
{ {
(on) ? __auxio_sbus_set(AUXIO_AUX1_LTE, 0) : __auxio_set_bit(AUXIO_AUX1_LTE, on, 0);
__auxio_sbus_set(0, AUXIO_AUX1_LTE) ;
} }
void auxio_set_lte(int on) void auxio_set_lte(int on)
......
...@@ -102,7 +102,7 @@ cheetah_plus_dcpe_trap_vector: ...@@ -102,7 +102,7 @@ cheetah_plus_dcpe_trap_vector:
.type do_cheetah_plus_data_parity,#function .type do_cheetah_plus_data_parity,#function
do_cheetah_plus_data_parity: do_cheetah_plus_data_parity:
rdpr %pil, %g2 rdpr %pil, %g2
wrpr %g0, 15, %pil wrpr %g0, PIL_NORMAL_MAX, %pil
ba,pt %xcc, etrap_irq ba,pt %xcc, etrap_irq
rd %pc, %g7 rd %pc, %g7
#ifdef CONFIG_TRACE_IRQFLAGS #ifdef CONFIG_TRACE_IRQFLAGS
...@@ -144,7 +144,7 @@ cheetah_plus_icpe_trap_vector: ...@@ -144,7 +144,7 @@ cheetah_plus_icpe_trap_vector:
.type do_cheetah_plus_insn_parity,#function .type do_cheetah_plus_insn_parity,#function
do_cheetah_plus_insn_parity: do_cheetah_plus_insn_parity:
rdpr %pil, %g2 rdpr %pil, %g2
wrpr %g0, 15, %pil wrpr %g0, PIL_NORMAL_MAX, %pil
ba,pt %xcc, etrap_irq ba,pt %xcc, etrap_irq
rd %pc, %g7 rd %pc, %g7
#ifdef CONFIG_TRACE_IRQFLAGS #ifdef CONFIG_TRACE_IRQFLAGS
...@@ -492,7 +492,7 @@ cheetah_fast_ecc: ...@@ -492,7 +492,7 @@ cheetah_fast_ecc:
.type c_fast_ecc,#function .type c_fast_ecc,#function
c_fast_ecc: c_fast_ecc:
rdpr %pil, %g2 rdpr %pil, %g2
wrpr %g0, 15, %pil wrpr %g0, PIL_NORMAL_MAX, %pil
ba,pt %xcc, etrap_irq ba,pt %xcc, etrap_irq
rd %pc, %g7 rd %pc, %g7
#ifdef CONFIG_TRACE_IRQFLAGS #ifdef CONFIG_TRACE_IRQFLAGS
...@@ -528,7 +528,7 @@ cheetah_cee: ...@@ -528,7 +528,7 @@ cheetah_cee:
.type c_cee,#function .type c_cee,#function
c_cee: c_cee:
rdpr %pil, %g2 rdpr %pil, %g2
wrpr %g0, 15, %pil wrpr %g0, PIL_NORMAL_MAX, %pil
ba,pt %xcc, etrap_irq ba,pt %xcc, etrap_irq
rd %pc, %g7 rd %pc, %g7
#ifdef CONFIG_TRACE_IRQFLAGS #ifdef CONFIG_TRACE_IRQFLAGS
...@@ -564,7 +564,7 @@ cheetah_deferred_trap: ...@@ -564,7 +564,7 @@ cheetah_deferred_trap:
.type c_deferred,#function .type c_deferred,#function
c_deferred: c_deferred:
rdpr %pil, %g2 rdpr %pil, %g2
wrpr %g0, 15, %pil wrpr %g0, PIL_NORMAL_MAX, %pil
ba,pt %xcc, etrap_irq ba,pt %xcc, etrap_irq
rd %pc, %g7 rd %pc, %g7
#ifdef CONFIG_TRACE_IRQFLAGS #ifdef CONFIG_TRACE_IRQFLAGS
......
#include <asm/unistd_32.h> #define __32bit_syscall_numbers__
#include <asm/unistd.h>
unsigned sparc32_dir_class[] = { unsigned sparc32_dir_class[] = {
#include <asm-generic/audit_dir_write.h> #include <asm-generic/audit_dir_write.h>
......
This diff is collapsed.
...@@ -133,14 +133,12 @@ void __init device_scan(void) ...@@ -133,14 +133,12 @@ void __init device_scan(void)
#endif /* !CONFIG_SMP */ #endif /* !CONFIG_SMP */
cpu_probe(); cpu_probe();
#ifdef CONFIG_SUN_AUXIO
{ {
extern void auxio_probe(void); extern void auxio_probe(void);
extern void auxio_power_probe(void); extern void auxio_power_probe(void);
auxio_probe(); auxio_probe();
auxio_power_probe(); auxio_power_probe();
} }
#endif
clock_stop_probe(); clock_stop_probe();
if (ARCH_SUN4C) if (ARCH_SUN4C)
......
...@@ -5,9 +5,43 @@ ...@@ -5,9 +5,43 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
extern const char *sparc_cpu_type; /* irq */
extern const char *sparc_fpu_type; extern void handler_irq(int irq, struct pt_regs *regs);
#ifdef CONFIG_SPARC32
/* traps */
extern void do_hw_interrupt(struct pt_regs *regs, unsigned long type);
extern void do_illegal_instruction(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void do_priv_instruction(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc,
unsigned long npc,
unsigned long psr);
extern void do_fpd_trap(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void do_fpe_trap(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void handle_tag_overflow(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void handle_watchpoint(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void handle_reg_access(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void handle_cp_disabled(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
extern void handle_cp_exception(struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
/* entry.S */
extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
void *fpqueue, unsigned long *fpqdepth);
extern void fpload(unsigned long *fpregs, unsigned long *fsr);
#else /* CONFIG_SPARC32 */
extern void __init per_cpu_patch(void); extern void __init per_cpu_patch(void);
extern void __init sun4v_patch(void); extern void __init sun4v_patch(void);
extern void __init boot_cpu_id_too_large(int cpu); extern void __init boot_cpu_id_too_large(int cpu);
...@@ -188,8 +222,8 @@ struct ino_bucket { ...@@ -188,8 +222,8 @@ struct ino_bucket {
extern struct ino_bucket *ivector_table; extern struct ino_bucket *ivector_table;
extern unsigned long ivector_table_pa; extern unsigned long ivector_table_pa;
extern void handler_irq(int irq, struct pt_regs *regs);
extern void init_irqwork_curcpu(void); extern void init_irqwork_curcpu(void);
extern void __cpuinit sun4v_register_mondo_queues(int this_cpu); extern void __cpuinit sun4v_register_mondo_queues(int this_cpu);
#endif /* CONFIG_SPARC32 */
#endif /* _ENTRY_H */ #endif /* _ENTRY_H */
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
#include <asm/mmu.h> #include <asm/mmu.h>
#define TASK_REGOFF (THREAD_SIZE-TRACEREG_SZ-STACKFRAME_SZ) #define TASK_REGOFF (THREAD_SIZE-TRACEREG_SZ-STACKFRAME_SZ)
#define ETRAP_PSTATE1 (PSTATE_RMO | PSTATE_PRIV) #define ETRAP_PSTATE1 (PSTATE_TSO | PSTATE_PRIV)
#define ETRAP_PSTATE2 \ #define ETRAP_PSTATE2 \
(PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE) (PSTATE_TSO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE)
/* /*
* On entry, %g7 is return address - 0x4. * On entry, %g7 is return address - 0x4.
...@@ -130,7 +130,7 @@ etrap_save: save %g2, -STACK_BIAS, %sp ...@@ -130,7 +130,7 @@ etrap_save: save %g2, -STACK_BIAS, %sp
stx %g6, [%sp + PTREGS_OFF + PT_V9_G6] stx %g6, [%sp + PTREGS_OFF + PT_V9_G6]
stx %g7, [%sp + PTREGS_OFF + PT_V9_G7] stx %g7, [%sp + PTREGS_OFF + PT_V9_G7]
or %l7, %l0, %l7 or %l7, %l0, %l7
sethi %hi(TSTATE_RMO | TSTATE_PEF), %l0 sethi %hi(TSTATE_TSO | TSTATE_PEF), %l0
or %l7, %l0, %l7 or %l7, %l0, %l7
wrpr %l2, %tnpc wrpr %l2, %tnpc
wrpr %l7, (TSTATE_PRIV | TSTATE_IE), %tstate wrpr %l7, (TSTATE_PRIV | TSTATE_IE), %tstate
......
...@@ -990,7 +990,7 @@ sun4c_continue_boot: ...@@ -990,7 +990,7 @@ sun4c_continue_boot:
/* Zero out our BSS section. */ /* Zero out our BSS section. */
set __bss_start , %o0 ! First address of BSS set __bss_start , %o0 ! First address of BSS
set end , %o1 ! Last address of BSS set _end , %o1 ! Last address of BSS
add %o0, 0x1, %o0 add %o0, 0x1, %o0
1: 1:
stb %g0, [%o0] stb %g0, [%o0]
......
...@@ -706,7 +706,7 @@ setup_trap_table: ...@@ -706,7 +706,7 @@ setup_trap_table:
andn %l0, PSTATE_IE, %o1 andn %l0, PSTATE_IE, %o1
wrpr %o1, 0x0, %pstate wrpr %o1, 0x0, %pstate
rdpr %pil, %l1 rdpr %pil, %l1
wrpr %g0, 15, %pil wrpr %g0, PIL_NORMAL_MAX, %pil
/* Make the firmware call to jump over to the Linux trap table. */ /* Make the firmware call to jump over to the Linux trap table. */
sethi %hi(is_sun4v), %o0 sethi %hi(is_sun4v), %o0
...@@ -825,8 +825,8 @@ setup_tba: ...@@ -825,8 +825,8 @@ setup_tba:
restore restore
sparc64_boot_end: sparc64_boot_end:
#include "etrap.S" #include "etrap_64.S"
#include "rtrap.S" #include "rtrap_64.S"
#include "winfixup.S" #include "winfixup.S"
#include "fpu_traps.S" #include "fpu_traps.S"
#include "ivec.S" #include "ivec.S"
...@@ -882,7 +882,7 @@ swapper_4m_tsb: ...@@ -882,7 +882,7 @@ swapper_4m_tsb:
! 0x0000000000428000 ! 0x0000000000428000
#include "systbls.S" #include "systbls_64.S"
.data .data
.align 8 .align 8
......
...@@ -766,3 +766,35 @@ ENTRY(sun4v_mmu_demap_all) ...@@ -766,3 +766,35 @@ ENTRY(sun4v_mmu_demap_all)
retl retl
nop nop
ENDPROC(sun4v_mmu_demap_all) ENDPROC(sun4v_mmu_demap_all)
ENTRY(sun4v_niagara_getperf)
mov %o0, %o4
mov HV_FAST_GET_PERFREG, %o5
ta HV_FAST_TRAP
stx %o1, [%o4]
retl
nop
ENDPROC(sun4v_niagara_getperf)
ENTRY(sun4v_niagara_setperf)
mov HV_FAST_SET_PERFREG, %o5
ta HV_FAST_TRAP
retl
nop
ENDPROC(sun4v_niagara_setperf)
ENTRY(sun4v_niagara2_getperf)
mov %o0, %o4
mov HV_FAST_N2_GET_PERFREG, %o5
ta HV_FAST_TRAP
stx %o1, [%o4]
retl
nop
ENDPROC(sun4v_niagara2_getperf)
ENTRY(sun4v_niagara2_setperf)
mov HV_FAST_N2_SET_PERFREG, %o5
ta HV_FAST_TRAP
retl
nop
ENDPROC(sun4v_niagara2_setperf)
/* hvtramp.S: Hypervisor start-cpu trampoline code. /* hvtramp.S: Hypervisor start-cpu trampoline code.
* *
* Copyright (C) 2007 David S. Miller <davem@davemloft.net> * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
*/ */
#include <linux/init.h> #include <linux/init.h>
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/head.h> #include <asm/head.h>
#include <asm/asi.h> #include <asm/asi.h>
#include <asm/pil.h>
__CPUINIT __CPUINIT
.align 8 .align 8
...@@ -32,7 +33,7 @@ ...@@ -32,7 +33,7 @@
*/ */
hv_cpu_startup: hv_cpu_startup:
SET_GL(0) SET_GL(0)
wrpr %g0, 15, %pil wrpr %g0, PIL_NORMAL_MAX, %pil
wrpr %g0, 0, %canrestore wrpr %g0, 0, %canrestore
wrpr %g0, 0, %otherwin wrpr %g0, 0, %otherwin
wrpr %g0, 6, %cansave wrpr %g0, 6, %cansave
......
...@@ -11,35 +11,37 @@ ...@@ -11,35 +11,37 @@
#include <asm/oplib.h> #include <asm/oplib.h>
#include <asm/idprom.h> #include <asm/idprom.h>
#include <asm/machines.h> /* Fun with Sun released architectures. */
struct idprom *idprom; struct idprom *idprom;
static struct idprom idprom_buffer; static struct idprom idprom_buffer;
#ifdef CONFIG_SPARC32
#include <asm/machines.h> /* Fun with Sun released architectures. */
/* Here is the master table of Sun machines which use some implementation /* Here is the master table of Sun machines which use some implementation
* of the Sparc CPU and have a meaningful IDPROM machtype value that we * of the Sparc CPU and have a meaningful IDPROM machtype value that we
* know about. See asm-sparc/machines.h for empirical constants. * know about. See asm-sparc/machines.h for empirical constants.
*/ */
static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = { static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
/* First, Sun4's */ /* First, Sun4's */
{ "Sun 4/100 Series", (SM_SUN4 | SM_4_110) }, { .name = "Sun 4/100 Series", .id_machtype = (SM_SUN4 | SM_4_110) },
{ "Sun 4/200 Series", (SM_SUN4 | SM_4_260) }, { .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) },
{ "Sun 4/300 Series", (SM_SUN4 | SM_4_330) }, { .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) },
{ "Sun 4/400 Series", (SM_SUN4 | SM_4_470) }, { .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) },
/* Now, Sun4c's */ /* Now, Sun4c's */
{ "Sun4c SparcStation 1", (SM_SUN4C | SM_4C_SS1) }, { .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) },
{ "Sun4c SparcStation IPC", (SM_SUN4C | SM_4C_IPC) }, { .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) },
{ "Sun4c SparcStation 1+", (SM_SUN4C | SM_4C_SS1PLUS) }, { .name = "Sun4c SparcStation 1+", .id_machtype = (SM_SUN4C | SM_4C_SS1PLUS) },
{ "Sun4c SparcStation SLC", (SM_SUN4C | SM_4C_SLC) }, { .name = "Sun4c SparcStation SLC", .id_machtype = (SM_SUN4C | SM_4C_SLC) },
{ "Sun4c SparcStation 2", (SM_SUN4C | SM_4C_SS2) }, { .name = "Sun4c SparcStation 2", .id_machtype = (SM_SUN4C | SM_4C_SS2) },
{ "Sun4c SparcStation ELC", (SM_SUN4C | SM_4C_ELC) }, { .name = "Sun4c SparcStation ELC", .id_machtype = (SM_SUN4C | SM_4C_ELC) },
{ "Sun4c SparcStation IPX", (SM_SUN4C | SM_4C_IPX) }, { .name = "Sun4c SparcStation IPX", .id_machtype = (SM_SUN4C | SM_4C_IPX) },
/* Finally, early Sun4m's */ /* Finally, early Sun4m's */
{ "Sun4m SparcSystem600", (SM_SUN4M | SM_4M_SS60) }, { .name = "Sun4m SparcSystem600", .id_machtype = (SM_SUN4M | SM_4M_SS60) },
{ "Sun4m SparcStation10/20", (SM_SUN4M | SM_4M_SS50) }, { .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) },
{ "Sun4m SparcStation5", (SM_SUN4M | SM_4M_SS40) }, { .name = "Sun4m SparcStation5", .id_machtype = (SM_SUN4M | SM_4M_SS40) },
/* One entry for the OBP arch's which are sun4d, sun4e, and newer sun4m's */ /* One entry for the OBP arch's which are sun4d, sun4e, and newer sun4m's */
{ "Sun4M OBP based system", (SM_SUN4M_OBP | 0x0) } }; { .name = "Sun4M OBP based system", .id_machtype = (SM_SUN4M_OBP | 0x0) } };
static void __init display_system_type(unsigned char machtype) static void __init display_system_type(unsigned char machtype)
{ {
...@@ -47,21 +49,25 @@ static void __init display_system_type(unsigned char machtype) ...@@ -47,21 +49,25 @@ static void __init display_system_type(unsigned char machtype)
register int i; register int i;
for (i = 0; i < NUM_SUN_MACHINES; i++) { for (i = 0; i < NUM_SUN_MACHINES; i++) {
if(Sun_Machines[i].id_machtype == machtype) { if (Sun_Machines[i].id_machtype == machtype) {
if (machtype != (SM_SUN4M_OBP | 0x00) || if (machtype != (SM_SUN4M_OBP | 0x00) ||
prom_getproperty(prom_root_node, "banner-name", prom_getproperty(prom_root_node, "banner-name",
sysname, sizeof(sysname)) <= 0) sysname, sizeof(sysname)) <= 0)
printk("TYPE: %s\n", Sun_Machines[i].name); printk(KERN_WARNING "TYPE: %s\n",
Sun_Machines[i].name);
else else
printk("TYPE: %s\n", sysname); printk(KERN_WARNING "TYPE: %s\n", sysname);
return; return;
} }
} }
prom_printf("IDPROM: Bogus id_machtype value, 0x%x\n", machtype); prom_printf("IDPROM: Warning, bogus id_machtype value, 0x%x\n", machtype);
prom_halt();
} }
#else
static void __init display_system_type(unsigned char machtype)
{
}
#endif
/* Calculate the IDPROM checksum (xor of the data bytes). */ /* Calculate the IDPROM checksum (xor of the data bytes). */
static unsigned char __init calc_idprom_cksum(struct idprom *idprom) static unsigned char __init calc_idprom_cksum(struct idprom *idprom)
{ {
...@@ -80,21 +86,14 @@ void __init idprom_init(void) ...@@ -80,21 +86,14 @@ void __init idprom_init(void)
idprom = &idprom_buffer; idprom = &idprom_buffer;
if (idprom->id_format != 0x01) { if (idprom->id_format != 0x01)
prom_printf("IDPROM: Unknown format type!\n"); prom_printf("IDPROM: Warning, unknown format type!\n");
prom_halt();
}
if (idprom->id_cksum != calc_idprom_cksum(idprom)) { if (idprom->id_cksum != calc_idprom_cksum(idprom))
prom_printf("IDPROM: Checksum failure (nvram=%x, calc=%x)!\n", prom_printf("IDPROM: Warning, checksum failure (nvram=%x, calc=%x)!\n",
idprom->id_cksum, calc_idprom_cksum(idprom)); idprom->id_cksum, calc_idprom_cksum(idprom));
prom_halt();
}
display_system_type(idprom->id_machtype); display_system_type(idprom->id_machtype);
printk("Ethernet address: %x:%x:%x:%x:%x:%x\n", printk(KERN_WARNING "Ethernet address: %pM\n", idprom->id_ethaddr);
idprom->id_ethaddr[0], idprom->id_ethaddr[1],
idprom->id_ethaddr[2], idprom->id_ethaddr[3],
idprom->id_ethaddr[4], idprom->id_ethaddr[5]);
} }
...@@ -23,6 +23,5 @@ EXPORT_SYMBOL(init_task); ...@@ -23,6 +23,5 @@ EXPORT_SYMBOL(init_task);
* in etrap.S which assumes it. * in etrap.S which assumes it.
*/ */
union thread_union init_thread_union union thread_union init_thread_union
__attribute__((section (".text\"\n\t#"))) __attribute__((section (".data.init_task")))
__attribute__((aligned (THREAD_SIZE)))
= { INIT_THREAD_INFO(init_task) }; = { INIT_THREAD_INFO(init_task) };
...@@ -552,8 +552,8 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, ...@@ -552,8 +552,8 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
/* IIep is write-through, not flushing. */ /* IIep is write-through, not flushing. */
for_each_sg(sgl, sg, nents, n) { for_each_sg(sgl, sg, nents, n) {
BUG_ON(page_address(sg_page(sg)) == NULL); BUG_ON(page_address(sg_page(sg)) == NULL);
sg->dvma_address = virt_to_phys(sg_virt(sg)); sg->dma_address = virt_to_phys(sg_virt(sg));
sg->dvma_length = sg->length; sg->dma_length = sg->length;
} }
return nents; return nents;
} }
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include "kernel.h"
#include "irq.h" #include "irq.h"
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -592,19 +593,19 @@ EXPORT_SYMBOL(request_irq); ...@@ -592,19 +593,19 @@ EXPORT_SYMBOL(request_irq);
void disable_irq_nosync(unsigned int irq) void disable_irq_nosync(unsigned int irq)
{ {
return __disable_irq(irq); __disable_irq(irq);
} }
EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(disable_irq_nosync);
void disable_irq(unsigned int irq) void disable_irq(unsigned int irq)
{ {
return __disable_irq(irq); __disable_irq(irq);
} }
EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq);
void enable_irq(unsigned int irq) void enable_irq(unsigned int irq)
{ {
return __enable_irq(irq); __enable_irq(irq);
} }
EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(enable_irq);
......
...@@ -775,6 +775,69 @@ void do_softirq(void) ...@@ -775,6 +775,69 @@ void do_softirq(void)
local_irq_restore(flags); local_irq_restore(flags);
} }
static void unhandled_perf_irq(struct pt_regs *regs)
{
unsigned long pcr, pic;
read_pcr(pcr);
read_pic(pic);
write_pcr(0);
printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n",
smp_processor_id());
printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n",
smp_processor_id(), pcr, pic);
}
/* Almost a direct copy of the powerpc PMC code. */
static DEFINE_SPINLOCK(perf_irq_lock);
static void *perf_irq_owner_caller; /* mostly for debugging */
static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq;
/* Invoked from level 15 PIL handler in trap table. */
void perfctr_irq(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
perf_irq(regs);
}
int register_perfctr_intr(void (*handler)(struct pt_regs *))
{
int ret;
if (!handler)
return -EINVAL;
spin_lock(&perf_irq_lock);
if (perf_irq != unhandled_perf_irq) {
printk(KERN_WARNING "register_perfctr_intr: "
"perf IRQ busy (reserved by caller %p)\n",
perf_irq_owner_caller);
ret = -EBUSY;
goto out;
}
perf_irq_owner_caller = __builtin_return_address(0);
perf_irq = handler;
ret = 0;
out:
spin_unlock(&perf_irq_lock);
return ret;
}
EXPORT_SYMBOL_GPL(register_perfctr_intr);
void release_perfctr_intr(void (*handler)(struct pt_regs *))
{
spin_lock(&perf_irq_lock);
perf_irq_owner_caller = NULL;
perf_irq = unhandled_perf_irq;
spin_unlock(&perf_irq_lock);
}
EXPORT_SYMBOL_GPL(release_perfctr_intr);
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(void) void fixup_irqs(void)
{ {
......
#ifndef __SPARC_KERNEL_H
#define __SPARC_KERNEL_H
#include <linux/interrupt.h>
/* cpu.c */
extern const char *sparc_cpu_type;
extern const char *sparc_fpu_type;
extern unsigned int fsr_storage;
#ifdef CONFIG_SPARC32
/* 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;
extern spinlock_t irq_action_lock;
extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs);
#else /* CONFIG_SPARC32 */
#endif /* CONFIG_SPARC32 */
#endif /* !(__SPARC_KERNEL_H) */
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <asm/cpudata.h>
#include <asm/hypervisor.h> #include <asm/hypervisor.h>
#include <asm/mdesc.h> #include <asm/mdesc.h>
#include <asm/prom.h> #include <asm/prom.h>
......
/* Kernel module help for sparc32. /* Kernel module help for sparc64.
* *
* Copyright (C) 2001 Rusty Russell. * Copyright (C) 2001 Rusty Russell.
* Copyright (C) 2002 David S. Miller. * Copyright (C) 2002 David S. Miller.
...@@ -11,6 +11,48 @@ ...@@ -11,6 +11,48 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <asm/processor.h>
#include <asm/spitfire.h>
#ifdef CONFIG_SPARC64
static void *module_map(unsigned long size)
{
struct vm_struct *area;
size = PAGE_ALIGN(size);
if (!size || size > MODULES_LEN)
return NULL;
area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
if (!area)
return NULL;
return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL);
}
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) void *module_alloc(unsigned long size)
{ {
...@@ -20,7 +62,7 @@ void *module_alloc(unsigned long size) ...@@ -20,7 +62,7 @@ void *module_alloc(unsigned long size)
if (size == 0) if (size == 0)
return NULL; return NULL;
ret = vmalloc(size); ret = module_map(size);
if (!ret) if (!ret)
ret = ERR_PTR(-ENOMEM); ret = ERR_PTR(-ENOMEM);
else else
...@@ -37,16 +79,14 @@ void module_free(struct module *mod, void *module_region) ...@@ -37,16 +79,14 @@ void module_free(struct module *mod, void *module_region)
table entries. */ table entries. */
} }
/* Make generic code ignore STT_REGISTER dummy undefined symbols, /* Make generic code ignore STT_REGISTER dummy undefined symbols. */
* and replace references to .func with _Func
*/
int module_frob_arch_sections(Elf_Ehdr *hdr, int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs, Elf_Shdr *sechdrs,
char *secstrings, char *secstrings,
struct module *mod) struct module *mod)
{ {
unsigned int symidx; unsigned int symidx;
Elf32_Sym *sym; Elf_Sym *sym;
char *strtab; char *strtab;
int i; int i;
...@@ -56,26 +96,23 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, ...@@ -56,26 +96,23 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
return -ENOEXEC; return -ENOEXEC;
} }
} }
sym = (Elf32_Sym *)sechdrs[symidx].sh_addr; sym = (Elf_Sym *)sechdrs[symidx].sh_addr;
strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr; strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr;
for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) { for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) {
if (sym[i].st_shndx == SHN_UNDEF) { if (sym[i].st_shndx == SHN_UNDEF) {
if (ELF32_ST_TYPE(sym[i].st_info) == STT_REGISTER) if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER) {
sym[i].st_shndx = SHN_ABS; sym[i].st_shndx = SHN_ABS;
else { } else {
char *name = strtab + sym[i].st_name; char *name = strtab + sym[i].st_name;
if (name[0] == '.') { dot2underscore(name);
name[0] = '_';
name[1] = toupper(name[1]);
}
} }
} }
} }
return 0; return 0;
} }
int apply_relocate(Elf32_Shdr *sechdrs, int apply_relocate(Elf_Shdr *sechdrs,
const char *strtab, const char *strtab,
unsigned int symindex, unsigned int symindex,
unsigned int relsec, unsigned int relsec,
...@@ -86,32 +123,68 @@ int apply_relocate(Elf32_Shdr *sechdrs, ...@@ -86,32 +123,68 @@ int apply_relocate(Elf32_Shdr *sechdrs,
return -ENOEXEC; return -ENOEXEC;
} }
int apply_relocate_add(Elf32_Shdr *sechdrs, int apply_relocate_add(Elf_Shdr *sechdrs,
const char *strtab, const char *strtab,
unsigned int symindex, unsigned int symindex,
unsigned int relsec, unsigned int relsec,
struct module *me) struct module *me)
{ {
unsigned int i; unsigned int i;
Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym; Elf_Sym *sym;
u8 *location; u8 *location;
u32 *loc32; u32 *loc32;
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
Elf32_Addr v; Elf_Addr v;
/* This is where to make the change */ /* This is where to make the change */
location = (u8 *)sechdrs[sechdrs[relsec].sh_info].sh_addr location = (u8 *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset; + rel[i].r_offset;
loc32 = (u32 *) location; loc32 = (u32 *) location;
#ifdef CONFIG_SPARC64
BUG_ON(((u64)location >> (u64)32) != (u64)0);
#endif /* CONFIG_SPARC64 */
/* This is the symbol it is referring to. Note that all /* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */ undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info); + ELF_R_SYM(rel[i].r_info);
v = sym->st_value + rel[i].r_addend; v = sym->st_value + rel[i].r_addend;
switch (ELF32_R_TYPE(rel[i].r_info)) { switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
#ifdef CONFIG_SPARC64
case R_SPARC_64:
location[0] = v >> 56;
location[1] = v >> 48;
location[2] = v >> 40;
location[3] = v >> 32;
location[4] = v >> 24;
location[5] = v >> 16;
location[6] = v >> 8;
location[7] = v >> 0;
break;
case R_SPARC_DISP32:
v -= (Elf_Addr) location;
*loc32 = v;
break;
case R_SPARC_WDISP19:
v -= (Elf_Addr) location;
*loc32 = (*loc32 & ~0x7ffff) |
((v >> 2) & 0x7ffff);
break;
case R_SPARC_OLO10:
*loc32 = (*loc32 & ~0x1fff) |
(((v & 0x3ff) +
(ELF_R_TYPE(rel[i].r_info) >> 8))
& 0x1fff);
break;
#endif /* CONFIG_SPARC64 */
case R_SPARC_32: case R_SPARC_32:
case R_SPARC_UA32: case R_SPARC_UA32:
location[0] = v >> 24; location[0] = v >> 24;
...@@ -121,13 +194,13 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, ...@@ -121,13 +194,13 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
break; break;
case R_SPARC_WDISP30: case R_SPARC_WDISP30:
v -= (Elf32_Addr) location; v -= (Elf_Addr) location;
*loc32 = (*loc32 & ~0x3fffffff) | *loc32 = (*loc32 & ~0x3fffffff) |
((v >> 2) & 0x3fffffff); ((v >> 2) & 0x3fffffff);
break; break;
case R_SPARC_WDISP22: case R_SPARC_WDISP22:
v -= (Elf32_Addr) location; v -= (Elf_Addr) location;
*loc32 = (*loc32 & ~0x3fffff) | *loc32 = (*loc32 & ~0x3fffff) |
((v >> 2) & 0x3fffff); ((v >> 2) & 0x3fffff);
break; break;
...@@ -144,19 +217,38 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, ...@@ -144,19 +217,38 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
default: default:
printk(KERN_ERR "module %s: Unknown relocation: %x\n", printk(KERN_ERR "module %s: Unknown relocation: %x\n",
me->name, me->name,
(int) (ELF32_R_TYPE(rel[i].r_info) & 0xff)); (int) (ELF_R_TYPE(rel[i].r_info) & 0xff));
return -ENOEXEC; return -ENOEXEC;
}; };
} }
return 0; return 0;
} }
#ifdef CONFIG_SPARC64
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
/* Cheetah's I-cache is fully coherent. */
if (tlb_type == spitfire) {
unsigned long va;
flushw_all();
for (va = 0; va < (PAGE_SIZE << 1); va += 32)
spitfire_put_icache_tag(va, 0x0);
__asm__ __volatile__("flush %g6");
}
return 0;
}
#else
int module_finalize(const Elf_Ehdr *hdr, int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, const Elf_Shdr *sechdrs,
struct module *me) struct module *me)
{ {
return 0; return 0;
} }
#endif /* CONFIG_SPARC64 */
void module_arch_cleanup(struct module *mod) void module_arch_cleanup(struct module *mod)
{ {
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "kernel.h"
/* #define DEBUG_MULDIV */ /* #define DEBUG_MULDIV */
static inline int has_imm13(int insn) static inline int has_imm13(int insn)
...@@ -89,9 +91,6 @@ store_reg(unsigned int result, unsigned int reg, struct pt_regs *regs) ...@@ -89,9 +91,6 @@ store_reg(unsigned int result, unsigned int reg, struct pt_regs *regs)
} }
} }
extern void handle_hw_divzero (struct pt_regs *regs, unsigned long pc,
unsigned long npc, unsigned long psr);
/* Should return 0 if mul/div emulation succeeded and SIGILL should /* Should return 0 if mul/div emulation succeeded and SIGILL should
* not be issued. * not be issued.
*/ */
......
...@@ -811,11 +811,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, ...@@ -811,11 +811,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
irq = of_get_property(dp, "interrupts", &len); irq = of_get_property(dp, "interrupts", &len);
if (irq) { if (irq) {
memcpy(op->irqs, irq, len);
op->num_irqs = len / 4; op->num_irqs = len / 4;
} else {
op->num_irqs = 0;
}
/* Prevent overrunning the op->irqs[] array. */ /* Prevent overrunning the op->irqs[] array. */
if (op->num_irqs > PROMINTR_MAX) { if (op->num_irqs > PROMINTR_MAX) {
...@@ -824,6 +820,10 @@ static struct of_device * __init scan_one_device(struct device_node *dp, ...@@ -824,6 +820,10 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
dp->full_name, op->num_irqs, PROMINTR_MAX); dp->full_name, op->num_irqs, PROMINTR_MAX);
op->num_irqs = PROMINTR_MAX; op->num_irqs = PROMINTR_MAX;
} }
memcpy(op->irqs, irq, op->num_irqs * 4);
} else {
op->num_irqs = 0;
}
build_device_resources(op, parent); build_device_resources(op, parent);
for (i = 0; i < op->num_irqs; i++) for (i = 0; i < op->num_irqs; i++)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment