sh: remove sh5 support
sh5 never became a product and has probably never really worked. Remove it by recursively deleting all associated Kconfig options and all corresponding files. Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Rich Felker <dalias@libc.org>
This commit is contained in:
Родитель
d1f56f318d
Коммит
37744feebc
|
@ -54,15 +54,6 @@ config SUPERH
|
||||||
select HAVE_NMI
|
select HAVE_NMI
|
||||||
select NEED_SG_DMA_LENGTH
|
select NEED_SG_DMA_LENGTH
|
||||||
select ARCH_HAS_GIGANTIC_PAGE
|
select ARCH_HAS_GIGANTIC_PAGE
|
||||||
|
|
||||||
help
|
|
||||||
The SuperH is a RISC processor targeted for use in embedded systems
|
|
||||||
and consumer electronics; it was also used in the Sega Dreamcast
|
|
||||||
gaming console. The SuperH port has a home page at
|
|
||||||
<http://www.linux-sh.org/>.
|
|
||||||
|
|
||||||
config SUPERH32
|
|
||||||
def_bool "$(ARCH)" = "sh"
|
|
||||||
select ARCH_32BIT_OFF_T
|
select ARCH_32BIT_OFF_T
|
||||||
select GUP_GET_PTE_LOW_HIGH if X2TLB
|
select GUP_GET_PTE_LOW_HIGH if X2TLB
|
||||||
select HAVE_KPROBES
|
select HAVE_KPROBES
|
||||||
|
@ -81,19 +72,15 @@ config SUPERH32
|
||||||
select ARCH_HIBERNATION_POSSIBLE if MMU
|
select ARCH_HIBERNATION_POSSIBLE if MMU
|
||||||
select SPARSE_IRQ
|
select SPARSE_IRQ
|
||||||
select HAVE_STACKPROTECTOR
|
select HAVE_STACKPROTECTOR
|
||||||
|
help
|
||||||
config SUPERH64
|
The SuperH is a RISC processor targeted for use in embedded systems
|
||||||
def_bool "$(ARCH)" = "sh64"
|
and consumer electronics; it was also used in the Sega Dreamcast
|
||||||
select HAVE_EXIT_THREAD
|
gaming console. The SuperH port has a home page at
|
||||||
select KALLSYMS
|
<http://www.linux-sh.org/>.
|
||||||
|
|
||||||
config GENERIC_BUG
|
config GENERIC_BUG
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on BUG && SUPERH32
|
depends on BUG
|
||||||
|
|
||||||
config GENERIC_CSUM
|
|
||||||
def_bool y
|
|
||||||
depends on SUPERH64
|
|
||||||
|
|
||||||
config GENERIC_HWEIGHT
|
config GENERIC_HWEIGHT
|
||||||
def_bool y
|
def_bool y
|
||||||
|
@ -203,12 +190,6 @@ config CPU_SH4AL_DSP
|
||||||
select CPU_SH4A
|
select CPU_SH4A
|
||||||
select CPU_HAS_DSP
|
select CPU_HAS_DSP
|
||||||
|
|
||||||
config CPU_SH5
|
|
||||||
bool
|
|
||||||
select CPU_HAS_FPU
|
|
||||||
select SYS_SUPPORTS_SH_TMU
|
|
||||||
select SYS_SUPPORTS_HUGETLBFS if MMU
|
|
||||||
|
|
||||||
config CPU_SHX2
|
config CPU_SHX2
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
@ -228,8 +209,6 @@ config CPU_HAS_PMU
|
||||||
default y
|
default y
|
||||||
bool
|
bool
|
||||||
|
|
||||||
if SUPERH32
|
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Processor sub-type selection"
|
prompt "Processor sub-type selection"
|
||||||
|
|
||||||
|
@ -518,27 +497,6 @@ config CPU_SUBTYPE_SH7366
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
if SUPERH64
|
|
||||||
|
|
||||||
choice
|
|
||||||
prompt "Processor sub-type selection"
|
|
||||||
|
|
||||||
# SH-5 Processor Support
|
|
||||||
|
|
||||||
config CPU_SUBTYPE_SH5_101
|
|
||||||
bool "Support SH5-101 processor"
|
|
||||||
select CPU_SH5
|
|
||||||
|
|
||||||
config CPU_SUBTYPE_SH5_103
|
|
||||||
bool "Support SH5-103 processor"
|
|
||||||
select CPU_SH5
|
|
||||||
|
|
||||||
endchoice
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
source "arch/sh/mm/Kconfig"
|
source "arch/sh/mm/Kconfig"
|
||||||
|
|
||||||
source "arch/sh/Kconfig.cpu"
|
source "arch/sh/Kconfig.cpu"
|
||||||
|
@ -592,7 +550,7 @@ source "kernel/Kconfig.hz"
|
||||||
|
|
||||||
config KEXEC
|
config KEXEC
|
||||||
bool "kexec system call (EXPERIMENTAL)"
|
bool "kexec system call (EXPERIMENTAL)"
|
||||||
depends on SUPERH32 && MMU
|
depends on MMU
|
||||||
select KEXEC_CORE
|
select KEXEC_CORE
|
||||||
help
|
help
|
||||||
kexec is a system call that implements the ability to shutdown your
|
kexec is a system call that implements the ability to shutdown your
|
||||||
|
@ -610,7 +568,7 @@ config KEXEC
|
||||||
|
|
||||||
config CRASH_DUMP
|
config CRASH_DUMP
|
||||||
bool "kernel crash dumps (EXPERIMENTAL)"
|
bool "kernel crash dumps (EXPERIMENTAL)"
|
||||||
depends on SUPERH32 && BROKEN_ON_SMP
|
depends on BROKEN_ON_SMP
|
||||||
help
|
help
|
||||||
Generate crash dump after being started by kexec.
|
Generate crash dump after being started by kexec.
|
||||||
This should be normally only set in special crash dump kernels
|
This should be normally only set in special crash dump kernels
|
||||||
|
@ -624,7 +582,7 @@ config CRASH_DUMP
|
||||||
|
|
||||||
config KEXEC_JUMP
|
config KEXEC_JUMP
|
||||||
bool "kexec jump (EXPERIMENTAL)"
|
bool "kexec jump (EXPERIMENTAL)"
|
||||||
depends on SUPERH32 && KEXEC && HIBERNATION
|
depends on KEXEC && HIBERNATION
|
||||||
help
|
help
|
||||||
Jump between original kernel and kexeced kernel and invoke
|
Jump between original kernel and kexeced kernel and invoke
|
||||||
code via KEXEC
|
code via KEXEC
|
||||||
|
@ -701,7 +659,7 @@ config HOTPLUG_CPU
|
||||||
|
|
||||||
config GUSA
|
config GUSA
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on !SMP && SUPERH32
|
depends on !SMP
|
||||||
help
|
help
|
||||||
This enables support for gUSA (general UserSpace Atomicity).
|
This enables support for gUSA (general UserSpace Atomicity).
|
||||||
This is the default implementation for both UP and non-ll/sc
|
This is the default implementation for both UP and non-ll/sc
|
||||||
|
|
|
@ -13,7 +13,6 @@ config CPU_LITTLE_ENDIAN
|
||||||
|
|
||||||
config CPU_BIG_ENDIAN
|
config CPU_BIG_ENDIAN
|
||||||
bool "Big Endian"
|
bool "Big Endian"
|
||||||
depends on !CPU_SH5
|
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
@ -27,10 +26,6 @@ config SH_FPU
|
||||||
|
|
||||||
This option must be set in order to enable the FPU.
|
This option must be set in order to enable the FPU.
|
||||||
|
|
||||||
config SH64_FPU_DENORM_FLUSH
|
|
||||||
bool "Flush floating point denorms to zero"
|
|
||||||
depends on SH_FPU && SUPERH64
|
|
||||||
|
|
||||||
config SH_FPU_EMU
|
config SH_FPU_EMU
|
||||||
def_bool n
|
def_bool n
|
||||||
prompt "FPU emulation support"
|
prompt "FPU emulation support"
|
||||||
|
@ -77,10 +72,6 @@ config SPECULATIVE_EXECUTION
|
||||||
|
|
||||||
If unsure, say N.
|
If unsure, say N.
|
||||||
|
|
||||||
config SH64_ID2815_WORKAROUND
|
|
||||||
bool "Include workaround for SH5-101 cut2 silicon defect ID2815"
|
|
||||||
depends on CPU_SUBTYPE_SH5_101
|
|
||||||
|
|
||||||
config CPU_HAS_INTEVT
|
config CPU_HAS_INTEVT
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ config TRACE_IRQFLAGS_SUPPORT
|
||||||
|
|
||||||
config SH_STANDARD_BIOS
|
config SH_STANDARD_BIOS
|
||||||
bool "Use LinuxSH standard BIOS"
|
bool "Use LinuxSH standard BIOS"
|
||||||
depends on SUPERH32
|
|
||||||
help
|
help
|
||||||
Say Y here if your target has the gdb-sh-stub
|
Say Y here if your target has the gdb-sh-stub
|
||||||
package from www.m17n.org (or any conforming standard LinuxSH BIOS)
|
package from www.m17n.org (or any conforming standard LinuxSH BIOS)
|
||||||
|
@ -19,7 +18,7 @@ config SH_STANDARD_BIOS
|
||||||
|
|
||||||
config STACK_DEBUG
|
config STACK_DEBUG
|
||||||
bool "Check for stack overflows"
|
bool "Check for stack overflows"
|
||||||
depends on DEBUG_KERNEL && SUPERH32
|
depends on DEBUG_KERNEL
|
||||||
help
|
help
|
||||||
This option will cause messages to be printed if free stack space
|
This option will cause messages to be printed if free stack space
|
||||||
drops below a certain limit. Saying Y here will add overhead to
|
drops below a certain limit. Saying Y here will add overhead to
|
||||||
|
@ -38,7 +37,7 @@ config 4KSTACKS
|
||||||
|
|
||||||
config IRQSTACKS
|
config IRQSTACKS
|
||||||
bool "Use separate kernel stacks when processing interrupts"
|
bool "Use separate kernel stacks when processing interrupts"
|
||||||
depends on DEBUG_KERNEL && SUPERH32 && BROKEN
|
depends on DEBUG_KERNEL && BROKEN
|
||||||
help
|
help
|
||||||
If you say Y here the kernel will use separate kernel stacks
|
If you say Y here the kernel will use separate kernel stacks
|
||||||
for handling hard and soft interrupts. This can help avoid
|
for handling hard and soft interrupts. This can help avoid
|
||||||
|
@ -46,7 +45,7 @@ config IRQSTACKS
|
||||||
|
|
||||||
config DUMP_CODE
|
config DUMP_CODE
|
||||||
bool "Show disassembly of nearby code in register dumps"
|
bool "Show disassembly of nearby code in register dumps"
|
||||||
depends on DEBUG_KERNEL && SUPERH32
|
depends on DEBUG_KERNEL
|
||||||
default y if DEBUG_BUGVERBOSE
|
default y if DEBUG_BUGVERBOSE
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
|
@ -59,7 +58,6 @@ config DUMP_CODE
|
||||||
config DWARF_UNWINDER
|
config DWARF_UNWINDER
|
||||||
bool "Enable the DWARF unwinder for stacktraces"
|
bool "Enable the DWARF unwinder for stacktraces"
|
||||||
select FRAME_POINTER
|
select FRAME_POINTER
|
||||||
depends on SUPERH32
|
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Enabling this option will make stacktraces more accurate, at
|
Enabling this option will make stacktraces more accurate, at
|
||||||
|
@ -77,11 +75,6 @@ config SH_NO_BSS_INIT
|
||||||
For all other cases, say N. If this option seems perplexing, or
|
For all other cases, say N. If this option seems perplexing, or
|
||||||
you aren't sure, say N.
|
you aren't sure, say N.
|
||||||
|
|
||||||
config SH64_SR_WATCH
|
|
||||||
bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
|
|
||||||
depends on SUPERH64
|
|
||||||
|
|
||||||
config MCOUNT
|
config MCOUNT
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on SUPERH32
|
|
||||||
depends on STACK_DEBUG || FUNCTION_TRACER
|
depends on STACK_DEBUG || FUNCTION_TRACER
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
ifneq ($(SUBARCH),$(ARCH))
|
ifneq ($(SUBARCH),$(ARCH))
|
||||||
ifeq ($(CROSS_COMPILE),)
|
ifeq ($(CROSS_COMPILE),)
|
||||||
CROSS_COMPILE := $(call cc-cross-prefix, $(UTS_MACHINE)-linux- $(UTS_MACHINE)-linux-gnu- $(UTS_MACHINE)-unknown-linux-gnu-)
|
CROSS_COMPILE := $(call cc-cross-prefix, sh-linux- sh-linux-gnu- sh-unknown-linux-gnu-)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -29,12 +29,9 @@ isa-$(CONFIG_CPU_SH3) := sh3
|
||||||
isa-$(CONFIG_CPU_SH4) := sh4
|
isa-$(CONFIG_CPU_SH4) := sh4
|
||||||
isa-$(CONFIG_CPU_SH4A) := sh4a
|
isa-$(CONFIG_CPU_SH4A) := sh4a
|
||||||
isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al
|
isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al
|
||||||
isa-$(CONFIG_CPU_SH5) := shmedia
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_SUPERH32),y)
|
|
||||||
isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp
|
isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp
|
||||||
isa-y := $(isa-y)-up
|
isa-y := $(isa-y)-up
|
||||||
endif
|
|
||||||
|
|
||||||
cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,)
|
cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,)
|
||||||
cflags-$(CONFIG_CPU_J2) += $(call cc-option,-mj2,)
|
cflags-$(CONFIG_CPU_J2) += $(call cc-option,-mj2,)
|
||||||
|
@ -47,7 +44,6 @@ cflags-$(CONFIG_CPU_SH4) := $(call cc-option,-m4,) \
|
||||||
cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \
|
cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \
|
||||||
$(call cc-option,-m4a-nofpu,)
|
$(call cc-option,-m4a-nofpu,)
|
||||||
cflags-$(CONFIG_CPU_SH4AL_DSP) += $(call cc-option,-m4al,)
|
cflags-$(CONFIG_CPU_SH4AL_DSP) += $(call cc-option,-m4al,)
|
||||||
cflags-$(CONFIG_CPU_SH5) := $(call cc-option,-m5-32media-nofpu,)
|
|
||||||
|
|
||||||
ifeq ($(cflags-y),)
|
ifeq ($(cflags-y),)
|
||||||
#
|
#
|
||||||
|
@ -88,7 +84,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment \
|
||||||
-R .stab -R .stabstr -S
|
-R .stab -R .stabstr -S
|
||||||
|
|
||||||
# Give the various platforms the opportunity to set default image types
|
# Give the various platforms the opportunity to set default image types
|
||||||
defaultimage-$(CONFIG_SUPERH32) := zImage
|
defaultimage-y := zImage
|
||||||
defaultimage-$(CONFIG_SH_SH7785LCR) := uImage
|
defaultimage-$(CONFIG_SH_SH7785LCR) := uImage
|
||||||
defaultimage-$(CONFIG_SH_RSK) := uImage
|
defaultimage-$(CONFIG_SH_RSK) := uImage
|
||||||
defaultimage-$(CONFIG_SH_URQUELL) := uImage
|
defaultimage-$(CONFIG_SH_URQUELL) := uImage
|
||||||
|
@ -107,31 +103,22 @@ KBUILD_IMAGE := $(boot)/$(defaultimage-y)
|
||||||
# Choosing incompatible machines durings configuration will result in
|
# Choosing incompatible machines durings configuration will result in
|
||||||
# error messages during linking.
|
# error messages during linking.
|
||||||
#
|
#
|
||||||
ifdef CONFIG_SUPERH32
|
|
||||||
UTS_MACHINE := sh
|
UTS_MACHINE := sh
|
||||||
BITS := 32
|
|
||||||
LDFLAGS_vmlinux += -e _stext
|
LDFLAGS_vmlinux += -e _stext
|
||||||
else
|
|
||||||
UTS_MACHINE := sh64
|
|
||||||
BITS := 64
|
|
||||||
LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_PAGE_OFFSET) \
|
|
||||||
--defsym phys_stext_shmedia=phys_stext+1 \
|
|
||||||
-e phys_stext_shmedia
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef CONFIG_CPU_LITTLE_ENDIAN
|
ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||||
ld-bfd := elf32-$(UTS_MACHINE)-linux
|
ld-bfd := elf32-sh-linux
|
||||||
LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld-bfd)
|
LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld-bfd)
|
||||||
KBUILD_LDFLAGS += -EL
|
KBUILD_LDFLAGS += -EL
|
||||||
else
|
else
|
||||||
ld-bfd := elf32-$(UTS_MACHINE)big-linux
|
ld-bfd := elf32-shbig-linux
|
||||||
LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd)
|
LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd)
|
||||||
KBUILD_LDFLAGS += -EB
|
KBUILD_LDFLAGS += -EB
|
||||||
endif
|
endif
|
||||||
|
|
||||||
export ld-bfd BITS
|
export ld-bfd
|
||||||
|
|
||||||
head-y := arch/sh/kernel/head_$(BITS).o
|
head-y := arch/sh/kernel/head_32.o
|
||||||
|
|
||||||
core-y += arch/sh/kernel/ arch/sh/mm/ arch/sh/boards/
|
core-y += arch/sh/kernel/ arch/sh/mm/ arch/sh/boards/
|
||||||
core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
|
core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
|
||||||
|
@ -185,7 +172,6 @@ cpuincdir-$(CONFIG_CPU_SH2) += cpu-sh2
|
||||||
cpuincdir-$(CONFIG_CPU_SH3) += cpu-sh3
|
cpuincdir-$(CONFIG_CPU_SH3) += cpu-sh3
|
||||||
cpuincdir-$(CONFIG_CPU_SH4A) += cpu-sh4a
|
cpuincdir-$(CONFIG_CPU_SH4A) += cpu-sh4a
|
||||||
cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4
|
cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4
|
||||||
cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5
|
|
||||||
cpuincdir-y += cpu-common # Must be last
|
cpuincdir-y += cpu-common # Must be last
|
||||||
|
|
||||||
drivers-y += arch/sh/drivers/
|
drivers-y += arch/sh/drivers/
|
||||||
|
@ -206,8 +192,7 @@ ifeq ($(CONFIG_DWARF_UNWINDER),y)
|
||||||
KBUILD_CFLAGS += -fasynchronous-unwind-tables
|
KBUILD_CFLAGS += -fasynchronous-unwind-tables
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
|
libs-y := arch/sh/lib/ $(libs-y)
|
||||||
libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
|
|
||||||
|
|
||||||
BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
|
BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
|
||||||
uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
|
uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
targets := vmlinux vmlinux.bin vmlinux.bin.gz \
|
targets := vmlinux vmlinux.bin vmlinux.bin.gz \
|
||||||
vmlinux.bin.bz2 vmlinux.bin.lzma \
|
vmlinux.bin.bz2 vmlinux.bin.lzma \
|
||||||
vmlinux.bin.xz vmlinux.bin.lzo \
|
vmlinux.bin.xz vmlinux.bin.lzo \
|
||||||
head_$(BITS).o misc.o piggy.o
|
head_32.o misc.o piggy.o
|
||||||
|
|
||||||
OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
|
OBJECTS = $(obj)/head_32.o $(obj)/misc.o $(obj)/cache.o
|
||||||
|
|
||||||
GCOV_PROFILE := n
|
GCOV_PROFILE := n
|
||||||
|
|
||||||
|
@ -39,15 +39,11 @@ LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \
|
||||||
#
|
#
|
||||||
# Pull in the necessary libgcc bits from the in-kernel implementation.
|
# Pull in the necessary libgcc bits from the in-kernel implementation.
|
||||||
#
|
#
|
||||||
lib1funcs-$(CONFIG_SUPERH32) := ashiftrt.S ashldi3.c ashrsi3.S ashlsi3.S \
|
lib1funcs-y := ashiftrt.S ashldi3.c ashrsi3.S ashlsi3.S lshrsi3.S
|
||||||
lshrsi3.S
|
|
||||||
lib1funcs-obj := \
|
lib1funcs-obj := \
|
||||||
$(addsuffix .o, $(basename $(addprefix $(obj)/, $(lib1funcs-y))))
|
$(addsuffix .o, $(basename $(addprefix $(obj)/, $(lib1funcs-y))))
|
||||||
|
|
||||||
lib1funcs-dir := $(srctree)/arch/$(SRCARCH)/lib
|
lib1funcs-dir := $(srctree)/arch/$(SRCARCH)/lib
|
||||||
ifeq ($(BITS),64)
|
|
||||||
lib1funcs-dir := $(addsuffix $(BITS), $(lib1funcs-dir))
|
|
||||||
endif
|
|
||||||
|
|
||||||
KBUILD_CFLAGS += -I$(lib1funcs-dir) -DDISABLE_BRANCH_PROFILING
|
KBUILD_CFLAGS += -I$(lib1funcs-dir) -DDISABLE_BRANCH_PROFILING
|
||||||
|
|
||||||
|
|
|
@ -116,11 +116,7 @@ void ftrace_stub(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
#define stackalign 8
|
|
||||||
#else
|
|
||||||
#define stackalign 4
|
#define stackalign 4
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STACK_SIZE (4096)
|
#define STACK_SIZE (4096)
|
||||||
long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
|
long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
|
||||||
|
@ -130,13 +126,9 @@ void decompress_kernel(void)
|
||||||
{
|
{
|
||||||
unsigned long output_addr;
|
unsigned long output_addr;
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
output_addr = (CONFIG_MEMORY_START + 0x2000);
|
|
||||||
#else
|
|
||||||
output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
|
output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
|
||||||
#if defined(CONFIG_29BIT)
|
#if defined(CONFIG_29BIT)
|
||||||
output_addr |= P2SEG;
|
output_addr |= P2SEG;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
output = (unsigned char *)output_addr;
|
output = (unsigned char *)output_addr;
|
||||||
|
|
|
@ -10,7 +10,6 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7763) += pci-sh7780.o ops-sh4.o
|
||||||
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
|
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
|
||||||
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
|
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
|
||||||
obj-$(CONFIG_CPU_SUBTYPE_SH7786) += pcie-sh7786.o ops-sh7786.o
|
obj-$(CONFIG_CPU_SUBTYPE_SH7786) += pcie-sh7786.o ops-sh7786.o
|
||||||
obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
|
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
|
||||||
pci-dreamcast.o
|
pci-dreamcast.o
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* Support functions for the SH5 PCI hardware.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
|
|
||||||
* Copyright (C) 2003, 2004 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/rwsem.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include "pci-sh5.h"
|
|
||||||
|
|
||||||
static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
|
|
||||||
int size, u32 *val)
|
|
||||||
{
|
|
||||||
SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
|
|
||||||
|
|
||||||
switch (size) {
|
|
||||||
case 1:
|
|
||||||
*val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
*val = SH5PCI_READ(PDR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PCIBIOS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
|
||||||
int size, u32 val)
|
|
||||||
{
|
|
||||||
SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
|
|
||||||
|
|
||||||
switch (size) {
|
|
||||||
case 1:
|
|
||||||
SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
SH5PCI_WRITE(PDR, val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PCIBIOS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pci_ops sh5_pci_ops = {
|
|
||||||
.read = sh5pci_read,
|
|
||||||
.write = sh5pci_write,
|
|
||||||
};
|
|
|
@ -1,217 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
|
|
||||||
* Copyright (C) 2003, 2004 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*
|
|
||||||
* Support functions for the SH5 PCI hardware.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/rwsem.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <cpu/irq.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include "pci-sh5.h"
|
|
||||||
|
|
||||||
unsigned long pcicr_virt;
|
|
||||||
unsigned long PCI_IO_AREA;
|
|
||||||
|
|
||||||
/* Rounds a number UP to the nearest power of two. Used for
|
|
||||||
* sizing the PCI window.
|
|
||||||
*/
|
|
||||||
static u32 __init r2p2(u32 num)
|
|
||||||
{
|
|
||||||
int i = 31;
|
|
||||||
u32 tmp = num;
|
|
||||||
|
|
||||||
if (num == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (tmp & (1 << 31))
|
|
||||||
break;
|
|
||||||
i--;
|
|
||||||
tmp <<= 1;
|
|
||||||
} while (i >= 0);
|
|
||||||
|
|
||||||
tmp = 1 << i;
|
|
||||||
/* If the original number isn't a power of 2, round it up */
|
|
||||||
if (tmp != num)
|
|
||||||
tmp <<= 1;
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t pcish5_err_irq(int irq, void *dev_id)
|
|
||||||
{
|
|
||||||
struct pt_regs *regs = get_irq_regs();
|
|
||||||
unsigned pci_int, pci_air, pci_cir, pci_aint;
|
|
||||||
|
|
||||||
pci_int = SH5PCI_READ(INT);
|
|
||||||
pci_cir = SH5PCI_READ(CIR);
|
|
||||||
pci_air = SH5PCI_READ(AIR);
|
|
||||||
|
|
||||||
if (pci_int) {
|
|
||||||
printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
|
|
||||||
printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
|
|
||||||
printk("PCI AIR -> 0x%x\n", pci_air);
|
|
||||||
printk("PCI CIR -> 0x%x\n", pci_cir);
|
|
||||||
SH5PCI_WRITE(INT, ~0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pci_aint = SH5PCI_READ(AINT);
|
|
||||||
if (pci_aint) {
|
|
||||||
printk("PCI ARB INTERRUPT!\n");
|
|
||||||
printk("PCI AINT -> 0x%x\n", pci_aint);
|
|
||||||
printk("PCI AIR -> 0x%x\n", pci_air);
|
|
||||||
printk("PCI CIR -> 0x%x\n", pci_cir);
|
|
||||||
SH5PCI_WRITE(AINT, ~0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
|
|
||||||
{
|
|
||||||
printk("SERR IRQ\n");
|
|
||||||
|
|
||||||
return IRQ_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct resource sh5_pci_resources[2];
|
|
||||||
|
|
||||||
static struct pci_channel sh5pci_controller = {
|
|
||||||
.pci_ops = &sh5_pci_ops,
|
|
||||||
.resources = sh5_pci_resources,
|
|
||||||
.nr_resources = ARRAY_SIZE(sh5_pci_resources),
|
|
||||||
.mem_offset = 0x00000000,
|
|
||||||
.io_offset = 0x00000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init sh5pci_init(void)
|
|
||||||
{
|
|
||||||
unsigned long memStart = __pa(memory_start);
|
|
||||||
unsigned long memSize = __pa(memory_end) - memStart;
|
|
||||||
u32 lsr0;
|
|
||||||
u32 uval;
|
|
||||||
|
|
||||||
if (request_irq(IRQ_ERR, pcish5_err_irq,
|
|
||||||
0, "PCI Error",NULL) < 0) {
|
|
||||||
printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request_irq(IRQ_SERR, pcish5_serr_irq,
|
|
||||||
0, "PCI SERR interrupt", NULL) < 0) {
|
|
||||||
printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pcicr_virt = (unsigned long)ioremap(SH5PCI_ICR_BASE, 1024);
|
|
||||||
if (!pcicr_virt) {
|
|
||||||
panic("Unable to remap PCICR\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
PCI_IO_AREA = (unsigned long)ioremap(SH5PCI_IO_BASE, 0x10000);
|
|
||||||
if (!PCI_IO_AREA) {
|
|
||||||
panic("Unable to remap PCIIO\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear snoop registers */
|
|
||||||
SH5PCI_WRITE(CSCR0, 0);
|
|
||||||
SH5PCI_WRITE(CSCR1, 0);
|
|
||||||
|
|
||||||
/* Switch off interrupts */
|
|
||||||
SH5PCI_WRITE(INTM, 0);
|
|
||||||
SH5PCI_WRITE(AINTM, 0);
|
|
||||||
SH5PCI_WRITE(PINTM, 0);
|
|
||||||
|
|
||||||
/* Set bus active, take it out of reset */
|
|
||||||
uval = SH5PCI_READ(CR);
|
|
||||||
|
|
||||||
/* Set command Register */
|
|
||||||
SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE |
|
|
||||||
CR_PFCS | CR_BMAM);
|
|
||||||
|
|
||||||
uval=SH5PCI_READ(CR);
|
|
||||||
|
|
||||||
/* Allow it to be a master */
|
|
||||||
/* NB - WE DISABLE I/O ACCESS to stop overlap */
|
|
||||||
/* set WAIT bit to enable stepping, an attempt to improve stability */
|
|
||||||
SH5PCI_WRITE_SHORT(CSR_CMD,
|
|
||||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
|
|
||||||
PCI_COMMAND_WAIT);
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Set translation mapping memory in order to convert the address
|
|
||||||
** used for the main bus, to the PCI internal address.
|
|
||||||
*/
|
|
||||||
SH5PCI_WRITE(MBR,0x40000000);
|
|
||||||
|
|
||||||
/* Always set the max size 512M */
|
|
||||||
SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
|
|
||||||
|
|
||||||
/*
|
|
||||||
** I/O addresses are mapped at internal PCI specific address
|
|
||||||
** as is described into the configuration bridge table.
|
|
||||||
** These are changed to 0, to allow cards that have legacy
|
|
||||||
** io such as vga to function correctly. We set the SH5 IOBAR to
|
|
||||||
** 256K, which is a bit big as we can only have 64K of address space
|
|
||||||
*/
|
|
||||||
|
|
||||||
SH5PCI_WRITE(IOBR,0x0);
|
|
||||||
|
|
||||||
/* Set up a 256K window. Totally pointless waste of address space */
|
|
||||||
SH5PCI_WRITE(IOBMR,0);
|
|
||||||
|
|
||||||
/* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec.
|
|
||||||
* Ideally, we would want to map the I/O region somewhere, but it
|
|
||||||
* is so big this is not that easy!
|
|
||||||
*/
|
|
||||||
SH5PCI_WRITE(CSR_IBAR0,~0);
|
|
||||||
/* Set memory size value */
|
|
||||||
memSize = memory_end - memory_start;
|
|
||||||
|
|
||||||
/* Now we set up the mbars so the PCI bus can see the memory of
|
|
||||||
* the machine */
|
|
||||||
if (memSize < (1024 * 1024)) {
|
|
||||||
printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%lx?\n",
|
|
||||||
memSize);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set LSR 0 */
|
|
||||||
lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 :
|
|
||||||
((r2p2(memSize) - 0x100000) | 0x1);
|
|
||||||
SH5PCI_WRITE(LSR0, lsr0);
|
|
||||||
|
|
||||||
/* Set MBAR 0 */
|
|
||||||
SH5PCI_WRITE(CSR_MBAR0, memory_start);
|
|
||||||
SH5PCI_WRITE(LAR0, memory_start);
|
|
||||||
|
|
||||||
SH5PCI_WRITE(CSR_MBAR1,0);
|
|
||||||
SH5PCI_WRITE(LAR1,0);
|
|
||||||
SH5PCI_WRITE(LSR1,0);
|
|
||||||
|
|
||||||
/* Enable the PCI interrupts on the device */
|
|
||||||
SH5PCI_WRITE(INTM, ~0);
|
|
||||||
SH5PCI_WRITE(AINTM, ~0);
|
|
||||||
SH5PCI_WRITE(PINTM, ~0);
|
|
||||||
|
|
||||||
sh5_pci_resources[0].start = PCI_IO_AREA;
|
|
||||||
sh5_pci_resources[0].end = PCI_IO_AREA + 0x10000;
|
|
||||||
|
|
||||||
sh5_pci_resources[1].start = memStart;
|
|
||||||
sh5_pci_resources[1].end = memStart + memSize;
|
|
||||||
|
|
||||||
return register_pci_controller(&sh5pci_controller);
|
|
||||||
}
|
|
||||||
arch_initcall(sh5pci_init);
|
|
|
@ -1,108 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
|
|
||||||
*
|
|
||||||
* Definitions for the SH5 PCI hardware.
|
|
||||||
*/
|
|
||||||
#ifndef __PCI_SH5_H
|
|
||||||
#define __PCI_SH5_H
|
|
||||||
|
|
||||||
/* Product ID */
|
|
||||||
#define PCISH5_PID 0x350d
|
|
||||||
|
|
||||||
/* vendor ID */
|
|
||||||
#define PCISH5_VID 0x1054
|
|
||||||
|
|
||||||
/* Configuration types */
|
|
||||||
#define ST_TYPE0 0x00 /* Configuration cycle type 0 */
|
|
||||||
#define ST_TYPE1 0x01 /* Configuration cycle type 1 */
|
|
||||||
|
|
||||||
/* VCR data */
|
|
||||||
#define PCISH5_VCR_STATUS 0x00
|
|
||||||
#define PCISH5_VCR_VERSION 0x08
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ICR register offsets and bits
|
|
||||||
*/
|
|
||||||
#define PCISH5_ICR_CR 0x100 /* PCI control register values */
|
|
||||||
#define CR_PBAM (1<<12)
|
|
||||||
#define CR_PFCS (1<<11)
|
|
||||||
#define CR_FTO (1<<10)
|
|
||||||
#define CR_PFE (1<<9)
|
|
||||||
#define CR_TBS (1<<8)
|
|
||||||
#define CR_SPUE (1<<7)
|
|
||||||
#define CR_BMAM (1<<6)
|
|
||||||
#define CR_HOST (1<<5)
|
|
||||||
#define CR_CLKEN (1<<4)
|
|
||||||
#define CR_SOCS (1<<3)
|
|
||||||
#define CR_IOCS (1<<2)
|
|
||||||
#define CR_RSTCTL (1<<1)
|
|
||||||
#define CR_CFINT (1<<0)
|
|
||||||
#define CR_LOCK_MASK 0xa5000000
|
|
||||||
|
|
||||||
#define PCISH5_ICR_INT 0x114 /* Interrupt registert values */
|
|
||||||
#define INT_MADIM (1<<2)
|
|
||||||
|
|
||||||
#define PCISH5_ICR_LSR0 0X104 /* Local space register values */
|
|
||||||
#define PCISH5_ICR_LSR1 0X108 /* Local space register values */
|
|
||||||
#define PCISH5_ICR_LAR0 0x10c /* Local address register values */
|
|
||||||
#define PCISH5_ICR_LAR1 0x110 /* Local address register values */
|
|
||||||
#define PCISH5_ICR_INTM 0x118 /* Interrupt mask register values */
|
|
||||||
#define PCISH5_ICR_AIR 0x11c /* Interrupt error address information register values */
|
|
||||||
#define PCISH5_ICR_CIR 0x120 /* Interrupt error command information register values */
|
|
||||||
#define PCISH5_ICR_AINT 0x130 /* Interrupt error arbiter interrupt register values */
|
|
||||||
#define PCISH5_ICR_AINTM 0x134 /* Interrupt error arbiter interrupt mask register values */
|
|
||||||
#define PCISH5_ICR_BMIR 0x138 /* Interrupt error info register of bus master values */
|
|
||||||
#define PCISH5_ICR_PAR 0x1c0 /* Pio address register values */
|
|
||||||
#define PCISH5_ICR_MBR 0x1c4 /* Memory space bank register values */
|
|
||||||
#define PCISH5_ICR_IOBR 0x1c8 /* I/O space bank register values */
|
|
||||||
#define PCISH5_ICR_PINT 0x1cc /* power management interrupt register values */
|
|
||||||
#define PCISH5_ICR_PINTM 0x1d0 /* power management interrupt mask register values */
|
|
||||||
#define PCISH5_ICR_MBMR 0x1d8 /* memory space bank mask register values */
|
|
||||||
#define PCISH5_ICR_IOBMR 0x1dc /* I/O space bank mask register values */
|
|
||||||
#define PCISH5_ICR_CSCR0 0x210 /* PCI cache snoop control register 0 */
|
|
||||||
#define PCISH5_ICR_CSCR1 0x214 /* PCI cache snoop control register 1 */
|
|
||||||
#define PCISH5_ICR_PDR 0x220 /* Pio data register values */
|
|
||||||
|
|
||||||
/* These are configs space registers */
|
|
||||||
#define PCISH5_ICR_CSR_VID 0x000 /* Vendor id */
|
|
||||||
#define PCISH5_ICR_CSR_DID 0x002 /* Device id */
|
|
||||||
#define PCISH5_ICR_CSR_CMD 0x004 /* Command register */
|
|
||||||
#define PCISH5_ICR_CSR_STATUS 0x006 /* Stautus */
|
|
||||||
#define PCISH5_ICR_CSR_IBAR0 0x010 /* I/O base address register */
|
|
||||||
#define PCISH5_ICR_CSR_MBAR0 0x014 /* First Memory base address register */
|
|
||||||
#define PCISH5_ICR_CSR_MBAR1 0x018 /* Second Memory base address register */
|
|
||||||
|
|
||||||
/* Base address of registers */
|
|
||||||
#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000)
|
|
||||||
#define SH5PCI_IO_BASE (PHYS_PCI_BLOCK + 0x00800000)
|
|
||||||
/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG) */
|
|
||||||
|
|
||||||
extern unsigned long pcicr_virt;
|
|
||||||
/* Register selection macro */
|
|
||||||
#define PCISH5_ICR_REG(x) ( pcicr_virt + (PCISH5_ICR_##x))
|
|
||||||
/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
|
|
||||||
|
|
||||||
/* Write I/O functions */
|
|
||||||
#define SH5PCI_WRITE(reg,val) __raw_writel((u32)(val),PCISH5_ICR_REG(reg))
|
|
||||||
#define SH5PCI_WRITE_SHORT(reg,val) __raw_writew((u16)(val),PCISH5_ICR_REG(reg))
|
|
||||||
#define SH5PCI_WRITE_BYTE(reg,val) __raw_writeb((u8)(val),PCISH5_ICR_REG(reg))
|
|
||||||
|
|
||||||
/* Read I/O functions */
|
|
||||||
#define SH5PCI_READ(reg) __raw_readl(PCISH5_ICR_REG(reg))
|
|
||||||
#define SH5PCI_READ_SHORT(reg) __raw_readw(PCISH5_ICR_REG(reg))
|
|
||||||
#define SH5PCI_READ_BYTE(reg) __raw_readb(PCISH5_ICR_REG(reg))
|
|
||||||
|
|
||||||
/* Set PCI config bits */
|
|
||||||
#define SET_CONFIG_BITS(bus,devfn,where) ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
|
|
||||||
|
|
||||||
/* Set PCI command register */
|
|
||||||
#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
|
|
||||||
|
|
||||||
/* Size converters */
|
|
||||||
#define PCISH5_MEM_SIZCONV(x) (((x / 0x40000) - 1) << 18)
|
|
||||||
#define PCISH5_IO_SIZCONV(x) (((x / 0x40000) - 1) << 18)
|
|
||||||
|
|
||||||
extern struct pci_ops sh5_pci_ops;
|
|
||||||
|
|
||||||
#endif /* __PCI_SH5_H */
|
|
|
@ -6,7 +6,7 @@
|
||||||
#ifndef __ASM_SH_BARRIER_H
|
#ifndef __ASM_SH_BARRIER_H
|
||||||
#define __ASM_SH_BARRIER_H
|
#define __ASM_SH_BARRIER_H
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5)
|
#if defined(CONFIG_CPU_SH4A)
|
||||||
#include <asm/cache_insns.h>
|
#include <asm/cache_insns.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
* Historically we have only done this type of barrier for the MMUCR, but
|
* Historically we have only done this type of barrier for the MMUCR, but
|
||||||
* it's also necessary for the CCR, so we make it generic here instead.
|
* it's also necessary for the CCR, so we make it generic here instead.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5)
|
#if defined(CONFIG_CPU_SH4A)
|
||||||
#define mb() __asm__ __volatile__ ("synco": : :"memory")
|
#define mb() __asm__ __volatile__ ("synco": : :"memory")
|
||||||
#define rmb() mb()
|
#define rmb() mb()
|
||||||
#define wmb() mb()
|
#define wmb() mb()
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include <asm-generic/bitops/non-atomic.h>
|
#include <asm-generic/bitops/non-atomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
static inline unsigned long ffz(unsigned long word)
|
static inline unsigned long ffz(unsigned long word)
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
|
@ -60,31 +59,6 @@ static inline unsigned long __ffs(unsigned long word)
|
||||||
: "t");
|
: "t");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static inline unsigned long ffz(unsigned long word)
|
|
||||||
{
|
|
||||||
unsigned long result, __d2, __d3;
|
|
||||||
|
|
||||||
__asm__("gettr tr0, %2\n\t"
|
|
||||||
"pta $+32, tr0\n\t"
|
|
||||||
"andi %1, 1, %3\n\t"
|
|
||||||
"beq %3, r63, tr0\n\t"
|
|
||||||
"pta $+4, tr0\n"
|
|
||||||
"0:\n\t"
|
|
||||||
"shlri.l %1, 1, %1\n\t"
|
|
||||||
"addi %0, 1, %0\n\t"
|
|
||||||
"andi %1, 1, %3\n\t"
|
|
||||||
"beqi %3, 1, tr0\n"
|
|
||||||
"1:\n\t"
|
|
||||||
"ptabs %2, tr0\n\t"
|
|
||||||
: "=r" (result), "=r" (word), "=r" (__d2), "=r" (__d3)
|
|
||||||
: "0" (0L), "1" (word));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <asm-generic/bitops/__ffs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <asm-generic/bitops/find.h>
|
#include <asm-generic/bitops/find.h>
|
||||||
#include <asm-generic/bitops/ffs.h>
|
#include <asm-generic/bitops/ffs.h>
|
||||||
|
|
|
@ -1,11 +1,2 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
#ifndef __ASM_SH_BL_BIT_H
|
|
||||||
#define __ASM_SH_BL_BIT_H
|
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/bl_bit_32.h>
|
#include <asm/bl_bit_32.h>
|
||||||
#else
|
|
||||||
# include <asm/bl_bit_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_BL_BIT_H */
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_SH_BL_BIT_64_H
|
|
||||||
#define __ASM_SH_BL_BIT_64_H
|
|
||||||
|
|
||||||
#include <asm/processor.h>
|
|
||||||
|
|
||||||
#define SR_BL_LL 0x0000000010000000LL
|
|
||||||
|
|
||||||
static inline void set_bl_bit(void)
|
|
||||||
{
|
|
||||||
unsigned long long __dummy0, __dummy1 = SR_BL_LL;
|
|
||||||
|
|
||||||
__asm__ __volatile__("getcon " __SR ", %0\n\t"
|
|
||||||
"or %0, %1, %0\n\t"
|
|
||||||
"putcon %0, " __SR "\n\t"
|
|
||||||
: "=&r" (__dummy0)
|
|
||||||
: "r" (__dummy1));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void clear_bl_bit(void)
|
|
||||||
{
|
|
||||||
unsigned long long __dummy0, __dummy1 = ~SR_BL_LL;
|
|
||||||
|
|
||||||
__asm__ __volatile__("getcon " __SR ", %0\n\t"
|
|
||||||
"and %0, %1, %0\n\t"
|
|
||||||
"putcon %0, " __SR "\n\t"
|
|
||||||
: "=&r" (__dummy0)
|
|
||||||
: "r" (__dummy1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_BL_BIT_64_H */
|
|
|
@ -53,10 +53,6 @@ static void __init check_bugs(void)
|
||||||
*p++ = 's';
|
*p++ = 's';
|
||||||
*p++ = 'p';
|
*p++ = 'p';
|
||||||
break;
|
break;
|
||||||
case CPU_FAMILY_SH5:
|
|
||||||
*p++ = '6';
|
|
||||||
*p++ = '4';
|
|
||||||
break;
|
|
||||||
case CPU_FAMILY_UNKNOWN:
|
case CPU_FAMILY_UNKNOWN:
|
||||||
/*
|
/*
|
||||||
* Specifically use CPU_FAMILY_UNKNOWN rather than
|
* Specifically use CPU_FAMILY_UNKNOWN rather than
|
||||||
|
|
|
@ -1,12 +1,2 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
#ifndef __ASM_SH_CACHE_INSNS_H
|
|
||||||
#define __ASM_SH_CACHE_INSNS_H
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/cache_insns_32.h>
|
#include <asm/cache_insns_32.h>
|
||||||
#else
|
|
||||||
# include <asm/cache_insns_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_CACHE_INSNS_H */
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_SH_CACHE_INSNS_64_H
|
|
||||||
#define __ASM_SH_CACHE_INSNS_64_H
|
|
||||||
|
|
||||||
#define __icbi(addr) __asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr))
|
|
||||||
#define __ocbp(addr) __asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr))
|
|
||||||
#define __ocbi(addr) __asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr))
|
|
||||||
#define __ocbwb(addr) __asm__ __volatile__ ( "ocbwb %0, 0\n\t" : : "r" (addr))
|
|
||||||
|
|
||||||
static inline reg_size_t register_align(void *val)
|
|
||||||
{
|
|
||||||
return (unsigned long long)(signed long long)(signed long)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_CACHE_INSNS_64_H */
|
|
|
@ -1,6 +1,2 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/checksum_32.h>
|
#include <asm/checksum_32.h>
|
||||||
#else
|
|
||||||
# include <asm-generic/checksum.h>
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -133,28 +133,6 @@ typedef struct user_fpu_struct elf_fpregset_t;
|
||||||
|
|
||||||
#define ELF_PLATFORM (utsname()->machine)
|
#define ELF_PLATFORM (utsname()->machine)
|
||||||
|
|
||||||
#ifdef __SH5__
|
|
||||||
#define ELF_PLAT_INIT(_r, load_addr) \
|
|
||||||
do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
|
|
||||||
_r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \
|
|
||||||
_r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \
|
|
||||||
_r->regs[12]=0; _r->regs[13]=0; _r->regs[14]=0; _r->regs[15]=0; \
|
|
||||||
_r->regs[16]=0; _r->regs[17]=0; _r->regs[18]=0; _r->regs[19]=0; \
|
|
||||||
_r->regs[20]=0; _r->regs[21]=0; _r->regs[22]=0; _r->regs[23]=0; \
|
|
||||||
_r->regs[24]=0; _r->regs[25]=0; _r->regs[26]=0; _r->regs[27]=0; \
|
|
||||||
_r->regs[28]=0; _r->regs[29]=0; _r->regs[30]=0; _r->regs[31]=0; \
|
|
||||||
_r->regs[32]=0; _r->regs[33]=0; _r->regs[34]=0; _r->regs[35]=0; \
|
|
||||||
_r->regs[36]=0; _r->regs[37]=0; _r->regs[38]=0; _r->regs[39]=0; \
|
|
||||||
_r->regs[40]=0; _r->regs[41]=0; _r->regs[42]=0; _r->regs[43]=0; \
|
|
||||||
_r->regs[44]=0; _r->regs[45]=0; _r->regs[46]=0; _r->regs[47]=0; \
|
|
||||||
_r->regs[48]=0; _r->regs[49]=0; _r->regs[50]=0; _r->regs[51]=0; \
|
|
||||||
_r->regs[52]=0; _r->regs[53]=0; _r->regs[54]=0; _r->regs[55]=0; \
|
|
||||||
_r->regs[56]=0; _r->regs[57]=0; _r->regs[58]=0; _r->regs[59]=0; \
|
|
||||||
_r->regs[60]=0; _r->regs[61]=0; _r->regs[62]=0; \
|
|
||||||
_r->tregs[0]=0; _r->tregs[1]=0; _r->tregs[2]=0; _r->tregs[3]=0; \
|
|
||||||
_r->tregs[4]=0; _r->tregs[5]=0; _r->tregs[6]=0; _r->tregs[7]=0; \
|
|
||||||
_r->sr = SR_FD | SR_MMU; } while (0)
|
|
||||||
#else
|
|
||||||
#define ELF_PLAT_INIT(_r, load_addr) \
|
#define ELF_PLAT_INIT(_r, load_addr) \
|
||||||
do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
|
do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
|
||||||
_r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \
|
_r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \
|
||||||
|
@ -182,7 +160,6 @@ do { \
|
||||||
_r->regs[14] = 0; \
|
_r->regs[14] = 0; \
|
||||||
_r->sr = SR_FD; \
|
_r->sr = SR_FD; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SET_PERSONALITY(ex) \
|
#define SET_PERSONALITY(ex) \
|
||||||
set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
|
set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
|
||||||
|
|
|
@ -4,8 +4,4 @@
|
||||||
|
|
||||||
#include <asm-generic/extable.h>
|
#include <asm-generic/extable.h>
|
||||||
|
|
||||||
#if defined(CONFIG_SUPERH64) && defined(CONFIG_MMU)
|
|
||||||
#define ARCH_HAS_SEARCH_EXTABLE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -83,11 +83,7 @@ extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags);
|
||||||
* the start of the fixmap, and leave one page empty
|
* the start of the fixmap, and leave one page empty
|
||||||
* at the top of mem..
|
* at the top of mem..
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#define FIXADDR_TOP (P4SEG - PAGE_SIZE)
|
#define FIXADDR_TOP (P4SEG - PAGE_SIZE)
|
||||||
#else
|
|
||||||
#define FIXADDR_TOP ((unsigned long)(-PAGE_SIZE))
|
|
||||||
#endif
|
|
||||||
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||||
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
||||||
|
|
||||||
|
|
|
@ -115,12 +115,8 @@ static inline void pfx##reads##bwlq(volatile void __iomem *mem, \
|
||||||
__BUILD_MEMORY_STRING(__raw_, b, u8)
|
__BUILD_MEMORY_STRING(__raw_, b, u8)
|
||||||
__BUILD_MEMORY_STRING(__raw_, w, u16)
|
__BUILD_MEMORY_STRING(__raw_, w, u16)
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
void __raw_writesl(void __iomem *addr, const void *data, int longlen);
|
void __raw_writesl(void __iomem *addr, const void *data, int longlen);
|
||||||
void __raw_readsl(const void __iomem *addr, void *data, int longlen);
|
void __raw_readsl(const void __iomem *addr, void *data, int longlen);
|
||||||
#else
|
|
||||||
__BUILD_MEMORY_STRING(__raw_, l, u32)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
__BUILD_MEMORY_STRING(__raw_, q, u64)
|
__BUILD_MEMORY_STRING(__raw_, q, u64)
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,5 @@ extern void irq_finish(unsigned int irq);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <asm-generic/irq.h>
|
#include <asm-generic/irq.h>
|
||||||
#ifdef CONFIG_CPU_SH5
|
|
||||||
#include <cpu/irq.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_IRQ_H */
|
#endif /* __ASM_SH_IRQ_H */
|
||||||
|
|
|
@ -48,11 +48,7 @@
|
||||||
*/
|
*/
|
||||||
#define MMU_VPN_MASK 0xfffff000
|
#define MMU_VPN_MASK 0xfffff000
|
||||||
|
|
||||||
#if defined(CONFIG_SUPERH32)
|
|
||||||
#include <asm/mmu_context_32.h>
|
#include <asm/mmu_context_32.h>
|
||||||
#else
|
|
||||||
#include <asm/mmu_context_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get MMU context if needed.
|
* Get MMU context if needed.
|
||||||
|
@ -74,14 +70,6 @@ static inline void get_mmu_context(struct mm_struct *mm, unsigned int cpu)
|
||||||
*/
|
*/
|
||||||
local_flush_tlb_all();
|
local_flush_tlb_all();
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
/*
|
|
||||||
* The SH-5 cache uses the ASIDs, requiring both the I and D
|
|
||||||
* cache to be flushed when the ASID is exhausted. Weak.
|
|
||||||
*/
|
|
||||||
flush_cache_all();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fix version; Note that we avoid version #0
|
* Fix version; Note that we avoid version #0
|
||||||
* to distinguish NO_CONTEXT.
|
* to distinguish NO_CONTEXT.
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_MMU_CONTEXT_64_H
|
|
||||||
#define __ASM_SH_MMU_CONTEXT_64_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sh64-specific mmu_context interface.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 - 2007 Paul Mundt
|
|
||||||
*/
|
|
||||||
#include <cpu/registers.h>
|
|
||||||
#include <asm/cacheflush.h>
|
|
||||||
|
|
||||||
#define SR_ASID_MASK 0xffffffffff00ffffULL
|
|
||||||
#define SR_ASID_SHIFT 16
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Destroy context related info for an mm_struct that is about
|
|
||||||
* to be put to rest.
|
|
||||||
*/
|
|
||||||
static inline void destroy_context(struct mm_struct *mm)
|
|
||||||
{
|
|
||||||
/* Well, at least free TLB entries */
|
|
||||||
flush_tlb_mm(mm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long get_asid(void)
|
|
||||||
{
|
|
||||||
unsigned long long sr;
|
|
||||||
|
|
||||||
asm volatile ("getcon " __SR ", %0\n\t"
|
|
||||||
: "=r" (sr));
|
|
||||||
|
|
||||||
sr = (sr >> SR_ASID_SHIFT) & MMU_CONTEXT_ASID_MASK;
|
|
||||||
return (unsigned long) sr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set ASID into SR */
|
|
||||||
static inline void set_asid(unsigned long asid)
|
|
||||||
{
|
|
||||||
unsigned long long sr, pc;
|
|
||||||
|
|
||||||
asm volatile ("getcon " __SR ", %0" : "=r" (sr));
|
|
||||||
|
|
||||||
sr = (sr & SR_ASID_MASK) | (asid << SR_ASID_SHIFT);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* It is possible that this function may be inlined and so to avoid
|
|
||||||
* the assembler reporting duplicate symbols we make use of the
|
|
||||||
* gas trick of generating symbols using numerics and forward
|
|
||||||
* reference.
|
|
||||||
*/
|
|
||||||
asm volatile ("movi 1, %1\n\t"
|
|
||||||
"shlli %1, 28, %1\n\t"
|
|
||||||
"or %0, %1, %1\n\t"
|
|
||||||
"putcon %1, " __SR "\n\t"
|
|
||||||
"putcon %0, " __SSR "\n\t"
|
|
||||||
"movi 1f, %1\n\t"
|
|
||||||
"ori %1, 1 , %1\n\t"
|
|
||||||
"putcon %1, " __SPC "\n\t"
|
|
||||||
"rte\n"
|
|
||||||
"1:\n\t"
|
|
||||||
: "=r" (sr), "=r" (pc) : "0" (sr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* arch/sh/kernel/cpu/sh5/entry.S */
|
|
||||||
extern unsigned long switch_and_save_asid(unsigned long new_asid);
|
|
||||||
|
|
||||||
/* No spare register to twiddle, so use a software cache */
|
|
||||||
extern pgd_t *mmu_pdtp_cache;
|
|
||||||
|
|
||||||
#define set_TTB(pgd) (mmu_pdtp_cache = (pgd))
|
|
||||||
#define get_TTB() (mmu_pdtp_cache)
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_MMU_CONTEXT_64_H */
|
|
|
@ -35,8 +35,6 @@
|
||||||
#define HPAGE_SHIFT 22
|
#define HPAGE_SHIFT 22
|
||||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
|
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
|
||||||
#define HPAGE_SHIFT 26
|
#define HPAGE_SHIFT 26
|
||||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512MB)
|
|
||||||
#define HPAGE_SHIFT 29
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_HUGETLB_PAGE
|
#ifdef CONFIG_HUGETLB_PAGE
|
||||||
|
@ -82,18 +80,12 @@ typedef struct { unsigned long long pgd; } pgd_t;
|
||||||
((x).pte_low | ((unsigned long long)(x).pte_high << 32))
|
((x).pte_low | ((unsigned long long)(x).pte_high << 32))
|
||||||
#define __pte(x) \
|
#define __pte(x) \
|
||||||
({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
|
({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
|
||||||
#elif defined(CONFIG_SUPERH32)
|
#else
|
||||||
typedef struct { unsigned long pte_low; } pte_t;
|
typedef struct { unsigned long pte_low; } pte_t;
|
||||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||||
typedef struct { unsigned long pgd; } pgd_t;
|
typedef struct { unsigned long pgd; } pgd_t;
|
||||||
#define pte_val(x) ((x).pte_low)
|
#define pte_val(x) ((x).pte_low)
|
||||||
#define __pte(x) ((pte_t) { (x) } )
|
#define __pte(x) ((pte_t) { (x) } )
|
||||||
#else
|
|
||||||
typedef struct { unsigned long long pte_low; } pte_t;
|
|
||||||
typedef struct { unsigned long long pgprot; } pgprot_t;
|
|
||||||
typedef struct { unsigned long pgd; } pgd_t;
|
|
||||||
#define pte_val(x) ((x).pte_low)
|
|
||||||
#define __pte(x) ((pte_t) { (x) } )
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define pgd_val(x) ((x).pgd)
|
#define pgd_val(x) ((x).pgd)
|
||||||
|
@ -191,15 +183,4 @@ typedef struct page *pgtable_t;
|
||||||
*/
|
*/
|
||||||
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
|
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
/*
|
|
||||||
* While BYTES_PER_WORD == 4 on the current sh64 ABI, GCC will still
|
|
||||||
* happily generate {ld/st}.q pairs, requiring us to have 8-byte
|
|
||||||
* alignment to avoid traps. The kmalloc alignment is guaranteed by
|
|
||||||
* virtue of L1_CACHE_BYTES, requiring this to only be special cased
|
|
||||||
* for slab caches.
|
|
||||||
*/
|
|
||||||
#define ARCH_SLAB_MINALIGN 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_PAGE_H */
|
#endif /* __ASM_SH_PAGE_H */
|
||||||
|
|
|
@ -76,18 +76,10 @@ static inline unsigned long phys_addr_mask(void)
|
||||||
#define PTE_PHYS_MASK (phys_addr_mask() & PAGE_MASK)
|
#define PTE_PHYS_MASK (phys_addr_mask() & PAGE_MASK)
|
||||||
#define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT)
|
#define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT)
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#define VMALLOC_START (P3SEG)
|
#define VMALLOC_START (P3SEG)
|
||||||
#else
|
|
||||||
#define VMALLOC_START (0xf0000000)
|
|
||||||
#endif
|
|
||||||
#define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
|
#define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
|
||||||
|
|
||||||
#if defined(CONFIG_SUPERH32)
|
|
||||||
#include <asm/pgtable_32.h>
|
#include <asm/pgtable_32.h>
|
||||||
#else
|
|
||||||
#include <asm/pgtable_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SH-X and lower (legacy) SuperH parts (SH-3, SH-4, some SH-4A) can't do page
|
* SH-X and lower (legacy) SuperH parts (SH-3, SH-4, some SH-4A) can't do page
|
||||||
|
@ -159,15 +151,6 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
|
||||||
prot |= _PAGE_EXT(_PAGE_EXT_KERN_WRITE | _PAGE_EXT_USER_WRITE);
|
prot |= _PAGE_EXT(_PAGE_EXT_KERN_WRITE | _PAGE_EXT_USER_WRITE);
|
||||||
return __pte_access_permitted(pte, prot);
|
return __pte_access_permitted(pte, prot);
|
||||||
}
|
}
|
||||||
#elif defined(CONFIG_SUPERH64)
|
|
||||||
static inline bool pte_access_permitted(pte_t pte, bool write)
|
|
||||||
{
|
|
||||||
u64 prot = _PAGE_PRESENT | _PAGE_USER | _PAGE_READ;
|
|
||||||
|
|
||||||
if (write)
|
|
||||||
prot |= _PAGE_WRITE;
|
|
||||||
return __pte_access_permitted(pte, prot);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
static inline bool pte_access_permitted(pte_t pte, bool write)
|
static inline bool pte_access_permitted(pte_t pte, bool write)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,307 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_PGTABLE_64_H
|
|
||||||
#define __ASM_SH_PGTABLE_64_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include/asm-sh/pgtable_64.h
|
|
||||||
*
|
|
||||||
* This file contains the functions and defines necessary to modify and use
|
|
||||||
* the SuperH page table tree.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003, 2004 Paul Mundt
|
|
||||||
* Copyright (C) 2003, 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#include <linux/threads.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/page.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Error outputs.
|
|
||||||
*/
|
|
||||||
#define pte_ERROR(e) \
|
|
||||||
printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e))
|
|
||||||
#define pgd_ERROR(e) \
|
|
||||||
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Table setting routines. Used within arch/mm only.
|
|
||||||
*/
|
|
||||||
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
|
|
||||||
|
|
||||||
static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
|
|
||||||
{
|
|
||||||
unsigned long long x = ((unsigned long long) pteval.pte_low);
|
|
||||||
unsigned long long *xp = (unsigned long long *) pteptr;
|
|
||||||
/*
|
|
||||||
* Sign-extend based on NPHYS.
|
|
||||||
*/
|
|
||||||
*(xp) = (x & NPHYS_SIGN) ? (x | NPHYS_MASK) : x;
|
|
||||||
}
|
|
||||||
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PGD defines. Top level.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* To find an entry in a generic PGD. */
|
|
||||||
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
|
|
||||||
#define __pgd_offset(address) pgd_index(address)
|
|
||||||
#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
|
|
||||||
|
|
||||||
/* To find an entry in a kernel PGD. */
|
|
||||||
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
|
||||||
|
|
||||||
#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
|
|
||||||
#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PMD level access routines. Same notes as above.
|
|
||||||
*/
|
|
||||||
#define _PMD_EMPTY 0x0
|
|
||||||
/* Either the PMD is empty or present, it's not paged out */
|
|
||||||
#define pmd_present(pmd_entry) (pmd_val(pmd_entry) & _PAGE_PRESENT)
|
|
||||||
#define pmd_clear(pmd_entry_p) (set_pmd((pmd_entry_p), __pmd(_PMD_EMPTY)))
|
|
||||||
#define pmd_none(pmd_entry) (pmd_val((pmd_entry)) == _PMD_EMPTY)
|
|
||||||
#define pmd_bad(pmd_entry) ((pmd_val(pmd_entry) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
|
|
||||||
|
|
||||||
#define pmd_page_vaddr(pmd_entry) \
|
|
||||||
((unsigned long) __va(pmd_val(pmd_entry) & PAGE_MASK))
|
|
||||||
|
|
||||||
#define pmd_page(pmd) \
|
|
||||||
(virt_to_page(pmd_val(pmd)))
|
|
||||||
|
|
||||||
/* PMD to PTE dereferencing */
|
|
||||||
#define pte_index(address) \
|
|
||||||
((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
|
||||||
|
|
||||||
#define __pte_offset(address) pte_index(address)
|
|
||||||
|
|
||||||
#define pte_offset_kernel(dir, addr) \
|
|
||||||
((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + pte_index((addr)))
|
|
||||||
|
|
||||||
#define pte_offset_map(dir,addr) pte_offset_kernel(dir, addr)
|
|
||||||
#define pte_unmap(pte) do { } while (0)
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
/*
|
|
||||||
* PTEL coherent flags.
|
|
||||||
* See Chapter 17 ST50 CPU Core Volume 1, Architecture.
|
|
||||||
*/
|
|
||||||
/* The bits that are required in the SH-5 TLB are placed in the h/w-defined
|
|
||||||
positions, to avoid expensive bit shuffling on every refill. The remaining
|
|
||||||
bits are used for s/w purposes and masked out on each refill.
|
|
||||||
|
|
||||||
Note, the PTE slots are used to hold data of type swp_entry_t when a page is
|
|
||||||
swapped out. Only the _PAGE_PRESENT flag is significant when the page is
|
|
||||||
swapped out, and it must be placed so that it doesn't overlap either the
|
|
||||||
type or offset fields of swp_entry_t. For x86, offset is at [31:8] and type
|
|
||||||
at [6:1], with _PAGE_PRESENT at bit 0 for both pte_t and swp_entry_t. This
|
|
||||||
scheme doesn't map to SH-5 because bit [0] controls cacheability. So bit
|
|
||||||
[2] is used for _PAGE_PRESENT and the type field of swp_entry_t is split
|
|
||||||
into 2 pieces. That is handled by SWP_ENTRY and SWP_TYPE below. */
|
|
||||||
#define _PAGE_WT 0x001 /* CB0: if cacheable, 1->write-thru, 0->write-back */
|
|
||||||
#define _PAGE_DEVICE 0x001 /* CB0: if uncacheable, 1->device (i.e. no write-combining or reordering at bus level) */
|
|
||||||
#define _PAGE_CACHABLE 0x002 /* CB1: uncachable/cachable */
|
|
||||||
#define _PAGE_PRESENT 0x004 /* software: page referenced */
|
|
||||||
#define _PAGE_SIZE0 0x008 /* SZ0-bit : size of page */
|
|
||||||
#define _PAGE_SIZE1 0x010 /* SZ1-bit : size of page */
|
|
||||||
#define _PAGE_SHARED 0x020 /* software: reflects PTEH's SH */
|
|
||||||
#define _PAGE_READ 0x040 /* PR0-bit : read access allowed */
|
|
||||||
#define _PAGE_EXECUTE 0x080 /* PR1-bit : execute access allowed */
|
|
||||||
#define _PAGE_WRITE 0x100 /* PR2-bit : write access allowed */
|
|
||||||
#define _PAGE_USER 0x200 /* PR3-bit : user space access allowed */
|
|
||||||
#define _PAGE_DIRTY 0x400 /* software: page accessed in write */
|
|
||||||
#define _PAGE_ACCESSED 0x800 /* software: page referenced */
|
|
||||||
|
|
||||||
/* Wrapper for extended mode pgprot twiddling */
|
|
||||||
#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We can use the sign-extended bits in the PTEL to get 32 bits of
|
|
||||||
* software flags. This works for now because no implementations uses
|
|
||||||
* anything above the PPN field.
|
|
||||||
*/
|
|
||||||
#define _PAGE_WIRED _PAGE_EXT(0x001) /* software: wire the tlb entry */
|
|
||||||
#define _PAGE_SPECIAL _PAGE_EXT(0x002)
|
|
||||||
|
|
||||||
#define _PAGE_CLEAR_FLAGS (_PAGE_PRESENT | _PAGE_SHARED | \
|
|
||||||
_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)
|
|
||||||
|
|
||||||
/* Mask which drops software flags */
|
|
||||||
#define _PAGE_FLAGS_HARDWARE_MASK (NEFF_MASK & ~(_PAGE_CLEAR_FLAGS))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HugeTLB support
|
|
||||||
*/
|
|
||||||
#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
|
|
||||||
#define _PAGE_SZHUGE (_PAGE_SIZE0)
|
|
||||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
|
|
||||||
#define _PAGE_SZHUGE (_PAGE_SIZE1)
|
|
||||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512MB)
|
|
||||||
#define _PAGE_SZHUGE (_PAGE_SIZE0 | _PAGE_SIZE1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stub out _PAGE_SZHUGE if we don't have a good definition for it,
|
|
||||||
* to make pte_mkhuge() happy.
|
|
||||||
*/
|
|
||||||
#ifndef _PAGE_SZHUGE
|
|
||||||
# define _PAGE_SZHUGE (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default flags for a Kernel page.
|
|
||||||
* This is fundametally also SHARED because the main use of this define
|
|
||||||
* (other than for PGD/PMD entries) is for the VMALLOC pool which is
|
|
||||||
* contextless.
|
|
||||||
*
|
|
||||||
* _PAGE_EXECUTE is required for modules
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
|
|
||||||
_PAGE_EXECUTE | \
|
|
||||||
_PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
|
||||||
_PAGE_SHARED)
|
|
||||||
|
|
||||||
/* Default flags for a User page */
|
|
||||||
#define _PAGE_TABLE (_KERNPG_TABLE | _PAGE_USER)
|
|
||||||
|
|
||||||
#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
|
|
||||||
_PAGE_SPECIAL)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We have full permissions (Read/Write/Execute/Shared).
|
|
||||||
*/
|
|
||||||
#define _PAGE_COMMON (_PAGE_PRESENT | _PAGE_USER | \
|
|
||||||
_PAGE_CACHABLE | _PAGE_ACCESSED)
|
|
||||||
|
|
||||||
#define PAGE_NONE __pgprot(_PAGE_CACHABLE | _PAGE_ACCESSED)
|
|
||||||
#define PAGE_SHARED __pgprot(_PAGE_COMMON | _PAGE_READ | _PAGE_WRITE | \
|
|
||||||
_PAGE_SHARED)
|
|
||||||
#define PAGE_EXECREAD __pgprot(_PAGE_COMMON | _PAGE_READ | _PAGE_EXECUTE)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need to include PAGE_EXECUTE in PAGE_COPY because it is the default
|
|
||||||
* protection mode for the stack.
|
|
||||||
*/
|
|
||||||
#define PAGE_COPY PAGE_EXECREAD
|
|
||||||
|
|
||||||
#define PAGE_READONLY __pgprot(_PAGE_COMMON | _PAGE_READ)
|
|
||||||
#define PAGE_WRITEONLY __pgprot(_PAGE_COMMON | _PAGE_WRITE)
|
|
||||||
#define PAGE_RWX __pgprot(_PAGE_COMMON | _PAGE_READ | \
|
|
||||||
_PAGE_WRITE | _PAGE_EXECUTE)
|
|
||||||
#define PAGE_KERNEL __pgprot(_KERNPG_TABLE)
|
|
||||||
|
|
||||||
#define PAGE_KERNEL_NOCACHE \
|
|
||||||
__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
|
|
||||||
_PAGE_EXECUTE | _PAGE_ACCESSED | \
|
|
||||||
_PAGE_DIRTY | _PAGE_SHARED)
|
|
||||||
|
|
||||||
/* Make it a device mapping for maximum safety (e.g. for mapping device
|
|
||||||
registers into user-space via /dev/map). */
|
|
||||||
#define pgprot_noncached(x) __pgprot(((x).pgprot & ~(_PAGE_CACHABLE)) | _PAGE_DEVICE)
|
|
||||||
#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PTE level access routines.
|
|
||||||
*
|
|
||||||
* Note1:
|
|
||||||
* It's the tree walk leaf. This is physical address to be stored.
|
|
||||||
*
|
|
||||||
* Note 2:
|
|
||||||
* Regarding the choice of _PTE_EMPTY:
|
|
||||||
|
|
||||||
We must choose a bit pattern that cannot be valid, whether or not the page
|
|
||||||
is present. bit[2]==1 => present, bit[2]==0 => swapped out. If swapped
|
|
||||||
out, bits [31:8], [6:3], [1:0] are under swapper control, so only bit[7] is
|
|
||||||
left for us to select. If we force bit[7]==0 when swapped out, we could use
|
|
||||||
the combination bit[7,2]=2'b10 to indicate an empty PTE. Alternatively, if
|
|
||||||
we force bit[7]==1 when swapped out, we can use all zeroes to indicate
|
|
||||||
empty. This is convenient, because the page tables get cleared to zero
|
|
||||||
when they are allocated.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#define _PTE_EMPTY 0x0
|
|
||||||
#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
|
|
||||||
#define pte_clear(mm,addr,xp) (set_pte_at(mm, addr, xp, __pte(_PTE_EMPTY)))
|
|
||||||
#define pte_none(x) (pte_val(x) == _PTE_EMPTY)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some definitions to translate between mem_map, PTEs, and page
|
|
||||||
* addresses:
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a PTE, return the index of the mem_map[] entry corresponding
|
|
||||||
* to the page frame the PTE. Get the absolute physical address, make
|
|
||||||
* a relative physical address and translate it to an index.
|
|
||||||
*/
|
|
||||||
#define pte_pagenr(x) (((unsigned long) (pte_val(x)) - \
|
|
||||||
__MEMORY_START) >> PAGE_SHIFT)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a PTE, return the "struct page *".
|
|
||||||
*/
|
|
||||||
#define pte_page(x) (mem_map + pte_pagenr(x))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return number of (down rounded) MB corresponding to x pages.
|
|
||||||
*/
|
|
||||||
#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following have defined behavior only work if pte_present() is true.
|
|
||||||
*/
|
|
||||||
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
|
|
||||||
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
|
||||||
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
|
|
||||||
static inline int pte_special(pte_t pte){ return pte_val(pte) & _PAGE_SPECIAL; }
|
|
||||||
|
|
||||||
static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; }
|
|
||||||
static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
|
|
||||||
static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
|
|
||||||
static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_WRITE)); return pte; }
|
|
||||||
static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
|
|
||||||
static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
|
|
||||||
static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
|
|
||||||
static inline pte_t pte_mkspecial(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SPECIAL)); return pte; }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Conversion functions: convert a page and protection to a page entry.
|
|
||||||
*
|
|
||||||
* extern pte_t mk_pte(struct page *page, pgprot_t pgprot)
|
|
||||||
*/
|
|
||||||
#define mk_pte(page,pgprot) \
|
|
||||||
({ \
|
|
||||||
pte_t __pte; \
|
|
||||||
\
|
|
||||||
set_pte(&__pte, __pte((((page)-mem_map) << PAGE_SHIFT) | \
|
|
||||||
__MEMORY_START | pgprot_val((pgprot)))); \
|
|
||||||
__pte; \
|
|
||||||
})
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This takes a (absolute) physical page address that is used
|
|
||||||
* by the remapping functions
|
|
||||||
*/
|
|
||||||
#define mk_pte_phys(physpage, pgprot) \
|
|
||||||
({ pte_t __pte; set_pte(&__pte, __pte(physpage | pgprot_val(pgprot))); __pte; })
|
|
||||||
|
|
||||||
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|
||||||
{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
|
|
||||||
|
|
||||||
/* Encode and decode a swap entry */
|
|
||||||
#define __swp_type(x) (((x).val & 3) + (((x).val >> 1) & 0x3c))
|
|
||||||
#define __swp_offset(x) ((x).val >> 8)
|
|
||||||
#define __swp_entry(type, offset) ((swp_entry_t) { ((offset << 8) + ((type & 0x3c) << 1) + (type & 3)) })
|
|
||||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
|
||||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
|
||||||
|
|
||||||
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
|
|
||||||
#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_PGTABLE_64_H */
|
|
|
@ -1,6 +1,2 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
# ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/posix_types_32.h>
|
#include <asm/posix_types_32.h>
|
||||||
# else
|
|
||||||
# include <asm/posix_types_64.h>
|
|
||||||
# endif
|
|
||||||
|
|
|
@ -39,9 +39,6 @@ enum cpu_type {
|
||||||
/* SH4AL-DSP types */
|
/* SH4AL-DSP types */
|
||||||
CPU_SH7343, CPU_SH7722, CPU_SH7366, CPU_SH7372,
|
CPU_SH7343, CPU_SH7722, CPU_SH7366, CPU_SH7372,
|
||||||
|
|
||||||
/* SH-5 types */
|
|
||||||
CPU_SH5_101, CPU_SH5_103,
|
|
||||||
|
|
||||||
/* Unknown subtype */
|
/* Unknown subtype */
|
||||||
CPU_SH_NONE
|
CPU_SH_NONE
|
||||||
};
|
};
|
||||||
|
@ -53,7 +50,6 @@ enum cpu_family {
|
||||||
CPU_FAMILY_SH4,
|
CPU_FAMILY_SH4,
|
||||||
CPU_FAMILY_SH4A,
|
CPU_FAMILY_SH4A,
|
||||||
CPU_FAMILY_SH4AL_DSP,
|
CPU_FAMILY_SH4AL_DSP,
|
||||||
CPU_FAMILY_SH5,
|
|
||||||
CPU_FAMILY_UNKNOWN,
|
CPU_FAMILY_UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,18 +163,12 @@ int vsyscall_init(void);
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_CPU_SH2A
|
#ifdef CONFIG_CPU_SH2A
|
||||||
extern unsigned int instruction_size(unsigned int insn);
|
extern unsigned int instruction_size(unsigned int insn);
|
||||||
#elif defined(CONFIG_SUPERH32)
|
|
||||||
#define instruction_size(insn) (2)
|
|
||||||
#else
|
#else
|
||||||
#define instruction_size(insn) (4)
|
#define instruction_size(insn) (2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/processor_32.h>
|
#include <asm/processor_32.h>
|
||||||
#else
|
|
||||||
# include <asm/processor_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_PROCESSOR_H */
|
#endif /* __ASM_SH_PROCESSOR_H */
|
||||||
|
|
|
@ -1,212 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_PROCESSOR_64_H
|
|
||||||
#define __ASM_SH_PROCESSOR_64_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include/asm-sh/processor_64.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/types.h>
|
|
||||||
#include <cpu/registers.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User space process size: 2GB - 4k.
|
|
||||||
*/
|
|
||||||
#define TASK_SIZE 0x7ffff000UL
|
|
||||||
|
|
||||||
#define STACK_TOP TASK_SIZE
|
|
||||||
#define STACK_TOP_MAX STACK_TOP
|
|
||||||
|
|
||||||
/* This decides where the kernel will search for a free chunk of vm
|
|
||||||
* space during mmap's.
|
|
||||||
*/
|
|
||||||
#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bit of SR register
|
|
||||||
*
|
|
||||||
* FD-bit:
|
|
||||||
* When it's set, it means the processor doesn't have right to use FPU,
|
|
||||||
* and it results exception when the floating operation is executed.
|
|
||||||
*
|
|
||||||
* IMASK-bit:
|
|
||||||
* Interrupt level mask
|
|
||||||
*
|
|
||||||
* STEP-bit:
|
|
||||||
* Single step bit
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#if defined(CONFIG_SH64_SR_WATCH)
|
|
||||||
#define SR_MMU 0x84000000
|
|
||||||
#else
|
|
||||||
#define SR_MMU 0x80000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SR_IMASK 0x000000f0
|
|
||||||
#define SR_FD 0x00008000
|
|
||||||
#define SR_SSTEP 0x08000000
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FPU structure and data : require 8-byte alignment as we need to access it
|
|
||||||
with fld.p, fst.p
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct sh_fpu_hard_struct {
|
|
||||||
unsigned long fp_regs[64];
|
|
||||||
unsigned int fpscr;
|
|
||||||
/* long status; * software status information */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Dummy fpu emulator */
|
|
||||||
struct sh_fpu_soft_struct {
|
|
||||||
unsigned long fp_regs[64];
|
|
||||||
unsigned int fpscr;
|
|
||||||
unsigned char lookahead;
|
|
||||||
unsigned long entry_pc;
|
|
||||||
};
|
|
||||||
|
|
||||||
union thread_xstate {
|
|
||||||
struct sh_fpu_hard_struct hardfpu;
|
|
||||||
struct sh_fpu_soft_struct softfpu;
|
|
||||||
/*
|
|
||||||
* The structure definitions only produce 32 bit alignment, yet we need
|
|
||||||
* to access them using 64 bit load/store as well.
|
|
||||||
*/
|
|
||||||
unsigned long long alignment_dummy;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct thread_struct {
|
|
||||||
unsigned long sp;
|
|
||||||
unsigned long pc;
|
|
||||||
|
|
||||||
/* Various thread flags, see SH_THREAD_xxx */
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
/* This stores the address of the pt_regs built during a context
|
|
||||||
switch, or of the register save area built for a kernel mode
|
|
||||||
exception. It is used for backtracing the stack of a sleeping task
|
|
||||||
or one that traps in kernel mode. */
|
|
||||||
struct pt_regs *kregs;
|
|
||||||
/* This stores the address of the pt_regs constructed on entry from
|
|
||||||
user mode. It is a fixed value over the lifetime of a process, or
|
|
||||||
NULL for a kernel thread. */
|
|
||||||
struct pt_regs *uregs;
|
|
||||||
|
|
||||||
unsigned long address;
|
|
||||||
/* Hardware debugging registers may come here */
|
|
||||||
|
|
||||||
/* floating point info */
|
|
||||||
union thread_xstate *xstate;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fpu_counter contains the number of consecutive context switches
|
|
||||||
* that the FPU is used. If this is over a threshold, the lazy fpu
|
|
||||||
* saving becomes unlazy to save the trap. This is an unsigned char
|
|
||||||
* so that after 256 times the counter wraps and the behavior turns
|
|
||||||
* lazy again; this to deal with bursty apps that only use FPU for
|
|
||||||
* a short time
|
|
||||||
*/
|
|
||||||
unsigned char fpu_counter;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define INIT_MMAP \
|
|
||||||
{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
|
|
||||||
|
|
||||||
#define INIT_THREAD { \
|
|
||||||
.sp = sizeof(init_stack) + \
|
|
||||||
(long) &init_stack, \
|
|
||||||
.pc = 0, \
|
|
||||||
.kregs = &fake_swapper_regs, \
|
|
||||||
.uregs = NULL, \
|
|
||||||
.address = 0, \
|
|
||||||
.flags = 0, \
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do necessary setup to start up a newly executed thread.
|
|
||||||
*/
|
|
||||||
#define SR_USER (SR_MMU | SR_FD)
|
|
||||||
|
|
||||||
#define start_thread(_regs, new_pc, new_sp) \
|
|
||||||
_regs->sr = SR_USER; /* User mode. */ \
|
|
||||||
_regs->pc = new_pc - 4; /* Compensate syscall exit */ \
|
|
||||||
_regs->pc |= 1; /* Set SHmedia ! */ \
|
|
||||||
_regs->regs[18] = 0; \
|
|
||||||
_regs->regs[15] = new_sp
|
|
||||||
|
|
||||||
/* Forward declaration, a strange C thing */
|
|
||||||
struct task_struct;
|
|
||||||
struct mm_struct;
|
|
||||||
|
|
||||||
/* Free all resources held by a thread. */
|
|
||||||
extern void release_thread(struct task_struct *);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FPU lazy state save handling.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void disable_fpu(void)
|
|
||||||
{
|
|
||||||
unsigned long long __dummy;
|
|
||||||
|
|
||||||
/* Set FD flag in SR */
|
|
||||||
__asm__ __volatile__("getcon " __SR ", %0\n\t"
|
|
||||||
"or %0, %1, %0\n\t"
|
|
||||||
"putcon %0, " __SR "\n\t"
|
|
||||||
: "=&r" (__dummy)
|
|
||||||
: "r" (SR_FD));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void enable_fpu(void)
|
|
||||||
{
|
|
||||||
unsigned long long __dummy;
|
|
||||||
|
|
||||||
/* Clear out FD flag in SR */
|
|
||||||
__asm__ __volatile__("getcon " __SR ", %0\n\t"
|
|
||||||
"and %0, %1, %0\n\t"
|
|
||||||
"putcon %0, " __SR "\n\t"
|
|
||||||
: "=&r" (__dummy)
|
|
||||||
: "r" (~SR_FD));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round to nearest, no exceptions on inexact, overflow, underflow,
|
|
||||||
zero-divide, invalid. Configure option for whether to flush denorms to
|
|
||||||
zero, or except if a denorm is encountered. */
|
|
||||||
#if defined(CONFIG_SH64_FPU_DENORM_FLUSH)
|
|
||||||
#define FPSCR_INIT 0x00040000
|
|
||||||
#else
|
|
||||||
#define FPSCR_INIT 0x00000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
/* Initialise the FP state of a task */
|
|
||||||
void fpinit(struct sh_fpu_hard_struct *fpregs);
|
|
||||||
#else
|
|
||||||
#define fpinit(fpregs) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern struct task_struct *last_task_used_math;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return saved PC of a blocked thread.
|
|
||||||
*/
|
|
||||||
#define thread_saved_pc(tsk) (tsk->thread.pc)
|
|
||||||
|
|
||||||
extern unsigned long get_wchan(struct task_struct *p);
|
|
||||||
|
|
||||||
#define KSTK_EIP(tsk) ((tsk)->thread.pc)
|
|
||||||
#define KSTK_ESP(tsk) ((tsk)->thread.sp)
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
#endif /* __ASM_SH_PROCESSOR_64_H */
|
|
|
@ -1,14 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_PTRACE_64_H
|
|
||||||
#define __ASM_SH_PTRACE_64_H
|
|
||||||
|
|
||||||
#include <uapi/asm/ptrace_64.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_REG_OFFSET offsetof(struct pt_regs, tregs[7])
|
|
||||||
static inline long regs_return_value(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return regs->regs[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_PTRACE_64_H */
|
|
|
@ -1,6 +1,2 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/string_32.h>
|
#include <asm/string_32.h>
|
||||||
#else
|
|
||||||
# include <asm/string_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_STRING_64_H
|
|
||||||
#define __ASM_SH_STRING_64_H
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_MEMSET
|
|
||||||
extern void *memset(void *__s, int __c, size_t __count);
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_MEMCPY
|
|
||||||
extern void *memcpy(void *dest, const void *src, size_t count);
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_STRLEN
|
|
||||||
extern size_t strlen(const char *);
|
|
||||||
|
|
||||||
#define __HAVE_ARCH_STRCPY
|
|
||||||
extern char *strcpy(char *__dest, const char *__src);
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_STRING_64_H */
|
|
|
@ -4,13 +4,4 @@
|
||||||
* Copyright (C) 2003 Paul Mundt
|
* Copyright (C) 2003 Paul Mundt
|
||||||
* Copyright (C) 2004 Richard Curnow
|
* Copyright (C) 2004 Richard Curnow
|
||||||
*/
|
*/
|
||||||
#ifndef __ASM_SH_SWITCH_TO_H
|
|
||||||
#define __ASM_SH_SWITCH_TO_H
|
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/switch_to_32.h>
|
#include <asm/switch_to_32.h>
|
||||||
#else
|
|
||||||
# include <asm/switch_to_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_SWITCH_TO_H */
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_SH_SWITCH_TO_64_H
|
|
||||||
#define __ASM_SH_SWITCH_TO_64_H
|
|
||||||
|
|
||||||
struct thread_struct;
|
|
||||||
struct task_struct;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* switch_to() should switch tasks to task nr n, first
|
|
||||||
*/
|
|
||||||
struct task_struct *sh64_switch_to(struct task_struct *prev,
|
|
||||||
struct thread_struct *prev_thread,
|
|
||||||
struct task_struct *next,
|
|
||||||
struct thread_struct *next_thread);
|
|
||||||
|
|
||||||
#define switch_to(prev,next,last) \
|
|
||||||
do { \
|
|
||||||
if (last_task_used_math != next) { \
|
|
||||||
struct pt_regs *regs = next->thread.uregs; \
|
|
||||||
if (regs) regs->sr |= SR_FD; \
|
|
||||||
} \
|
|
||||||
last = sh64_switch_to(prev, &prev->thread, next, \
|
|
||||||
&next->thread); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_SWITCH_TO_64_H */
|
|
|
@ -4,10 +4,6 @@
|
||||||
|
|
||||||
extern const unsigned long sys_call_table[];
|
extern const unsigned long sys_call_table[];
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/syscall_32.h>
|
#include <asm/syscall_32.h>
|
||||||
#else
|
|
||||||
# include <asm/syscall_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_SYSCALL_H */
|
#endif /* __ASM_SH_SYSCALL_H */
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_SYSCALL_64_H
|
|
||||||
#define __ASM_SH_SYSCALL_64_H
|
|
||||||
|
|
||||||
#include <uapi/linux/audit.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <asm/ptrace.h>
|
|
||||||
|
|
||||||
/* The system call number is given by the user in R9 */
|
|
||||||
static inline long syscall_get_nr(struct task_struct *task,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return (regs->syscall_nr >= 0) ? regs->regs[9] : -1L;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void syscall_rollback(struct task_struct *task,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* XXX: This needs some thought. On SH we don't
|
|
||||||
* save away the original R9 value anywhere.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline long syscall_get_error(struct task_struct *task,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline long syscall_get_return_value(struct task_struct *task,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return regs->regs[9];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void syscall_set_return_value(struct task_struct *task,
|
|
||||||
struct pt_regs *regs,
|
|
||||||
int error, long val)
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
regs->regs[9] = -error;
|
|
||||||
else
|
|
||||||
regs->regs[9] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void syscall_get_arguments(struct task_struct *task,
|
|
||||||
struct pt_regs *regs,
|
|
||||||
unsigned long *args)
|
|
||||||
{
|
|
||||||
memcpy(args, ®s->regs[2], 6 * sizeof(args[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void syscall_set_arguments(struct task_struct *task,
|
|
||||||
struct pt_regs *regs,
|
|
||||||
const unsigned long *args)
|
|
||||||
{
|
|
||||||
memcpy(®s->regs[2], args, 6 * sizeof(args[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int syscall_get_arch(struct task_struct *task)
|
|
||||||
{
|
|
||||||
int arch = AUDIT_ARCH_SH;
|
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
|
||||||
arch |= __AUDIT_ARCH_64BIT;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
|
||||||
arch |= __AUDIT_ARCH_LE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return arch;
|
|
||||||
}
|
|
||||||
#endif /* __ASM_SH_SYSCALL_64_H */
|
|
|
@ -2,8 +2,6 @@
|
||||||
#ifndef __ASM_SH_SYSCALLS_H
|
#ifndef __ASM_SH_SYSCALLS_H
|
||||||
#define __ASM_SH_SYSCALLS_H
|
#define __ASM_SH_SYSCALLS_H
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
|
|
||||||
asmlinkage int old_mmap(unsigned long addr, unsigned long len,
|
asmlinkage int old_mmap(unsigned long addr, unsigned long len,
|
||||||
unsigned long prot, unsigned long flags,
|
unsigned long prot, unsigned long flags,
|
||||||
int fd, unsigned long off);
|
int fd, unsigned long off);
|
||||||
|
@ -11,11 +9,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
||||||
unsigned long prot, unsigned long flags,
|
unsigned long prot, unsigned long flags,
|
||||||
unsigned long fd, unsigned long pgoff);
|
unsigned long fd, unsigned long pgoff);
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/syscalls_32.h>
|
#include <asm/syscalls_32.h>
|
||||||
#else
|
|
||||||
# include <asm/syscalls_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
#endif /* __ASM_SH_SYSCALLS_H */
|
#endif /* __ASM_SH_SYSCALLS_H */
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_SYSCALLS_64_H
|
|
||||||
#define __ASM_SH_SYSCALLS_64_H
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
#include <linux/linkage.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
struct pt_regs;
|
|
||||||
|
|
||||||
/* Misc syscall related bits */
|
|
||||||
asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs);
|
|
||||||
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
#endif /* __ASM_SH_SYSCALLS_64_H */
|
|
|
@ -70,9 +70,7 @@ register unsigned long current_stack_pointer asm("r15") __used;
|
||||||
static inline struct thread_info *current_thread_info(void)
|
static inline struct thread_info *current_thread_info(void)
|
||||||
{
|
{
|
||||||
struct thread_info *ti;
|
struct thread_info *ti;
|
||||||
#if defined(CONFIG_SUPERH64)
|
#if defined(CONFIG_CPU_HAS_SR_RB)
|
||||||
__asm__ __volatile__ ("getcon cr17, %0" : "=r" (ti));
|
|
||||||
#elif defined(CONFIG_CPU_HAS_SR_RB)
|
|
||||||
__asm__ __volatile__ ("stc r7_bank, %0" : "=r" (ti));
|
__asm__ __volatile__ ("stc r7_bank, %0" : "=r" (ti));
|
||||||
#else
|
#else
|
||||||
unsigned long __dummy;
|
unsigned long __dummy;
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
#ifndef __ASM_SH_TLB_H
|
#ifndef __ASM_SH_TLB_H
|
||||||
#define __ASM_SH_TLB_H
|
#define __ASM_SH_TLB_H
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
# include <asm/tlb_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
|
|
||||||
|
@ -14,7 +10,7 @@
|
||||||
|
|
||||||
#include <asm-generic/tlb.h>
|
#include <asm-generic/tlb.h>
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SUPERH64)
|
#if defined(CONFIG_CPU_SH4)
|
||||||
extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
|
extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
|
||||||
extern void tlb_unwire_entry(void);
|
extern void tlb_unwire_entry(void);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* include/asm-sh/tlb_64.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Paul Mundt
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_SH_TLB_64_H
|
|
||||||
#define __ASM_SH_TLB_64_H
|
|
||||||
|
|
||||||
/* ITLB defines */
|
|
||||||
#define ITLB_FIXED 0x00000000 /* First fixed ITLB, see head.S */
|
|
||||||
#define ITLB_LAST_VAR_UNRESTRICTED 0x000003F0 /* Last ITLB */
|
|
||||||
|
|
||||||
/* DTLB defines */
|
|
||||||
#define DTLB_FIXED 0x00800000 /* First fixed DTLB, see head.S */
|
|
||||||
#define DTLB_LAST_VAR_UNRESTRICTED 0x008003F0 /* Last DTLB */
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* for_each_dtlb_entry - Iterate over free (non-wired) DTLB entries
|
|
||||||
*
|
|
||||||
* @tlb: TLB entry
|
|
||||||
*/
|
|
||||||
#define for_each_dtlb_entry(tlb) \
|
|
||||||
for (tlb = cpu_data->dtlb.first; \
|
|
||||||
tlb <= cpu_data->dtlb.last; \
|
|
||||||
tlb += cpu_data->dtlb.step)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* for_each_itlb_entry - Iterate over free (non-wired) ITLB entries
|
|
||||||
*
|
|
||||||
* @tlb: TLB entry
|
|
||||||
*/
|
|
||||||
#define for_each_itlb_entry(tlb) \
|
|
||||||
for (tlb = cpu_data->itlb.first; \
|
|
||||||
tlb <= cpu_data->itlb.last; \
|
|
||||||
tlb += cpu_data->itlb.step)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __flush_tlb_slot - Flushes TLB slot @slot.
|
|
||||||
*
|
|
||||||
* @slot: Address of TLB slot.
|
|
||||||
*/
|
|
||||||
static inline void __flush_tlb_slot(unsigned long long slot)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__ ("putcfg %0, 0, r63\n" : : "r" (slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_MMU
|
|
||||||
/* arch/sh64/mm/tlb.c */
|
|
||||||
int sh64_tlb_init(void);
|
|
||||||
unsigned long long sh64_next_free_dtlb_entry(void);
|
|
||||||
unsigned long long sh64_get_wired_dtlb_entry(void);
|
|
||||||
int sh64_put_wired_dtlb_entry(unsigned long long entry);
|
|
||||||
void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr,
|
|
||||||
unsigned long asid, unsigned long paddr);
|
|
||||||
void sh64_teardown_tlb_slot(unsigned long long config_addr);
|
|
||||||
#else
|
|
||||||
#define sh64_tlb_init() do { } while (0)
|
|
||||||
#define sh64_next_free_dtlb_entry() (0)
|
|
||||||
#define sh64_get_wired_dtlb_entry() (0)
|
|
||||||
#define sh64_put_wired_dtlb_entry(entry) do { } while (0)
|
|
||||||
#define sh64_setup_tlb_slot(conf, virt, asid, phys) do { } while (0)
|
|
||||||
#define sh64_teardown_tlb_slot(addr) do { } while (0)
|
|
||||||
#endif /* CONFIG_MMU */
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
#endif /* __ASM_SH_TLB_64_H */
|
|
|
@ -4,11 +4,7 @@
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
# include <asm/traps_32.h>
|
# include <asm/traps_32.h>
|
||||||
#else
|
|
||||||
# include <asm/traps_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BUILD_TRAP_HANDLER(address_error);
|
BUILD_TRAP_HANDLER(address_error);
|
||||||
BUILD_TRAP_HANDLER(debug);
|
BUILD_TRAP_HANDLER(debug);
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#ifndef __ASM_SH_TRAPS_64_H
|
|
||||||
#define __ASM_SH_TRAPS_64_H
|
|
||||||
|
|
||||||
#include <cpu/registers.h>
|
|
||||||
|
|
||||||
extern void phys_stext(void);
|
|
||||||
|
|
||||||
#define lookup_exception_vector() \
|
|
||||||
({ \
|
|
||||||
unsigned long _vec; \
|
|
||||||
\
|
|
||||||
__asm__ __volatile__ ( \
|
|
||||||
"getcon " __EXPEVT ", %0\n\t" \
|
|
||||||
: "=r" (_vec) \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
_vec; \
|
|
||||||
})
|
|
||||||
|
|
||||||
static inline void trigger_address_error(void)
|
|
||||||
{
|
|
||||||
phys_stext();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BUILD_TRAP_HANDLER(name) \
|
|
||||||
asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs)
|
|
||||||
#define TRAP_HANDLER_DECL
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_TRAPS_64_H */
|
|
|
@ -9,13 +9,8 @@
|
||||||
*/
|
*/
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
typedef u16 insn_size_t;
|
typedef u16 insn_size_t;
|
||||||
typedef u32 reg_size_t;
|
typedef u32 reg_size_t;
|
||||||
#else
|
|
||||||
typedef u32 insn_size_t;
|
|
||||||
typedef u64 reg_size_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
#endif /* __ASM_SH_TYPES_H */
|
#endif /* __ASM_SH_TYPES_H */
|
||||||
|
|
|
@ -96,11 +96,7 @@ struct __large_struct { unsigned long buf[100]; };
|
||||||
__pu_err; \
|
__pu_err; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
# include <asm/uaccess_32.h>
|
# include <asm/uaccess_32.h>
|
||||||
#else
|
|
||||||
# include <asm/uaccess_64.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern long strncpy_from_user(char *dest, const char __user *src, long count);
|
extern long strncpy_from_user(char *dest, const char __user *src, long count);
|
||||||
|
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_UACCESS_64_H
|
|
||||||
#define __ASM_SH_UACCESS_64_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include/asm-sh/uaccess_64.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003, 2004 Paul Mundt
|
|
||||||
*
|
|
||||||
* User space memory access functions
|
|
||||||
*
|
|
||||||
* Copyright (C) 1999 Niibe Yutaka
|
|
||||||
*
|
|
||||||
* Based on:
|
|
||||||
* MIPS implementation version 1.15 by
|
|
||||||
* Copyright (C) 1996, 1997, 1998 by Ralf Baechle
|
|
||||||
* and i386 version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __get_user_size(x,ptr,size,retval) \
|
|
||||||
do { \
|
|
||||||
retval = 0; \
|
|
||||||
x = 0; \
|
|
||||||
switch (size) { \
|
|
||||||
case 1: \
|
|
||||||
retval = __get_user_asm_b((void *)&x, \
|
|
||||||
(long)ptr); \
|
|
||||||
break; \
|
|
||||||
case 2: \
|
|
||||||
retval = __get_user_asm_w((void *)&x, \
|
|
||||||
(long)ptr); \
|
|
||||||
break; \
|
|
||||||
case 4: \
|
|
||||||
retval = __get_user_asm_l((void *)&x, \
|
|
||||||
(long)ptr); \
|
|
||||||
break; \
|
|
||||||
case 8: \
|
|
||||||
retval = __get_user_asm_q((void *)&x, \
|
|
||||||
(long)ptr); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
__get_user_unknown(); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
extern long __get_user_asm_b(void *, long);
|
|
||||||
extern long __get_user_asm_w(void *, long);
|
|
||||||
extern long __get_user_asm_l(void *, long);
|
|
||||||
extern long __get_user_asm_q(void *, long);
|
|
||||||
extern void __get_user_unknown(void);
|
|
||||||
|
|
||||||
#define __put_user_size(x,ptr,size,retval) \
|
|
||||||
do { \
|
|
||||||
retval = 0; \
|
|
||||||
switch (size) { \
|
|
||||||
case 1: \
|
|
||||||
retval = __put_user_asm_b((void *)&x, \
|
|
||||||
(__force long)ptr); \
|
|
||||||
break; \
|
|
||||||
case 2: \
|
|
||||||
retval = __put_user_asm_w((void *)&x, \
|
|
||||||
(__force long)ptr); \
|
|
||||||
break; \
|
|
||||||
case 4: \
|
|
||||||
retval = __put_user_asm_l((void *)&x, \
|
|
||||||
(__force long)ptr); \
|
|
||||||
break; \
|
|
||||||
case 8: \
|
|
||||||
retval = __put_user_asm_q((void *)&x, \
|
|
||||||
(__force long)ptr); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
__put_user_unknown(); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
extern long __put_user_asm_b(void *, long);
|
|
||||||
extern long __put_user_asm_w(void *, long);
|
|
||||||
extern long __put_user_asm_l(void *, long);
|
|
||||||
extern long __put_user_asm_q(void *, long);
|
|
||||||
extern void __put_user_unknown(void);
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_UACCESS_64_H */
|
|
|
@ -1,9 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
# ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/unistd_32.h>
|
#include <asm/unistd_32.h>
|
||||||
# else
|
|
||||||
# include <asm/unistd_64.h>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#define NR_syscalls __NR_syscalls
|
#define NR_syscalls __NR_syscalls
|
||||||
|
|
||||||
|
|
|
@ -28,19 +28,12 @@
|
||||||
* to write an integer number of pages.
|
* to write an integer number of pages.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
|
|
||||||
struct user_fpu_struct {
|
|
||||||
unsigned long fp_regs[32];
|
|
||||||
unsigned int fpscr;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
struct user_fpu_struct {
|
struct user_fpu_struct {
|
||||||
unsigned long fp_regs[16];
|
unsigned long fp_regs[16];
|
||||||
unsigned long xfp_regs[16];
|
unsigned long xfp_regs[16];
|
||||||
unsigned long fpscr;
|
unsigned long fpscr;
|
||||||
unsigned long fpul;
|
unsigned long fpul;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct user {
|
struct user {
|
||||||
struct pt_regs regs; /* entire machine state */
|
struct pt_regs regs; /* entire machine state */
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
# define MODULE_PROC_FAMILY "SH3LE "
|
# define MODULE_PROC_FAMILY "SH3LE "
|
||||||
# elif defined CONFIG_CPU_SH4
|
# elif defined CONFIG_CPU_SH4
|
||||||
# define MODULE_PROC_FAMILY "SH4LE "
|
# define MODULE_PROC_FAMILY "SH4LE "
|
||||||
# elif defined CONFIG_CPU_SH5
|
|
||||||
# define MODULE_PROC_FAMILY "SH5LE "
|
|
||||||
# else
|
# else
|
||||||
# error unknown processor family
|
# error unknown processor family
|
||||||
# endif
|
# endif
|
||||||
|
@ -22,8 +20,6 @@
|
||||||
# define MODULE_PROC_FAMILY "SH3BE "
|
# define MODULE_PROC_FAMILY "SH3BE "
|
||||||
# elif defined CONFIG_CPU_SH4
|
# elif defined CONFIG_CPU_SH4
|
||||||
# define MODULE_PROC_FAMILY "SH4BE "
|
# define MODULE_PROC_FAMILY "SH4BE "
|
||||||
# elif defined CONFIG_CPU_SH5
|
|
||||||
# define MODULE_PROC_FAMILY "SH5BE "
|
|
||||||
# else
|
# else
|
||||||
# error unknown processor family
|
# error unknown processor family
|
||||||
# endif
|
# endif
|
||||||
|
|
|
@ -15,12 +15,4 @@
|
||||||
#define DWARF_EH_FRAME
|
#define DWARF_EH_FRAME
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
#define EXTRA_TEXT \
|
|
||||||
*(.text64) \
|
|
||||||
*(.text..SHmedia32)
|
|
||||||
#else
|
|
||||||
#define EXTRA_TEXT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_VMLINUX_LDS_H */
|
#endif /* __ASM_SH_VMLINUX_LDS_H */
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_CPU_SH5_ADDRSPACE_H
|
|
||||||
#define __ASM_SH_CPU_SH5_ADDRSPACE_H
|
|
||||||
|
|
||||||
#define PHYS_PERIPHERAL_BLOCK 0x09000000
|
|
||||||
#define PHYS_DMAC_BLOCK 0x0e000000
|
|
||||||
#define PHYS_PCI_BLOCK 0x60000000
|
|
||||||
#define PHYS_EMI_BLOCK 0xff000000
|
|
||||||
|
|
||||||
/* No segmentation.. */
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_CPU_SH5_ADDRSPACE_H */
|
|
|
@ -1,94 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_CPU_SH5_CACHE_H
|
|
||||||
#define __ASM_SH_CPU_SH5_CACHE_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include/asm-sh/cpu-sh5/cache.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003, 2004 Paul Mundt
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define L1_CACHE_SHIFT 5
|
|
||||||
|
|
||||||
/* Valid and Dirty bits */
|
|
||||||
#define SH_CACHE_VALID (1LL<<0)
|
|
||||||
#define SH_CACHE_UPDATED (1LL<<57)
|
|
||||||
|
|
||||||
/* Unimplemented compat bits.. */
|
|
||||||
#define SH_CACHE_COMBINED 0
|
|
||||||
#define SH_CACHE_ASSOC 0
|
|
||||||
|
|
||||||
/* Cache flags */
|
|
||||||
#define SH_CACHE_MODE_WT (1LL<<0)
|
|
||||||
#define SH_CACHE_MODE_WB (1LL<<1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Control Registers.
|
|
||||||
*/
|
|
||||||
#define ICCR_BASE 0x01600000 /* Instruction Cache Control Register */
|
|
||||||
#define ICCR_REG0 0 /* Register 0 offset */
|
|
||||||
#define ICCR_REG1 1 /* Register 1 offset */
|
|
||||||
#define ICCR0 ICCR_BASE+ICCR_REG0
|
|
||||||
#define ICCR1 ICCR_BASE+ICCR_REG1
|
|
||||||
|
|
||||||
#define ICCR0_OFF 0x0 /* Set ICACHE off */
|
|
||||||
#define ICCR0_ON 0x1 /* Set ICACHE on */
|
|
||||||
#define ICCR0_ICI 0x2 /* Invalidate all in IC */
|
|
||||||
|
|
||||||
#define ICCR1_NOLOCK 0x0 /* Set No Locking */
|
|
||||||
|
|
||||||
#define OCCR_BASE 0x01E00000 /* Operand Cache Control Register */
|
|
||||||
#define OCCR_REG0 0 /* Register 0 offset */
|
|
||||||
#define OCCR_REG1 1 /* Register 1 offset */
|
|
||||||
#define OCCR0 OCCR_BASE+OCCR_REG0
|
|
||||||
#define OCCR1 OCCR_BASE+OCCR_REG1
|
|
||||||
|
|
||||||
#define OCCR0_OFF 0x0 /* Set OCACHE off */
|
|
||||||
#define OCCR0_ON 0x1 /* Set OCACHE on */
|
|
||||||
#define OCCR0_OCI 0x2 /* Invalidate all in OC */
|
|
||||||
#define OCCR0_WT 0x4 /* Set OCACHE in WT Mode */
|
|
||||||
#define OCCR0_WB 0x0 /* Set OCACHE in WB Mode */
|
|
||||||
|
|
||||||
#define OCCR1_NOLOCK 0x0 /* Set No Locking */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SH-5
|
|
||||||
* A bit of description here, for neff=32.
|
|
||||||
*
|
|
||||||
* |<--- tag (19 bits) --->|
|
|
||||||
* +-----------------------------+-----------------+------+----------+------+
|
|
||||||
* | | | ways |set index |offset|
|
|
||||||
* +-----------------------------+-----------------+------+----------+------+
|
|
||||||
* ^ 2 bits 8 bits 5 bits
|
|
||||||
* +- Bit 31
|
|
||||||
*
|
|
||||||
* Cacheline size is based on offset: 5 bits = 32 bytes per line
|
|
||||||
* A cache line is identified by a tag + set but OCACHETAG/ICACHETAG
|
|
||||||
* have a broader space for registers. These are outlined by
|
|
||||||
* CACHE_?C_*_STEP below.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Instruction cache */
|
|
||||||
#define CACHE_IC_ADDRESS_ARRAY 0x01000000
|
|
||||||
|
|
||||||
/* Operand Cache */
|
|
||||||
#define CACHE_OC_ADDRESS_ARRAY 0x01800000
|
|
||||||
|
|
||||||
/* These declarations relate to cache 'synonyms' in the operand cache. A
|
|
||||||
'synonym' occurs where effective address bits overlap between those used for
|
|
||||||
indexing the cache sets and those passed to the MMU for translation. In the
|
|
||||||
case of SH5-101 & SH5-103, only bit 12 is affected for 4k pages. */
|
|
||||||
|
|
||||||
#define CACHE_OC_N_SYNBITS 1 /* Number of synonym bits */
|
|
||||||
#define CACHE_OC_SYN_SHIFT 12
|
|
||||||
/* Mask to select synonym bit(s) */
|
|
||||||
#define CACHE_OC_SYN_MASK (((1UL<<CACHE_OC_N_SYNBITS)-1)<<CACHE_OC_SYN_SHIFT)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Instruction cache can't be invalidated based on physical addresses.
|
|
||||||
* No Instruction Cache defines required, then.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_CPU_SH5_CACHE_H */
|
|
|
@ -1,113 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_CPU_SH5_IRQ_H
|
|
||||||
#define __ASM_SH_CPU_SH5_IRQ_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include/asm-sh/cpu-sh5/irq.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Encoded IRQs are not considered worth to be supported.
|
|
||||||
* Main reason is that there's no per-encoded-interrupt
|
|
||||||
* enable/disable mechanism (as there was in SH3/4).
|
|
||||||
* An all enabled/all disabled is worth only if there's
|
|
||||||
* a cascaded IC to disable/enable/ack on. Until such
|
|
||||||
* IC is available there's no such support.
|
|
||||||
*
|
|
||||||
* Presumably Encoded IRQs may use extra IRQs beyond 64,
|
|
||||||
* below. Some logic must be added to cope with IRQ_IRL?
|
|
||||||
* in an exclusive way.
|
|
||||||
*
|
|
||||||
* Priorities are set at Platform level, when IRQ_IRL0-3
|
|
||||||
* are set to 0 Encoding is allowed. Otherwise it's not
|
|
||||||
* allowed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Independent IRQs */
|
|
||||||
#define IRQ_IRL0 0
|
|
||||||
#define IRQ_IRL1 1
|
|
||||||
#define IRQ_IRL2 2
|
|
||||||
#define IRQ_IRL3 3
|
|
||||||
|
|
||||||
#define IRQ_INTA 4
|
|
||||||
#define IRQ_INTB 5
|
|
||||||
#define IRQ_INTC 6
|
|
||||||
#define IRQ_INTD 7
|
|
||||||
|
|
||||||
#define IRQ_SERR 12
|
|
||||||
#define IRQ_ERR 13
|
|
||||||
#define IRQ_PWR3 14
|
|
||||||
#define IRQ_PWR2 15
|
|
||||||
#define IRQ_PWR1 16
|
|
||||||
#define IRQ_PWR0 17
|
|
||||||
|
|
||||||
#define IRQ_DMTE0 18
|
|
||||||
#define IRQ_DMTE1 19
|
|
||||||
#define IRQ_DMTE2 20
|
|
||||||
#define IRQ_DMTE3 21
|
|
||||||
#define IRQ_DAERR 22
|
|
||||||
|
|
||||||
#define IRQ_TUNI0 32
|
|
||||||
#define IRQ_TUNI1 33
|
|
||||||
#define IRQ_TUNI2 34
|
|
||||||
#define IRQ_TICPI2 35
|
|
||||||
|
|
||||||
#define IRQ_ATI 36
|
|
||||||
#define IRQ_PRI 37
|
|
||||||
#define IRQ_CUI 38
|
|
||||||
|
|
||||||
#define IRQ_ERI 39
|
|
||||||
#define IRQ_RXI 40
|
|
||||||
#define IRQ_BRI 41
|
|
||||||
#define IRQ_TXI 42
|
|
||||||
|
|
||||||
#define IRQ_ITI 63
|
|
||||||
|
|
||||||
#define NR_INTC_IRQS 64
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_CAYMAN
|
|
||||||
#define NR_EXT_IRQS 32
|
|
||||||
#define START_EXT_IRQS 64
|
|
||||||
|
|
||||||
/* PCI bus 2 uses encoded external interrupts on the Cayman board */
|
|
||||||
#define IRQ_P2INTA (START_EXT_IRQS + (3*8) + 0)
|
|
||||||
#define IRQ_P2INTB (START_EXT_IRQS + (3*8) + 1)
|
|
||||||
#define IRQ_P2INTC (START_EXT_IRQS + (3*8) + 2)
|
|
||||||
#define IRQ_P2INTD (START_EXT_IRQS + (3*8) + 3)
|
|
||||||
|
|
||||||
#define I8042_KBD_IRQ (START_EXT_IRQS + 2)
|
|
||||||
#define I8042_AUX_IRQ (START_EXT_IRQS + 6)
|
|
||||||
|
|
||||||
#define IRQ_CFCARD (START_EXT_IRQS + 7)
|
|
||||||
#define IRQ_PCMCIA (0)
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define NR_EXT_IRQS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Default IRQs, fixed */
|
|
||||||
#define TIMER_IRQ IRQ_TUNI0
|
|
||||||
#define RTC_IRQ IRQ_CUI
|
|
||||||
|
|
||||||
/* Default Priorities, Platform may choose differently */
|
|
||||||
#define NO_PRIORITY 0 /* Disabled */
|
|
||||||
#define TIMER_PRIORITY 2
|
|
||||||
#define RTC_PRIORITY TIMER_PRIORITY
|
|
||||||
#define SCIF_PRIORITY 3
|
|
||||||
#define INTD_PRIORITY 3
|
|
||||||
#define IRL3_PRIORITY 4
|
|
||||||
#define INTC_PRIORITY 6
|
|
||||||
#define IRL2_PRIORITY 7
|
|
||||||
#define INTB_PRIORITY 9
|
|
||||||
#define IRL1_PRIORITY 10
|
|
||||||
#define INTA_PRIORITY 12
|
|
||||||
#define IRL0_PRIORITY 13
|
|
||||||
#define TOP_PRIORITY 15
|
|
||||||
|
|
||||||
extern int intc_evt_to_irq[(0xE20/0x20)+1];
|
|
||||||
extern int platform_int_priority[NR_INTC_IRQS];
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_CPU_SH5_IRQ_H */
|
|
|
@ -1,22 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_CPU_SH5_MMU_CONTEXT_H
|
|
||||||
#define __ASM_SH_CPU_SH5_MMU_CONTEXT_H
|
|
||||||
|
|
||||||
/* Common defines */
|
|
||||||
#define TLB_STEP 0x00000010
|
|
||||||
#define TLB_PTEH 0x00000000
|
|
||||||
#define TLB_PTEL 0x00000008
|
|
||||||
|
|
||||||
/* PTEH defines */
|
|
||||||
#define PTEH_ASID_SHIFT 2
|
|
||||||
#define PTEH_VALID 0x0000000000000001
|
|
||||||
#define PTEH_SHARED 0x0000000000000002
|
|
||||||
#define PTEH_MATCH_ASID 0x00000000000003ff
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
/* This has to be a common function because the next location to fill
|
|
||||||
* information is shared. */
|
|
||||||
extern void __do_tlb_refill(unsigned long address, unsigned long long is_text_not_data, pte_t *pte);
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_CPU_SH5_MMU_CONTEXT_H */
|
|
|
@ -1,103 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_CPU_SH5_REGISTERS_H
|
|
||||||
#define __ASM_SH_CPU_SH5_REGISTERS_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include/asm-sh/cpu-sh5/registers.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __ASSEMBLY__
|
|
||||||
/* =====================================================================
|
|
||||||
**
|
|
||||||
** Section 1: acts on assembly sources pre-processed by GPP ( <source.S>).
|
|
||||||
** Assigns symbolic names to control & target registers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define some useful aliases for control registers.
|
|
||||||
*/
|
|
||||||
#define SR cr0
|
|
||||||
#define SSR cr1
|
|
||||||
#define PSSR cr2
|
|
||||||
/* cr3 UNDEFINED */
|
|
||||||
#define INTEVT cr4
|
|
||||||
#define EXPEVT cr5
|
|
||||||
#define PEXPEVT cr6
|
|
||||||
#define TRA cr7
|
|
||||||
#define SPC cr8
|
|
||||||
#define PSPC cr9
|
|
||||||
#define RESVEC cr10
|
|
||||||
#define VBR cr11
|
|
||||||
/* cr12 UNDEFINED */
|
|
||||||
#define TEA cr13
|
|
||||||
/* cr14-cr15 UNDEFINED */
|
|
||||||
#define DCR cr16
|
|
||||||
#define KCR0 cr17
|
|
||||||
#define KCR1 cr18
|
|
||||||
/* cr19-cr31 UNDEFINED */
|
|
||||||
/* cr32-cr61 RESERVED */
|
|
||||||
#define CTC cr62
|
|
||||||
#define USR cr63
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ABI dependent registers (general purpose set)
|
|
||||||
*/
|
|
||||||
#define RET r2
|
|
||||||
#define ARG1 r2
|
|
||||||
#define ARG2 r3
|
|
||||||
#define ARG3 r4
|
|
||||||
#define ARG4 r5
|
|
||||||
#define ARG5 r6
|
|
||||||
#define ARG6 r7
|
|
||||||
#define SP r15
|
|
||||||
#define LINK r18
|
|
||||||
#define ZERO r63
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Status register defines: used only by assembly sources (and
|
|
||||||
* syntax independednt)
|
|
||||||
*/
|
|
||||||
#define SR_RESET_VAL 0x0000000050008000
|
|
||||||
#define SR_HARMLESS 0x00000000500080f0 /* Write ignores for most */
|
|
||||||
#define SR_ENABLE_FPU 0xffffffffffff7fff /* AND with this */
|
|
||||||
|
|
||||||
#if defined (CONFIG_SH64_SR_WATCH)
|
|
||||||
#define SR_ENABLE_MMU 0x0000000084000000 /* OR with this */
|
|
||||||
#else
|
|
||||||
#define SR_ENABLE_MMU 0x0000000080000000 /* OR with this */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SR_UNBLOCK_EXC 0xffffffffefffffff /* AND with this */
|
|
||||||
#define SR_BLOCK_EXC 0x0000000010000000 /* OR with this */
|
|
||||||
|
|
||||||
#else /* Not __ASSEMBLY__ syntax */
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Stringify reg. name
|
|
||||||
*/
|
|
||||||
#define __str(x) #x
|
|
||||||
|
|
||||||
/* Stringify control register names for use in inline assembly */
|
|
||||||
#define __SR __str(SR)
|
|
||||||
#define __SSR __str(SSR)
|
|
||||||
#define __PSSR __str(PSSR)
|
|
||||||
#define __INTEVT __str(INTEVT)
|
|
||||||
#define __EXPEVT __str(EXPEVT)
|
|
||||||
#define __PEXPEVT __str(PEXPEVT)
|
|
||||||
#define __TRA __str(TRA)
|
|
||||||
#define __SPC __str(SPC)
|
|
||||||
#define __PSPC __str(PSPC)
|
|
||||||
#define __RESVEC __str(RESVEC)
|
|
||||||
#define __VBR __str(VBR)
|
|
||||||
#define __TEA __str(TEA)
|
|
||||||
#define __DCR __str(DCR)
|
|
||||||
#define __KCR0 __str(KCR0)
|
|
||||||
#define __KCR1 __str(KCR1)
|
|
||||||
#define __CTC __str(CTC)
|
|
||||||
#define __USR __str(USR)
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
#endif /* __ASM_SH_CPU_SH5_REGISTERS_H */
|
|
|
@ -1,9 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __ASM_SH_CPU_SH5_RTC_H
|
|
||||||
#define __ASM_SH_CPU_SH5_RTC_H
|
|
||||||
|
|
||||||
#define rtc_reg_size sizeof(u32)
|
|
||||||
#define RTC_BIT_INVERTED 0 /* The SH-5 RTC is surprisingly sane! */
|
|
||||||
#define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_CPU_SH5_RTC_H */
|
|
|
@ -1,8 +1,2 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||||
#ifndef __KERNEL__
|
|
||||||
# ifdef __SH5__
|
|
||||||
# include <asm/posix_types_64.h>
|
|
||||||
# else
|
|
||||||
#include <asm/posix_types_32.h>
|
#include <asm/posix_types_32.h>
|
||||||
# endif
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
|
||||||
#ifndef __ASM_SH_POSIX_TYPES_64_H
|
|
||||||
#define __ASM_SH_POSIX_TYPES_64_H
|
|
||||||
|
|
||||||
typedef unsigned short __kernel_mode_t;
|
|
||||||
#define __kernel_mode_t __kernel_mode_t
|
|
||||||
typedef unsigned short __kernel_ipc_pid_t;
|
|
||||||
#define __kernel_ipc_pid_t __kernel_ipc_pid_t
|
|
||||||
typedef unsigned short __kernel_uid_t;
|
|
||||||
#define __kernel_uid_t __kernel_uid_t
|
|
||||||
typedef unsigned short __kernel_gid_t;
|
|
||||||
#define __kernel_gid_t __kernel_gid_t
|
|
||||||
typedef long unsigned int __kernel_size_t;
|
|
||||||
#define __kernel_size_t __kernel_size_t
|
|
||||||
typedef int __kernel_ssize_t;
|
|
||||||
#define __kernel_ssize_t __kernel_ssize_t
|
|
||||||
typedef int __kernel_ptrdiff_t;
|
|
||||||
#define __kernel_ptrdiff_t __kernel_ptrdiff_t
|
|
||||||
|
|
||||||
typedef unsigned short __kernel_old_uid_t;
|
|
||||||
#define __kernel_old_uid_t __kernel_old_uid_t
|
|
||||||
typedef unsigned short __kernel_old_gid_t;
|
|
||||||
#define __kernel_old_gid_t __kernel_old_gid_t
|
|
||||||
typedef unsigned short __kernel_old_dev_t;
|
|
||||||
#define __kernel_old_dev_t __kernel_old_dev_t
|
|
||||||
|
|
||||||
#include <asm-generic/posix_types.h>
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_POSIX_TYPES_64_H */
|
|
|
@ -25,11 +25,6 @@
|
||||||
#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
|
#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
|
||||||
#define PT_TEXT_LEN 252
|
#define PT_TEXT_LEN 252
|
||||||
|
|
||||||
#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
|
|
||||||
#include <asm/ptrace_64.h>
|
|
||||||
#else
|
|
||||||
#include <asm/ptrace_32.h>
|
#include <asm/ptrace_32.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _UAPI__ASM_SH_PTRACE_H */
|
#endif /* _UAPI__ASM_SH_PTRACE_H */
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
|
||||||
#ifndef _UAPI__ASM_SH_PTRACE_64_H
|
|
||||||
#define _UAPI__ASM_SH_PTRACE_64_H
|
|
||||||
|
|
||||||
struct pt_regs {
|
|
||||||
unsigned long long pc;
|
|
||||||
unsigned long long sr;
|
|
||||||
long long syscall_nr;
|
|
||||||
unsigned long long regs[63];
|
|
||||||
unsigned long long tregs[8];
|
|
||||||
unsigned long long pad[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _UAPI__ASM_SH_PTRACE_64_H */
|
|
|
@ -5,18 +5,6 @@
|
||||||
struct sigcontext {
|
struct sigcontext {
|
||||||
unsigned long oldmask;
|
unsigned long oldmask;
|
||||||
|
|
||||||
#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
|
|
||||||
/* CPU registers */
|
|
||||||
unsigned long long sc_regs[63];
|
|
||||||
unsigned long long sc_tregs[8];
|
|
||||||
unsigned long long sc_pc;
|
|
||||||
unsigned long long sc_sr;
|
|
||||||
|
|
||||||
/* FPU registers */
|
|
||||||
unsigned long long sc_fpregs[32];
|
|
||||||
unsigned int sc_fpscr;
|
|
||||||
unsigned int sc_fpvalid;
|
|
||||||
#else
|
|
||||||
/* CPU registers */
|
/* CPU registers */
|
||||||
unsigned long sc_regs[16];
|
unsigned long sc_regs[16];
|
||||||
unsigned long sc_pc;
|
unsigned long sc_pc;
|
||||||
|
@ -32,7 +20,6 @@ struct sigcontext {
|
||||||
unsigned int sc_fpscr;
|
unsigned int sc_fpscr;
|
||||||
unsigned int sc_fpul;
|
unsigned int sc_fpul;
|
||||||
unsigned int sc_ownedfp;
|
unsigned int sc_ownedfp;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ASM_SH_SIGCONTEXT_H */
|
#endif /* __ASM_SH_SIGCONTEXT_H */
|
||||||
|
|
|
@ -16,66 +16,6 @@ struct __old_kernel_stat {
|
||||||
unsigned long st_ctime;
|
unsigned long st_ctime;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
|
|
||||||
struct stat {
|
|
||||||
unsigned short st_dev;
|
|
||||||
unsigned short __pad1;
|
|
||||||
unsigned long st_ino;
|
|
||||||
unsigned short st_mode;
|
|
||||||
unsigned short st_nlink;
|
|
||||||
unsigned short st_uid;
|
|
||||||
unsigned short st_gid;
|
|
||||||
unsigned short st_rdev;
|
|
||||||
unsigned short __pad2;
|
|
||||||
unsigned long st_size;
|
|
||||||
unsigned long st_blksize;
|
|
||||||
unsigned long st_blocks;
|
|
||||||
unsigned long st_atime;
|
|
||||||
unsigned long st_atime_nsec;
|
|
||||||
unsigned long st_mtime;
|
|
||||||
unsigned long st_mtime_nsec;
|
|
||||||
unsigned long st_ctime;
|
|
||||||
unsigned long st_ctime_nsec;
|
|
||||||
unsigned long __unused4;
|
|
||||||
unsigned long __unused5;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This matches struct stat64 in glibc2.1, hence the absolutely
|
|
||||||
* insane amounts of padding around dev_t's.
|
|
||||||
*/
|
|
||||||
struct stat64 {
|
|
||||||
unsigned short st_dev;
|
|
||||||
unsigned char __pad0[10];
|
|
||||||
|
|
||||||
unsigned long st_ino;
|
|
||||||
unsigned int st_mode;
|
|
||||||
unsigned int st_nlink;
|
|
||||||
|
|
||||||
unsigned long st_uid;
|
|
||||||
unsigned long st_gid;
|
|
||||||
|
|
||||||
unsigned short st_rdev;
|
|
||||||
unsigned char __pad3[10];
|
|
||||||
|
|
||||||
long long st_size;
|
|
||||||
unsigned long st_blksize;
|
|
||||||
|
|
||||||
unsigned long st_blocks; /* Number 512-byte blocks allocated. */
|
|
||||||
unsigned long __pad4; /* future possible st_blocks high bits */
|
|
||||||
|
|
||||||
unsigned long st_atime;
|
|
||||||
unsigned long st_atime_nsec;
|
|
||||||
|
|
||||||
unsigned long st_mtime;
|
|
||||||
unsigned long st_mtime_nsec;
|
|
||||||
|
|
||||||
unsigned long st_ctime;
|
|
||||||
unsigned long st_ctime_nsec; /* will be high 32 bits of ctime someday */
|
|
||||||
|
|
||||||
unsigned long __unused1;
|
|
||||||
unsigned long __unused2;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
struct stat {
|
struct stat {
|
||||||
unsigned long st_dev;
|
unsigned long st_dev;
|
||||||
unsigned long st_ino;
|
unsigned long st_ino;
|
||||||
|
@ -134,6 +74,5 @@ struct stat64 {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define STAT_HAVE_NSEC 1
|
#define STAT_HAVE_NSEC 1
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_STAT_H */
|
#endif /* __ASM_SH_STAT_H */
|
||||||
|
|
|
@ -13,14 +13,9 @@
|
||||||
static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
|
static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
|
||||||
{
|
{
|
||||||
__asm__(
|
__asm__(
|
||||||
#ifdef __SH5__
|
|
||||||
"byterev %1, %0\n\t"
|
|
||||||
"shari %0, 32, %0"
|
|
||||||
#else
|
|
||||||
"swap.b %1, %0\n\t"
|
"swap.b %1, %0\n\t"
|
||||||
"swap.w %0, %0\n\t"
|
"swap.w %0, %0\n\t"
|
||||||
"swap.b %0, %0"
|
"swap.b %0, %0"
|
||||||
#endif
|
|
||||||
: "=r" (x)
|
: "=r" (x)
|
||||||
: "r" (x));
|
: "r" (x));
|
||||||
|
|
||||||
|
@ -31,12 +26,7 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
|
||||||
static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
|
static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
|
||||||
{
|
{
|
||||||
__asm__(
|
__asm__(
|
||||||
#ifdef __SH5__
|
|
||||||
"byterev %1, %0\n\t"
|
|
||||||
"shari %0, 32, %0"
|
|
||||||
#else
|
|
||||||
"swap.b %1, %0"
|
"swap.b %1, %0"
|
||||||
#endif
|
|
||||||
: "=r" (x)
|
: "=r" (x)
|
||||||
: "r" (x));
|
: "r" (x));
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,2 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||||
#ifndef __KERNEL__
|
|
||||||
# ifdef __SH5__
|
|
||||||
# include <asm/unistd_64.h>
|
|
||||||
# else
|
|
||||||
#include <asm/unistd_32.h>
|
#include <asm/unistd_32.h>
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,423 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
|
||||||
#ifndef __ASM_SH_UNISTD_64_H
|
|
||||||
#define __ASM_SH_UNISTD_64_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include/asm-sh/unistd_64.h
|
|
||||||
*
|
|
||||||
* This file contains the system call numbers.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 - 2007 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Sean McGoogan
|
|
||||||
*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
#define __NR_restart_syscall 0
|
|
||||||
#define __NR_exit 1
|
|
||||||
#define __NR_fork 2
|
|
||||||
#define __NR_read 3
|
|
||||||
#define __NR_write 4
|
|
||||||
#define __NR_open 5
|
|
||||||
#define __NR_close 6
|
|
||||||
#define __NR_waitpid 7
|
|
||||||
#define __NR_creat 8
|
|
||||||
#define __NR_link 9
|
|
||||||
#define __NR_unlink 10
|
|
||||||
#define __NR_execve 11
|
|
||||||
#define __NR_chdir 12
|
|
||||||
#define __NR_time 13
|
|
||||||
#define __NR_mknod 14
|
|
||||||
#define __NR_chmod 15
|
|
||||||
#define __NR_lchown 16
|
|
||||||
/* 17 was sys_break */
|
|
||||||
#define __NR_oldstat 18
|
|
||||||
#define __NR_lseek 19
|
|
||||||
#define __NR_getpid 20
|
|
||||||
#define __NR_mount 21
|
|
||||||
#define __NR_umount 22
|
|
||||||
#define __NR_setuid 23
|
|
||||||
#define __NR_getuid 24
|
|
||||||
#define __NR_stime 25
|
|
||||||
#define __NR_ptrace 26
|
|
||||||
#define __NR_alarm 27
|
|
||||||
#define __NR_oldfstat 28
|
|
||||||
#define __NR_pause 29
|
|
||||||
#define __NR_utime 30
|
|
||||||
/* 31 was sys_stty */
|
|
||||||
/* 32 was sys_gtty */
|
|
||||||
#define __NR_access 33
|
|
||||||
#define __NR_nice 34
|
|
||||||
/* 35 was sys_ftime */
|
|
||||||
#define __NR_sync 36
|
|
||||||
#define __NR_kill 37
|
|
||||||
#define __NR_rename 38
|
|
||||||
#define __NR_mkdir 39
|
|
||||||
#define __NR_rmdir 40
|
|
||||||
#define __NR_dup 41
|
|
||||||
#define __NR_pipe 42
|
|
||||||
#define __NR_times 43
|
|
||||||
/* 44 was sys_prof */
|
|
||||||
#define __NR_brk 45
|
|
||||||
#define __NR_setgid 46
|
|
||||||
#define __NR_getgid 47
|
|
||||||
#define __NR_signal 48
|
|
||||||
#define __NR_geteuid 49
|
|
||||||
#define __NR_getegid 50
|
|
||||||
#define __NR_acct 51
|
|
||||||
#define __NR_umount2 52
|
|
||||||
/* 53 was sys_lock */
|
|
||||||
#define __NR_ioctl 54
|
|
||||||
#define __NR_fcntl 55
|
|
||||||
/* 56 was sys_mpx */
|
|
||||||
#define __NR_setpgid 57
|
|
||||||
/* 58 was sys_ulimit */
|
|
||||||
/* 59 was sys_olduname */
|
|
||||||
#define __NR_umask 60
|
|
||||||
#define __NR_chroot 61
|
|
||||||
#define __NR_ustat 62
|
|
||||||
#define __NR_dup2 63
|
|
||||||
#define __NR_getppid 64
|
|
||||||
#define __NR_getpgrp 65
|
|
||||||
#define __NR_setsid 66
|
|
||||||
#define __NR_sigaction 67
|
|
||||||
#define __NR_sgetmask 68
|
|
||||||
#define __NR_ssetmask 69
|
|
||||||
#define __NR_setreuid 70
|
|
||||||
#define __NR_setregid 71
|
|
||||||
#define __NR_sigsuspend 72
|
|
||||||
#define __NR_sigpending 73
|
|
||||||
#define __NR_sethostname 74
|
|
||||||
#define __NR_setrlimit 75
|
|
||||||
#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
|
|
||||||
#define __NR_getrusage 77
|
|
||||||
#define __NR_gettimeofday 78
|
|
||||||
#define __NR_settimeofday 79
|
|
||||||
#define __NR_getgroups 80
|
|
||||||
#define __NR_setgroups 81
|
|
||||||
/* 82 was sys_select */
|
|
||||||
#define __NR_symlink 83
|
|
||||||
#define __NR_oldlstat 84
|
|
||||||
#define __NR_readlink 85
|
|
||||||
#define __NR_uselib 86
|
|
||||||
#define __NR_swapon 87
|
|
||||||
#define __NR_reboot 88
|
|
||||||
#define __NR_readdir 89
|
|
||||||
#define __NR_mmap 90
|
|
||||||
#define __NR_munmap 91
|
|
||||||
#define __NR_truncate 92
|
|
||||||
#define __NR_ftruncate 93
|
|
||||||
#define __NR_fchmod 94
|
|
||||||
#define __NR_fchown 95
|
|
||||||
#define __NR_getpriority 96
|
|
||||||
#define __NR_setpriority 97
|
|
||||||
/* 98 was sys_profil */
|
|
||||||
#define __NR_statfs 99
|
|
||||||
#define __NR_fstatfs 100
|
|
||||||
/* 101 was sys_ioperm */
|
|
||||||
#define __NR_socketcall 102 /* old implementation of socket systemcall */
|
|
||||||
#define __NR_syslog 103
|
|
||||||
#define __NR_setitimer 104
|
|
||||||
#define __NR_getitimer 105
|
|
||||||
#define __NR_stat 106
|
|
||||||
#define __NR_lstat 107
|
|
||||||
#define __NR_fstat 108
|
|
||||||
#define __NR_olduname 109
|
|
||||||
/* 110 was sys_iopl */
|
|
||||||
#define __NR_vhangup 111
|
|
||||||
/* 112 was sys_idle */
|
|
||||||
/* 113 was sys_vm86old */
|
|
||||||
#define __NR_wait4 114
|
|
||||||
#define __NR_swapoff 115
|
|
||||||
#define __NR_sysinfo 116
|
|
||||||
#define __NR_ipc 117
|
|
||||||
#define __NR_fsync 118
|
|
||||||
#define __NR_sigreturn 119
|
|
||||||
#define __NR_clone 120
|
|
||||||
#define __NR_setdomainname 121
|
|
||||||
#define __NR_uname 122
|
|
||||||
#define __NR_cacheflush 123
|
|
||||||
#define __NR_adjtimex 124
|
|
||||||
#define __NR_mprotect 125
|
|
||||||
#define __NR_sigprocmask 126
|
|
||||||
/* 127 was sys_create_module */
|
|
||||||
#define __NR_init_module 128
|
|
||||||
#define __NR_delete_module 129
|
|
||||||
/* 130 was sys_get_kernel_syms */
|
|
||||||
#define __NR_quotactl 131
|
|
||||||
#define __NR_getpgid 132
|
|
||||||
#define __NR_fchdir 133
|
|
||||||
#define __NR_bdflush 134
|
|
||||||
#define __NR_sysfs 135
|
|
||||||
#define __NR_personality 136
|
|
||||||
/* 137 was sys_afs_syscall */
|
|
||||||
#define __NR_setfsuid 138
|
|
||||||
#define __NR_setfsgid 139
|
|
||||||
#define __NR__llseek 140
|
|
||||||
#define __NR_getdents 141
|
|
||||||
#define __NR__newselect 142
|
|
||||||
#define __NR_flock 143
|
|
||||||
#define __NR_msync 144
|
|
||||||
#define __NR_readv 145
|
|
||||||
#define __NR_writev 146
|
|
||||||
#define __NR_getsid 147
|
|
||||||
#define __NR_fdatasync 148
|
|
||||||
#define __NR__sysctl 149
|
|
||||||
#define __NR_mlock 150
|
|
||||||
#define __NR_munlock 151
|
|
||||||
#define __NR_mlockall 152
|
|
||||||
#define __NR_munlockall 153
|
|
||||||
#define __NR_sched_setparam 154
|
|
||||||
#define __NR_sched_getparam 155
|
|
||||||
#define __NR_sched_setscheduler 156
|
|
||||||
#define __NR_sched_getscheduler 157
|
|
||||||
#define __NR_sched_yield 158
|
|
||||||
#define __NR_sched_get_priority_max 159
|
|
||||||
#define __NR_sched_get_priority_min 160
|
|
||||||
#define __NR_sched_rr_get_interval 161
|
|
||||||
#define __NR_nanosleep 162
|
|
||||||
#define __NR_mremap 163
|
|
||||||
#define __NR_setresuid 164
|
|
||||||
#define __NR_getresuid 165
|
|
||||||
/* 166 was sys_vm86 */
|
|
||||||
/* 167 was sys_query_module */
|
|
||||||
#define __NR_poll 168
|
|
||||||
#define __NR_nfsservctl 169
|
|
||||||
#define __NR_setresgid 170
|
|
||||||
#define __NR_getresgid 171
|
|
||||||
#define __NR_prctl 172
|
|
||||||
#define __NR_rt_sigreturn 173
|
|
||||||
#define __NR_rt_sigaction 174
|
|
||||||
#define __NR_rt_sigprocmask 175
|
|
||||||
#define __NR_rt_sigpending 176
|
|
||||||
#define __NR_rt_sigtimedwait 177
|
|
||||||
#define __NR_rt_sigqueueinfo 178
|
|
||||||
#define __NR_rt_sigsuspend 179
|
|
||||||
#define __NR_pread64 180
|
|
||||||
#define __NR_pwrite64 181
|
|
||||||
#define __NR_chown 182
|
|
||||||
#define __NR_getcwd 183
|
|
||||||
#define __NR_capget 184
|
|
||||||
#define __NR_capset 185
|
|
||||||
#define __NR_sigaltstack 186
|
|
||||||
#define __NR_sendfile 187
|
|
||||||
/* 188 reserved for getpmsg */
|
|
||||||
/* 189 reserved for putpmsg */
|
|
||||||
#define __NR_vfork 190
|
|
||||||
#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
|
|
||||||
#define __NR_mmap2 192
|
|
||||||
#define __NR_truncate64 193
|
|
||||||
#define __NR_ftruncate64 194
|
|
||||||
#define __NR_stat64 195
|
|
||||||
#define __NR_lstat64 196
|
|
||||||
#define __NR_fstat64 197
|
|
||||||
#define __NR_lchown32 198
|
|
||||||
#define __NR_getuid32 199
|
|
||||||
#define __NR_getgid32 200
|
|
||||||
#define __NR_geteuid32 201
|
|
||||||
#define __NR_getegid32 202
|
|
||||||
#define __NR_setreuid32 203
|
|
||||||
#define __NR_setregid32 204
|
|
||||||
#define __NR_getgroups32 205
|
|
||||||
#define __NR_setgroups32 206
|
|
||||||
#define __NR_fchown32 207
|
|
||||||
#define __NR_setresuid32 208
|
|
||||||
#define __NR_getresuid32 209
|
|
||||||
#define __NR_setresgid32 210
|
|
||||||
#define __NR_getresgid32 211
|
|
||||||
#define __NR_chown32 212
|
|
||||||
#define __NR_setuid32 213
|
|
||||||
#define __NR_setgid32 214
|
|
||||||
#define __NR_setfsuid32 215
|
|
||||||
#define __NR_setfsgid32 216
|
|
||||||
#define __NR_pivot_root 217
|
|
||||||
#define __NR_mincore 218
|
|
||||||
#define __NR_madvise 219
|
|
||||||
|
|
||||||
/* Non-multiplexed socket family */
|
|
||||||
#define __NR_socket 220
|
|
||||||
#define __NR_bind 221
|
|
||||||
#define __NR_connect 222
|
|
||||||
#define __NR_listen 223
|
|
||||||
#define __NR_accept 224
|
|
||||||
#define __NR_getsockname 225
|
|
||||||
#define __NR_getpeername 226
|
|
||||||
#define __NR_socketpair 227
|
|
||||||
#define __NR_send 228
|
|
||||||
#define __NR_sendto 229
|
|
||||||
#define __NR_recv 230
|
|
||||||
#define __NR_recvfrom 231
|
|
||||||
#define __NR_shutdown 232
|
|
||||||
#define __NR_setsockopt 233
|
|
||||||
#define __NR_getsockopt 234
|
|
||||||
#define __NR_sendmsg 235
|
|
||||||
#define __NR_recvmsg 236
|
|
||||||
|
|
||||||
/* Non-multiplexed IPC family */
|
|
||||||
#define __NR_semop 237
|
|
||||||
#define __NR_semget 238
|
|
||||||
#define __NR_semctl 239
|
|
||||||
#define __NR_msgsnd 240
|
|
||||||
#define __NR_msgrcv 241
|
|
||||||
#define __NR_msgget 242
|
|
||||||
#define __NR_msgctl 243
|
|
||||||
#define __NR_shmat 244
|
|
||||||
#define __NR_shmdt 245
|
|
||||||
#define __NR_shmget 246
|
|
||||||
#define __NR_shmctl 247
|
|
||||||
|
|
||||||
#define __NR_getdents64 248
|
|
||||||
#define __NR_fcntl64 249
|
|
||||||
/* 250 is reserved for tux */
|
|
||||||
/* 251 is unused */
|
|
||||||
#define __NR_gettid 252
|
|
||||||
#define __NR_readahead 253
|
|
||||||
#define __NR_setxattr 254
|
|
||||||
#define __NR_lsetxattr 255
|
|
||||||
#define __NR_fsetxattr 256
|
|
||||||
#define __NR_getxattr 257
|
|
||||||
#define __NR_lgetxattr 258
|
|
||||||
#define __NR_fgetxattr 259
|
|
||||||
#define __NR_listxattr 260
|
|
||||||
#define __NR_llistxattr 261
|
|
||||||
#define __NR_flistxattr 262
|
|
||||||
#define __NR_removexattr 263
|
|
||||||
#define __NR_lremovexattr 264
|
|
||||||
#define __NR_fremovexattr 265
|
|
||||||
#define __NR_tkill 266
|
|
||||||
#define __NR_sendfile64 267
|
|
||||||
#define __NR_futex 268
|
|
||||||
#define __NR_sched_setaffinity 269
|
|
||||||
#define __NR_sched_getaffinity 270
|
|
||||||
/* 271 is reserved for set_thread_area */
|
|
||||||
/* 272 is reserved for get_thread_area */
|
|
||||||
#define __NR_io_setup 273
|
|
||||||
#define __NR_io_destroy 274
|
|
||||||
#define __NR_io_getevents 275
|
|
||||||
#define __NR_io_submit 276
|
|
||||||
#define __NR_io_cancel 277
|
|
||||||
#define __NR_fadvise64 278
|
|
||||||
/* 279 is unused */
|
|
||||||
#define __NR_exit_group 280
|
|
||||||
|
|
||||||
#define __NR_lookup_dcookie 281
|
|
||||||
#define __NR_epoll_create 282
|
|
||||||
#define __NR_epoll_ctl 283
|
|
||||||
#define __NR_epoll_wait 284
|
|
||||||
#define __NR_remap_file_pages 285
|
|
||||||
#define __NR_set_tid_address 286
|
|
||||||
#define __NR_timer_create 287
|
|
||||||
#define __NR_timer_settime (__NR_timer_create+1)
|
|
||||||
#define __NR_timer_gettime (__NR_timer_create+2)
|
|
||||||
#define __NR_timer_getoverrun (__NR_timer_create+3)
|
|
||||||
#define __NR_timer_delete (__NR_timer_create+4)
|
|
||||||
#define __NR_clock_settime (__NR_timer_create+5)
|
|
||||||
#define __NR_clock_gettime (__NR_timer_create+6)
|
|
||||||
#define __NR_clock_getres (__NR_timer_create+7)
|
|
||||||
#define __NR_clock_nanosleep (__NR_timer_create+8)
|
|
||||||
#define __NR_statfs64 296
|
|
||||||
#define __NR_fstatfs64 297
|
|
||||||
#define __NR_tgkill 298
|
|
||||||
#define __NR_utimes 299
|
|
||||||
#define __NR_fadvise64_64 300
|
|
||||||
/* 301 is reserved for vserver */
|
|
||||||
/* 302 is reserved for mbind */
|
|
||||||
/* 303 is reserved for get_mempolicy */
|
|
||||||
/* 304 is reserved for set_mempolicy */
|
|
||||||
#define __NR_mq_open 305
|
|
||||||
#define __NR_mq_unlink (__NR_mq_open+1)
|
|
||||||
#define __NR_mq_timedsend (__NR_mq_open+2)
|
|
||||||
#define __NR_mq_timedreceive (__NR_mq_open+3)
|
|
||||||
#define __NR_mq_notify (__NR_mq_open+4)
|
|
||||||
#define __NR_mq_getsetattr (__NR_mq_open+5)
|
|
||||||
/* 311 is reserved for kexec */
|
|
||||||
#define __NR_waitid 312
|
|
||||||
#define __NR_add_key 313
|
|
||||||
#define __NR_request_key 314
|
|
||||||
#define __NR_keyctl 315
|
|
||||||
#define __NR_ioprio_set 316
|
|
||||||
#define __NR_ioprio_get 317
|
|
||||||
#define __NR_inotify_init 318
|
|
||||||
#define __NR_inotify_add_watch 319
|
|
||||||
#define __NR_inotify_rm_watch 320
|
|
||||||
/* 321 is unused */
|
|
||||||
#define __NR_migrate_pages 322
|
|
||||||
#define __NR_openat 323
|
|
||||||
#define __NR_mkdirat 324
|
|
||||||
#define __NR_mknodat 325
|
|
||||||
#define __NR_fchownat 326
|
|
||||||
#define __NR_futimesat 327
|
|
||||||
#define __NR_fstatat64 328
|
|
||||||
#define __NR_unlinkat 329
|
|
||||||
#define __NR_renameat 330
|
|
||||||
#define __NR_linkat 331
|
|
||||||
#define __NR_symlinkat 332
|
|
||||||
#define __NR_readlinkat 333
|
|
||||||
#define __NR_fchmodat 334
|
|
||||||
#define __NR_faccessat 335
|
|
||||||
#define __NR_pselect6 336
|
|
||||||
#define __NR_ppoll 337
|
|
||||||
#define __NR_unshare 338
|
|
||||||
#define __NR_set_robust_list 339
|
|
||||||
#define __NR_get_robust_list 340
|
|
||||||
#define __NR_splice 341
|
|
||||||
#define __NR_sync_file_range 342
|
|
||||||
#define __NR_tee 343
|
|
||||||
#define __NR_vmsplice 344
|
|
||||||
#define __NR_move_pages 345
|
|
||||||
#define __NR_getcpu 346
|
|
||||||
#define __NR_epoll_pwait 347
|
|
||||||
#define __NR_utimensat 348
|
|
||||||
#define __NR_signalfd 349
|
|
||||||
#define __NR_timerfd_create 350
|
|
||||||
#define __NR_eventfd 351
|
|
||||||
#define __NR_fallocate 352
|
|
||||||
#define __NR_timerfd_settime 353
|
|
||||||
#define __NR_timerfd_gettime 354
|
|
||||||
#define __NR_signalfd4 355
|
|
||||||
#define __NR_eventfd2 356
|
|
||||||
#define __NR_epoll_create1 357
|
|
||||||
#define __NR_dup3 358
|
|
||||||
#define __NR_pipe2 359
|
|
||||||
#define __NR_inotify_init1 360
|
|
||||||
#define __NR_preadv 361
|
|
||||||
#define __NR_pwritev 362
|
|
||||||
#define __NR_rt_tgsigqueueinfo 363
|
|
||||||
#define __NR_perf_event_open 364
|
|
||||||
#define __NR_recvmmsg 365
|
|
||||||
#define __NR_accept4 366
|
|
||||||
#define __NR_fanotify_init 367
|
|
||||||
#define __NR_fanotify_mark 368
|
|
||||||
#define __NR_prlimit64 369
|
|
||||||
#define __NR_name_to_handle_at 370
|
|
||||||
#define __NR_open_by_handle_at 371
|
|
||||||
#define __NR_clock_adjtime 372
|
|
||||||
#define __NR_syncfs 373
|
|
||||||
#define __NR_sendmmsg 374
|
|
||||||
#define __NR_setns 375
|
|
||||||
#define __NR_process_vm_readv 376
|
|
||||||
#define __NR_process_vm_writev 377
|
|
||||||
#define __NR_kcmp 378
|
|
||||||
#define __NR_finit_module 379
|
|
||||||
#define __NR_sched_getattr 380
|
|
||||||
#define __NR_sched_setattr 381
|
|
||||||
#define __NR_renameat2 382
|
|
||||||
#define __NR_seccomp 383
|
|
||||||
#define __NR_getrandom 384
|
|
||||||
#define __NR_memfd_create 385
|
|
||||||
#define __NR_bpf 386
|
|
||||||
#define __NR_execveat 387
|
|
||||||
#define __NR_userfaultfd 388
|
|
||||||
#define __NR_membarrier 389
|
|
||||||
#define __NR_mlock2 390
|
|
||||||
#define __NR_copy_file_range 391
|
|
||||||
#define __NR_preadv2 392
|
|
||||||
#define __NR_pwritev2 393
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
#define __NR_syscalls 394
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASM_SH_UNISTD_64_H */
|
|
|
@ -3,7 +3,7 @@
|
||||||
# Makefile for the Linux/SuperH kernel.
|
# Makefile for the Linux/SuperH kernel.
|
||||||
#
|
#
|
||||||
|
|
||||||
extra-y := head_$(BITS).o vmlinux.lds
|
extra-y := head_32.o vmlinux.lds
|
||||||
|
|
||||||
ifdef CONFIG_FUNCTION_TRACER
|
ifdef CONFIG_FUNCTION_TRACER
|
||||||
# Do not profile debug and lowlevel utilities
|
# Do not profile debug and lowlevel utilities
|
||||||
|
@ -13,26 +13,26 @@ endif
|
||||||
CFLAGS_REMOVE_return_address.o = -pg
|
CFLAGS_REMOVE_return_address.o = -pg
|
||||||
|
|
||||||
obj-y := debugtraps.o dumpstack.o \
|
obj-y := debugtraps.o dumpstack.o \
|
||||||
idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \
|
idle.o io.o irq.o irq_32.o kdebugfs.o \
|
||||||
machvec.o nmi_debug.o process.o \
|
machvec.o nmi_debug.o process.o \
|
||||||
process_$(BITS).o ptrace.o ptrace_$(BITS).o \
|
process_32.o ptrace.o ptrace_32.o \
|
||||||
reboot.o return_address.o \
|
reboot.o return_address.o \
|
||||||
setup.o signal_$(BITS).o sys_sh.o \
|
setup.o signal_32.o sys_sh.o \
|
||||||
syscalls_$(BITS).o time.o topology.o traps.o \
|
syscalls_32.o time.o topology.o traps.o \
|
||||||
traps_$(BITS).o unwinder.o
|
traps_32.o unwinder.o
|
||||||
|
|
||||||
ifndef CONFIG_GENERIC_IOMAP
|
ifndef CONFIG_GENERIC_IOMAP
|
||||||
obj-y += iomap.o
|
obj-y += iomap.o
|
||||||
obj-$(CONFIG_HAS_IOPORT_MAP) += ioport.o
|
obj-$(CONFIG_HAS_IOPORT_MAP) += ioport.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_SUPERH32) += sys_sh32.o
|
obj-y += sys_sh32.o
|
||||||
obj-y += cpu/
|
obj-y += cpu/
|
||||||
obj-$(CONFIG_VSYSCALL) += vsyscall/
|
obj-$(CONFIG_VSYSCALL) += vsyscall/
|
||||||
obj-$(CONFIG_SMP) += smp.o
|
obj-$(CONFIG_SMP) += smp.o
|
||||||
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
|
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
|
||||||
obj-$(CONFIG_KGDB) += kgdb.o
|
obj-$(CONFIG_KGDB) += kgdb.o
|
||||||
obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o
|
obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
|
||||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
||||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||||
|
|
|
@ -7,7 +7,6 @@ obj-$(CONFIG_CPU_SH2) = sh2/
|
||||||
obj-$(CONFIG_CPU_SH2A) = sh2a/
|
obj-$(CONFIG_CPU_SH2A) = sh2a/
|
||||||
obj-$(CONFIG_CPU_SH3) = sh3/
|
obj-$(CONFIG_CPU_SH3) = sh3/
|
||||||
obj-$(CONFIG_CPU_SH4) = sh4/
|
obj-$(CONFIG_CPU_SH4) = sh4/
|
||||||
obj-$(CONFIG_CPU_SH5) = sh5/
|
|
||||||
|
|
||||||
# Special cases for family ancestry.
|
# Special cases for family ancestry.
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ void __attribute__ ((weak)) l2_cache_init(void)
|
||||||
/*
|
/*
|
||||||
* Generic first-level cache init
|
* Generic first-level cache init
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_SUPERH32) && !defined(CONFIG_CPU_J2)
|
#if !defined(CONFIG_CPU_J2)
|
||||||
static void cache_init(void)
|
static void cache_init(void)
|
||||||
{
|
{
|
||||||
unsigned long ccr, flags;
|
unsigned long ccr, flags;
|
||||||
|
|
|
@ -2,6 +2,5 @@
|
||||||
#
|
#
|
||||||
# Makefile for the Linux/SuperH CPU-specific IRQ handlers.
|
# Makefile for the Linux/SuperH CPU-specific IRQ handlers.
|
||||||
#
|
#
|
||||||
obj-$(CONFIG_SUPERH32) += imask.o
|
obj-y += imask.o
|
||||||
obj-$(CONFIG_CPU_SH5) += intc-sh5.o
|
|
||||||
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
|
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
|
||||||
|
|
|
@ -1,194 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/cpu/irq/intc-sh5.c
|
|
||||||
*
|
|
||||||
* Interrupt Controller support for SH5 INTC.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 Paul Mundt
|
|
||||||
*
|
|
||||||
* Per-interrupt selective. IRLM=0 (Fixed priority) is not
|
|
||||||
* supported being useless without a cascaded interrupt
|
|
||||||
* controller.
|
|
||||||
*/
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <cpu/irq.h>
|
|
||||||
#include <asm/page.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maybe the generic Peripheral block could move to a more
|
|
||||||
* generic include file. INTC Block will be defined here
|
|
||||||
* and only here to make INTC self-contained in a single
|
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
#define INTC_BLOCK_OFFSET 0x01000000
|
|
||||||
|
|
||||||
/* Base */
|
|
||||||
#define INTC_BASE PHYS_PERIPHERAL_BLOCK + \
|
|
||||||
INTC_BLOCK_OFFSET
|
|
||||||
|
|
||||||
/* Address */
|
|
||||||
#define INTC_ICR_SET (intc_virt + 0x0)
|
|
||||||
#define INTC_ICR_CLEAR (intc_virt + 0x8)
|
|
||||||
#define INTC_INTPRI_0 (intc_virt + 0x10)
|
|
||||||
#define INTC_INTSRC_0 (intc_virt + 0x50)
|
|
||||||
#define INTC_INTSRC_1 (intc_virt + 0x58)
|
|
||||||
#define INTC_INTREQ_0 (intc_virt + 0x60)
|
|
||||||
#define INTC_INTREQ_1 (intc_virt + 0x68)
|
|
||||||
#define INTC_INTENB_0 (intc_virt + 0x70)
|
|
||||||
#define INTC_INTENB_1 (intc_virt + 0x78)
|
|
||||||
#define INTC_INTDSB_0 (intc_virt + 0x80)
|
|
||||||
#define INTC_INTDSB_1 (intc_virt + 0x88)
|
|
||||||
|
|
||||||
#define INTC_ICR_IRLM 0x1
|
|
||||||
#define INTC_INTPRI_PREGS 8 /* 8 Priority Registers */
|
|
||||||
#define INTC_INTPRI_PPREG 8 /* 8 Priorities per Register */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mapper between the vector ordinal and the IRQ number
|
|
||||||
* passed to kernel/device drivers.
|
|
||||||
*/
|
|
||||||
int intc_evt_to_irq[(0xE20/0x20)+1] = {
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, /* 0x000 - 0x0E0 */
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, /* 0x100 - 0x1E0 */
|
|
||||||
0, 0, 0, 0, 0, 1, 0, 0, /* 0x200 - 0x2E0 */
|
|
||||||
2, 0, 0, 3, 0, 0, 0, -1, /* 0x300 - 0x3E0 */
|
|
||||||
32, 33, 34, 35, 36, 37, 38, -1, /* 0x400 - 0x4E0 */
|
|
||||||
-1, -1, -1, 63, -1, -1, -1, -1, /* 0x500 - 0x5E0 */
|
|
||||||
-1, -1, 18, 19, 20, 21, 22, -1, /* 0x600 - 0x6E0 */
|
|
||||||
39, 40, 41, 42, -1, -1, -1, -1, /* 0x700 - 0x7E0 */
|
|
||||||
4, 5, 6, 7, -1, -1, -1, -1, /* 0x800 - 0x8E0 */
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, /* 0x900 - 0x9E0 */
|
|
||||||
12, 13, 14, 15, 16, 17, -1, -1, /* 0xA00 - 0xAE0 */
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, /* 0xB00 - 0xBE0 */
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, /* 0xC00 - 0xCE0 */
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, /* 0xD00 - 0xDE0 */
|
|
||||||
-1, -1 /* 0xE00 - 0xE20 */
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned long intc_virt;
|
|
||||||
static int irlm; /* IRL mode */
|
|
||||||
|
|
||||||
static void enable_intc_irq(struct irq_data *data)
|
|
||||||
{
|
|
||||||
unsigned int irq = data->irq;
|
|
||||||
unsigned long reg;
|
|
||||||
unsigned long bitmask;
|
|
||||||
|
|
||||||
if ((irq <= IRQ_IRL3) && (irlm == NO_PRIORITY))
|
|
||||||
printk("Trying to use straight IRL0-3 with an encoding platform.\n");
|
|
||||||
|
|
||||||
if (irq < 32) {
|
|
||||||
reg = INTC_INTENB_0;
|
|
||||||
bitmask = 1 << irq;
|
|
||||||
} else {
|
|
||||||
reg = INTC_INTENB_1;
|
|
||||||
bitmask = 1 << (irq - 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
__raw_writel(bitmask, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disable_intc_irq(struct irq_data *data)
|
|
||||||
{
|
|
||||||
unsigned int irq = data->irq;
|
|
||||||
unsigned long reg;
|
|
||||||
unsigned long bitmask;
|
|
||||||
|
|
||||||
if (irq < 32) {
|
|
||||||
reg = INTC_INTDSB_0;
|
|
||||||
bitmask = 1 << irq;
|
|
||||||
} else {
|
|
||||||
reg = INTC_INTDSB_1;
|
|
||||||
bitmask = 1 << (irq - 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
__raw_writel(bitmask, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip intc_irq_type = {
|
|
||||||
.name = "INTC",
|
|
||||||
.irq_enable = enable_intc_irq,
|
|
||||||
.irq_disable = disable_intc_irq,
|
|
||||||
};
|
|
||||||
|
|
||||||
void __init plat_irq_setup(void)
|
|
||||||
{
|
|
||||||
unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
|
|
||||||
unsigned long reg;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
intc_virt = (unsigned long)ioremap(INTC_BASE, 1024);
|
|
||||||
if (!intc_virt) {
|
|
||||||
panic("Unable to remap INTC\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Set default: per-line enable/disable, priority driven ack/eoi */
|
|
||||||
for (i = 0; i < NR_INTC_IRQS; i++)
|
|
||||||
irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq);
|
|
||||||
|
|
||||||
|
|
||||||
/* Disable all interrupts and set all priorities to 0 to avoid trouble */
|
|
||||||
__raw_writel(-1, INTC_INTDSB_0);
|
|
||||||
__raw_writel(-1, INTC_INTDSB_1);
|
|
||||||
|
|
||||||
for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8)
|
|
||||||
__raw_writel( NO_PRIORITY, reg);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_CAYMAN
|
|
||||||
{
|
|
||||||
unsigned long data;
|
|
||||||
|
|
||||||
/* Set IRLM */
|
|
||||||
/* If all the priorities are set to 'no priority', then
|
|
||||||
* assume we are using encoded mode.
|
|
||||||
*/
|
|
||||||
irlm = platform_int_priority[IRQ_IRL0] +
|
|
||||||
platform_int_priority[IRQ_IRL1] +
|
|
||||||
platform_int_priority[IRQ_IRL2] +
|
|
||||||
platform_int_priority[IRQ_IRL3];
|
|
||||||
if (irlm == NO_PRIORITY) {
|
|
||||||
/* IRLM = 0 */
|
|
||||||
reg = INTC_ICR_CLEAR;
|
|
||||||
i = IRQ_INTA;
|
|
||||||
printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
|
|
||||||
} else {
|
|
||||||
/* IRLM = 1 */
|
|
||||||
reg = INTC_ICR_SET;
|
|
||||||
i = IRQ_IRL0;
|
|
||||||
}
|
|
||||||
__raw_writel(INTC_ICR_IRLM, reg);
|
|
||||||
|
|
||||||
/* Set interrupt priorities according to platform description */
|
|
||||||
for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
|
|
||||||
data |= platform_int_priority[i] <<
|
|
||||||
((i % INTC_INTPRI_PPREG) * 4);
|
|
||||||
if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
|
|
||||||
/* Upon the 7th, set Priority Register */
|
|
||||||
__raw_writel(data, reg);
|
|
||||||
data = 0;
|
|
||||||
reg += 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* And now let interrupts come in.
|
|
||||||
* sti() is not enough, we need to
|
|
||||||
* lower priority, too.
|
|
||||||
*/
|
|
||||||
__asm__ __volatile__("getcon " __SR ", %0\n\t"
|
|
||||||
"and %0, %1, %0\n\t"
|
|
||||||
"putcon %0, " __SR "\n\t"
|
|
||||||
: "=&r" (__dummy0)
|
|
||||||
: "r" (__dummy1));
|
|
||||||
}
|
|
|
@ -24,7 +24,6 @@ static const char *cpu_name[] = {
|
||||||
[CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
|
[CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
|
||||||
[CPU_SH7786] = "SH7786", [CPU_SH7757] = "SH7757",
|
[CPU_SH7786] = "SH7786", [CPU_SH7757] = "SH7757",
|
||||||
[CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
|
[CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
|
||||||
[CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103",
|
|
||||||
[CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
|
[CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
|
||||||
[CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
|
[CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
|
||||||
[CPU_SH7372] = "SH7372", [CPU_SH7734] = "SH7734",
|
[CPU_SH7372] = "SH7372", [CPU_SH7734] = "SH7734",
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
#
|
|
||||||
# Makefile for the Linux/SuperH SH-5 backends.
|
|
||||||
#
|
|
||||||
obj-y := entry.o probe.o switchto.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_SH_FPU) += fpu.o
|
|
||||||
obj-$(CONFIG_KALLSYMS) += unwind.o
|
|
||||||
|
|
||||||
# CPU subtype setup
|
|
||||||
obj-$(CONFIG_CPU_SH5) += setup-sh5.o
|
|
||||||
|
|
||||||
# Primary on-chip clocks (common)
|
|
||||||
clock-$(CONFIG_CPU_SH5) := clock-sh5.o
|
|
||||||
|
|
||||||
obj-y += $(clock-y)
|
|
|
@ -1,76 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/cpu/sh5/clock-sh5.c
|
|
||||||
*
|
|
||||||
* SH-5 support for the clock framework
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 Paul Mundt
|
|
||||||
*/
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <asm/clock.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
|
|
||||||
static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
|
|
||||||
|
|
||||||
/* Clock, Power and Reset Controller */
|
|
||||||
#define CPRC_BLOCK_OFF 0x01010000
|
|
||||||
#define CPRC_BASE (PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF)
|
|
||||||
|
|
||||||
static unsigned long cprc_base;
|
|
||||||
|
|
||||||
static void master_clk_init(struct clk *clk)
|
|
||||||
{
|
|
||||||
int idx = (__raw_readl(cprc_base + 0x00) >> 6) & 0x0007;
|
|
||||||
clk->rate *= ifc_table[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sh_clk_ops sh5_master_clk_ops = {
|
|
||||||
.init = master_clk_init,
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned long module_clk_recalc(struct clk *clk)
|
|
||||||
{
|
|
||||||
int idx = (__raw_readw(cprc_base) >> 12) & 0x0007;
|
|
||||||
return clk->parent->rate / ifc_table[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sh_clk_ops sh5_module_clk_ops = {
|
|
||||||
.recalc = module_clk_recalc,
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned long bus_clk_recalc(struct clk *clk)
|
|
||||||
{
|
|
||||||
int idx = (__raw_readw(cprc_base) >> 3) & 0x0007;
|
|
||||||
return clk->parent->rate / ifc_table[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sh_clk_ops sh5_bus_clk_ops = {
|
|
||||||
.recalc = bus_clk_recalc,
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned long cpu_clk_recalc(struct clk *clk)
|
|
||||||
{
|
|
||||||
int idx = (__raw_readw(cprc_base) & 0x0007);
|
|
||||||
return clk->parent->rate / ifc_table[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sh_clk_ops sh5_cpu_clk_ops = {
|
|
||||||
.recalc = cpu_clk_recalc,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sh_clk_ops *sh5_clk_ops[] = {
|
|
||||||
&sh5_master_clk_ops,
|
|
||||||
&sh5_module_clk_ops,
|
|
||||||
&sh5_bus_clk_ops,
|
|
||||||
&sh5_cpu_clk_ops,
|
|
||||||
};
|
|
||||||
|
|
||||||
void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
|
|
||||||
{
|
|
||||||
cprc_base = (unsigned long)ioremap(CPRC_BASE, 1024);
|
|
||||||
BUG_ON(!cprc_base);
|
|
||||||
|
|
||||||
if (idx < ARRAY_SIZE(sh5_clk_ops))
|
|
||||||
*ops = sh5_clk_ops[idx];
|
|
||||||
}
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,106 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/cpu/sh5/fpu.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli
|
|
||||||
* Copyright (C) 2002 STMicroelectronics Limited
|
|
||||||
* Author : Stuart Menefy
|
|
||||||
*
|
|
||||||
* Started from SH4 version:
|
|
||||||
* Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
|
|
||||||
*/
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/signal.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
|
|
||||||
void save_fpu(struct task_struct *tsk)
|
|
||||||
{
|
|
||||||
asm volatile("fst.p %0, (0*8), fp0\n\t"
|
|
||||||
"fst.p %0, (1*8), fp2\n\t"
|
|
||||||
"fst.p %0, (2*8), fp4\n\t"
|
|
||||||
"fst.p %0, (3*8), fp6\n\t"
|
|
||||||
"fst.p %0, (4*8), fp8\n\t"
|
|
||||||
"fst.p %0, (5*8), fp10\n\t"
|
|
||||||
"fst.p %0, (6*8), fp12\n\t"
|
|
||||||
"fst.p %0, (7*8), fp14\n\t"
|
|
||||||
"fst.p %0, (8*8), fp16\n\t"
|
|
||||||
"fst.p %0, (9*8), fp18\n\t"
|
|
||||||
"fst.p %0, (10*8), fp20\n\t"
|
|
||||||
"fst.p %0, (11*8), fp22\n\t"
|
|
||||||
"fst.p %0, (12*8), fp24\n\t"
|
|
||||||
"fst.p %0, (13*8), fp26\n\t"
|
|
||||||
"fst.p %0, (14*8), fp28\n\t"
|
|
||||||
"fst.p %0, (15*8), fp30\n\t"
|
|
||||||
"fst.p %0, (16*8), fp32\n\t"
|
|
||||||
"fst.p %0, (17*8), fp34\n\t"
|
|
||||||
"fst.p %0, (18*8), fp36\n\t"
|
|
||||||
"fst.p %0, (19*8), fp38\n\t"
|
|
||||||
"fst.p %0, (20*8), fp40\n\t"
|
|
||||||
"fst.p %0, (21*8), fp42\n\t"
|
|
||||||
"fst.p %0, (22*8), fp44\n\t"
|
|
||||||
"fst.p %0, (23*8), fp46\n\t"
|
|
||||||
"fst.p %0, (24*8), fp48\n\t"
|
|
||||||
"fst.p %0, (25*8), fp50\n\t"
|
|
||||||
"fst.p %0, (26*8), fp52\n\t"
|
|
||||||
"fst.p %0, (27*8), fp54\n\t"
|
|
||||||
"fst.p %0, (28*8), fp56\n\t"
|
|
||||||
"fst.p %0, (29*8), fp58\n\t"
|
|
||||||
"fst.p %0, (30*8), fp60\n\t"
|
|
||||||
"fst.p %0, (31*8), fp62\n\t"
|
|
||||||
|
|
||||||
"fgetscr fr63\n\t"
|
|
||||||
"fst.s %0, (32*8), fr63\n\t"
|
|
||||||
: /* no output */
|
|
||||||
: "r" (&tsk->thread.xstate->hardfpu)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
void restore_fpu(struct task_struct *tsk)
|
|
||||||
{
|
|
||||||
asm volatile("fld.p %0, (0*8), fp0\n\t"
|
|
||||||
"fld.p %0, (1*8), fp2\n\t"
|
|
||||||
"fld.p %0, (2*8), fp4\n\t"
|
|
||||||
"fld.p %0, (3*8), fp6\n\t"
|
|
||||||
"fld.p %0, (4*8), fp8\n\t"
|
|
||||||
"fld.p %0, (5*8), fp10\n\t"
|
|
||||||
"fld.p %0, (6*8), fp12\n\t"
|
|
||||||
"fld.p %0, (7*8), fp14\n\t"
|
|
||||||
"fld.p %0, (8*8), fp16\n\t"
|
|
||||||
"fld.p %0, (9*8), fp18\n\t"
|
|
||||||
"fld.p %0, (10*8), fp20\n\t"
|
|
||||||
"fld.p %0, (11*8), fp22\n\t"
|
|
||||||
"fld.p %0, (12*8), fp24\n\t"
|
|
||||||
"fld.p %0, (13*8), fp26\n\t"
|
|
||||||
"fld.p %0, (14*8), fp28\n\t"
|
|
||||||
"fld.p %0, (15*8), fp30\n\t"
|
|
||||||
"fld.p %0, (16*8), fp32\n\t"
|
|
||||||
"fld.p %0, (17*8), fp34\n\t"
|
|
||||||
"fld.p %0, (18*8), fp36\n\t"
|
|
||||||
"fld.p %0, (19*8), fp38\n\t"
|
|
||||||
"fld.p %0, (20*8), fp40\n\t"
|
|
||||||
"fld.p %0, (21*8), fp42\n\t"
|
|
||||||
"fld.p %0, (22*8), fp44\n\t"
|
|
||||||
"fld.p %0, (23*8), fp46\n\t"
|
|
||||||
"fld.p %0, (24*8), fp48\n\t"
|
|
||||||
"fld.p %0, (25*8), fp50\n\t"
|
|
||||||
"fld.p %0, (26*8), fp52\n\t"
|
|
||||||
"fld.p %0, (27*8), fp54\n\t"
|
|
||||||
"fld.p %0, (28*8), fp56\n\t"
|
|
||||||
"fld.p %0, (29*8), fp58\n\t"
|
|
||||||
"fld.p %0, (30*8), fp60\n\t"
|
|
||||||
|
|
||||||
"fld.s %0, (32*8), fr63\n\t"
|
|
||||||
"fputscr fr63\n\t"
|
|
||||||
|
|
||||||
"fld.p %0, (31*8), fp62\n\t"
|
|
||||||
: /* no output */
|
|
||||||
: "r" (&tsk->thread.xstate->hardfpu)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void do_fpu_error(unsigned long ex, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
regs->pc += 4;
|
|
||||||
|
|
||||||
force_sig(SIGFPE);
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/cpu/sh5/probe.c
|
|
||||||
*
|
|
||||||
* CPU Subtype Probing for SH-5.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 - 2007 Paul Mundt
|
|
||||||
*/
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/cache.h>
|
|
||||||
#include <asm/tlb.h>
|
|
||||||
|
|
||||||
void cpu_probe(void)
|
|
||||||
{
|
|
||||||
unsigned long long cir;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do peeks in real mode to avoid having to set up a mapping for
|
|
||||||
* the WPC registers. On SH5-101 cut2, such a mapping would be
|
|
||||||
* exposed to an address translation erratum which would make it
|
|
||||||
* hard to set up correctly.
|
|
||||||
*/
|
|
||||||
cir = peek_real_address_q(0x0d000008);
|
|
||||||
if ((cir & 0xffff) == 0x5103)
|
|
||||||
boot_cpu_data.type = CPU_SH5_103;
|
|
||||||
else if (((cir >> 32) & 0xffff) == 0x51e2)
|
|
||||||
/* CPU.VCR aliased at CIR address on SH5-101 */
|
|
||||||
boot_cpu_data.type = CPU_SH5_101;
|
|
||||||
|
|
||||||
boot_cpu_data.family = CPU_FAMILY_SH5;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First, setup some sane values for the I-cache.
|
|
||||||
*/
|
|
||||||
boot_cpu_data.icache.ways = 4;
|
|
||||||
boot_cpu_data.icache.sets = 256;
|
|
||||||
boot_cpu_data.icache.linesz = L1_CACHE_BYTES;
|
|
||||||
boot_cpu_data.icache.way_incr = (1 << 13);
|
|
||||||
boot_cpu_data.icache.entry_shift = 5;
|
|
||||||
boot_cpu_data.icache.way_size = boot_cpu_data.icache.sets *
|
|
||||||
boot_cpu_data.icache.linesz;
|
|
||||||
boot_cpu_data.icache.entry_mask = 0x1fe0;
|
|
||||||
boot_cpu_data.icache.flags = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Next, setup some sane values for the D-cache.
|
|
||||||
*
|
|
||||||
* On the SH5, these are pretty consistent with the I-cache settings,
|
|
||||||
* so we just copy over the existing definitions.. these can be fixed
|
|
||||||
* up later, especially if we add runtime CPU probing.
|
|
||||||
*
|
|
||||||
* Though in the meantime it saves us from having to duplicate all of
|
|
||||||
* the above definitions..
|
|
||||||
*/
|
|
||||||
boot_cpu_data.dcache = boot_cpu_data.icache;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup any cache-related flags here
|
|
||||||
*/
|
|
||||||
#if defined(CONFIG_CACHE_WRITETHROUGH)
|
|
||||||
set_bit(SH_CACHE_MODE_WT, &(boot_cpu_data.dcache.flags));
|
|
||||||
#elif defined(CONFIG_CACHE_WRITEBACK)
|
|
||||||
set_bit(SH_CACHE_MODE_WB, &(boot_cpu_data.dcache.flags));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Setup some I/D TLB defaults */
|
|
||||||
sh64_tlb_init();
|
|
||||||
}
|
|
|
@ -1,121 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* SH5-101/SH5-103 CPU Setup
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Paul Mundt
|
|
||||||
*/
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/serial.h>
|
|
||||||
#include <linux/serial_sci.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/sh_timer.h>
|
|
||||||
#include <asm/addrspace.h>
|
|
||||||
#include <asm/platform_early.h>
|
|
||||||
|
|
||||||
static struct plat_sci_port scif0_platform_data = {
|
|
||||||
.flags = UPF_IOREMAP,
|
|
||||||
.scscr = SCSCR_REIE,
|
|
||||||
.type = PORT_SCIF,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource scif0_resources[] = {
|
|
||||||
DEFINE_RES_MEM(PHYS_PERIPHERAL_BLOCK + 0x01030000, 0x100),
|
|
||||||
DEFINE_RES_IRQ(39),
|
|
||||||
DEFINE_RES_IRQ(40),
|
|
||||||
DEFINE_RES_IRQ(42),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device scif0_device = {
|
|
||||||
.name = "sh-sci",
|
|
||||||
.id = 0,
|
|
||||||
.resource = scif0_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(scif0_resources),
|
|
||||||
.dev = {
|
|
||||||
.platform_data = &scif0_platform_data,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource rtc_resources[] = {
|
|
||||||
[0] = {
|
|
||||||
.start = PHYS_PERIPHERAL_BLOCK + 0x01040000,
|
|
||||||
.end = PHYS_PERIPHERAL_BLOCK + 0x01040000 + 0x58 - 1,
|
|
||||||
.flags = IORESOURCE_IO,
|
|
||||||
},
|
|
||||||
[1] = {
|
|
||||||
/* Period IRQ */
|
|
||||||
.start = IRQ_PRI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
[2] = {
|
|
||||||
/* Carry IRQ */
|
|
||||||
.start = IRQ_CUI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
[3] = {
|
|
||||||
/* Alarm IRQ */
|
|
||||||
.start = IRQ_ATI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device rtc_device = {
|
|
||||||
.name = "sh-rtc",
|
|
||||||
.id = -1,
|
|
||||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
|
||||||
.resource = rtc_resources,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TMU_BLOCK_OFF 0x01020000
|
|
||||||
#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
|
|
||||||
|
|
||||||
static struct sh_timer_config tmu0_platform_data = {
|
|
||||||
.channels_mask = 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource tmu0_resources[] = {
|
|
||||||
DEFINE_RES_MEM(TMU_BASE, 0x30),
|
|
||||||
DEFINE_RES_IRQ(IRQ_TUNI0),
|
|
||||||
DEFINE_RES_IRQ(IRQ_TUNI1),
|
|
||||||
DEFINE_RES_IRQ(IRQ_TUNI2),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device tmu0_device = {
|
|
||||||
.name = "sh-tmu",
|
|
||||||
.id = 0,
|
|
||||||
.dev = {
|
|
||||||
.platform_data = &tmu0_platform_data,
|
|
||||||
},
|
|
||||||
.resource = tmu0_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(tmu0_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device *sh5_early_devices[] __initdata = {
|
|
||||||
&scif0_device,
|
|
||||||
&tmu0_device,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device *sh5_devices[] __initdata = {
|
|
||||||
&rtc_device,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init sh5_devices_setup(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = platform_add_devices(sh5_early_devices,
|
|
||||||
ARRAY_SIZE(sh5_early_devices));
|
|
||||||
if (unlikely(ret != 0))
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return platform_add_devices(sh5_devices,
|
|
||||||
ARRAY_SIZE(sh5_devices));
|
|
||||||
}
|
|
||||||
arch_initcall(sh5_devices_setup);
|
|
||||||
|
|
||||||
void __init plat_early_device_setup(void)
|
|
||||||
{
|
|
||||||
sh_early_platform_add_devices(sh5_early_devices,
|
|
||||||
ARRAY_SIZE(sh5_early_devices));
|
|
||||||
}
|
|
|
@ -1,195 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* arch/sh/kernel/cpu/sh5/switchto.S
|
|
||||||
*
|
|
||||||
* sh64 context switch
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
|
|
||||||
.section .text..SHmedia32,"ax"
|
|
||||||
.little
|
|
||||||
|
|
||||||
.balign 32
|
|
||||||
|
|
||||||
.type sh64_switch_to,@function
|
|
||||||
.global sh64_switch_to
|
|
||||||
.global __sh64_switch_to_end
|
|
||||||
sh64_switch_to:
|
|
||||||
|
|
||||||
/* Incoming args
|
|
||||||
r2 - prev
|
|
||||||
r3 - &prev->thread
|
|
||||||
r4 - next
|
|
||||||
r5 - &next->thread
|
|
||||||
|
|
||||||
Outgoing results
|
|
||||||
r2 - last (=prev) : this just stays in r2 throughout
|
|
||||||
|
|
||||||
Want to create a full (struct pt_regs) on the stack to allow backtracing
|
|
||||||
functions to work. However, we only need to populate the callee-save
|
|
||||||
register slots in this structure; since we're a function our ancestors must
|
|
||||||
have themselves preserved all caller saved state in the stack. This saves
|
|
||||||
some wasted effort since we won't need to look at the values.
|
|
||||||
|
|
||||||
In particular, all caller-save registers are immediately available for
|
|
||||||
scratch use.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FRAME_SIZE (76*8 + 8)
|
|
||||||
|
|
||||||
movi FRAME_SIZE, r0
|
|
||||||
sub.l r15, r0, r15
|
|
||||||
! Do normal-style register save to support backtrace
|
|
||||||
|
|
||||||
st.l r15, 0, r18 ! save link reg
|
|
||||||
st.l r15, 4, r14 ! save fp
|
|
||||||
add.l r15, r63, r14 ! setup frame pointer
|
|
||||||
|
|
||||||
! hopefully this looks normal to the backtrace now.
|
|
||||||
|
|
||||||
addi.l r15, 8, r1 ! base of pt_regs
|
|
||||||
addi.l r1, 24, r0 ! base of pt_regs.regs
|
|
||||||
addi.l r0, (63*8), r8 ! base of pt_regs.trregs
|
|
||||||
|
|
||||||
/* Note : to be fixed?
|
|
||||||
struct pt_regs is really designed for holding the state on entry
|
|
||||||
to an exception, i.e. pc,sr,regs etc. However, for the context
|
|
||||||
switch state, some of this is not required. But the unwinder takes
|
|
||||||
struct pt_regs * as an arg so we have to build this structure
|
|
||||||
to allow unwinding switched tasks in show_state() */
|
|
||||||
|
|
||||||
st.q r0, ( 9*8), r9
|
|
||||||
st.q r0, (10*8), r10
|
|
||||||
st.q r0, (11*8), r11
|
|
||||||
st.q r0, (12*8), r12
|
|
||||||
st.q r0, (13*8), r13
|
|
||||||
st.q r0, (14*8), r14 ! for unwind, want to look as though we took a trap at
|
|
||||||
! the point where the process is left in suspended animation, i.e. current
|
|
||||||
! fp here, not the saved one.
|
|
||||||
st.q r0, (16*8), r16
|
|
||||||
|
|
||||||
st.q r0, (24*8), r24
|
|
||||||
st.q r0, (25*8), r25
|
|
||||||
st.q r0, (26*8), r26
|
|
||||||
st.q r0, (27*8), r27
|
|
||||||
st.q r0, (28*8), r28
|
|
||||||
st.q r0, (29*8), r29
|
|
||||||
st.q r0, (30*8), r30
|
|
||||||
st.q r0, (31*8), r31
|
|
||||||
st.q r0, (32*8), r32
|
|
||||||
st.q r0, (33*8), r33
|
|
||||||
st.q r0, (34*8), r34
|
|
||||||
st.q r0, (35*8), r35
|
|
||||||
|
|
||||||
st.q r0, (44*8), r44
|
|
||||||
st.q r0, (45*8), r45
|
|
||||||
st.q r0, (46*8), r46
|
|
||||||
st.q r0, (47*8), r47
|
|
||||||
st.q r0, (48*8), r48
|
|
||||||
st.q r0, (49*8), r49
|
|
||||||
st.q r0, (50*8), r50
|
|
||||||
st.q r0, (51*8), r51
|
|
||||||
st.q r0, (52*8), r52
|
|
||||||
st.q r0, (53*8), r53
|
|
||||||
st.q r0, (54*8), r54
|
|
||||||
st.q r0, (55*8), r55
|
|
||||||
st.q r0, (56*8), r56
|
|
||||||
st.q r0, (57*8), r57
|
|
||||||
st.q r0, (58*8), r58
|
|
||||||
st.q r0, (59*8), r59
|
|
||||||
|
|
||||||
! do this early as pta->gettr has no pipeline forwarding (=> 5 cycle latency)
|
|
||||||
! Use a local label to avoid creating a symbol that will confuse the !
|
|
||||||
! backtrace
|
|
||||||
pta .Lsave_pc, tr0
|
|
||||||
|
|
||||||
gettr tr5, r45
|
|
||||||
gettr tr6, r46
|
|
||||||
gettr tr7, r47
|
|
||||||
st.q r8, (5*8), r45
|
|
||||||
st.q r8, (6*8), r46
|
|
||||||
st.q r8, (7*8), r47
|
|
||||||
|
|
||||||
! Now switch context
|
|
||||||
gettr tr0, r9
|
|
||||||
st.l r3, 0, r15 ! prev->thread.sp
|
|
||||||
st.l r3, 8, r1 ! prev->thread.kregs
|
|
||||||
st.l r3, 4, r9 ! prev->thread.pc
|
|
||||||
st.q r1, 0, r9 ! save prev->thread.pc into pt_regs->pc
|
|
||||||
|
|
||||||
! Load PC for next task (init value or save_pc later)
|
|
||||||
ld.l r5, 4, r18 ! next->thread.pc
|
|
||||||
! Switch stacks
|
|
||||||
ld.l r5, 0, r15 ! next->thread.sp
|
|
||||||
ptabs r18, tr0
|
|
||||||
|
|
||||||
! Update current
|
|
||||||
ld.l r4, 4, r9 ! next->thread_info (2nd element of next task_struct)
|
|
||||||
putcon r9, kcr0 ! current = next->thread_info
|
|
||||||
|
|
||||||
! go to save_pc for a reschedule, or the initial thread.pc for a new process
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
! Restore (when we come back to a previously saved task)
|
|
||||||
.Lsave_pc:
|
|
||||||
addi.l r15, 32, r0 ! r0 = next's regs
|
|
||||||
addi.l r0, (63*8), r8 ! r8 = next's tr_regs
|
|
||||||
|
|
||||||
ld.q r8, (5*8), r45
|
|
||||||
ld.q r8, (6*8), r46
|
|
||||||
ld.q r8, (7*8), r47
|
|
||||||
ptabs r45, tr5
|
|
||||||
ptabs r46, tr6
|
|
||||||
ptabs r47, tr7
|
|
||||||
|
|
||||||
ld.q r0, ( 9*8), r9
|
|
||||||
ld.q r0, (10*8), r10
|
|
||||||
ld.q r0, (11*8), r11
|
|
||||||
ld.q r0, (12*8), r12
|
|
||||||
ld.q r0, (13*8), r13
|
|
||||||
ld.q r0, (14*8), r14
|
|
||||||
ld.q r0, (16*8), r16
|
|
||||||
|
|
||||||
ld.q r0, (24*8), r24
|
|
||||||
ld.q r0, (25*8), r25
|
|
||||||
ld.q r0, (26*8), r26
|
|
||||||
ld.q r0, (27*8), r27
|
|
||||||
ld.q r0, (28*8), r28
|
|
||||||
ld.q r0, (29*8), r29
|
|
||||||
ld.q r0, (30*8), r30
|
|
||||||
ld.q r0, (31*8), r31
|
|
||||||
ld.q r0, (32*8), r32
|
|
||||||
ld.q r0, (33*8), r33
|
|
||||||
ld.q r0, (34*8), r34
|
|
||||||
ld.q r0, (35*8), r35
|
|
||||||
|
|
||||||
ld.q r0, (44*8), r44
|
|
||||||
ld.q r0, (45*8), r45
|
|
||||||
ld.q r0, (46*8), r46
|
|
||||||
ld.q r0, (47*8), r47
|
|
||||||
ld.q r0, (48*8), r48
|
|
||||||
ld.q r0, (49*8), r49
|
|
||||||
ld.q r0, (50*8), r50
|
|
||||||
ld.q r0, (51*8), r51
|
|
||||||
ld.q r0, (52*8), r52
|
|
||||||
ld.q r0, (53*8), r53
|
|
||||||
ld.q r0, (54*8), r54
|
|
||||||
ld.q r0, (55*8), r55
|
|
||||||
ld.q r0, (56*8), r56
|
|
||||||
ld.q r0, (57*8), r57
|
|
||||||
ld.q r0, (58*8), r58
|
|
||||||
ld.q r0, (59*8), r59
|
|
||||||
|
|
||||||
! epilogue
|
|
||||||
ld.l r15, 0, r18
|
|
||||||
ld.l r15, 4, r14
|
|
||||||
ptabs r18, tr0
|
|
||||||
movi FRAME_SIZE, r0
|
|
||||||
add r15, r0, r15
|
|
||||||
blink tr0, r63
|
|
||||||
__sh64_switch_to_end:
|
|
||||||
.LFE1:
|
|
||||||
.size sh64_switch_to,.LFE1-sh64_switch_to
|
|
||||||
|
|
|
@ -1,342 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/cpu/sh5/unwind.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#include <linux/kallsyms.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/ptrace.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <asm/unwinder.h>
|
|
||||||
#include <asm/stacktrace.h>
|
|
||||||
|
|
||||||
static u8 regcache[63];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finding the previous stack frame isn't horribly straightforward as it is
|
|
||||||
* on some other platforms. In the sh64 case, we don't have "linked" stack
|
|
||||||
* frames, so we need to do a bit of work to determine the previous frame,
|
|
||||||
* and in turn, the previous r14/r18 pair.
|
|
||||||
*
|
|
||||||
* There are generally a few cases which determine where we can find out
|
|
||||||
* the r14/r18 values. In the general case, this can be determined by poking
|
|
||||||
* around the prologue of the symbol PC is in (note that we absolutely must
|
|
||||||
* have frame pointer support as well as the kernel symbol table mapped,
|
|
||||||
* otherwise we can't even get this far).
|
|
||||||
*
|
|
||||||
* In other cases, such as the interrupt/exception path, we can poke around
|
|
||||||
* the sp/fp.
|
|
||||||
*
|
|
||||||
* Notably, this entire approach is somewhat error prone, and in the event
|
|
||||||
* that the previous frame cannot be determined, that's all we can do.
|
|
||||||
* Either way, this still leaves us with a more correct backtrace then what
|
|
||||||
* we would be able to come up with by walking the stack (which is garbage
|
|
||||||
* for anything beyond the first frame).
|
|
||||||
* -- PFM.
|
|
||||||
*/
|
|
||||||
static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc,
|
|
||||||
unsigned long *pprev_fp, unsigned long *pprev_pc,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
const char *sym;
|
|
||||||
char namebuf[128];
|
|
||||||
unsigned long offset;
|
|
||||||
unsigned long prologue = 0;
|
|
||||||
unsigned long fp_displacement = 0;
|
|
||||||
unsigned long fp_prev = 0;
|
|
||||||
unsigned long offset_r14 = 0, offset_r18 = 0;
|
|
||||||
int i, found_prologue_end = 0;
|
|
||||||
|
|
||||||
sym = kallsyms_lookup(pc, NULL, &offset, NULL, namebuf);
|
|
||||||
if (!sym)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
prologue = pc - offset;
|
|
||||||
if (!prologue)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Validate fp, to avoid risk of dereferencing a bad pointer later.
|
|
||||||
Assume 128Mb since that's the amount of RAM on a Cayman. Modify
|
|
||||||
when there is an SH-5 board with more. */
|
|
||||||
if ((fp < (unsigned long) phys_to_virt(__MEMORY_START)) ||
|
|
||||||
(fp >= (unsigned long)(phys_to_virt(__MEMORY_START)) + 128*1024*1024) ||
|
|
||||||
((fp & 7) != 0)) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Depth to walk, depth is completely arbitrary.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 100; i++, prologue += sizeof(unsigned long)) {
|
|
||||||
unsigned long op;
|
|
||||||
u8 major, minor;
|
|
||||||
u8 src, dest, disp;
|
|
||||||
|
|
||||||
op = *(unsigned long *)prologue;
|
|
||||||
|
|
||||||
major = (op >> 26) & 0x3f;
|
|
||||||
src = (op >> 20) & 0x3f;
|
|
||||||
minor = (op >> 16) & 0xf;
|
|
||||||
disp = (op >> 10) & 0x3f;
|
|
||||||
dest = (op >> 4) & 0x3f;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack frame creation happens in a number of ways.. in the
|
|
||||||
* general case when the stack frame is less than 511 bytes,
|
|
||||||
* it's generally created by an addi or addi.l:
|
|
||||||
*
|
|
||||||
* addi/addi.l r15, -FRAME_SIZE, r15
|
|
||||||
*
|
|
||||||
* in the event that the frame size is bigger than this, it's
|
|
||||||
* typically created using a movi/sub pair as follows:
|
|
||||||
*
|
|
||||||
* movi FRAME_SIZE, rX
|
|
||||||
* sub r15, rX, r15
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (major) {
|
|
||||||
case (0x00 >> 2):
|
|
||||||
switch (minor) {
|
|
||||||
case 0x8: /* add.l */
|
|
||||||
case 0x9: /* add */
|
|
||||||
/* Look for r15, r63, r14 */
|
|
||||||
if (src == 15 && disp == 63 && dest == 14)
|
|
||||||
found_prologue_end = 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 0xa: /* sub.l */
|
|
||||||
case 0xb: /* sub */
|
|
||||||
if (src != 15 || dest != 15)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
fp_displacement -= regcache[disp];
|
|
||||||
fp_prev = fp - fp_displacement;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case (0xa8 >> 2): /* st.l */
|
|
||||||
if (src != 15)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (dest) {
|
|
||||||
case 14:
|
|
||||||
if (offset_r14 || fp_displacement == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
offset_r14 = (u64)(((((s64)op >> 10) & 0x3ff) << 54) >> 54);
|
|
||||||
offset_r14 *= sizeof(unsigned long);
|
|
||||||
offset_r14 += fp_displacement;
|
|
||||||
break;
|
|
||||||
case 18:
|
|
||||||
if (offset_r18 || fp_displacement == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
offset_r18 = (u64)(((((s64)op >> 10) & 0x3ff) << 54) >> 54);
|
|
||||||
offset_r18 *= sizeof(unsigned long);
|
|
||||||
offset_r18 += fp_displacement;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case (0xcc >> 2): /* movi */
|
|
||||||
if (dest >= 63) {
|
|
||||||
printk(KERN_NOTICE "%s: Invalid dest reg %d "
|
|
||||||
"specified in movi handler. Failed "
|
|
||||||
"opcode was 0x%lx: ", __func__,
|
|
||||||
dest, op);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sign extend */
|
|
||||||
regcache[dest] =
|
|
||||||
sign_extend64((((u64)op >> 10) & 0xffff), 9);
|
|
||||||
break;
|
|
||||||
case (0xd0 >> 2): /* addi */
|
|
||||||
case (0xd4 >> 2): /* addi.l */
|
|
||||||
/* Look for r15, -FRAME_SIZE, r15 */
|
|
||||||
if (src != 15 || dest != 15)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Sign extended frame size.. */
|
|
||||||
fp_displacement +=
|
|
||||||
(u64)(((((s64)op >> 10) & 0x3ff) << 54) >> 54);
|
|
||||||
fp_prev = fp - fp_displacement;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_prologue_end && offset_r14 && (offset_r18 || *pprev_pc) && fp_prev)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset_r14 == 0 || fp_prev == 0) {
|
|
||||||
if (!offset_r14)
|
|
||||||
pr_debug("Unable to find r14 offset\n");
|
|
||||||
if (!fp_prev)
|
|
||||||
pr_debug("Unable to find previous fp\n");
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For innermost leaf function, there might not be a offset_r18 */
|
|
||||||
if (!*pprev_pc && (offset_r18 == 0))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
*pprev_fp = *(unsigned long *)(fp_prev + offset_r14);
|
|
||||||
|
|
||||||
if (offset_r18)
|
|
||||||
*pprev_pc = *(unsigned long *)(fp_prev + offset_r18);
|
|
||||||
|
|
||||||
*pprev_pc &= ~1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Don't put this on the stack since we'll want to call in to
|
|
||||||
* sh64_unwinder_dump() when we're close to underflowing the stack
|
|
||||||
* anyway.
|
|
||||||
*/
|
|
||||||
static struct pt_regs here_regs;
|
|
||||||
|
|
||||||
extern const char syscall_ret;
|
|
||||||
extern const char ret_from_syscall;
|
|
||||||
extern const char ret_from_exception;
|
|
||||||
extern const char ret_from_irq;
|
|
||||||
|
|
||||||
static void sh64_unwind_inner(const struct stacktrace_ops *ops,
|
|
||||||
void *data, struct pt_regs *regs);
|
|
||||||
|
|
||||||
static inline void unwind_nested(const struct stacktrace_ops *ops, void *data,
|
|
||||||
unsigned long pc, unsigned long fp)
|
|
||||||
{
|
|
||||||
if ((fp >= __MEMORY_START) &&
|
|
||||||
((fp & 7) == 0))
|
|
||||||
sh64_unwind_inner(ops, data, (struct pt_regs *)fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sh64_unwind_inner(const struct stacktrace_ops *ops,
|
|
||||||
void *data, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
unsigned long pc, fp;
|
|
||||||
int ofs = 0;
|
|
||||||
int first_pass;
|
|
||||||
|
|
||||||
pc = regs->pc & ~1;
|
|
||||||
fp = regs->regs[14];
|
|
||||||
|
|
||||||
first_pass = 1;
|
|
||||||
for (;;) {
|
|
||||||
int cond;
|
|
||||||
unsigned long next_fp, next_pc;
|
|
||||||
|
|
||||||
if (pc == ((unsigned long)&syscall_ret & ~1)) {
|
|
||||||
printk("SYSCALL\n");
|
|
||||||
unwind_nested(ops, data, pc, fp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pc == ((unsigned long)&ret_from_syscall & ~1)) {
|
|
||||||
printk("SYSCALL (PREEMPTED)\n");
|
|
||||||
unwind_nested(ops, data, pc, fp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In this case, the PC is discovered by lookup_prev_stack_frame but
|
|
||||||
it has 4 taken off it to look like the 'caller' */
|
|
||||||
if (pc == ((unsigned long)&ret_from_exception & ~1)) {
|
|
||||||
printk("EXCEPTION\n");
|
|
||||||
unwind_nested(ops, data, pc, fp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pc == ((unsigned long)&ret_from_irq & ~1)) {
|
|
||||||
printk("IRQ\n");
|
|
||||||
unwind_nested(ops, data, pc, fp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cond = ((pc >= __MEMORY_START) && (fp >= __MEMORY_START) &&
|
|
||||||
((pc & 3) == 0) && ((fp & 7) == 0));
|
|
||||||
|
|
||||||
pc -= ofs;
|
|
||||||
|
|
||||||
ops->address(data, pc, 1);
|
|
||||||
|
|
||||||
if (first_pass) {
|
|
||||||
/* If the innermost frame is a leaf function, it's
|
|
||||||
* possible that r18 is never saved out to the stack.
|
|
||||||
*/
|
|
||||||
next_pc = regs->regs[18];
|
|
||||||
} else {
|
|
||||||
next_pc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lookup_prev_stack_frame(fp, pc, &next_fp, &next_pc, regs) == 0) {
|
|
||||||
ofs = sizeof(unsigned long);
|
|
||||||
pc = next_pc & ~1;
|
|
||||||
fp = next_fp;
|
|
||||||
} else {
|
|
||||||
printk("Unable to lookup previous stack frame\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
first_pass = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printk("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sh64_unwinder_dump(struct task_struct *task,
|
|
||||||
struct pt_regs *regs,
|
|
||||||
unsigned long *sp,
|
|
||||||
const struct stacktrace_ops *ops,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
if (!regs) {
|
|
||||||
/*
|
|
||||||
* Fetch current regs if we have no other saved state to back
|
|
||||||
* trace from.
|
|
||||||
*/
|
|
||||||
regs = &here_regs;
|
|
||||||
|
|
||||||
__asm__ __volatile__ ("ori r14, 0, %0" : "=r" (regs->regs[14]));
|
|
||||||
__asm__ __volatile__ ("ori r15, 0, %0" : "=r" (regs->regs[15]));
|
|
||||||
__asm__ __volatile__ ("ori r18, 0, %0" : "=r" (regs->regs[18]));
|
|
||||||
|
|
||||||
__asm__ __volatile__ ("gettr tr0, %0" : "=r" (regs->tregs[0]));
|
|
||||||
__asm__ __volatile__ ("gettr tr1, %0" : "=r" (regs->tregs[1]));
|
|
||||||
__asm__ __volatile__ ("gettr tr2, %0" : "=r" (regs->tregs[2]));
|
|
||||||
__asm__ __volatile__ ("gettr tr3, %0" : "=r" (regs->tregs[3]));
|
|
||||||
__asm__ __volatile__ ("gettr tr4, %0" : "=r" (regs->tregs[4]));
|
|
||||||
__asm__ __volatile__ ("gettr tr5, %0" : "=r" (regs->tregs[5]));
|
|
||||||
__asm__ __volatile__ ("gettr tr6, %0" : "=r" (regs->tregs[6]));
|
|
||||||
__asm__ __volatile__ ("gettr tr7, %0" : "=r" (regs->tregs[7]));
|
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"pta 0f, tr0\n\t"
|
|
||||||
"blink tr0, %0\n\t"
|
|
||||||
"0: nop"
|
|
||||||
: "=r" (regs->pc)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sh64_unwind_inner(ops, data, regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct unwinder sh64_unwinder = {
|
|
||||||
.name = "sh64-unwinder",
|
|
||||||
.dump = sh64_unwinder_dump,
|
|
||||||
.rating = 150,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init sh64_unwinder_init(void)
|
|
||||||
{
|
|
||||||
return unwinder_register(&sh64_unwinder);
|
|
||||||
}
|
|
||||||
early_initcall(sh64_unwinder_init);
|
|
|
@ -1,346 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* arch/sh/kernel/head_64.S
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003, 2004 Paul Mundt
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/cache.h>
|
|
||||||
#include <asm/tlb.h>
|
|
||||||
#include <cpu/registers.h>
|
|
||||||
#include <cpu/mmu_context.h>
|
|
||||||
#include <asm/thread_info.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MMU defines: TLB boundaries.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MMUIR_FIRST ITLB_FIXED
|
|
||||||
#define MMUIR_END ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP
|
|
||||||
#define MMUIR_STEP TLB_STEP
|
|
||||||
|
|
||||||
#define MMUDR_FIRST DTLB_FIXED
|
|
||||||
#define MMUDR_END DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP
|
|
||||||
#define MMUDR_STEP TLB_STEP
|
|
||||||
|
|
||||||
/* Safety check : CONFIG_PAGE_OFFSET has to be a multiple of 512Mb */
|
|
||||||
#if (CONFIG_PAGE_OFFSET & ((1UL<<29)-1))
|
|
||||||
#error "CONFIG_PAGE_OFFSET must be a multiple of 512Mb"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MMU defines: Fixed TLBs.
|
|
||||||
*/
|
|
||||||
/* Deal safely with the case where the base of RAM is not 512Mb aligned */
|
|
||||||
|
|
||||||
#define ALIGN_512M_MASK (0xffffffffe0000000)
|
|
||||||
#define ALIGNED_EFFECTIVE ((CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START) & ALIGN_512M_MASK)
|
|
||||||
#define ALIGNED_PHYSICAL (CONFIG_MEMORY_START & ALIGN_512M_MASK)
|
|
||||||
|
|
||||||
#define MMUIR_TEXT_H (0x0000000000000003 | ALIGNED_EFFECTIVE)
|
|
||||||
/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
|
|
||||||
|
|
||||||
#define MMUIR_TEXT_L (0x000000000000009a | ALIGNED_PHYSICAL)
|
|
||||||
/* 512 Mb, Cacheable, Write-back, execute, Not User, Ph. Add. */
|
|
||||||
|
|
||||||
#define MMUDR_CACHED_H 0x0000000000000003 | ALIGNED_EFFECTIVE
|
|
||||||
/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
|
|
||||||
#define MMUDR_CACHED_L 0x000000000000015a | ALIGNED_PHYSICAL
|
|
||||||
/* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */
|
|
||||||
|
|
||||||
#ifdef CONFIG_CACHE_OFF
|
|
||||||
#define ICCR0_INIT_VAL ICCR0_OFF /* ICACHE off */
|
|
||||||
#else
|
|
||||||
#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */
|
|
||||||
#endif
|
|
||||||
#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */
|
|
||||||
|
|
||||||
#if defined (CONFIG_CACHE_OFF)
|
|
||||||
#define OCCR0_INIT_VAL OCCR0_OFF /* D-cache: off */
|
|
||||||
#elif defined (CONFIG_CACHE_WRITETHROUGH)
|
|
||||||
#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WT /* D-cache: on, */
|
|
||||||
/* WT, invalidate */
|
|
||||||
#elif defined (CONFIG_CACHE_WRITEBACK)
|
|
||||||
#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* D-cache: on, */
|
|
||||||
/* WB, invalidate */
|
|
||||||
#else
|
|
||||||
#error preprocessor flag CONFIG_CACHE_... not recognized!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */
|
|
||||||
|
|
||||||
.section .empty_zero_page, "aw"
|
|
||||||
.global empty_zero_page
|
|
||||||
|
|
||||||
empty_zero_page:
|
|
||||||
.long 1 /* MOUNT_ROOT_RDONLY */
|
|
||||||
.long 0 /* RAMDISK_FLAGS */
|
|
||||||
.long 0x0200 /* ORIG_ROOT_DEV */
|
|
||||||
.long 1 /* LOADER_TYPE */
|
|
||||||
.long 0x00800000 /* INITRD_START */
|
|
||||||
.long 0x00800000 /* INITRD_SIZE */
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
.text
|
|
||||||
.balign 4096,0,4096
|
|
||||||
|
|
||||||
.section .data, "aw"
|
|
||||||
.balign PAGE_SIZE
|
|
||||||
|
|
||||||
.section .data, "aw"
|
|
||||||
.balign PAGE_SIZE
|
|
||||||
|
|
||||||
.global mmu_pdtp_cache
|
|
||||||
mmu_pdtp_cache:
|
|
||||||
.space PAGE_SIZE, 0
|
|
||||||
|
|
||||||
.global fpu_in_use
|
|
||||||
fpu_in_use: .quad 0
|
|
||||||
|
|
||||||
|
|
||||||
__HEAD
|
|
||||||
.balign L1_CACHE_BYTES
|
|
||||||
/*
|
|
||||||
* Condition at the entry of __stext:
|
|
||||||
* . Reset state:
|
|
||||||
* . SR.FD = 1 (FPU disabled)
|
|
||||||
* . SR.BL = 1 (Exceptions disabled)
|
|
||||||
* . SR.MD = 1 (Privileged Mode)
|
|
||||||
* . SR.MMU = 0 (MMU Disabled)
|
|
||||||
* . SR.CD = 0 (CTC User Visible)
|
|
||||||
* . SR.IMASK = Undefined (Interrupt Mask)
|
|
||||||
*
|
|
||||||
* Operations supposed to be performed by __stext:
|
|
||||||
* . prevent speculative fetch onto device memory while MMU is off
|
|
||||||
* . reflect as much as possible SH5 ABI (r15, r26, r27, r18)
|
|
||||||
* . first, save CPU state and set it to something harmless
|
|
||||||
* . any CPU detection and/or endianness settings (?)
|
|
||||||
* . initialize EMI/LMI (but not TMU/RTC/INTC/SCIF): TBD
|
|
||||||
* . set initial TLB entries for cached and uncached regions
|
|
||||||
* (no fine granularity paging)
|
|
||||||
* . set initial cache state
|
|
||||||
* . enable MMU and caches
|
|
||||||
* . set CPU to a consistent state
|
|
||||||
* . registers (including stack pointer and current/KCR0)
|
|
||||||
* . NOT expecting to set Exception handling nor VBR/RESVEC/DCR
|
|
||||||
* at this stage. This is all to later Linux initialization steps.
|
|
||||||
* . initialize FPU
|
|
||||||
* . clear BSS
|
|
||||||
* . jump into start_kernel()
|
|
||||||
* . be prepared to hopeless start_kernel() returns.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.global _stext
|
|
||||||
_stext:
|
|
||||||
/*
|
|
||||||
* Prevent speculative fetch on device memory due to
|
|
||||||
* uninitialized target registers.
|
|
||||||
*/
|
|
||||||
ptabs/u ZERO, tr0
|
|
||||||
ptabs/u ZERO, tr1
|
|
||||||
ptabs/u ZERO, tr2
|
|
||||||
ptabs/u ZERO, tr3
|
|
||||||
ptabs/u ZERO, tr4
|
|
||||||
ptabs/u ZERO, tr5
|
|
||||||
ptabs/u ZERO, tr6
|
|
||||||
ptabs/u ZERO, tr7
|
|
||||||
synci
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read/Set CPU state. After this block:
|
|
||||||
* r29 = Initial SR
|
|
||||||
*/
|
|
||||||
getcon SR, r29
|
|
||||||
movi SR_HARMLESS, r20
|
|
||||||
putcon r20, SR
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize EMI/LMI. To Be Done.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CPU detection and/or endianness settings (?). To Be Done.
|
|
||||||
* Pure PIC code here, please ! Just save state into r30.
|
|
||||||
* After this block:
|
|
||||||
* r30 = CPU type/Platform Endianness
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set initial TLB entries for cached and uncached regions.
|
|
||||||
* Note: PTA/BLINK is PIC code, PTABS/BLINK isn't !
|
|
||||||
*/
|
|
||||||
/* Clear ITLBs */
|
|
||||||
pta clear_ITLB, tr1
|
|
||||||
movi MMUIR_FIRST, r21
|
|
||||||
movi MMUIR_END, r22
|
|
||||||
clear_ITLB:
|
|
||||||
putcfg r21, 0, ZERO /* Clear MMUIR[n].PTEH.V */
|
|
||||||
addi r21, MMUIR_STEP, r21
|
|
||||||
bne r21, r22, tr1
|
|
||||||
|
|
||||||
/* Clear DTLBs */
|
|
||||||
pta clear_DTLB, tr1
|
|
||||||
movi MMUDR_FIRST, r21
|
|
||||||
movi MMUDR_END, r22
|
|
||||||
clear_DTLB:
|
|
||||||
putcfg r21, 0, ZERO /* Clear MMUDR[n].PTEH.V */
|
|
||||||
addi r21, MMUDR_STEP, r21
|
|
||||||
bne r21, r22, tr1
|
|
||||||
|
|
||||||
/* Map one big (512Mb) page for ITLB */
|
|
||||||
movi MMUIR_FIRST, r21
|
|
||||||
movi MMUIR_TEXT_L, r22 /* PTEL first */
|
|
||||||
add.l r22, r63, r22 /* Sign extend */
|
|
||||||
putcfg r21, 1, r22 /* Set MMUIR[0].PTEL */
|
|
||||||
movi MMUIR_TEXT_H, r22 /* PTEH last */
|
|
||||||
add.l r22, r63, r22 /* Sign extend */
|
|
||||||
putcfg r21, 0, r22 /* Set MMUIR[0].PTEH */
|
|
||||||
|
|
||||||
/* Map one big CACHED (512Mb) page for DTLB */
|
|
||||||
movi MMUDR_FIRST, r21
|
|
||||||
movi MMUDR_CACHED_L, r22 /* PTEL first */
|
|
||||||
add.l r22, r63, r22 /* Sign extend */
|
|
||||||
putcfg r21, 1, r22 /* Set MMUDR[0].PTEL */
|
|
||||||
movi MMUDR_CACHED_H, r22 /* PTEH last */
|
|
||||||
add.l r22, r63, r22 /* Sign extend */
|
|
||||||
putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup a DTLB translation for SCIF phys.
|
|
||||||
*/
|
|
||||||
addi r21, MMUDR_STEP, r21
|
|
||||||
movi 0x0a03, r22 /* SCIF phys */
|
|
||||||
shori 0x0148, r22
|
|
||||||
putcfg r21, 1, r22 /* PTEL first */
|
|
||||||
movi 0xfa03, r22 /* 0xfa030000, fixed SCIF virt */
|
|
||||||
shori 0x0003, r22
|
|
||||||
putcfg r21, 0, r22 /* PTEH last */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set cache behaviours.
|
|
||||||
*/
|
|
||||||
/* ICache */
|
|
||||||
movi ICCR_BASE, r21
|
|
||||||
movi ICCR0_INIT_VAL, r22
|
|
||||||
movi ICCR1_INIT_VAL, r23
|
|
||||||
putcfg r21, ICCR_REG0, r22
|
|
||||||
putcfg r21, ICCR_REG1, r23
|
|
||||||
|
|
||||||
/* OCache */
|
|
||||||
movi OCCR_BASE, r21
|
|
||||||
movi OCCR0_INIT_VAL, r22
|
|
||||||
movi OCCR1_INIT_VAL, r23
|
|
||||||
putcfg r21, OCCR_REG0, r22
|
|
||||||
putcfg r21, OCCR_REG1, r23
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable Caches and MMU. Do the first non-PIC jump.
|
|
||||||
* Now head.S global variables, constants and externs
|
|
||||||
* can be used.
|
|
||||||
*/
|
|
||||||
getcon SR, r21
|
|
||||||
movi SR_ENABLE_MMU, r22
|
|
||||||
or r21, r22, r21
|
|
||||||
putcon r21, SSR
|
|
||||||
movi hyperspace, r22
|
|
||||||
ori r22, 1, r22 /* Make it SHmedia, not required but..*/
|
|
||||||
putcon r22, SPC
|
|
||||||
synco
|
|
||||||
rte /* And now go into the hyperspace ... */
|
|
||||||
hyperspace: /* ... that's the next instruction ! */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set CPU to a consistent state.
|
|
||||||
* r31 = FPU support flag
|
|
||||||
* tr0/tr7 in use. Others give a chance to loop somewhere safe
|
|
||||||
*/
|
|
||||||
movi start_kernel, r32
|
|
||||||
ori r32, 1, r32
|
|
||||||
|
|
||||||
ptabs r32, tr0 /* r32 = _start_kernel address */
|
|
||||||
pta/u hopeless, tr1
|
|
||||||
pta/u hopeless, tr2
|
|
||||||
pta/u hopeless, tr3
|
|
||||||
pta/u hopeless, tr4
|
|
||||||
pta/u hopeless, tr5
|
|
||||||
pta/u hopeless, tr6
|
|
||||||
pta/u hopeless, tr7
|
|
||||||
gettr tr1, r28 /* r28 = hopeless address */
|
|
||||||
|
|
||||||
/* Set initial stack pointer */
|
|
||||||
movi init_thread_union, SP
|
|
||||||
putcon SP, KCR0 /* Set current to init_task */
|
|
||||||
movi THREAD_SIZE, r22 /* Point to the end */
|
|
||||||
add SP, r22, SP
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize FPU.
|
|
||||||
* Keep FPU flag in r31. After this block:
|
|
||||||
* r31 = FPU flag
|
|
||||||
*/
|
|
||||||
movi fpu_in_use, r31 /* Temporary */
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
getcon SR, r21
|
|
||||||
movi SR_ENABLE_FPU, r22
|
|
||||||
and r21, r22, r22
|
|
||||||
putcon r22, SR /* Try to enable */
|
|
||||||
getcon SR, r22
|
|
||||||
xor r21, r22, r21
|
|
||||||
shlri r21, 15, r21 /* Supposedly 0/1 */
|
|
||||||
st.q r31, 0 , r21 /* Set fpu_in_use */
|
|
||||||
#else
|
|
||||||
movi 0, r21
|
|
||||||
st.q r31, 0 , r21 /* Set fpu_in_use */
|
|
||||||
#endif
|
|
||||||
or r21, ZERO, r31 /* Set FPU flag at last */
|
|
||||||
|
|
||||||
#ifndef CONFIG_SH_NO_BSS_INIT
|
|
||||||
/* Don't clear BSS if running on slow platforms such as an RTL simulation,
|
|
||||||
remote memory via SHdebug link, etc. For these the memory can be guaranteed
|
|
||||||
to be all zero on boot anyway. */
|
|
||||||
/*
|
|
||||||
* Clear bss
|
|
||||||
*/
|
|
||||||
pta clear_quad, tr1
|
|
||||||
movi __bss_start, r22
|
|
||||||
movi _end, r23
|
|
||||||
clear_quad:
|
|
||||||
st.q r22, 0, ZERO
|
|
||||||
addi r22, 8, r22
|
|
||||||
bne r22, r23, tr1 /* Both quad aligned, see vmlinux.lds.S */
|
|
||||||
#endif
|
|
||||||
pta/u hopeless, tr1
|
|
||||||
|
|
||||||
/* Say bye to head.S but be prepared to wrongly get back ... */
|
|
||||||
blink tr0, LINK
|
|
||||||
|
|
||||||
/* If we ever get back here through LINK/tr1-tr7 */
|
|
||||||
pta/u hopeless, tr7
|
|
||||||
|
|
||||||
hopeless:
|
|
||||||
/*
|
|
||||||
* Something's badly wrong here. Loop endlessly,
|
|
||||||
* there's nothing more we can do about it.
|
|
||||||
*
|
|
||||||
* Note on hopeless: it can be jumped into invariably
|
|
||||||
* before or after jumping into hyperspace. The only
|
|
||||||
* requirement is to be PIC called (PTA) before and
|
|
||||||
* any way (PTA/PTABS) after. According to Virtual
|
|
||||||
* to Physical mapping a simulator/emulator can easily
|
|
||||||
* tell where we came here from just looking at hopeless
|
|
||||||
* (PC) address.
|
|
||||||
*
|
|
||||||
* For debugging purposes:
|
|
||||||
* (r28) hopeless/loop address
|
|
||||||
* (r29) Original SR
|
|
||||||
* (r30) CPU type/Platform endianness
|
|
||||||
* (r31) FPU Support
|
|
||||||
* (r32) _start_kernel address
|
|
||||||
*/
|
|
||||||
blink tr7, ZERO
|
|
|
@ -1,48 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* SHmedia irqflags support
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 - 2009 Paul Mundt
|
|
||||||
*/
|
|
||||||
#include <linux/irqflags.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <cpu/registers.h>
|
|
||||||
|
|
||||||
void notrace arch_local_irq_restore(unsigned long flags)
|
|
||||||
{
|
|
||||||
unsigned long long __dummy;
|
|
||||||
|
|
||||||
if (flags == ARCH_IRQ_DISABLED) {
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"getcon " __SR ", %0\n\t"
|
|
||||||
"or %0, %1, %0\n\t"
|
|
||||||
"putcon %0, " __SR "\n\t"
|
|
||||||
: "=&r" (__dummy)
|
|
||||||
: "r" (ARCH_IRQ_DISABLED)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"getcon " __SR ", %0\n\t"
|
|
||||||
"and %0, %1, %0\n\t"
|
|
||||||
"putcon %0, " __SR "\n\t"
|
|
||||||
: "=&r" (__dummy)
|
|
||||||
: "r" (~ARCH_IRQ_DISABLED)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(arch_local_irq_restore);
|
|
||||||
|
|
||||||
unsigned long notrace arch_local_save_flags(void)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"getcon " __SR ", %0\n\t"
|
|
||||||
"and %0, %1, %0"
|
|
||||||
: "=&r" (flags)
|
|
||||||
: "r" (ARCH_IRQ_DISABLED)
|
|
||||||
);
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(arch_local_save_flags);
|
|
|
@ -46,15 +46,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
|
||||||
+ ELF32_R_SYM(rel[i].r_info);
|
+ ELF32_R_SYM(rel[i].r_info);
|
||||||
relocation = sym->st_value + rel[i].r_addend;
|
relocation = sym->st_value + rel[i].r_addend;
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
/* For text addresses, bit2 of the st_other field indicates
|
|
||||||
* whether the symbol is SHmedia (1) or SHcompact (0). If
|
|
||||||
* SHmedia, the LSB of the symbol needs to be asserted
|
|
||||||
* for the CPU to be in SHmedia mode when it starts executing
|
|
||||||
* the branch target. */
|
|
||||||
relocation |= !!(sym->st_other & 4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (ELF32_R_TYPE(rel[i].r_info)) {
|
switch (ELF32_R_TYPE(rel[i].r_info)) {
|
||||||
case R_SH_NONE:
|
case R_SH_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -23,9 +23,7 @@ EXPORT_SYMBOL(__stack_chk_guard);
|
||||||
*/
|
*/
|
||||||
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
unlazy_fpu(src, task_pt_regs(src));
|
unlazy_fpu(src, task_pt_regs(src));
|
||||||
#endif
|
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
|
|
||||||
if (src->thread.xstate) {
|
if (src->thread.xstate) {
|
||||||
|
|
|
@ -1,461 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/process_64.c
|
|
||||||
*
|
|
||||||
* This file handles the architecture-dependent parts of process handling..
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 - 2007 Paul Mundt
|
|
||||||
* Copyright (C) 2003, 2004 Richard Curnow
|
|
||||||
*
|
|
||||||
* Started from SH3/4 version:
|
|
||||||
* Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
|
|
||||||
*
|
|
||||||
* In turn started from i386 version:
|
|
||||||
* Copyright (C) 1995 Linus Torvalds
|
|
||||||
*/
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/reboot.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/sched/debug.h>
|
|
||||||
#include <linux/sched/task.h>
|
|
||||||
#include <linux/sched/task_stack.h>
|
|
||||||
#include <asm/syscalls.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/mmu_context.h>
|
|
||||||
#include <asm/fpu.h>
|
|
||||||
#include <asm/switch_to.h>
|
|
||||||
|
|
||||||
struct task_struct *last_task_used_math = NULL;
|
|
||||||
struct pt_regs fake_swapper_regs = { 0, };
|
|
||||||
|
|
||||||
void show_regs(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
unsigned long long ah, al, bh, bl, ch, cl;
|
|
||||||
|
|
||||||
printk("\n");
|
|
||||||
show_regs_print_info(KERN_DEFAULT);
|
|
||||||
|
|
||||||
ah = (regs->pc) >> 32;
|
|
||||||
al = (regs->pc) & 0xffffffff;
|
|
||||||
bh = (regs->regs[18]) >> 32;
|
|
||||||
bl = (regs->regs[18]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[15]) >> 32;
|
|
||||||
cl = (regs->regs[15]) & 0xffffffff;
|
|
||||||
printk("PC : %08Lx%08Lx LINK: %08Lx%08Lx SP : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->sr) >> 32;
|
|
||||||
al = (regs->sr) & 0xffffffff;
|
|
||||||
asm volatile ("getcon " __TEA ", %0" : "=r" (bh));
|
|
||||||
asm volatile ("getcon " __TEA ", %0" : "=r" (bl));
|
|
||||||
bh = (bh) >> 32;
|
|
||||||
bl = (bl) & 0xffffffff;
|
|
||||||
asm volatile ("getcon " __KCR0 ", %0" : "=r" (ch));
|
|
||||||
asm volatile ("getcon " __KCR0 ", %0" : "=r" (cl));
|
|
||||||
ch = (ch) >> 32;
|
|
||||||
cl = (cl) & 0xffffffff;
|
|
||||||
printk("SR : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[0]) >> 32;
|
|
||||||
al = (regs->regs[0]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[1]) >> 32;
|
|
||||||
bl = (regs->regs[1]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[2]) >> 32;
|
|
||||||
cl = (regs->regs[2]) & 0xffffffff;
|
|
||||||
printk("R0 : %08Lx%08Lx R1 : %08Lx%08Lx R2 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[3]) >> 32;
|
|
||||||
al = (regs->regs[3]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[4]) >> 32;
|
|
||||||
bl = (regs->regs[4]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[5]) >> 32;
|
|
||||||
cl = (regs->regs[5]) & 0xffffffff;
|
|
||||||
printk("R3 : %08Lx%08Lx R4 : %08Lx%08Lx R5 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[6]) >> 32;
|
|
||||||
al = (regs->regs[6]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[7]) >> 32;
|
|
||||||
bl = (regs->regs[7]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[8]) >> 32;
|
|
||||||
cl = (regs->regs[8]) & 0xffffffff;
|
|
||||||
printk("R6 : %08Lx%08Lx R7 : %08Lx%08Lx R8 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[9]) >> 32;
|
|
||||||
al = (regs->regs[9]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[10]) >> 32;
|
|
||||||
bl = (regs->regs[10]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[11]) >> 32;
|
|
||||||
cl = (regs->regs[11]) & 0xffffffff;
|
|
||||||
printk("R9 : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[12]) >> 32;
|
|
||||||
al = (regs->regs[12]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[13]) >> 32;
|
|
||||||
bl = (regs->regs[13]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[14]) >> 32;
|
|
||||||
cl = (regs->regs[14]) & 0xffffffff;
|
|
||||||
printk("R12 : %08Lx%08Lx R13 : %08Lx%08Lx R14 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[16]) >> 32;
|
|
||||||
al = (regs->regs[16]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[17]) >> 32;
|
|
||||||
bl = (regs->regs[17]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[19]) >> 32;
|
|
||||||
cl = (regs->regs[19]) & 0xffffffff;
|
|
||||||
printk("R16 : %08Lx%08Lx R17 : %08Lx%08Lx R19 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[20]) >> 32;
|
|
||||||
al = (regs->regs[20]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[21]) >> 32;
|
|
||||||
bl = (regs->regs[21]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[22]) >> 32;
|
|
||||||
cl = (regs->regs[22]) & 0xffffffff;
|
|
||||||
printk("R20 : %08Lx%08Lx R21 : %08Lx%08Lx R22 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[23]) >> 32;
|
|
||||||
al = (regs->regs[23]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[24]) >> 32;
|
|
||||||
bl = (regs->regs[24]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[25]) >> 32;
|
|
||||||
cl = (regs->regs[25]) & 0xffffffff;
|
|
||||||
printk("R23 : %08Lx%08Lx R24 : %08Lx%08Lx R25 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[26]) >> 32;
|
|
||||||
al = (regs->regs[26]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[27]) >> 32;
|
|
||||||
bl = (regs->regs[27]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[28]) >> 32;
|
|
||||||
cl = (regs->regs[28]) & 0xffffffff;
|
|
||||||
printk("R26 : %08Lx%08Lx R27 : %08Lx%08Lx R28 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[29]) >> 32;
|
|
||||||
al = (regs->regs[29]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[30]) >> 32;
|
|
||||||
bl = (regs->regs[30]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[31]) >> 32;
|
|
||||||
cl = (regs->regs[31]) & 0xffffffff;
|
|
||||||
printk("R29 : %08Lx%08Lx R30 : %08Lx%08Lx R31 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[32]) >> 32;
|
|
||||||
al = (regs->regs[32]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[33]) >> 32;
|
|
||||||
bl = (regs->regs[33]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[34]) >> 32;
|
|
||||||
cl = (regs->regs[34]) & 0xffffffff;
|
|
||||||
printk("R32 : %08Lx%08Lx R33 : %08Lx%08Lx R34 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[35]) >> 32;
|
|
||||||
al = (regs->regs[35]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[36]) >> 32;
|
|
||||||
bl = (regs->regs[36]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[37]) >> 32;
|
|
||||||
cl = (regs->regs[37]) & 0xffffffff;
|
|
||||||
printk("R35 : %08Lx%08Lx R36 : %08Lx%08Lx R37 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[38]) >> 32;
|
|
||||||
al = (regs->regs[38]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[39]) >> 32;
|
|
||||||
bl = (regs->regs[39]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[40]) >> 32;
|
|
||||||
cl = (regs->regs[40]) & 0xffffffff;
|
|
||||||
printk("R38 : %08Lx%08Lx R39 : %08Lx%08Lx R40 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[41]) >> 32;
|
|
||||||
al = (regs->regs[41]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[42]) >> 32;
|
|
||||||
bl = (regs->regs[42]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[43]) >> 32;
|
|
||||||
cl = (regs->regs[43]) & 0xffffffff;
|
|
||||||
printk("R41 : %08Lx%08Lx R42 : %08Lx%08Lx R43 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[44]) >> 32;
|
|
||||||
al = (regs->regs[44]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[45]) >> 32;
|
|
||||||
bl = (regs->regs[45]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[46]) >> 32;
|
|
||||||
cl = (regs->regs[46]) & 0xffffffff;
|
|
||||||
printk("R44 : %08Lx%08Lx R45 : %08Lx%08Lx R46 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[47]) >> 32;
|
|
||||||
al = (regs->regs[47]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[48]) >> 32;
|
|
||||||
bl = (regs->regs[48]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[49]) >> 32;
|
|
||||||
cl = (regs->regs[49]) & 0xffffffff;
|
|
||||||
printk("R47 : %08Lx%08Lx R48 : %08Lx%08Lx R49 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[50]) >> 32;
|
|
||||||
al = (regs->regs[50]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[51]) >> 32;
|
|
||||||
bl = (regs->regs[51]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[52]) >> 32;
|
|
||||||
cl = (regs->regs[52]) & 0xffffffff;
|
|
||||||
printk("R50 : %08Lx%08Lx R51 : %08Lx%08Lx R52 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[53]) >> 32;
|
|
||||||
al = (regs->regs[53]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[54]) >> 32;
|
|
||||||
bl = (regs->regs[54]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[55]) >> 32;
|
|
||||||
cl = (regs->regs[55]) & 0xffffffff;
|
|
||||||
printk("R53 : %08Lx%08Lx R54 : %08Lx%08Lx R55 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[56]) >> 32;
|
|
||||||
al = (regs->regs[56]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[57]) >> 32;
|
|
||||||
bl = (regs->regs[57]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[58]) >> 32;
|
|
||||||
cl = (regs->regs[58]) & 0xffffffff;
|
|
||||||
printk("R56 : %08Lx%08Lx R57 : %08Lx%08Lx R58 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[59]) >> 32;
|
|
||||||
al = (regs->regs[59]) & 0xffffffff;
|
|
||||||
bh = (regs->regs[60]) >> 32;
|
|
||||||
bl = (regs->regs[60]) & 0xffffffff;
|
|
||||||
ch = (regs->regs[61]) >> 32;
|
|
||||||
cl = (regs->regs[61]) & 0xffffffff;
|
|
||||||
printk("R59 : %08Lx%08Lx R60 : %08Lx%08Lx R61 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->regs[62]) >> 32;
|
|
||||||
al = (regs->regs[62]) & 0xffffffff;
|
|
||||||
bh = (regs->tregs[0]) >> 32;
|
|
||||||
bl = (regs->tregs[0]) & 0xffffffff;
|
|
||||||
ch = (regs->tregs[1]) >> 32;
|
|
||||||
cl = (regs->tregs[1]) & 0xffffffff;
|
|
||||||
printk("R62 : %08Lx%08Lx T0 : %08Lx%08Lx T1 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->tregs[2]) >> 32;
|
|
||||||
al = (regs->tregs[2]) & 0xffffffff;
|
|
||||||
bh = (regs->tregs[3]) >> 32;
|
|
||||||
bl = (regs->tregs[3]) & 0xffffffff;
|
|
||||||
ch = (regs->tregs[4]) >> 32;
|
|
||||||
cl = (regs->tregs[4]) & 0xffffffff;
|
|
||||||
printk("T2 : %08Lx%08Lx T3 : %08Lx%08Lx T4 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
ah = (regs->tregs[5]) >> 32;
|
|
||||||
al = (regs->tregs[5]) & 0xffffffff;
|
|
||||||
bh = (regs->tregs[6]) >> 32;
|
|
||||||
bl = (regs->tregs[6]) & 0xffffffff;
|
|
||||||
ch = (regs->tregs[7]) >> 32;
|
|
||||||
cl = (regs->tregs[7]) & 0xffffffff;
|
|
||||||
printk("T5 : %08Lx%08Lx T6 : %08Lx%08Lx T7 : %08Lx%08Lx\n",
|
|
||||||
ah, al, bh, bl, ch, cl);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're in kernel mode, dump the stack too..
|
|
||||||
*/
|
|
||||||
if (!user_mode(regs)) {
|
|
||||||
void show_stack(struct task_struct *tsk, unsigned long *sp);
|
|
||||||
unsigned long sp = regs->regs[15] & 0xffffffff;
|
|
||||||
struct task_struct *tsk = get_current();
|
|
||||||
|
|
||||||
tsk->thread.kregs = regs;
|
|
||||||
|
|
||||||
show_stack(tsk, (unsigned long *)sp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free current thread data structures etc..
|
|
||||||
*/
|
|
||||||
void exit_thread(struct task_struct *tsk)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* See arch/sparc/kernel/process.c for the precedent for doing
|
|
||||||
* this -- RPC.
|
|
||||||
*
|
|
||||||
* The SH-5 FPU save/restore approach relies on
|
|
||||||
* last_task_used_math pointing to a live task_struct. When
|
|
||||||
* another task tries to use the FPU for the 1st time, the FPUDIS
|
|
||||||
* trap handling (see arch/sh/kernel/cpu/sh5/fpu.c) will save the
|
|
||||||
* existing FPU state to the FP regs field within
|
|
||||||
* last_task_used_math before re-loading the new task's FPU state
|
|
||||||
* (or initialising it if the FPU has been used before). So if
|
|
||||||
* last_task_used_math is stale, and its page has already been
|
|
||||||
* re-allocated for another use, the consequences are rather
|
|
||||||
* grim. Unless we null it here, there is no other path through
|
|
||||||
* which it would get safely nulled.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
if (last_task_used_math == tsk)
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_thread(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Called by fs/exec.c (setup_new_exec) to remove traces of a
|
|
||||||
* previously running executable. */
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
if (last_task_used_math == current) {
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
}
|
|
||||||
/* Force FPU state to be reinitialised after exec */
|
|
||||||
clear_used_math();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* if we are a kernel thread, about to change to user thread,
|
|
||||||
* update kreg
|
|
||||||
*/
|
|
||||||
if(current->thread.kregs==&fake_swapper_regs) {
|
|
||||||
current->thread.kregs =
|
|
||||||
((struct pt_regs *)(THREAD_SIZE + (unsigned long) current) - 1);
|
|
||||||
current->thread.uregs = current->thread.kregs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void release_thread(struct task_struct *dead_task)
|
|
||||||
{
|
|
||||||
/* do nothing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in the fpu structure for a core dump.. */
|
|
||||||
int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
int fpvalid;
|
|
||||||
struct task_struct *tsk = current;
|
|
||||||
|
|
||||||
fpvalid = !!tsk_used_math(tsk);
|
|
||||||
if (fpvalid) {
|
|
||||||
if (current == last_task_used_math) {
|
|
||||||
enable_fpu();
|
|
||||||
save_fpu(tsk);
|
|
||||||
disable_fpu();
|
|
||||||
last_task_used_math = 0;
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(fpu, &tsk->thread.xstate->hardfpu, sizeof(*fpu));
|
|
||||||
}
|
|
||||||
|
|
||||||
return fpvalid;
|
|
||||||
#else
|
|
||||||
return 0; /* Task didn't use the fpu at all. */
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dump_fpu);
|
|
||||||
|
|
||||||
asmlinkage void ret_from_fork(void);
|
|
||||||
asmlinkage void ret_from_kernel_thread(void);
|
|
||||||
|
|
||||||
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|
||||||
unsigned long arg, struct task_struct *p)
|
|
||||||
{
|
|
||||||
struct pt_regs *childregs;
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
/* can't happen for a kernel thread */
|
|
||||||
if (last_task_used_math == current) {
|
|
||||||
enable_fpu();
|
|
||||||
save_fpu(current);
|
|
||||||
disable_fpu();
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
current_pt_regs()->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Copy from sh version */
|
|
||||||
childregs = (struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1;
|
|
||||||
p->thread.sp = (unsigned long) childregs;
|
|
||||||
|
|
||||||
if (unlikely(p->flags & PF_KTHREAD)) {
|
|
||||||
memset(childregs, 0, sizeof(struct pt_regs));
|
|
||||||
childregs->regs[2] = (unsigned long)arg;
|
|
||||||
childregs->regs[3] = (unsigned long)usp;
|
|
||||||
childregs->sr = (1 << 30); /* not user_mode */
|
|
||||||
childregs->sr |= SR_FD; /* Invalidate FPU flag */
|
|
||||||
p->thread.pc = (unsigned long) ret_from_kernel_thread;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*childregs = *current_pt_regs();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sign extend the edited stack.
|
|
||||||
* Note that thread.pc and thread.pc will stay
|
|
||||||
* 32-bit wide and context switch must take care
|
|
||||||
* of NEFF sign extension.
|
|
||||||
*/
|
|
||||||
if (usp)
|
|
||||||
childregs->regs[15] = neff_sign_extend(usp);
|
|
||||||
p->thread.uregs = childregs;
|
|
||||||
|
|
||||||
childregs->regs[9] = 0; /* Set return value for child */
|
|
||||||
childregs->sr |= SR_FD; /* Invalidate FPU flag */
|
|
||||||
|
|
||||||
p->thread.pc = (unsigned long) ret_from_fork;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_FRAME_POINTER
|
|
||||||
static int in_sh64_switch_to(unsigned long pc)
|
|
||||||
{
|
|
||||||
extern char __sh64_switch_to_end;
|
|
||||||
/* For a sleeping task, the PC is somewhere in the middle of the function,
|
|
||||||
so we don't have to worry about masking the LSB off */
|
|
||||||
return (pc >= (unsigned long) sh64_switch_to) &&
|
|
||||||
(pc < (unsigned long) &__sh64_switch_to_end);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned long get_wchan(struct task_struct *p)
|
|
||||||
{
|
|
||||||
unsigned long pc;
|
|
||||||
|
|
||||||
if (!p || p == current || p->state == TASK_RUNNING)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The same comment as on the Alpha applies here, too ...
|
|
||||||
*/
|
|
||||||
pc = thread_saved_pc(p);
|
|
||||||
|
|
||||||
#ifdef CONFIG_FRAME_POINTER
|
|
||||||
if (in_sh64_switch_to(pc)) {
|
|
||||||
unsigned long schedule_fp;
|
|
||||||
unsigned long sh64_switch_to_fp;
|
|
||||||
unsigned long schedule_caller_pc;
|
|
||||||
|
|
||||||
sh64_switch_to_fp = (long) p->thread.sp;
|
|
||||||
/* r14 is saved at offset 4 in the sh64_switch_to frame */
|
|
||||||
schedule_fp = *(unsigned long *) (long)(sh64_switch_to_fp + 4);
|
|
||||||
|
|
||||||
/* and the caller of 'schedule' is (currently!) saved at offset 24
|
|
||||||
in the frame of schedule (from disasm) */
|
|
||||||
schedule_caller_pc = *(unsigned long *) (long)(schedule_fp + 24);
|
|
||||||
return schedule_caller_pc;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return pc;
|
|
||||||
}
|
|
|
@ -1,576 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/ptrace_64.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 - 2008 Paul Mundt
|
|
||||||
*
|
|
||||||
* Started from SH3/4 version:
|
|
||||||
* SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
|
|
||||||
*
|
|
||||||
* Original x86 implementation:
|
|
||||||
* By Ross Biro 1/23/92
|
|
||||||
* edited by Linus Torvalds
|
|
||||||
*/
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/rwsem.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/sched/task_stack.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/user.h>
|
|
||||||
#include <linux/signal.h>
|
|
||||||
#include <linux/syscalls.h>
|
|
||||||
#include <linux/audit.h>
|
|
||||||
#include <linux/seccomp.h>
|
|
||||||
#include <linux/tracehook.h>
|
|
||||||
#include <linux/elf.h>
|
|
||||||
#include <linux/regset.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/mmu_context.h>
|
|
||||||
#include <asm/syscalls.h>
|
|
||||||
#include <asm/fpu.h>
|
|
||||||
#include <asm/traps.h>
|
|
||||||
|
|
||||||
#define CREATE_TRACE_POINTS
|
|
||||||
#include <trace/events/syscalls.h>
|
|
||||||
|
|
||||||
/* This mask defines the bits of the SR which the user is not allowed to
|
|
||||||
change, which are everything except S, Q, M, PR, SZ, FR. */
|
|
||||||
#define SR_MASK (0xffff8cfd)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* does not yet catch signals sent when the child dies.
|
|
||||||
* in exit.c or in signal.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This routine will get a word from the user area in the process kernel stack.
|
|
||||||
*/
|
|
||||||
static inline int get_stack_long(struct task_struct *task, int offset)
|
|
||||||
{
|
|
||||||
unsigned char *stack;
|
|
||||||
|
|
||||||
stack = (unsigned char *)(task->thread.uregs);
|
|
||||||
stack += offset;
|
|
||||||
return (*((int *)stack));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
get_fpu_long(struct task_struct *task, unsigned long addr)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
struct pt_regs *regs;
|
|
||||||
regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
|
|
||||||
|
|
||||||
if (!tsk_used_math(task)) {
|
|
||||||
if (addr == offsetof(struct user_fpu_struct, fpscr)) {
|
|
||||||
tmp = FPSCR_INIT;
|
|
||||||
} else {
|
|
||||||
tmp = 0xffffffffUL; /* matches initial value in fpu.c */
|
|
||||||
}
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_task_used_math == task) {
|
|
||||||
enable_fpu();
|
|
||||||
save_fpu(task);
|
|
||||||
disable_fpu();
|
|
||||||
last_task_used_math = 0;
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = ((long *)task->thread.xstate)[addr / sizeof(unsigned long)];
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This routine will put a word into the user area in the process kernel stack.
|
|
||||||
*/
|
|
||||||
static inline int put_stack_long(struct task_struct *task, int offset,
|
|
||||||
unsigned long data)
|
|
||||||
{
|
|
||||||
unsigned char *stack;
|
|
||||||
|
|
||||||
stack = (unsigned char *)(task->thread.uregs);
|
|
||||||
stack += offset;
|
|
||||||
*(unsigned long *) stack = data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
|
|
||||||
{
|
|
||||||
struct pt_regs *regs;
|
|
||||||
|
|
||||||
regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1;
|
|
||||||
|
|
||||||
if (!tsk_used_math(task)) {
|
|
||||||
init_fpu(task);
|
|
||||||
} else if (last_task_used_math == task) {
|
|
||||||
enable_fpu();
|
|
||||||
save_fpu(task);
|
|
||||||
disable_fpu();
|
|
||||||
last_task_used_math = 0;
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
((long *)task->thread.xstate)[addr / sizeof(unsigned long)] = data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_enable_single_step(struct task_struct *child)
|
|
||||||
{
|
|
||||||
struct pt_regs *regs = child->thread.uregs;
|
|
||||||
|
|
||||||
regs->sr |= SR_SSTEP; /* auto-resetting upon exception */
|
|
||||||
|
|
||||||
set_tsk_thread_flag(child, TIF_SINGLESTEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_disable_single_step(struct task_struct *child)
|
|
||||||
{
|
|
||||||
struct pt_regs *regs = child->thread.uregs;
|
|
||||||
|
|
||||||
regs->sr &= ~SR_SSTEP;
|
|
||||||
|
|
||||||
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int genregs_get(struct task_struct *target,
|
|
||||||
const struct user_regset *regset,
|
|
||||||
unsigned int pos, unsigned int count,
|
|
||||||
void *kbuf, void __user *ubuf)
|
|
||||||
{
|
|
||||||
const struct pt_regs *regs = task_pt_regs(target);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* PC, SR, SYSCALL */
|
|
||||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
|
||||||
®s->pc,
|
|
||||||
0, 3 * sizeof(unsigned long long));
|
|
||||||
|
|
||||||
/* R1 -> R63 */
|
|
||||||
if (!ret)
|
|
||||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
|
||||||
regs->regs,
|
|
||||||
offsetof(struct pt_regs, regs[0]),
|
|
||||||
63 * sizeof(unsigned long long));
|
|
||||||
/* TR0 -> TR7 */
|
|
||||||
if (!ret)
|
|
||||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
|
||||||
regs->tregs,
|
|
||||||
offsetof(struct pt_regs, tregs[0]),
|
|
||||||
8 * sizeof(unsigned long long));
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
|
|
||||||
sizeof(struct pt_regs), -1);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int genregs_set(struct task_struct *target,
|
|
||||||
const struct user_regset *regset,
|
|
||||||
unsigned int pos, unsigned int count,
|
|
||||||
const void *kbuf, const void __user *ubuf)
|
|
||||||
{
|
|
||||||
struct pt_regs *regs = task_pt_regs(target);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* PC, SR, SYSCALL */
|
|
||||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
|
||||||
®s->pc,
|
|
||||||
0, 3 * sizeof(unsigned long long));
|
|
||||||
|
|
||||||
/* R1 -> R63 */
|
|
||||||
if (!ret && count > 0)
|
|
||||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
|
||||||
regs->regs,
|
|
||||||
offsetof(struct pt_regs, regs[0]),
|
|
||||||
63 * sizeof(unsigned long long));
|
|
||||||
|
|
||||||
/* TR0 -> TR7 */
|
|
||||||
if (!ret && count > 0)
|
|
||||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
|
||||||
regs->tregs,
|
|
||||||
offsetof(struct pt_regs, tregs[0]),
|
|
||||||
8 * sizeof(unsigned long long));
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
|
|
||||||
sizeof(struct pt_regs), -1);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
int fpregs_get(struct task_struct *target,
|
|
||||||
const struct user_regset *regset,
|
|
||||||
unsigned int pos, unsigned int count,
|
|
||||||
void *kbuf, void __user *ubuf)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = init_fpu(target);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
|
||||||
&target->thread.xstate->hardfpu, 0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fpregs_set(struct task_struct *target,
|
|
||||||
const struct user_regset *regset,
|
|
||||||
unsigned int pos, unsigned int count,
|
|
||||||
const void *kbuf, const void __user *ubuf)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = init_fpu(target);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
set_stopped_child_used_math(target);
|
|
||||||
|
|
||||||
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
|
||||||
&target->thread.xstate->hardfpu, 0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fpregs_active(struct task_struct *target,
|
|
||||||
const struct user_regset *regset)
|
|
||||||
{
|
|
||||||
return tsk_used_math(target) ? regset->n : 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const struct pt_regs_offset regoffset_table[] = {
|
|
||||||
REG_OFFSET_NAME(pc),
|
|
||||||
REG_OFFSET_NAME(sr),
|
|
||||||
REG_OFFSET_NAME(syscall_nr),
|
|
||||||
REGS_OFFSET_NAME(0),
|
|
||||||
REGS_OFFSET_NAME(1),
|
|
||||||
REGS_OFFSET_NAME(2),
|
|
||||||
REGS_OFFSET_NAME(3),
|
|
||||||
REGS_OFFSET_NAME(4),
|
|
||||||
REGS_OFFSET_NAME(5),
|
|
||||||
REGS_OFFSET_NAME(6),
|
|
||||||
REGS_OFFSET_NAME(7),
|
|
||||||
REGS_OFFSET_NAME(8),
|
|
||||||
REGS_OFFSET_NAME(9),
|
|
||||||
REGS_OFFSET_NAME(10),
|
|
||||||
REGS_OFFSET_NAME(11),
|
|
||||||
REGS_OFFSET_NAME(12),
|
|
||||||
REGS_OFFSET_NAME(13),
|
|
||||||
REGS_OFFSET_NAME(14),
|
|
||||||
REGS_OFFSET_NAME(15),
|
|
||||||
REGS_OFFSET_NAME(16),
|
|
||||||
REGS_OFFSET_NAME(17),
|
|
||||||
REGS_OFFSET_NAME(18),
|
|
||||||
REGS_OFFSET_NAME(19),
|
|
||||||
REGS_OFFSET_NAME(20),
|
|
||||||
REGS_OFFSET_NAME(21),
|
|
||||||
REGS_OFFSET_NAME(22),
|
|
||||||
REGS_OFFSET_NAME(23),
|
|
||||||
REGS_OFFSET_NAME(24),
|
|
||||||
REGS_OFFSET_NAME(25),
|
|
||||||
REGS_OFFSET_NAME(26),
|
|
||||||
REGS_OFFSET_NAME(27),
|
|
||||||
REGS_OFFSET_NAME(28),
|
|
||||||
REGS_OFFSET_NAME(29),
|
|
||||||
REGS_OFFSET_NAME(30),
|
|
||||||
REGS_OFFSET_NAME(31),
|
|
||||||
REGS_OFFSET_NAME(32),
|
|
||||||
REGS_OFFSET_NAME(33),
|
|
||||||
REGS_OFFSET_NAME(34),
|
|
||||||
REGS_OFFSET_NAME(35),
|
|
||||||
REGS_OFFSET_NAME(36),
|
|
||||||
REGS_OFFSET_NAME(37),
|
|
||||||
REGS_OFFSET_NAME(38),
|
|
||||||
REGS_OFFSET_NAME(39),
|
|
||||||
REGS_OFFSET_NAME(40),
|
|
||||||
REGS_OFFSET_NAME(41),
|
|
||||||
REGS_OFFSET_NAME(42),
|
|
||||||
REGS_OFFSET_NAME(43),
|
|
||||||
REGS_OFFSET_NAME(44),
|
|
||||||
REGS_OFFSET_NAME(45),
|
|
||||||
REGS_OFFSET_NAME(46),
|
|
||||||
REGS_OFFSET_NAME(47),
|
|
||||||
REGS_OFFSET_NAME(48),
|
|
||||||
REGS_OFFSET_NAME(49),
|
|
||||||
REGS_OFFSET_NAME(50),
|
|
||||||
REGS_OFFSET_NAME(51),
|
|
||||||
REGS_OFFSET_NAME(52),
|
|
||||||
REGS_OFFSET_NAME(53),
|
|
||||||
REGS_OFFSET_NAME(54),
|
|
||||||
REGS_OFFSET_NAME(55),
|
|
||||||
REGS_OFFSET_NAME(56),
|
|
||||||
REGS_OFFSET_NAME(57),
|
|
||||||
REGS_OFFSET_NAME(58),
|
|
||||||
REGS_OFFSET_NAME(59),
|
|
||||||
REGS_OFFSET_NAME(60),
|
|
||||||
REGS_OFFSET_NAME(61),
|
|
||||||
REGS_OFFSET_NAME(62),
|
|
||||||
REGS_OFFSET_NAME(63),
|
|
||||||
TREGS_OFFSET_NAME(0),
|
|
||||||
TREGS_OFFSET_NAME(1),
|
|
||||||
TREGS_OFFSET_NAME(2),
|
|
||||||
TREGS_OFFSET_NAME(3),
|
|
||||||
TREGS_OFFSET_NAME(4),
|
|
||||||
TREGS_OFFSET_NAME(5),
|
|
||||||
TREGS_OFFSET_NAME(6),
|
|
||||||
TREGS_OFFSET_NAME(7),
|
|
||||||
REG_OFFSET_END,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are our native regset flavours.
|
|
||||||
*/
|
|
||||||
enum sh_regset {
|
|
||||||
REGSET_GENERAL,
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
REGSET_FPU,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct user_regset sh_regsets[] = {
|
|
||||||
/*
|
|
||||||
* Format is:
|
|
||||||
* PC, SR, SYSCALL,
|
|
||||||
* R1 --> R63,
|
|
||||||
* TR0 --> TR7,
|
|
||||||
*/
|
|
||||||
[REGSET_GENERAL] = {
|
|
||||||
.core_note_type = NT_PRSTATUS,
|
|
||||||
.n = ELF_NGREG,
|
|
||||||
.size = sizeof(long long),
|
|
||||||
.align = sizeof(long long),
|
|
||||||
.get = genregs_get,
|
|
||||||
.set = genregs_set,
|
|
||||||
},
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
[REGSET_FPU] = {
|
|
||||||
.core_note_type = NT_PRFPREG,
|
|
||||||
.n = sizeof(struct user_fpu_struct) /
|
|
||||||
sizeof(long long),
|
|
||||||
.size = sizeof(long long),
|
|
||||||
.align = sizeof(long long),
|
|
||||||
.get = fpregs_get,
|
|
||||||
.set = fpregs_set,
|
|
||||||
.active = fpregs_active,
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct user_regset_view user_sh64_native_view = {
|
|
||||||
.name = "sh64",
|
|
||||||
.e_machine = EM_SH,
|
|
||||||
.regsets = sh_regsets,
|
|
||||||
.n = ARRAY_SIZE(sh_regsets),
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
|
|
||||||
{
|
|
||||||
return &user_sh64_native_view;
|
|
||||||
}
|
|
||||||
|
|
||||||
long arch_ptrace(struct task_struct *child, long request,
|
|
||||||
unsigned long addr, unsigned long data)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
unsigned long __user *datap = (unsigned long __user *) data;
|
|
||||||
|
|
||||||
switch (request) {
|
|
||||||
/* read the word at location addr in the USER area. */
|
|
||||||
case PTRACE_PEEKUSR: {
|
|
||||||
unsigned long tmp;
|
|
||||||
|
|
||||||
ret = -EIO;
|
|
||||||
if ((addr & 3) || addr < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (addr < sizeof(struct pt_regs))
|
|
||||||
tmp = get_stack_long(child, addr);
|
|
||||||
else if ((addr >= offsetof(struct user, fpu)) &&
|
|
||||||
(addr < offsetof(struct user, u_fpvalid))) {
|
|
||||||
unsigned long index;
|
|
||||||
ret = init_fpu(child);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
index = addr - offsetof(struct user, fpu);
|
|
||||||
tmp = get_fpu_long(child, index);
|
|
||||||
} else if (addr == offsetof(struct user, u_fpvalid)) {
|
|
||||||
tmp = !!tsk_used_math(child);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = put_user(tmp, datap);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PTRACE_POKEUSR:
|
|
||||||
/* write the word at location addr in the USER area. We must
|
|
||||||
disallow any changes to certain SR bits or u_fpvalid, since
|
|
||||||
this could crash the kernel or result in a security
|
|
||||||
loophole. */
|
|
||||||
ret = -EIO;
|
|
||||||
if ((addr & 3) || addr < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (addr < sizeof(struct pt_regs)) {
|
|
||||||
/* Ignore change of top 32 bits of SR */
|
|
||||||
if (addr == offsetof (struct pt_regs, sr)+4)
|
|
||||||
{
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* If lower 32 bits of SR, ignore non-user bits */
|
|
||||||
if (addr == offsetof (struct pt_regs, sr))
|
|
||||||
{
|
|
||||||
long cursr = get_stack_long(child, addr);
|
|
||||||
data &= ~(SR_MASK);
|
|
||||||
data |= (cursr & SR_MASK);
|
|
||||||
}
|
|
||||||
ret = put_stack_long(child, addr, data);
|
|
||||||
}
|
|
||||||
else if ((addr >= offsetof(struct user, fpu)) &&
|
|
||||||
(addr < offsetof(struct user, u_fpvalid))) {
|
|
||||||
unsigned long index;
|
|
||||||
ret = init_fpu(child);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
index = addr - offsetof(struct user, fpu);
|
|
||||||
ret = put_fpu_long(child, index, data);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_GETREGS:
|
|
||||||
return copy_regset_to_user(child, &user_sh64_native_view,
|
|
||||||
REGSET_GENERAL,
|
|
||||||
0, sizeof(struct pt_regs),
|
|
||||||
datap);
|
|
||||||
case PTRACE_SETREGS:
|
|
||||||
return copy_regset_from_user(child, &user_sh64_native_view,
|
|
||||||
REGSET_GENERAL,
|
|
||||||
0, sizeof(struct pt_regs),
|
|
||||||
datap);
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
case PTRACE_GETFPREGS:
|
|
||||||
return copy_regset_to_user(child, &user_sh64_native_view,
|
|
||||||
REGSET_FPU,
|
|
||||||
0, sizeof(struct user_fpu_struct),
|
|
||||||
datap);
|
|
||||||
case PTRACE_SETFPREGS:
|
|
||||||
return copy_regset_from_user(child, &user_sh64_native_view,
|
|
||||||
REGSET_FPU,
|
|
||||||
0, sizeof(struct user_fpu_struct),
|
|
||||||
datap);
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
ret = ptrace_request(child, request, addr, data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int sh64_ptrace(long request, long pid,
|
|
||||||
unsigned long addr, unsigned long data)
|
|
||||||
{
|
|
||||||
#define WPC_DBRMODE 0x0d104008
|
|
||||||
static unsigned long first_call;
|
|
||||||
|
|
||||||
if (!test_and_set_bit(0, &first_call)) {
|
|
||||||
/* Set WPC.DBRMODE to 0. This makes all debug events get
|
|
||||||
* delivered through RESVEC, i.e. into the handlers in entry.S.
|
|
||||||
* (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
|
|
||||||
* would normally be left set to 1, which makes debug events get
|
|
||||||
* delivered through DBRVEC, i.e. into the remote gdb's
|
|
||||||
* handlers. This prevents ptrace getting them, and confuses
|
|
||||||
* the remote gdb.) */
|
|
||||||
printk("DBRMODE set to 0 to permit native debugging\n");
|
|
||||||
poke_real_address_q(WPC_DBRMODE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sys_ptrace(request, pid, addr, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
long long ret = 0;
|
|
||||||
|
|
||||||
secure_computing_strict(regs->regs[9]);
|
|
||||||
|
|
||||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
|
||||||
tracehook_report_syscall_entry(regs))
|
|
||||||
/*
|
|
||||||
* Tracing decided this syscall should not happen.
|
|
||||||
* We'll return a bogus call number to get an ENOSYS
|
|
||||||
* error, but leave the original number in regs->regs[0].
|
|
||||||
*/
|
|
||||||
ret = -1LL;
|
|
||||||
|
|
||||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
|
||||||
trace_sys_enter(regs, regs->regs[9]);
|
|
||||||
|
|
||||||
audit_syscall_entry(regs->regs[1], regs->regs[2], regs->regs[3],
|
|
||||||
regs->regs[4], regs->regs[5]);
|
|
||||||
|
|
||||||
return ret ?: regs->regs[9];
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
int step;
|
|
||||||
|
|
||||||
audit_syscall_exit(regs);
|
|
||||||
|
|
||||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
|
||||||
trace_sys_exit(regs, regs->regs[9]);
|
|
||||||
|
|
||||||
step = test_thread_flag(TIF_SINGLESTEP);
|
|
||||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
|
||||||
tracehook_report_syscall_exit(regs, step);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called with interrupts disabled */
|
|
||||||
asmlinkage void do_single_step(unsigned long long vec, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
/* This is called after a single step exception (DEBUGSS).
|
|
||||||
There is no need to change the PC, as it is a post-execution
|
|
||||||
exception, as entry.S does not do anything to the PC for DEBUGSS.
|
|
||||||
We need to clear the Single Step setting in SR to avoid
|
|
||||||
continually stepping. */
|
|
||||||
local_irq_enable();
|
|
||||||
regs->sr &= ~SR_SSTEP;
|
|
||||||
force_sig(SIGTRAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called with interrupts disabled */
|
|
||||||
BUILD_TRAP_HANDLER(breakpoint)
|
|
||||||
{
|
|
||||||
TRAP_HANDLER_DECL;
|
|
||||||
|
|
||||||
/* We need to forward step the PC, to counteract the backstep done
|
|
||||||
in signal.c. */
|
|
||||||
local_irq_enable();
|
|
||||||
force_sig(SIGTRAP);
|
|
||||||
regs->pc += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by kernel/ptrace.c when detaching..
|
|
||||||
*
|
|
||||||
* Make sure single step bits etc are not set.
|
|
||||||
*/
|
|
||||||
void ptrace_disable(struct task_struct *child)
|
|
||||||
{
|
|
||||||
user_disable_single_step(child);
|
|
||||||
}
|
|
|
@ -4,9 +4,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
#include <asm/watchdog.h>
|
#include <asm/watchdog.h>
|
||||||
#endif
|
|
||||||
#include <asm/addrspace.h>
|
#include <asm/addrspace.h>
|
||||||
#include <asm/reboot.h>
|
#include <asm/reboot.h>
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
|
@ -15,13 +13,11 @@
|
||||||
void (*pm_power_off)(void);
|
void (*pm_power_off)(void);
|
||||||
EXPORT_SYMBOL(pm_power_off);
|
EXPORT_SYMBOL(pm_power_off);
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
static void watchdog_trigger_immediate(void)
|
static void watchdog_trigger_immediate(void)
|
||||||
{
|
{
|
||||||
sh_wdt_write_cnt(0xFF);
|
sh_wdt_write_cnt(0xFF);
|
||||||
sh_wdt_write_csr(0xC2);
|
sh_wdt_write_csr(0xC2);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void native_machine_restart(char * __unused)
|
static void native_machine_restart(char * __unused)
|
||||||
{
|
{
|
||||||
|
@ -33,10 +29,8 @@ static void native_machine_restart(char * __unused)
|
||||||
/* Address error with SR.BL=1 first. */
|
/* Address error with SR.BL=1 first. */
|
||||||
trigger_address_error();
|
trigger_address_error();
|
||||||
|
|
||||||
#ifdef CONFIG_SUPERH32
|
|
||||||
/* If that fails or is unsupported, go for the watchdog next. */
|
/* If that fails or is unsupported, go for the watchdog next. */
|
||||||
watchdog_trigger_immediate();
|
watchdog_trigger_immediate();
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give up and sleep.
|
* Give up and sleep.
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/sh_ksyms_64.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
*/
|
|
||||||
#include <linux/rwsem.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/user.h>
|
|
||||||
#include <linux/elfcore.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/in6.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/screen_info.h>
|
|
||||||
#include <asm/cacheflush.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <asm/checksum.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <asm/delay.h>
|
|
||||||
#include <asm/irq.h>
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(__put_user_asm_b);
|
|
||||||
EXPORT_SYMBOL(__put_user_asm_w);
|
|
||||||
EXPORT_SYMBOL(__put_user_asm_l);
|
|
||||||
EXPORT_SYMBOL(__put_user_asm_q);
|
|
||||||
EXPORT_SYMBOL(__get_user_asm_b);
|
|
||||||
EXPORT_SYMBOL(__get_user_asm_w);
|
|
||||||
EXPORT_SYMBOL(__get_user_asm_l);
|
|
||||||
EXPORT_SYMBOL(__get_user_asm_q);
|
|
||||||
EXPORT_SYMBOL(__clear_user);
|
|
||||||
EXPORT_SYMBOL(copy_page);
|
|
||||||
EXPORT_SYMBOL(__copy_user);
|
|
||||||
EXPORT_SYMBOL(empty_zero_page);
|
|
||||||
EXPORT_SYMBOL(memcpy);
|
|
||||||
EXPORT_SYMBOL(memset);
|
|
||||||
EXPORT_SYMBOL(__udelay);
|
|
||||||
EXPORT_SYMBOL(__ndelay);
|
|
||||||
EXPORT_SYMBOL(__const_udelay);
|
|
||||||
EXPORT_SYMBOL(strlen);
|
|
||||||
EXPORT_SYMBOL(strcpy);
|
|
||||||
|
|
||||||
/* Ugh. These come in from libgcc.a at link time. */
|
|
||||||
#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
|
|
||||||
|
|
||||||
DECLARE_EXPORT(__sdivsi3);
|
|
||||||
DECLARE_EXPORT(__sdivsi3_1);
|
|
||||||
DECLARE_EXPORT(__sdivsi3_2);
|
|
||||||
DECLARE_EXPORT(__udivsi3);
|
|
||||||
DECLARE_EXPORT(__div_table);
|
|
|
@ -1,567 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/signal_64.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003 - 2008 Paul Mundt
|
|
||||||
* Copyright (C) 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#include <linux/rwsem.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/signal.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/wait.h>
|
|
||||||
#include <linux/personality.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/unistd.h>
|
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/tracehook.h>
|
|
||||||
#include <asm/ucontext.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/cacheflush.h>
|
|
||||||
#include <asm/fpu.h>
|
|
||||||
|
|
||||||
#define REG_RET 9
|
|
||||||
#define REG_ARG1 2
|
|
||||||
#define REG_ARG2 3
|
|
||||||
#define REG_ARG3 4
|
|
||||||
#define REG_SP 15
|
|
||||||
#define REG_PR 18
|
|
||||||
#define REF_REG_RET regs->regs[REG_RET]
|
|
||||||
#define REF_REG_SP regs->regs[REG_SP]
|
|
||||||
#define DEREF_REG_PR regs->regs[REG_PR]
|
|
||||||
|
|
||||||
#define DEBUG_SIG 0
|
|
||||||
|
|
||||||
static void
|
|
||||||
handle_signal(struct ksignal *ksig, struct pt_regs *regs);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
|
|
||||||
{
|
|
||||||
/* If we're not from a syscall, bail out */
|
|
||||||
if (regs->syscall_nr < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* check for system call restart.. */
|
|
||||||
switch (regs->regs[REG_RET]) {
|
|
||||||
case -ERESTART_RESTARTBLOCK:
|
|
||||||
case -ERESTARTNOHAND:
|
|
||||||
no_system_call_restart:
|
|
||||||
regs->regs[REG_RET] = -EINTR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case -ERESTARTSYS:
|
|
||||||
if (!(sa->sa_flags & SA_RESTART))
|
|
||||||
goto no_system_call_restart;
|
|
||||||
/* fallthrough */
|
|
||||||
case -ERESTARTNOINTR:
|
|
||||||
/* Decode syscall # */
|
|
||||||
regs->regs[REG_RET] = regs->syscall_nr;
|
|
||||||
regs->pc -= 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that 'init' is a special process: it doesn't get signals it doesn't
|
|
||||||
* want to handle. Thus you cannot kill init even with a SIGKILL even by
|
|
||||||
* mistake.
|
|
||||||
*
|
|
||||||
* Note that we go through the signals twice: once to check the signals that
|
|
||||||
* the kernel can handle, and then we build all the user-level signal handling
|
|
||||||
* stack-frames in one go after that.
|
|
||||||
*/
|
|
||||||
static void do_signal(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
struct ksignal ksig;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We want the common case to go fast, which
|
|
||||||
* is why we may in certain cases get here from
|
|
||||||
* kernel mode. Just return without doing anything
|
|
||||||
* if so.
|
|
||||||
*/
|
|
||||||
if (!user_mode(regs))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (get_signal(&ksig)) {
|
|
||||||
handle_syscall_restart(regs, &ksig.ka.sa);
|
|
||||||
|
|
||||||
/* Whee! Actually deliver the signal. */
|
|
||||||
handle_signal(&ksig, regs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Did we come from a system call? */
|
|
||||||
if (regs->syscall_nr >= 0) {
|
|
||||||
/* Restart the system call - no handlers present */
|
|
||||||
switch (regs->regs[REG_RET]) {
|
|
||||||
case -ERESTARTNOHAND:
|
|
||||||
case -ERESTARTSYS:
|
|
||||||
case -ERESTARTNOINTR:
|
|
||||||
/* Decode Syscall # */
|
|
||||||
regs->regs[REG_RET] = regs->syscall_nr;
|
|
||||||
regs->pc -= 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case -ERESTART_RESTARTBLOCK:
|
|
||||||
regs->regs[REG_RET] = __NR_restart_syscall;
|
|
||||||
regs->pc -= 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No signal to deliver -- put the saved sigmask back */
|
|
||||||
restore_saved_sigmask();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do a signal return; undo the signal stack.
|
|
||||||
*/
|
|
||||||
struct sigframe {
|
|
||||||
struct sigcontext sc;
|
|
||||||
unsigned long extramask[_NSIG_WORDS-1];
|
|
||||||
long long retcode[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rt_sigframe {
|
|
||||||
struct siginfo __user *pinfo;
|
|
||||||
void *puc;
|
|
||||||
struct siginfo info;
|
|
||||||
struct ucontext uc;
|
|
||||||
long long retcode[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_SH_FPU
|
|
||||||
static inline int
|
|
||||||
restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
int fpvalid;
|
|
||||||
|
|
||||||
err |= __get_user (fpvalid, &sc->sc_fpvalid);
|
|
||||||
conditional_used_math(fpvalid);
|
|
||||||
if (! fpvalid)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (current == last_task_used_math) {
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
err |= __copy_from_user(¤t->thread.xstate->hardfpu, &sc->sc_fpregs[0],
|
|
||||||
(sizeof(long long) * 32) + (sizeof(int) * 1));
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
int fpvalid;
|
|
||||||
|
|
||||||
fpvalid = !!used_math();
|
|
||||||
err |= __put_user(fpvalid, &sc->sc_fpvalid);
|
|
||||||
if (! fpvalid)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (current == last_task_used_math) {
|
|
||||||
enable_fpu();
|
|
||||||
save_fpu(current);
|
|
||||||
disable_fpu();
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
err |= __copy_to_user(&sc->sc_fpregs[0], ¤t->thread.xstate->hardfpu,
|
|
||||||
(sizeof(long long) * 32) + (sizeof(int) * 1));
|
|
||||||
clear_used_math();
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline int
|
|
||||||
restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static inline int
|
|
||||||
setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, long long *r2_p)
|
|
||||||
{
|
|
||||||
unsigned int err = 0;
|
|
||||||
unsigned long long current_sr, new_sr;
|
|
||||||
#define SR_MASK 0xffff8cfd
|
|
||||||
|
|
||||||
#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
|
|
||||||
|
|
||||||
COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]);
|
|
||||||
COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]);
|
|
||||||
COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]);
|
|
||||||
COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
|
|
||||||
COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
|
|
||||||
COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
|
|
||||||
COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
|
|
||||||
COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
|
|
||||||
COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
|
|
||||||
COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
|
|
||||||
COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
|
|
||||||
COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
|
|
||||||
COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
|
|
||||||
COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
|
|
||||||
COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
|
|
||||||
COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
|
|
||||||
COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
|
|
||||||
COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
|
|
||||||
|
|
||||||
/* Prevent the signal handler manipulating SR in a way that can
|
|
||||||
crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be
|
|
||||||
modified */
|
|
||||||
current_sr = regs->sr;
|
|
||||||
err |= __get_user(new_sr, &sc->sc_sr);
|
|
||||||
regs->sr &= SR_MASK;
|
|
||||||
regs->sr |= (new_sr & ~SR_MASK);
|
|
||||||
|
|
||||||
COPY(pc);
|
|
||||||
|
|
||||||
#undef COPY
|
|
||||||
|
|
||||||
/* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr
|
|
||||||
* has been restored above.) */
|
|
||||||
err |= restore_sigcontext_fpu(regs, sc);
|
|
||||||
|
|
||||||
regs->syscall_nr = -1; /* disable syscall checks */
|
|
||||||
err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
|
|
||||||
unsigned long r4, unsigned long r5,
|
|
||||||
unsigned long r6, unsigned long r7,
|
|
||||||
struct pt_regs * regs)
|
|
||||||
{
|
|
||||||
struct sigframe __user *frame = (struct sigframe __user *) (long) REF_REG_SP;
|
|
||||||
sigset_t set;
|
|
||||||
long long ret;
|
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
|
||||||
current->restart_block.fn = do_no_restart_syscall;
|
|
||||||
|
|
||||||
if (!access_ok(frame, sizeof(*frame)))
|
|
||||||
goto badframe;
|
|
||||||
|
|
||||||
if (__get_user(set.sig[0], &frame->sc.oldmask)
|
|
||||||
|| (_NSIG_WORDS > 1
|
|
||||||
&& __copy_from_user(&set.sig[1], &frame->extramask,
|
|
||||||
sizeof(frame->extramask))))
|
|
||||||
goto badframe;
|
|
||||||
|
|
||||||
set_current_blocked(&set);
|
|
||||||
|
|
||||||
if (restore_sigcontext(regs, &frame->sc, &ret))
|
|
||||||
goto badframe;
|
|
||||||
regs->pc -= 4;
|
|
||||||
|
|
||||||
return (int) ret;
|
|
||||||
|
|
||||||
badframe:
|
|
||||||
force_sig(SIGSEGV);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
|
|
||||||
unsigned long r4, unsigned long r5,
|
|
||||||
unsigned long r6, unsigned long r7,
|
|
||||||
struct pt_regs * regs)
|
|
||||||
{
|
|
||||||
struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
|
|
||||||
sigset_t set;
|
|
||||||
long long ret;
|
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
|
||||||
current->restart_block.fn = do_no_restart_syscall;
|
|
||||||
|
|
||||||
if (!access_ok(frame, sizeof(*frame)))
|
|
||||||
goto badframe;
|
|
||||||
|
|
||||||
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
|
|
||||||
goto badframe;
|
|
||||||
|
|
||||||
set_current_blocked(&set);
|
|
||||||
|
|
||||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
|
|
||||||
goto badframe;
|
|
||||||
regs->pc -= 4;
|
|
||||||
|
|
||||||
if (restore_altstack(&frame->uc.uc_stack))
|
|
||||||
goto badframe;
|
|
||||||
|
|
||||||
return (int) ret;
|
|
||||||
|
|
||||||
badframe:
|
|
||||||
force_sig(SIGSEGV);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up a signal frame.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
|
|
||||||
unsigned long mask)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
/* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */
|
|
||||||
err |= setup_sigcontext_fpu(regs, sc);
|
|
||||||
|
|
||||||
#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
|
|
||||||
|
|
||||||
COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]);
|
|
||||||
COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]);
|
|
||||||
COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]);
|
|
||||||
COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
|
|
||||||
COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
|
|
||||||
COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
|
|
||||||
COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
|
|
||||||
COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
|
|
||||||
COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
|
|
||||||
COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
|
|
||||||
COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
|
|
||||||
COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
|
|
||||||
COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
|
|
||||||
COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
|
|
||||||
COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
|
|
||||||
COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
|
|
||||||
COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
|
|
||||||
COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
|
|
||||||
COPY(sr); COPY(pc);
|
|
||||||
|
|
||||||
#undef COPY
|
|
||||||
|
|
||||||
err |= __put_user(mask, &sc->oldmask);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine which stack to use..
|
|
||||||
*/
|
|
||||||
static inline void __user *
|
|
||||||
get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
|
|
||||||
{
|
|
||||||
if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
|
|
||||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
|
||||||
|
|
||||||
return (void __user *)((sp - frame_size) & -8ul);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sa_default_restorer(void); /* See comments below */
|
|
||||||
void sa_default_rt_restorer(void); /* See comments below */
|
|
||||||
|
|
||||||
static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
struct sigframe __user *frame;
|
|
||||||
int err = 0, sig = ksig->sig;
|
|
||||||
int signal;
|
|
||||||
|
|
||||||
frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
|
|
||||||
|
|
||||||
if (!access_ok(frame, sizeof(*frame)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
|
|
||||||
|
|
||||||
/* Give up earlier as i386, in case */
|
|
||||||
if (err)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (_NSIG_WORDS > 1) {
|
|
||||||
err |= __copy_to_user(frame->extramask, &set->sig[1],
|
|
||||||
sizeof(frame->extramask)); }
|
|
||||||
|
|
||||||
/* Give up earlier as i386, in case */
|
|
||||||
if (err)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
/* Set up to return from userspace. If provided, use a stub
|
|
||||||
already in userspace. */
|
|
||||||
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
|
|
||||||
/*
|
|
||||||
* On SH5 all edited pointers are subject to NEFF
|
|
||||||
*/
|
|
||||||
DEREF_REG_PR = neff_sign_extend((unsigned long)
|
|
||||||
ksig->ka->sa.sa_restorer | 0x1);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Different approach on SH5.
|
|
||||||
* . Endianness independent asm code gets placed in entry.S .
|
|
||||||
* This is limited to four ASM instructions corresponding
|
|
||||||
* to two long longs in size.
|
|
||||||
* . err checking is done on the else branch only
|
|
||||||
* . flush_icache_range() is called upon __put_user() only
|
|
||||||
* . all edited pointers are subject to NEFF
|
|
||||||
* . being code, linker turns ShMedia bit on, always
|
|
||||||
* dereference index -1.
|
|
||||||
*/
|
|
||||||
DEREF_REG_PR = neff_sign_extend((unsigned long)
|
|
||||||
frame->retcode | 0x01);
|
|
||||||
|
|
||||||
if (__copy_to_user(frame->retcode,
|
|
||||||
(void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
/* Cohere the trampoline with the I-cache. */
|
|
||||||
flush_cache_sigtramp(DEREF_REG_PR-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up registers for signal handler.
|
|
||||||
* All edited pointers are subject to NEFF.
|
|
||||||
*/
|
|
||||||
regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
|
|
||||||
regs->regs[REG_ARG1] = sig; /* Arg for signal handler */
|
|
||||||
|
|
||||||
/* FIXME:
|
|
||||||
The glibc profiling support for SH-5 needs to be passed a sigcontext
|
|
||||||
so it can retrieve the PC. At some point during 2003 the glibc
|
|
||||||
support was changed to receive the sigcontext through the 2nd
|
|
||||||
argument, but there are still versions of libc.so in use that use
|
|
||||||
the 3rd argument. Until libc.so is stabilised, pass the sigcontext
|
|
||||||
through both 2nd and 3rd arguments.
|
|
||||||
*/
|
|
||||||
|
|
||||||
regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
|
|
||||||
regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
|
|
||||||
|
|
||||||
regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
|
|
||||||
|
|
||||||
/* Broken %016Lx */
|
|
||||||
pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
|
|
||||||
sig, current->comm, current->pid, frame,
|
|
||||||
regs->pc >> 32, regs->pc & 0xffffffff,
|
|
||||||
DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setup_rt_frame(struct ksignal *kig, sigset_t *set,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
struct rt_sigframe __user *frame;
|
|
||||||
int err = 0, sig = ksig->sig;
|
|
||||||
|
|
||||||
frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
|
|
||||||
|
|
||||||
if (!access_ok(frame, sizeof(*frame)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
err |= __put_user(&frame->info, &frame->pinfo);
|
|
||||||
err |= __put_user(&frame->uc, &frame->puc);
|
|
||||||
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
|
|
||||||
|
|
||||||
/* Give up earlier as i386, in case */
|
|
||||||
if (err)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
/* Create the ucontext. */
|
|
||||||
err |= __put_user(0, &frame->uc.uc_flags);
|
|
||||||
err |= __put_user(0, &frame->uc.uc_link);
|
|
||||||
err |= __save_altstack(&frame->uc.uc_stack, regs->regs[REG_SP]);
|
|
||||||
err |= setup_sigcontext(&frame->uc.uc_mcontext,
|
|
||||||
regs, set->sig[0]);
|
|
||||||
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
|
|
||||||
|
|
||||||
/* Give up earlier as i386, in case */
|
|
||||||
if (err)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
/* Set up to return from userspace. If provided, use a stub
|
|
||||||
already in userspace. */
|
|
||||||
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
|
|
||||||
/*
|
|
||||||
* On SH5 all edited pointers are subject to NEFF
|
|
||||||
*/
|
|
||||||
DEREF_REG_PR = neff_sign_extend((unsigned long)
|
|
||||||
ksig->ka.sa.sa_restorer | 0x1);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Different approach on SH5.
|
|
||||||
* . Endianness independent asm code gets placed in entry.S .
|
|
||||||
* This is limited to four ASM instructions corresponding
|
|
||||||
* to two long longs in size.
|
|
||||||
* . err checking is done on the else branch only
|
|
||||||
* . flush_icache_range() is called upon __put_user() only
|
|
||||||
* . all edited pointers are subject to NEFF
|
|
||||||
* . being code, linker turns ShMedia bit on, always
|
|
||||||
* dereference index -1.
|
|
||||||
*/
|
|
||||||
DEREF_REG_PR = neff_sign_extend((unsigned long)
|
|
||||||
frame->retcode | 0x01);
|
|
||||||
|
|
||||||
if (__copy_to_user(frame->retcode,
|
|
||||||
(void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
/* Cohere the trampoline with the I-cache. */
|
|
||||||
flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up registers for signal handler.
|
|
||||||
* All edited pointers are subject to NEFF.
|
|
||||||
*/
|
|
||||||
regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
|
|
||||||
regs->regs[REG_ARG1] = sig; /* Arg for signal handler */
|
|
||||||
regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
|
|
||||||
regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
|
|
||||||
regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
|
|
||||||
|
|
||||||
pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
|
|
||||||
sig, current->comm, current->pid, frame,
|
|
||||||
regs->pc >> 32, regs->pc & 0xffffffff,
|
|
||||||
DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* OK, we're invoking a handler
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
sigset_t *oldset = sigmask_to_save();
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Set up the stack frame */
|
|
||||||
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
|
|
||||||
ret = setup_rt_frame(ksig, oldset, regs);
|
|
||||||
else
|
|
||||||
ret = setup_frame(ksig, oldset, regs);
|
|
||||||
|
|
||||||
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
|
|
||||||
{
|
|
||||||
if (thread_info_flags & _TIF_SIGPENDING)
|
|
||||||
do_signal(regs);
|
|
||||||
|
|
||||||
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
|
|
||||||
clear_thread_flag(TIF_NOTIFY_RESUME);
|
|
||||||
tracehook_notify_resume(regs);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,419 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* arch/sh/kernel/syscalls_64.S
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2004 - 2007 Paul Mundt
|
|
||||||
* Copyright (C) 2003, 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/sys.h>
|
|
||||||
|
|
||||||
.section .data, "aw"
|
|
||||||
.balign 32
|
|
||||||
|
|
||||||
/*
|
|
||||||
* System calls jump table
|
|
||||||
*/
|
|
||||||
.globl sys_call_table
|
|
||||||
sys_call_table:
|
|
||||||
.long sys_restart_syscall /* 0 - old "setup()" system call */
|
|
||||||
.long sys_exit
|
|
||||||
.long sys_fork
|
|
||||||
.long sys_read
|
|
||||||
.long sys_write
|
|
||||||
.long sys_open /* 5 */
|
|
||||||
.long sys_close
|
|
||||||
.long sys_waitpid
|
|
||||||
.long sys_creat
|
|
||||||
.long sys_link
|
|
||||||
.long sys_unlink /* 10 */
|
|
||||||
.long sys_execve
|
|
||||||
.long sys_chdir
|
|
||||||
.long sys_time
|
|
||||||
.long sys_mknod
|
|
||||||
.long sys_chmod /* 15 */
|
|
||||||
.long sys_lchown16
|
|
||||||
.long sys_ni_syscall /* old break syscall holder */
|
|
||||||
.long sys_stat
|
|
||||||
.long sys_lseek
|
|
||||||
.long sys_getpid /* 20 */
|
|
||||||
.long sys_mount
|
|
||||||
.long sys_oldumount
|
|
||||||
.long sys_setuid16
|
|
||||||
.long sys_getuid16
|
|
||||||
.long sys_stime /* 25 */
|
|
||||||
.long sh64_ptrace
|
|
||||||
.long sys_alarm
|
|
||||||
.long sys_fstat
|
|
||||||
.long sys_pause
|
|
||||||
.long sys_utime /* 30 */
|
|
||||||
.long sys_ni_syscall /* old stty syscall holder */
|
|
||||||
.long sys_ni_syscall /* old gtty syscall holder */
|
|
||||||
.long sys_access
|
|
||||||
.long sys_nice
|
|
||||||
.long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
|
|
||||||
.long sys_sync
|
|
||||||
.long sys_kill
|
|
||||||
.long sys_rename
|
|
||||||
.long sys_mkdir
|
|
||||||
.long sys_rmdir /* 40 */
|
|
||||||
.long sys_dup
|
|
||||||
.long sys_pipe
|
|
||||||
.long sys_times
|
|
||||||
.long sys_ni_syscall /* old prof syscall holder */
|
|
||||||
.long sys_brk /* 45 */
|
|
||||||
.long sys_setgid16
|
|
||||||
.long sys_getgid16
|
|
||||||
.long sys_signal
|
|
||||||
.long sys_geteuid16
|
|
||||||
.long sys_getegid16 /* 50 */
|
|
||||||
.long sys_acct
|
|
||||||
.long sys_umount /* recycled never used phys( */
|
|
||||||
.long sys_ni_syscall /* old lock syscall holder */
|
|
||||||
.long sys_ioctl
|
|
||||||
.long sys_fcntl /* 55 */
|
|
||||||
.long sys_ni_syscall /* old mpx syscall holder */
|
|
||||||
.long sys_setpgid
|
|
||||||
.long sys_ni_syscall /* old ulimit syscall holder */
|
|
||||||
.long sys_ni_syscall /* sys_olduname */
|
|
||||||
.long sys_umask /* 60 */
|
|
||||||
.long sys_chroot
|
|
||||||
.long sys_ustat
|
|
||||||
.long sys_dup2
|
|
||||||
.long sys_getppid
|
|
||||||
.long sys_getpgrp /* 65 */
|
|
||||||
.long sys_setsid
|
|
||||||
.long sys_sigaction
|
|
||||||
.long sys_sgetmask
|
|
||||||
.long sys_ssetmask
|
|
||||||
.long sys_setreuid16 /* 70 */
|
|
||||||
.long sys_setregid16
|
|
||||||
.long sys_sigsuspend
|
|
||||||
.long sys_sigpending
|
|
||||||
.long sys_sethostname
|
|
||||||
.long sys_setrlimit /* 75 */
|
|
||||||
.long sys_old_getrlimit
|
|
||||||
.long sys_getrusage
|
|
||||||
.long sys_gettimeofday
|
|
||||||
.long sys_settimeofday
|
|
||||||
.long sys_getgroups16 /* 80 */
|
|
||||||
.long sys_setgroups16
|
|
||||||
.long sys_ni_syscall /* sys_oldselect */
|
|
||||||
.long sys_symlink
|
|
||||||
.long sys_lstat
|
|
||||||
.long sys_readlink /* 85 */
|
|
||||||
.long sys_uselib
|
|
||||||
.long sys_swapon
|
|
||||||
.long sys_reboot
|
|
||||||
.long sys_old_readdir
|
|
||||||
.long old_mmap /* 90 */
|
|
||||||
.long sys_munmap
|
|
||||||
.long sys_truncate
|
|
||||||
.long sys_ftruncate
|
|
||||||
.long sys_fchmod
|
|
||||||
.long sys_fchown16 /* 95 */
|
|
||||||
.long sys_getpriority
|
|
||||||
.long sys_setpriority
|
|
||||||
.long sys_ni_syscall /* old profil syscall holder */
|
|
||||||
.long sys_statfs
|
|
||||||
.long sys_fstatfs /* 100 */
|
|
||||||
.long sys_ni_syscall /* ioperm */
|
|
||||||
.long sys_socketcall /* Obsolete implementation of socket syscall */
|
|
||||||
.long sys_syslog
|
|
||||||
.long sys_setitimer
|
|
||||||
.long sys_getitimer /* 105 */
|
|
||||||
.long sys_newstat
|
|
||||||
.long sys_newlstat
|
|
||||||
.long sys_newfstat
|
|
||||||
.long sys_uname
|
|
||||||
.long sys_ni_syscall /* 110 */ /* iopl */
|
|
||||||
.long sys_vhangup
|
|
||||||
.long sys_ni_syscall /* idle */
|
|
||||||
.long sys_ni_syscall /* vm86old */
|
|
||||||
.long sys_wait4
|
|
||||||
.long sys_swapoff /* 115 */
|
|
||||||
.long sys_sysinfo
|
|
||||||
.long sys_ipc /* Obsolete ipc syscall implementation */
|
|
||||||
.long sys_fsync
|
|
||||||
.long sys_sigreturn
|
|
||||||
.long sys_clone /* 120 */
|
|
||||||
.long sys_setdomainname
|
|
||||||
.long sys_newuname
|
|
||||||
.long sys_cacheflush /* x86: sys_modify_ldt */
|
|
||||||
.long sys_adjtimex
|
|
||||||
.long sys_mprotect /* 125 */
|
|
||||||
.long sys_sigprocmask
|
|
||||||
.long sys_ni_syscall /* old "create_module" */
|
|
||||||
.long sys_init_module
|
|
||||||
.long sys_delete_module
|
|
||||||
.long sys_ni_syscall /* 130: old "get_kernel_syms" */
|
|
||||||
.long sys_quotactl
|
|
||||||
.long sys_getpgid
|
|
||||||
.long sys_fchdir
|
|
||||||
.long sys_bdflush
|
|
||||||
.long sys_sysfs /* 135 */
|
|
||||||
.long sys_personality
|
|
||||||
.long sys_ni_syscall /* for afs_syscall */
|
|
||||||
.long sys_setfsuid16
|
|
||||||
.long sys_setfsgid16
|
|
||||||
.long sys_llseek /* 140 */
|
|
||||||
.long sys_getdents
|
|
||||||
.long sys_select
|
|
||||||
.long sys_flock
|
|
||||||
.long sys_msync
|
|
||||||
.long sys_readv /* 145 */
|
|
||||||
.long sys_writev
|
|
||||||
.long sys_getsid
|
|
||||||
.long sys_fdatasync
|
|
||||||
.long sys_sysctl
|
|
||||||
.long sys_mlock /* 150 */
|
|
||||||
.long sys_munlock
|
|
||||||
.long sys_mlockall
|
|
||||||
.long sys_munlockall
|
|
||||||
.long sys_sched_setparam
|
|
||||||
.long sys_sched_getparam /* 155 */
|
|
||||||
.long sys_sched_setscheduler
|
|
||||||
.long sys_sched_getscheduler
|
|
||||||
.long sys_sched_yield
|
|
||||||
.long sys_sched_get_priority_max
|
|
||||||
.long sys_sched_get_priority_min /* 160 */
|
|
||||||
.long sys_sched_rr_get_interval
|
|
||||||
.long sys_nanosleep
|
|
||||||
.long sys_mremap
|
|
||||||
.long sys_setresuid16
|
|
||||||
.long sys_getresuid16 /* 165 */
|
|
||||||
.long sys_ni_syscall /* vm86 */
|
|
||||||
.long sys_ni_syscall /* old "query_module" */
|
|
||||||
.long sys_poll
|
|
||||||
.long sys_ni_syscall /* was nfsservctl */
|
|
||||||
.long sys_setresgid16 /* 170 */
|
|
||||||
.long sys_getresgid16
|
|
||||||
.long sys_prctl
|
|
||||||
.long sys_rt_sigreturn
|
|
||||||
.long sys_rt_sigaction
|
|
||||||
.long sys_rt_sigprocmask /* 175 */
|
|
||||||
.long sys_rt_sigpending
|
|
||||||
.long sys_rt_sigtimedwait
|
|
||||||
.long sys_rt_sigqueueinfo
|
|
||||||
.long sys_rt_sigsuspend
|
|
||||||
.long sys_pread64 /* 180 */
|
|
||||||
.long sys_pwrite64
|
|
||||||
.long sys_chown16
|
|
||||||
.long sys_getcwd
|
|
||||||
.long sys_capget
|
|
||||||
.long sys_capset /* 185 */
|
|
||||||
.long sys_sigaltstack
|
|
||||||
.long sys_sendfile
|
|
||||||
.long sys_ni_syscall /* getpmsg */
|
|
||||||
.long sys_ni_syscall /* putpmsg */
|
|
||||||
.long sys_vfork /* 190 */
|
|
||||||
.long sys_getrlimit
|
|
||||||
.long sys_mmap2
|
|
||||||
.long sys_truncate64
|
|
||||||
.long sys_ftruncate64
|
|
||||||
.long sys_stat64 /* 195 */
|
|
||||||
.long sys_lstat64
|
|
||||||
.long sys_fstat64
|
|
||||||
.long sys_lchown
|
|
||||||
.long sys_getuid
|
|
||||||
.long sys_getgid /* 200 */
|
|
||||||
.long sys_geteuid
|
|
||||||
.long sys_getegid
|
|
||||||
.long sys_setreuid
|
|
||||||
.long sys_setregid
|
|
||||||
.long sys_getgroups /* 205 */
|
|
||||||
.long sys_setgroups
|
|
||||||
.long sys_fchown
|
|
||||||
.long sys_setresuid
|
|
||||||
.long sys_getresuid
|
|
||||||
.long sys_setresgid /* 210 */
|
|
||||||
.long sys_getresgid
|
|
||||||
.long sys_chown
|
|
||||||
.long sys_setuid
|
|
||||||
.long sys_setgid
|
|
||||||
.long sys_setfsuid /* 215 */
|
|
||||||
.long sys_setfsgid
|
|
||||||
.long sys_pivot_root
|
|
||||||
.long sys_mincore
|
|
||||||
.long sys_madvise
|
|
||||||
/* Broken-out socket family (maintain backwards compatibility in syscall
|
|
||||||
numbering with 2.4) */
|
|
||||||
.long sys_socket /* 220 */
|
|
||||||
.long sys_bind
|
|
||||||
.long sys_connect
|
|
||||||
.long sys_listen
|
|
||||||
.long sys_accept
|
|
||||||
.long sys_getsockname /* 225 */
|
|
||||||
.long sys_getpeername
|
|
||||||
.long sys_socketpair
|
|
||||||
.long sys_send
|
|
||||||
.long sys_sendto
|
|
||||||
.long sys_recv /* 230*/
|
|
||||||
.long sys_recvfrom
|
|
||||||
.long sys_shutdown
|
|
||||||
.long sys_setsockopt
|
|
||||||
.long sys_getsockopt
|
|
||||||
.long sys_sendmsg /* 235 */
|
|
||||||
.long sys_recvmsg
|
|
||||||
/* Broken-out IPC family (maintain backwards compatibility in syscall
|
|
||||||
numbering with 2.4) */
|
|
||||||
.long sys_semop
|
|
||||||
.long sys_semget
|
|
||||||
.long sys_semctl
|
|
||||||
.long sys_msgsnd /* 240 */
|
|
||||||
.long sys_msgrcv
|
|
||||||
.long sys_msgget
|
|
||||||
.long sys_msgctl
|
|
||||||
.long sys_shmat
|
|
||||||
.long sys_shmdt /* 245 */
|
|
||||||
.long sys_shmget
|
|
||||||
.long sys_shmctl
|
|
||||||
/* Rest of syscalls listed in 2.4 i386 unistd.h */
|
|
||||||
.long sys_getdents64
|
|
||||||
.long sys_fcntl64
|
|
||||||
.long sys_ni_syscall /* 250 reserved for TUX */
|
|
||||||
.long sys_ni_syscall /* Reserved for Security */
|
|
||||||
.long sys_gettid
|
|
||||||
.long sys_readahead
|
|
||||||
.long sys_setxattr
|
|
||||||
.long sys_lsetxattr /* 255 */
|
|
||||||
.long sys_fsetxattr
|
|
||||||
.long sys_getxattr
|
|
||||||
.long sys_lgetxattr
|
|
||||||
.long sys_fgetxattr
|
|
||||||
.long sys_listxattr /* 260 */
|
|
||||||
.long sys_llistxattr
|
|
||||||
.long sys_flistxattr
|
|
||||||
.long sys_removexattr
|
|
||||||
.long sys_lremovexattr
|
|
||||||
.long sys_fremovexattr /* 265 */
|
|
||||||
.long sys_tkill
|
|
||||||
.long sys_sendfile64
|
|
||||||
.long sys_futex
|
|
||||||
.long sys_sched_setaffinity
|
|
||||||
.long sys_sched_getaffinity /* 270 */
|
|
||||||
.long sys_ni_syscall /* reserved for set_thread_area */
|
|
||||||
.long sys_ni_syscall /* reserved for get_thread_area */
|
|
||||||
.long sys_io_setup
|
|
||||||
.long sys_io_destroy
|
|
||||||
.long sys_io_getevents /* 275 */
|
|
||||||
.long sys_io_submit
|
|
||||||
.long sys_io_cancel
|
|
||||||
.long sys_fadvise64
|
|
||||||
.long sys_ni_syscall
|
|
||||||
.long sys_exit_group /* 280 */
|
|
||||||
/* Rest of new 2.6 syscalls */
|
|
||||||
.long sys_lookup_dcookie
|
|
||||||
.long sys_epoll_create
|
|
||||||
.long sys_epoll_ctl
|
|
||||||
.long sys_epoll_wait
|
|
||||||
.long sys_remap_file_pages /* 285 */
|
|
||||||
.long sys_set_tid_address
|
|
||||||
.long sys_timer_create
|
|
||||||
.long sys_timer_settime
|
|
||||||
.long sys_timer_gettime
|
|
||||||
.long sys_timer_getoverrun /* 290 */
|
|
||||||
.long sys_timer_delete
|
|
||||||
.long sys_clock_settime
|
|
||||||
.long sys_clock_gettime
|
|
||||||
.long sys_clock_getres
|
|
||||||
.long sys_clock_nanosleep /* 295 */
|
|
||||||
.long sys_statfs64
|
|
||||||
.long sys_fstatfs64
|
|
||||||
.long sys_tgkill
|
|
||||||
.long sys_utimes
|
|
||||||
.long sys_fadvise64_64 /* 300 */
|
|
||||||
.long sys_ni_syscall /* Reserved for vserver */
|
|
||||||
.long sys_ni_syscall /* Reserved for mbind */
|
|
||||||
.long sys_ni_syscall /* get_mempolicy */
|
|
||||||
.long sys_ni_syscall /* set_mempolicy */
|
|
||||||
.long sys_mq_open /* 305 */
|
|
||||||
.long sys_mq_unlink
|
|
||||||
.long sys_mq_timedsend
|
|
||||||
.long sys_mq_timedreceive
|
|
||||||
.long sys_mq_notify
|
|
||||||
.long sys_mq_getsetattr /* 310 */
|
|
||||||
.long sys_ni_syscall /* Reserved for kexec */
|
|
||||||
.long sys_waitid
|
|
||||||
.long sys_add_key
|
|
||||||
.long sys_request_key
|
|
||||||
.long sys_keyctl /* 315 */
|
|
||||||
.long sys_ioprio_set
|
|
||||||
.long sys_ioprio_get
|
|
||||||
.long sys_inotify_init
|
|
||||||
.long sys_inotify_add_watch
|
|
||||||
.long sys_inotify_rm_watch /* 320 */
|
|
||||||
.long sys_ni_syscall
|
|
||||||
.long sys_migrate_pages
|
|
||||||
.long sys_openat
|
|
||||||
.long sys_mkdirat
|
|
||||||
.long sys_mknodat /* 325 */
|
|
||||||
.long sys_fchownat
|
|
||||||
.long sys_futimesat
|
|
||||||
.long sys_fstatat64
|
|
||||||
.long sys_unlinkat
|
|
||||||
.long sys_renameat /* 330 */
|
|
||||||
.long sys_linkat
|
|
||||||
.long sys_symlinkat
|
|
||||||
.long sys_readlinkat
|
|
||||||
.long sys_fchmodat
|
|
||||||
.long sys_faccessat /* 335 */
|
|
||||||
.long sys_pselect6
|
|
||||||
.long sys_ppoll
|
|
||||||
.long sys_unshare
|
|
||||||
.long sys_set_robust_list
|
|
||||||
.long sys_get_robust_list /* 340 */
|
|
||||||
.long sys_splice
|
|
||||||
.long sys_sync_file_range
|
|
||||||
.long sys_tee
|
|
||||||
.long sys_vmsplice
|
|
||||||
.long sys_move_pages /* 345 */
|
|
||||||
.long sys_getcpu
|
|
||||||
.long sys_epoll_pwait
|
|
||||||
.long sys_utimensat
|
|
||||||
.long sys_signalfd
|
|
||||||
.long sys_timerfd_create /* 350 */
|
|
||||||
.long sys_eventfd
|
|
||||||
.long sys_fallocate
|
|
||||||
.long sys_timerfd_settime
|
|
||||||
.long sys_timerfd_gettime
|
|
||||||
.long sys_signalfd4 /* 355 */
|
|
||||||
.long sys_eventfd2
|
|
||||||
.long sys_epoll_create1
|
|
||||||
.long sys_dup3
|
|
||||||
.long sys_pipe2
|
|
||||||
.long sys_inotify_init1 /* 360 */
|
|
||||||
.long sys_preadv
|
|
||||||
.long sys_pwritev
|
|
||||||
.long sys_rt_tgsigqueueinfo
|
|
||||||
.long sys_perf_event_open
|
|
||||||
.long sys_recvmmsg /* 365 */
|
|
||||||
.long sys_accept4
|
|
||||||
.long sys_fanotify_init
|
|
||||||
.long sys_fanotify_mark
|
|
||||||
.long sys_prlimit64
|
|
||||||
.long sys_name_to_handle_at /* 370 */
|
|
||||||
.long sys_open_by_handle_at
|
|
||||||
.long sys_clock_adjtime
|
|
||||||
.long sys_syncfs
|
|
||||||
.long sys_sendmmsg
|
|
||||||
.long sys_setns /* 375 */
|
|
||||||
.long sys_process_vm_readv
|
|
||||||
.long sys_process_vm_writev
|
|
||||||
.long sys_kcmp
|
|
||||||
.long sys_finit_module
|
|
||||||
.long sys_sched_getattr /* 380 */
|
|
||||||
.long sys_sched_setattr
|
|
||||||
.long sys_renameat2
|
|
||||||
.long sys_seccomp
|
|
||||||
.long sys_getrandom
|
|
||||||
.long sys_memfd_create /* 385 */
|
|
||||||
.long sys_bpf
|
|
||||||
.long sys_execveat
|
|
||||||
.long sys_userfaultfd
|
|
||||||
.long sys_membarrier
|
|
||||||
.long sys_mlock2 /* 390 */
|
|
||||||
.long sys_copy_file_range
|
|
||||||
.long sys_preadv2
|
|
||||||
.long sys_pwritev2
|
|
|
@ -1,814 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* arch/sh/kernel/traps_64.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
* Copyright (C) 2003, 2004 Paul Mundt
|
|
||||||
* Copyright (C) 2003, 2004 Richard Curnow
|
|
||||||
*/
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/sched/debug.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/timer.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/kallsyms.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/sysctl.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/perf_event.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <asm/alignment.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/fpu.h>
|
|
||||||
|
|
||||||
static int read_opcode(reg_size_t pc, insn_size_t *result_opcode, int from_user_mode)
|
|
||||||
{
|
|
||||||
int get_user_error;
|
|
||||||
unsigned long aligned_pc;
|
|
||||||
insn_size_t opcode;
|
|
||||||
|
|
||||||
if ((pc & 3) == 1) {
|
|
||||||
/* SHmedia */
|
|
||||||
aligned_pc = pc & ~3;
|
|
||||||
if (from_user_mode) {
|
|
||||||
if (!access_ok(aligned_pc, sizeof(insn_size_t))) {
|
|
||||||
get_user_error = -EFAULT;
|
|
||||||
} else {
|
|
||||||
get_user_error = __get_user(opcode, (insn_size_t *)aligned_pc);
|
|
||||||
*result_opcode = opcode;
|
|
||||||
}
|
|
||||||
return get_user_error;
|
|
||||||
} else {
|
|
||||||
/* If the fault was in the kernel, we can either read
|
|
||||||
* this directly, or if not, we fault.
|
|
||||||
*/
|
|
||||||
*result_opcode = *(insn_size_t *)aligned_pc;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else if ((pc & 1) == 0) {
|
|
||||||
/* SHcompact */
|
|
||||||
/* TODO : provide handling for this. We don't really support
|
|
||||||
user-mode SHcompact yet, and for a kernel fault, this would
|
|
||||||
have to come from a module built for SHcompact. */
|
|
||||||
return -EFAULT;
|
|
||||||
} else {
|
|
||||||
/* misaligned */
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int address_is_sign_extended(__u64 a)
|
|
||||||
{
|
|
||||||
__u64 b;
|
|
||||||
#if (NEFF == 32)
|
|
||||||
b = (__u64)(__s64)(__s32)(a & 0xffffffffUL);
|
|
||||||
return (b == a) ? 1 : 0;
|
|
||||||
#else
|
|
||||||
#error "Sign extend check only works for NEFF==32"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return -1 for fault, 0 for OK */
|
|
||||||
static int generate_and_check_address(struct pt_regs *regs,
|
|
||||||
insn_size_t opcode,
|
|
||||||
int displacement_not_indexed,
|
|
||||||
int width_shift,
|
|
||||||
__u64 *address)
|
|
||||||
{
|
|
||||||
__u64 base_address, addr;
|
|
||||||
int basereg;
|
|
||||||
|
|
||||||
switch (1 << width_shift) {
|
|
||||||
case 1: inc_unaligned_byte_access(); break;
|
|
||||||
case 2: inc_unaligned_word_access(); break;
|
|
||||||
case 4: inc_unaligned_dword_access(); break;
|
|
||||||
case 8: inc_unaligned_multi_access(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
basereg = (opcode >> 20) & 0x3f;
|
|
||||||
base_address = regs->regs[basereg];
|
|
||||||
if (displacement_not_indexed) {
|
|
||||||
__s64 displacement;
|
|
||||||
displacement = (opcode >> 10) & 0x3ff;
|
|
||||||
displacement = sign_extend64(displacement, 9);
|
|
||||||
addr = (__u64)((__s64)base_address + (displacement << width_shift));
|
|
||||||
} else {
|
|
||||||
__u64 offset;
|
|
||||||
int offsetreg;
|
|
||||||
offsetreg = (opcode >> 10) & 0x3f;
|
|
||||||
offset = regs->regs[offsetreg];
|
|
||||||
addr = base_address + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check sign extended */
|
|
||||||
if (!address_is_sign_extended(addr))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Check accessible. For misaligned access in the kernel, assume the
|
|
||||||
address is always accessible (and if not, just fault when the
|
|
||||||
load/store gets done.) */
|
|
||||||
if (user_mode(regs)) {
|
|
||||||
inc_unaligned_user_access();
|
|
||||||
|
|
||||||
if (addr >= TASK_SIZE)
|
|
||||||
return -1;
|
|
||||||
} else
|
|
||||||
inc_unaligned_kernel_access();
|
|
||||||
|
|
||||||
*address = addr;
|
|
||||||
|
|
||||||
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, addr);
|
|
||||||
unaligned_fixups_notify(current, opcode, regs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void misaligned_kernel_word_load(__u64 address, int do_sign_extend, __u64 *result)
|
|
||||||
{
|
|
||||||
unsigned short x;
|
|
||||||
unsigned char *p, *q;
|
|
||||||
p = (unsigned char *) (int) address;
|
|
||||||
q = (unsigned char *) &x;
|
|
||||||
q[0] = p[0];
|
|
||||||
q[1] = p[1];
|
|
||||||
|
|
||||||
if (do_sign_extend) {
|
|
||||||
*result = (__u64)(__s64) *(short *) &x;
|
|
||||||
} else {
|
|
||||||
*result = (__u64) x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void misaligned_kernel_word_store(__u64 address, __u64 value)
|
|
||||||
{
|
|
||||||
unsigned short x;
|
|
||||||
unsigned char *p, *q;
|
|
||||||
p = (unsigned char *) (int) address;
|
|
||||||
q = (unsigned char *) &x;
|
|
||||||
|
|
||||||
x = (__u16) value;
|
|
||||||
p[0] = q[0];
|
|
||||||
p[1] = q[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
static int misaligned_load(struct pt_regs *regs,
|
|
||||||
insn_size_t opcode,
|
|
||||||
int displacement_not_indexed,
|
|
||||||
int width_shift,
|
|
||||||
int do_sign_extend)
|
|
||||||
{
|
|
||||||
/* Return -1 for a fault, 0 for OK */
|
|
||||||
int error;
|
|
||||||
int destreg;
|
|
||||||
__u64 address;
|
|
||||||
|
|
||||||
error = generate_and_check_address(regs, opcode,
|
|
||||||
displacement_not_indexed, width_shift, &address);
|
|
||||||
if (error < 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
destreg = (opcode >> 4) & 0x3f;
|
|
||||||
if (user_mode(regs)) {
|
|
||||||
__u64 buffer;
|
|
||||||
|
|
||||||
if (!access_ok((unsigned long) address, 1UL<<width_shift)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__copy_user(&buffer, (const void *)(int)address, (1 << width_shift)) > 0) {
|
|
||||||
return -1; /* fault */
|
|
||||||
}
|
|
||||||
switch (width_shift) {
|
|
||||||
case 1:
|
|
||||||
if (do_sign_extend) {
|
|
||||||
regs->regs[destreg] = (__u64)(__s64) *(__s16 *) &buffer;
|
|
||||||
} else {
|
|
||||||
regs->regs[destreg] = (__u64) *(__u16 *) &buffer;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
regs->regs[destreg] = (__u64)(__s64) *(__s32 *) &buffer;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
regs->regs[destreg] = buffer;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk("Unexpected width_shift %d in misaligned_load, PC=%08lx\n",
|
|
||||||
width_shift, (unsigned long) regs->pc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* kernel mode - we can take short cuts since if we fault, it's a genuine bug */
|
|
||||||
__u64 lo, hi;
|
|
||||||
|
|
||||||
switch (width_shift) {
|
|
||||||
case 1:
|
|
||||||
misaligned_kernel_word_load(address, do_sign_extend, ®s->regs[destreg]);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
asm ("ldlo.l %1, 0, %0" : "=r" (lo) : "r" (address));
|
|
||||||
asm ("ldhi.l %1, 3, %0" : "=r" (hi) : "r" (address));
|
|
||||||
regs->regs[destreg] = lo | hi;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
asm ("ldlo.q %1, 0, %0" : "=r" (lo) : "r" (address));
|
|
||||||
asm ("ldhi.q %1, 7, %0" : "=r" (hi) : "r" (address));
|
|
||||||
regs->regs[destreg] = lo | hi;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printk("Unexpected width_shift %d in misaligned_load, PC=%08lx\n",
|
|
||||||
width_shift, (unsigned long) regs->pc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int misaligned_store(struct pt_regs *regs,
|
|
||||||
insn_size_t opcode,
|
|
||||||
int displacement_not_indexed,
|
|
||||||
int width_shift)
|
|
||||||
{
|
|
||||||
/* Return -1 for a fault, 0 for OK */
|
|
||||||
int error;
|
|
||||||
int srcreg;
|
|
||||||
__u64 address;
|
|
||||||
|
|
||||||
error = generate_and_check_address(regs, opcode,
|
|
||||||
displacement_not_indexed, width_shift, &address);
|
|
||||||
if (error < 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
srcreg = (opcode >> 4) & 0x3f;
|
|
||||||
if (user_mode(regs)) {
|
|
||||||
__u64 buffer;
|
|
||||||
|
|
||||||
if (!access_ok((unsigned long) address, 1UL<<width_shift)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (width_shift) {
|
|
||||||
case 1:
|
|
||||||
*(__u16 *) &buffer = (__u16) regs->regs[srcreg];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*(__u32 *) &buffer = (__u32) regs->regs[srcreg];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
buffer = regs->regs[srcreg];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk("Unexpected width_shift %d in misaligned_store, PC=%08lx\n",
|
|
||||||
width_shift, (unsigned long) regs->pc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__copy_user((void *)(int)address, &buffer, (1 << width_shift)) > 0) {
|
|
||||||
return -1; /* fault */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* kernel mode - we can take short cuts since if we fault, it's a genuine bug */
|
|
||||||
__u64 val = regs->regs[srcreg];
|
|
||||||
|
|
||||||
switch (width_shift) {
|
|
||||||
case 1:
|
|
||||||
misaligned_kernel_word_store(address, val);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
asm ("stlo.l %1, 0, %0" : : "r" (val), "r" (address));
|
|
||||||
asm ("sthi.l %1, 3, %0" : : "r" (val), "r" (address));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
asm ("stlo.q %1, 0, %0" : : "r" (val), "r" (address));
|
|
||||||
asm ("sthi.q %1, 7, %0" : : "r" (val), "r" (address));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printk("Unexpected width_shift %d in misaligned_store, PC=%08lx\n",
|
|
||||||
width_shift, (unsigned long) regs->pc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Never need to fix up misaligned FPU accesses within the kernel since that's a real
|
|
||||||
error. */
|
|
||||||
static int misaligned_fpu_load(struct pt_regs *regs,
|
|
||||||
insn_size_t opcode,
|
|
||||||
int displacement_not_indexed,
|
|
||||||
int width_shift,
|
|
||||||
int do_paired_load)
|
|
||||||
{
|
|
||||||
/* Return -1 for a fault, 0 for OK */
|
|
||||||
int error;
|
|
||||||
int destreg;
|
|
||||||
__u64 address;
|
|
||||||
|
|
||||||
error = generate_and_check_address(regs, opcode,
|
|
||||||
displacement_not_indexed, width_shift, &address);
|
|
||||||
if (error < 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
destreg = (opcode >> 4) & 0x3f;
|
|
||||||
if (user_mode(regs)) {
|
|
||||||
__u64 buffer;
|
|
||||||
__u32 buflo, bufhi;
|
|
||||||
|
|
||||||
if (!access_ok((unsigned long) address, 1UL<<width_shift)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__copy_user(&buffer, (const void *)(int)address, (1 << width_shift)) > 0) {
|
|
||||||
return -1; /* fault */
|
|
||||||
}
|
|
||||||
/* 'current' may be the current owner of the FPU state, so
|
|
||||||
context switch the registers into memory so they can be
|
|
||||||
indexed by register number. */
|
|
||||||
if (last_task_used_math == current) {
|
|
||||||
enable_fpu();
|
|
||||||
save_fpu(current);
|
|
||||||
disable_fpu();
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
buflo = *(__u32*) &buffer;
|
|
||||||
bufhi = *(1 + (__u32*) &buffer);
|
|
||||||
|
|
||||||
switch (width_shift) {
|
|
||||||
case 2:
|
|
||||||
current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (do_paired_load) {
|
|
||||||
current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
|
|
||||||
current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
|
|
||||||
} else {
|
|
||||||
#if defined(CONFIG_CPU_LITTLE_ENDIAN)
|
|
||||||
current->thread.xstate->hardfpu.fp_regs[destreg] = bufhi;
|
|
||||||
current->thread.xstate->hardfpu.fp_regs[destreg+1] = buflo;
|
|
||||||
#else
|
|
||||||
current->thread.xstate->hardfpu.fp_regs[destreg] = buflo;
|
|
||||||
current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk("Unexpected width_shift %d in misaligned_fpu_load, PC=%08lx\n",
|
|
||||||
width_shift, (unsigned long) regs->pc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
die ("Misaligned FPU load inside kernel", regs, 0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int misaligned_fpu_store(struct pt_regs *regs,
|
|
||||||
insn_size_t opcode,
|
|
||||||
int displacement_not_indexed,
|
|
||||||
int width_shift,
|
|
||||||
int do_paired_load)
|
|
||||||
{
|
|
||||||
/* Return -1 for a fault, 0 for OK */
|
|
||||||
int error;
|
|
||||||
int srcreg;
|
|
||||||
__u64 address;
|
|
||||||
|
|
||||||
error = generate_and_check_address(regs, opcode,
|
|
||||||
displacement_not_indexed, width_shift, &address);
|
|
||||||
if (error < 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
srcreg = (opcode >> 4) & 0x3f;
|
|
||||||
if (user_mode(regs)) {
|
|
||||||
__u64 buffer;
|
|
||||||
/* Initialise these to NaNs. */
|
|
||||||
__u32 buflo=0xffffffffUL, bufhi=0xffffffffUL;
|
|
||||||
|
|
||||||
if (!access_ok((unsigned long) address, 1UL<<width_shift)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 'current' may be the current owner of the FPU state, so
|
|
||||||
context switch the registers into memory so they can be
|
|
||||||
indexed by register number. */
|
|
||||||
if (last_task_used_math == current) {
|
|
||||||
enable_fpu();
|
|
||||||
save_fpu(current);
|
|
||||||
disable_fpu();
|
|
||||||
last_task_used_math = NULL;
|
|
||||||
regs->sr |= SR_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (width_shift) {
|
|
||||||
case 2:
|
|
||||||
buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (do_paired_load) {
|
|
||||||
buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
|
|
||||||
bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
|
|
||||||
} else {
|
|
||||||
#if defined(CONFIG_CPU_LITTLE_ENDIAN)
|
|
||||||
bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg];
|
|
||||||
buflo = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
|
|
||||||
#else
|
|
||||||
buflo = current->thread.xstate->hardfpu.fp_regs[srcreg];
|
|
||||||
bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk("Unexpected width_shift %d in misaligned_fpu_store, PC=%08lx\n",
|
|
||||||
width_shift, (unsigned long) regs->pc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__u32*) &buffer = buflo;
|
|
||||||
*(1 + (__u32*) &buffer) = bufhi;
|
|
||||||
if (__copy_user((void *)(int)address, &buffer, (1 << width_shift)) > 0) {
|
|
||||||
return -1; /* fault */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
die ("Misaligned FPU load inside kernel", regs, 0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int misaligned_fixup(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
insn_size_t opcode;
|
|
||||||
int error;
|
|
||||||
int major, minor;
|
|
||||||
unsigned int user_action;
|
|
||||||
|
|
||||||
user_action = unaligned_user_action();
|
|
||||||
if (!(user_action & UM_FIXUP))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
error = read_opcode(regs->pc, &opcode, user_mode(regs));
|
|
||||||
if (error < 0) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
major = (opcode >> 26) & 0x3f;
|
|
||||||
minor = (opcode >> 16) & 0xf;
|
|
||||||
|
|
||||||
switch (major) {
|
|
||||||
case (0x84>>2): /* LD.W */
|
|
||||||
error = misaligned_load(regs, opcode, 1, 1, 1);
|
|
||||||
break;
|
|
||||||
case (0xb0>>2): /* LD.UW */
|
|
||||||
error = misaligned_load(regs, opcode, 1, 1, 0);
|
|
||||||
break;
|
|
||||||
case (0x88>>2): /* LD.L */
|
|
||||||
error = misaligned_load(regs, opcode, 1, 2, 1);
|
|
||||||
break;
|
|
||||||
case (0x8c>>2): /* LD.Q */
|
|
||||||
error = misaligned_load(regs, opcode, 1, 3, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (0xa4>>2): /* ST.W */
|
|
||||||
error = misaligned_store(regs, opcode, 1, 1);
|
|
||||||
break;
|
|
||||||
case (0xa8>>2): /* ST.L */
|
|
||||||
error = misaligned_store(regs, opcode, 1, 2);
|
|
||||||
break;
|
|
||||||
case (0xac>>2): /* ST.Q */
|
|
||||||
error = misaligned_store(regs, opcode, 1, 3);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (0x40>>2): /* indexed loads */
|
|
||||||
switch (minor) {
|
|
||||||
case 0x1: /* LDX.W */
|
|
||||||
error = misaligned_load(regs, opcode, 0, 1, 1);
|
|
||||||
break;
|
|
||||||
case 0x5: /* LDX.UW */
|
|
||||||
error = misaligned_load(regs, opcode, 0, 1, 0);
|
|
||||||
break;
|
|
||||||
case 0x2: /* LDX.L */
|
|
||||||
error = misaligned_load(regs, opcode, 0, 2, 1);
|
|
||||||
break;
|
|
||||||
case 0x3: /* LDX.Q */
|
|
||||||
error = misaligned_load(regs, opcode, 0, 3, 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (0x60>>2): /* indexed stores */
|
|
||||||
switch (minor) {
|
|
||||||
case 0x1: /* STX.W */
|
|
||||||
error = misaligned_store(regs, opcode, 0, 1);
|
|
||||||
break;
|
|
||||||
case 0x2: /* STX.L */
|
|
||||||
error = misaligned_store(regs, opcode, 0, 2);
|
|
||||||
break;
|
|
||||||
case 0x3: /* STX.Q */
|
|
||||||
error = misaligned_store(regs, opcode, 0, 3);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (0x94>>2): /* FLD.S */
|
|
||||||
error = misaligned_fpu_load(regs, opcode, 1, 2, 0);
|
|
||||||
break;
|
|
||||||
case (0x98>>2): /* FLD.P */
|
|
||||||
error = misaligned_fpu_load(regs, opcode, 1, 3, 1);
|
|
||||||
break;
|
|
||||||
case (0x9c>>2): /* FLD.D */
|
|
||||||
error = misaligned_fpu_load(regs, opcode, 1, 3, 0);
|
|
||||||
break;
|
|
||||||
case (0x1c>>2): /* floating indexed loads */
|
|
||||||
switch (minor) {
|
|
||||||
case 0x8: /* FLDX.S */
|
|
||||||
error = misaligned_fpu_load(regs, opcode, 0, 2, 0);
|
|
||||||
break;
|
|
||||||
case 0xd: /* FLDX.P */
|
|
||||||
error = misaligned_fpu_load(regs, opcode, 0, 3, 1);
|
|
||||||
break;
|
|
||||||
case 0x9: /* FLDX.D */
|
|
||||||
error = misaligned_fpu_load(regs, opcode, 0, 3, 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case (0xb4>>2): /* FLD.S */
|
|
||||||
error = misaligned_fpu_store(regs, opcode, 1, 2, 0);
|
|
||||||
break;
|
|
||||||
case (0xb8>>2): /* FLD.P */
|
|
||||||
error = misaligned_fpu_store(regs, opcode, 1, 3, 1);
|
|
||||||
break;
|
|
||||||
case (0xbc>>2): /* FLD.D */
|
|
||||||
error = misaligned_fpu_store(regs, opcode, 1, 3, 0);
|
|
||||||
break;
|
|
||||||
case (0x3c>>2): /* floating indexed stores */
|
|
||||||
switch (minor) {
|
|
||||||
case 0x8: /* FSTX.S */
|
|
||||||
error = misaligned_fpu_store(regs, opcode, 0, 2, 0);
|
|
||||||
break;
|
|
||||||
case 0xd: /* FSTX.P */
|
|
||||||
error = misaligned_fpu_store(regs, opcode, 0, 3, 1);
|
|
||||||
break;
|
|
||||||
case 0x9: /* FSTX.D */
|
|
||||||
error = misaligned_fpu_store(regs, opcode, 0, 3, 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Fault */
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error < 0) {
|
|
||||||
return error;
|
|
||||||
} else {
|
|
||||||
regs->pc += 4; /* Skip the instruction that's just been emulated */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_unhandled_exception(int signr, char *str, unsigned long error,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
if (user_mode(regs))
|
|
||||||
force_sig(signr);
|
|
||||||
|
|
||||||
die_if_no_fixup(str, regs, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DO_ERROR(signr, str, name) \
|
|
||||||
asmlinkage void do_##name(unsigned long error_code, struct pt_regs *regs) \
|
|
||||||
{ \
|
|
||||||
do_unhandled_exception(signr, str, error_code, regs); \
|
|
||||||
}
|
|
||||||
|
|
||||||
DO_ERROR(SIGILL, "illegal slot instruction", illegal_slot_inst)
|
|
||||||
DO_ERROR(SIGSEGV, "address error (exec)", address_error_exec)
|
|
||||||
|
|
||||||
#if defined(CONFIG_SH64_ID2815_WORKAROUND)
|
|
||||||
|
|
||||||
#define OPCODE_INVALID 0
|
|
||||||
#define OPCODE_USER_VALID 1
|
|
||||||
#define OPCODE_PRIV_VALID 2
|
|
||||||
|
|
||||||
/* getcon/putcon - requires checking which control register is referenced. */
|
|
||||||
#define OPCODE_CTRL_REG 3
|
|
||||||
|
|
||||||
/* Table of valid opcodes for SHmedia mode.
|
|
||||||
Form a 10-bit value by concatenating the major/minor opcodes i.e.
|
|
||||||
opcode[31:26,20:16]. The 6 MSBs of this value index into the following
|
|
||||||
array. The 4 LSBs select the bit-pair in the entry (bits 1:0 correspond to
|
|
||||||
LSBs==4'b0000 etc). */
|
|
||||||
static unsigned long shmedia_opcode_table[64] = {
|
|
||||||
0x55554044,0x54445055,0x15141514,0x14541414,0x00000000,0x10001000,0x01110055,0x04050015,
|
|
||||||
0x00000444,0xc0000000,0x44545515,0x40405555,0x55550015,0x10005555,0x55555505,0x04050000,
|
|
||||||
0x00000555,0x00000404,0x00040445,0x15151414,0x00000000,0x00000000,0x00000000,0x00000000,
|
|
||||||
0x00000055,0x40404444,0x00000404,0xc0009495,0x00000000,0x00000000,0x00000000,0x00000000,
|
|
||||||
0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,
|
|
||||||
0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,
|
|
||||||
0x80005050,0x04005055,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,0x55555555,
|
|
||||||
0x81055554,0x00000404,0x55555555,0x55555555,0x00000000,0x00000000,0x00000000,0x00000000
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Workaround SH5-101 cut2 silicon defect #2815 :
|
|
||||||
in some situations, inter-mode branches from SHcompact -> SHmedia
|
|
||||||
which should take ITLBMISS or EXECPROT exceptions at the target
|
|
||||||
falsely take RESINST at the target instead. */
|
|
||||||
void do_reserved_inst(unsigned long error_code, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
insn_size_t opcode = 0x6ff4fff0; /* guaranteed reserved opcode */
|
|
||||||
unsigned long pc, aligned_pc;
|
|
||||||
unsigned long index, shift;
|
|
||||||
unsigned long major, minor, combined;
|
|
||||||
unsigned long reserved_field;
|
|
||||||
int opcode_state;
|
|
||||||
int get_user_error;
|
|
||||||
int signr = SIGILL;
|
|
||||||
char *exception_name = "reserved_instruction";
|
|
||||||
|
|
||||||
pc = regs->pc;
|
|
||||||
|
|
||||||
/* SHcompact is not handled */
|
|
||||||
if (unlikely((pc & 3) == 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* SHmedia : check for defect. This requires executable vmas
|
|
||||||
to be readable too. */
|
|
||||||
aligned_pc = pc & ~3;
|
|
||||||
if (!access_ok(aligned_pc, sizeof(insn_size_t)))
|
|
||||||
get_user_error = -EFAULT;
|
|
||||||
else
|
|
||||||
get_user_error = __get_user(opcode, (insn_size_t *)aligned_pc);
|
|
||||||
|
|
||||||
if (get_user_error < 0) {
|
|
||||||
/*
|
|
||||||
* Error trying to read opcode. This typically means a
|
|
||||||
* real fault, not a RESINST any more. So change the
|
|
||||||
* codes.
|
|
||||||
*/
|
|
||||||
exception_name = "address error (exec)";
|
|
||||||
signr = SIGSEGV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These bits are currently reserved as zero in all valid opcodes */
|
|
||||||
reserved_field = opcode & 0xf;
|
|
||||||
if (unlikely(reserved_field))
|
|
||||||
goto out; /* invalid opcode */
|
|
||||||
|
|
||||||
major = (opcode >> 26) & 0x3f;
|
|
||||||
minor = (opcode >> 16) & 0xf;
|
|
||||||
combined = (major << 4) | minor;
|
|
||||||
index = major;
|
|
||||||
shift = minor << 1;
|
|
||||||
opcode_state = (shmedia_opcode_table[index] >> shift) & 0x3;
|
|
||||||
switch (opcode_state) {
|
|
||||||
case OPCODE_INVALID:
|
|
||||||
/* Trap. */
|
|
||||||
break;
|
|
||||||
case OPCODE_USER_VALID:
|
|
||||||
/*
|
|
||||||
* Restart the instruction: the branch to the instruction
|
|
||||||
* will now be from an RTE not from SHcompact so the
|
|
||||||
* silicon defect won't be triggered.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
case OPCODE_PRIV_VALID:
|
|
||||||
if (!user_mode(regs)) {
|
|
||||||
/*
|
|
||||||
* Should only ever get here if a module has
|
|
||||||
* SHcompact code inside it. If so, the same fix
|
|
||||||
* up is needed.
|
|
||||||
*/
|
|
||||||
return; /* same reason */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Otherwise, user mode trying to execute a privileged
|
|
||||||
* instruction - fall through to trap.
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case OPCODE_CTRL_REG:
|
|
||||||
/* If in privileged mode, return as above. */
|
|
||||||
if (!user_mode(regs))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* In user mode ... */
|
|
||||||
if (combined == 0x9f) { /* GETCON */
|
|
||||||
unsigned long regno = (opcode >> 20) & 0x3f;
|
|
||||||
|
|
||||||
if (regno >= 62)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* reserved/privileged control register => trap */
|
|
||||||
} else if (combined == 0x1bf) { /* PUTCON */
|
|
||||||
unsigned long regno = (opcode >> 4) & 0x3f;
|
|
||||||
|
|
||||||
if (regno >= 62)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* reserved/privileged control register => trap */
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Fall through to trap. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
do_unhandled_exception(signr, exception_name, error_code, regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* CONFIG_SH64_ID2815_WORKAROUND */
|
|
||||||
|
|
||||||
/* If the workaround isn't needed, this is just a straightforward reserved
|
|
||||||
instruction */
|
|
||||||
DO_ERROR(SIGILL, "reserved instruction", reserved_inst)
|
|
||||||
|
|
||||||
#endif /* CONFIG_SH64_ID2815_WORKAROUND */
|
|
||||||
|
|
||||||
/* Called with interrupts disabled */
|
|
||||||
asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
die_if_kernel("exception", regs, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int do_unknown_trapa(unsigned long scId, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
/* Syscall debug */
|
|
||||||
printk("System call ID error: [0x1#args:8 #syscall:16 0x%lx]\n", scId);
|
|
||||||
|
|
||||||
die_if_kernel("unknown trapa", regs, scId);
|
|
||||||
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implement misaligned load/store handling for kernel (and optionally for user
|
|
||||||
mode too). Limitation : only SHmedia mode code is handled - there is no
|
|
||||||
handling at all for misaligned accesses occurring in SHcompact code yet. */
|
|
||||||
|
|
||||||
asmlinkage void do_address_error_load(unsigned long error_code, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
if (misaligned_fixup(regs) < 0)
|
|
||||||
do_unhandled_exception(SIGSEGV, "address error(load)",
|
|
||||||
error_code, regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void do_address_error_store(unsigned long error_code, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
if (misaligned_fixup(regs) < 0)
|
|
||||||
do_unhandled_exception(SIGSEGV, "address error(store)",
|
|
||||||
error_code, regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
u64 peek_real_address_q(u64 addr);
|
|
||||||
u64 poke_real_address_q(u64 addr, u64 val);
|
|
||||||
unsigned long long DM_EXP_CAUSE_PHY = 0x0c100010;
|
|
||||||
unsigned long long exp_cause;
|
|
||||||
/* It's not worth ioremapping the debug module registers for the amount
|
|
||||||
of access we make to them - just go direct to their physical
|
|
||||||
addresses. */
|
|
||||||
exp_cause = peek_real_address_q(DM_EXP_CAUSE_PHY);
|
|
||||||
if (exp_cause & ~4)
|
|
||||||
printk("DM.EXP_CAUSE had unexpected bits set (=%08lx)\n",
|
|
||||||
(unsigned long)(exp_cause & 0xffffffff));
|
|
||||||
show_state();
|
|
||||||
/* Clear all DEBUGINT causes */
|
|
||||||
poke_real_address_q(DM_EXP_CAUSE_PHY, 0x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void per_cpu_trap_init(void)
|
|
||||||
{
|
|
||||||
/* Nothing to do for now, VBR initialization later. */
|
|
||||||
}
|
|
|
@ -3,14 +3,7 @@
|
||||||
* ld script to make SuperH Linux kernel
|
* ld script to make SuperH Linux kernel
|
||||||
* Written by Niibe Yutaka and Paul Mundt
|
* Written by Niibe Yutaka and Paul Mundt
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_SUPERH64
|
|
||||||
#define LOAD_OFFSET PAGE_OFFSET
|
|
||||||
OUTPUT_ARCH(sh:sh5)
|
|
||||||
#else
|
|
||||||
#define LOAD_OFFSET 0
|
|
||||||
OUTPUT_ARCH(sh)
|
OUTPUT_ARCH(sh)
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <asm/thread_info.h>
|
#include <asm/thread_info.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
#include <asm/vmlinux.lds.h>
|
#include <asm/vmlinux.lds.h>
|
||||||
|
@ -28,14 +21,13 @@ SECTIONS
|
||||||
|
|
||||||
_text = .; /* Text and read-only data */
|
_text = .; /* Text and read-only data */
|
||||||
|
|
||||||
.empty_zero_page : AT(ADDR(.empty_zero_page) - LOAD_OFFSET) {
|
.empty_zero_page : AT(ADDR(.empty_zero_page)) {
|
||||||
*(.empty_zero_page)
|
*(.empty_zero_page)
|
||||||
} = 0
|
} = 0
|
||||||
|
|
||||||
.text : AT(ADDR(.text) - LOAD_OFFSET) {
|
.text : AT(ADDR(.text)) {
|
||||||
HEAD_TEXT
|
HEAD_TEXT
|
||||||
TEXT_TEXT
|
TEXT_TEXT
|
||||||
EXTRA_TEXT
|
|
||||||
SCHED_TEXT
|
SCHED_TEXT
|
||||||
CPUIDLE_TEXT
|
CPUIDLE_TEXT
|
||||||
LOCK_TEXT
|
LOCK_TEXT
|
||||||
|
@ -62,7 +54,7 @@ SECTIONS
|
||||||
INIT_DATA_SECTION(16)
|
INIT_DATA_SECTION(16)
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
.machvec.init : AT(ADDR(.machvec.init) - LOAD_OFFSET) {
|
.machvec.init : AT(ADDR(.machvec.init)) {
|
||||||
__machvec_start = .;
|
__machvec_start = .;
|
||||||
*(.machvec.init)
|
*(.machvec.init)
|
||||||
__machvec_end = .;
|
__machvec_end = .;
|
||||||
|
@ -74,8 +66,8 @@ SECTIONS
|
||||||
* .exit.text is discarded at runtime, not link time, to deal with
|
* .exit.text is discarded at runtime, not link time, to deal with
|
||||||
* references from __bug_table
|
* references from __bug_table
|
||||||
*/
|
*/
|
||||||
.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { EXIT_TEXT }
|
.exit.text : AT(ADDR(.exit.text)) { EXIT_TEXT }
|
||||||
.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { EXIT_DATA }
|
.exit.data : AT(ADDR(.exit.data)) { EXIT_DATA }
|
||||||
|
|
||||||
. = ALIGN(PAGE_SIZE);
|
. = ALIGN(PAGE_SIZE);
|
||||||
__init_end = .;
|
__init_end = .;
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#
|
|
||||||
# Makefile for the SH-5 specific library files..
|
|
||||||
#
|
|
||||||
# Copyright (C) 2000, 2001 Paolo Alberelli
|
|
||||||
# Copyright (C) 2003 - 2008 Paul Mundt
|
|
||||||
#
|
|
||||||
# This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
# License. See the file "COPYING" in the main directory of this archive
|
|
||||||
# for more details.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Panic should really be compiled as PIC
|
|
||||||
lib-y := udelay.o panic.o memcpy.o memset.o \
|
|
||||||
copy_user_memcpy.o copy_page.o strcpy.o strlen.o
|
|
||||||
|
|
||||||
# Extracted from libgcc
|
|
||||||
lib-y += udivsi3.o udivdi3.o sdivsi3.o
|
|
|
@ -1,89 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2003 Richard Curnow, SuperH (UK) Ltd.
|
|
||||||
|
|
||||||
This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
License. See the file "COPYING" in the main directory of this archive
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
Tight version of mempy for the case of just copying a page.
|
|
||||||
Prefetch strategy empirically optimised against RTL simulations
|
|
||||||
of SH5-101 cut2 eval chip with Cayman board DDR memory.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
r2 : destination effective address (start of page)
|
|
||||||
r3 : source effective address (start of page)
|
|
||||||
|
|
||||||
Always copies 4096 bytes.
|
|
||||||
|
|
||||||
Points to review.
|
|
||||||
* Currently the prefetch is 4 lines ahead and the alloco is 2 lines ahead.
|
|
||||||
It seems like the prefetch needs to be at at least 4 lines ahead to get
|
|
||||||
the data into the cache in time, and the allocos contend with outstanding
|
|
||||||
prefetches for the same cache set, so it's better to have the numbers
|
|
||||||
different.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.section .text..SHmedia32,"ax"
|
|
||||||
.little
|
|
||||||
|
|
||||||
.balign 8
|
|
||||||
.global copy_page
|
|
||||||
copy_page:
|
|
||||||
|
|
||||||
/* Copy 4096 bytes worth of data from r3 to r2.
|
|
||||||
Do prefetches 4 lines ahead.
|
|
||||||
Do alloco 2 lines ahead */
|
|
||||||
|
|
||||||
pta 1f, tr1
|
|
||||||
pta 2f, tr2
|
|
||||||
pta 3f, tr3
|
|
||||||
ptabs r18, tr0
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* TAKum03020 */
|
|
||||||
ld.q r3, 0x00, r63
|
|
||||||
ld.q r3, 0x20, r63
|
|
||||||
ld.q r3, 0x40, r63
|
|
||||||
ld.q r3, 0x60, r63
|
|
||||||
#endif
|
|
||||||
alloco r2, 0x00
|
|
||||||
synco ! TAKum03020
|
|
||||||
alloco r2, 0x20
|
|
||||||
synco ! TAKum03020
|
|
||||||
|
|
||||||
movi 3968, r6
|
|
||||||
add r2, r6, r6
|
|
||||||
addi r6, 64, r7
|
|
||||||
addi r7, 64, r8
|
|
||||||
sub r3, r2, r60
|
|
||||||
addi r60, 8, r61
|
|
||||||
addi r61, 8, r62
|
|
||||||
addi r62, 8, r23
|
|
||||||
addi r60, 0x80, r22
|
|
||||||
|
|
||||||
/* Minimal code size. The extra branches inside the loop don't cost much
|
|
||||||
because they overlap with the time spent waiting for prefetches to
|
|
||||||
complete. */
|
|
||||||
1:
|
|
||||||
#if 0
|
|
||||||
/* TAKum03020 */
|
|
||||||
bge/u r2, r6, tr2 ! skip prefetch for last 4 lines
|
|
||||||
ldx.q r2, r22, r63 ! prefetch 4 lines hence
|
|
||||||
#endif
|
|
||||||
2:
|
|
||||||
bge/u r2, r7, tr3 ! skip alloco for last 2 lines
|
|
||||||
alloco r2, 0x40 ! alloc destination line 2 lines ahead
|
|
||||||
synco ! TAKum03020
|
|
||||||
3:
|
|
||||||
ldx.q r2, r60, r36
|
|
||||||
ldx.q r2, r61, r37
|
|
||||||
ldx.q r2, r62, r38
|
|
||||||
ldx.q r2, r23, r39
|
|
||||||
st.q r2, 0, r36
|
|
||||||
st.q r2, 8, r37
|
|
||||||
st.q r2, 16, r38
|
|
||||||
st.q r2, 24, r39
|
|
||||||
addi r2, 32, r2
|
|
||||||
bgt/l r8, r2, tr1
|
|
||||||
|
|
||||||
blink tr0, r63 ! return
|
|
|
@ -1,218 +0,0 @@
|
||||||
! SPDX-License-Identifier: GPL-2.0
|
|
||||||
!
|
|
||||||
! Fast SH memcpy
|
|
||||||
!
|
|
||||||
! by Toshiyasu Morita (tm@netcom.com)
|
|
||||||
! hacked by J"orn Rernnecke (joern.rennecke@superh.com) ("o for o-umlaut)
|
|
||||||
! SH5 code Copyright 2002 SuperH Ltd.
|
|
||||||
!
|
|
||||||
! Entry: ARG0: destination pointer
|
|
||||||
! ARG1: source pointer
|
|
||||||
! ARG2: byte count
|
|
||||||
!
|
|
||||||
! Exit: RESULT: destination pointer
|
|
||||||
! any other registers in the range r0-r7: trashed
|
|
||||||
!
|
|
||||||
! Notes: Usually one wants to do small reads and write a longword, but
|
|
||||||
! unfortunately it is difficult in some cases to concatanate bytes
|
|
||||||
! into a longword on the SH, so this does a longword read and small
|
|
||||||
! writes.
|
|
||||||
!
|
|
||||||
! This implementation makes two assumptions about how it is called:
|
|
||||||
!
|
|
||||||
! 1.: If the byte count is nonzero, the address of the last byte to be
|
|
||||||
! copied is unsigned greater than the address of the first byte to
|
|
||||||
! be copied. This could be easily swapped for a signed comparison,
|
|
||||||
! but the algorithm used needs some comparison.
|
|
||||||
!
|
|
||||||
! 2.: When there are two or three bytes in the last word of an 11-or-more
|
|
||||||
! bytes memory chunk to b copied, the rest of the word can be read
|
|
||||||
! without side effects.
|
|
||||||
! This could be easily changed by increasing the minimum size of
|
|
||||||
! a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2,
|
|
||||||
! however, this would cost a few extra cyles on average.
|
|
||||||
! For SHmedia, the assumption is that any quadword can be read in its
|
|
||||||
! enirety if at least one byte is included in the copy.
|
|
||||||
|
|
||||||
/* Imported into Linux kernel by Richard Curnow. This is used to implement the
|
|
||||||
__copy_user function in the general case, so it has to be a distinct
|
|
||||||
function from intra-kernel memcpy to allow for exception fix-ups in the
|
|
||||||
event that the user pointer is bad somewhere in the copy (e.g. due to
|
|
||||||
running off the end of the vma).
|
|
||||||
|
|
||||||
Note, this algorithm will be slightly wasteful in the case where the source
|
|
||||||
and destination pointers are equally aligned, because the stlo/sthi pairs
|
|
||||||
could then be merged back into single stores. If there are a lot of cache
|
|
||||||
misses, this is probably offset by the stall lengths on the preloads.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* NOTE : Prefetches removed and allocos guarded by synco to avoid TAKum03020
|
|
||||||
* erratum. The first two prefetches are nop-ed out to avoid upsetting the
|
|
||||||
* instruction counts used in the jump address calculation.
|
|
||||||
* */
|
|
||||||
|
|
||||||
.section .text..SHmedia32,"ax"
|
|
||||||
.little
|
|
||||||
.balign 32
|
|
||||||
.global copy_user_memcpy
|
|
||||||
.global copy_user_memcpy_end
|
|
||||||
copy_user_memcpy:
|
|
||||||
|
|
||||||
#define LDUAQ(P,O,D0,D1) ldlo.q P,O,D0; ldhi.q P,O+7,D1
|
|
||||||
#define STUAQ(P,O,D0,D1) stlo.q P,O,D0; sthi.q P,O+7,D1
|
|
||||||
#define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1
|
|
||||||
#define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1
|
|
||||||
|
|
||||||
nop ! ld.b r3,0,r63 ! TAKum03020
|
|
||||||
pta/l Large,tr0
|
|
||||||
movi 25,r0
|
|
||||||
bgeu/u r4,r0,tr0
|
|
||||||
nsb r4,r0
|
|
||||||
shlli r0,5,r0
|
|
||||||
movi (L1-L0+63*32 + 1) & 0xffff,r1
|
|
||||||
sub r1, r0, r0
|
|
||||||
L0: ptrel r0,tr0
|
|
||||||
add r2,r4,r5
|
|
||||||
ptabs r18,tr1
|
|
||||||
add r3,r4,r6
|
|
||||||
blink tr0,r63
|
|
||||||
|
|
||||||
/* Rearranged to make cut2 safe */
|
|
||||||
.balign 8
|
|
||||||
L4_7: /* 4..7 byte memcpy cntd. */
|
|
||||||
stlo.l r2, 0, r0
|
|
||||||
or r6, r7, r6
|
|
||||||
sthi.l r5, -1, r6
|
|
||||||
stlo.l r5, -4, r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
.balign 8
|
|
||||||
L1: /* 0 byte memcpy */
|
|
||||||
nop
|
|
||||||
blink tr1,r63
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
L2_3: /* 2 or 3 byte memcpy cntd. */
|
|
||||||
st.b r5,-1,r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
/* 1 byte memcpy */
|
|
||||||
ld.b r3,0,r0
|
|
||||||
st.b r2,0,r0
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
L8_15: /* 8..15 byte memcpy cntd. */
|
|
||||||
stlo.q r2, 0, r0
|
|
||||||
or r6, r7, r6
|
|
||||||
sthi.q r5, -1, r6
|
|
||||||
stlo.q r5, -8, r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
/* 2 or 3 byte memcpy */
|
|
||||||
ld.b r3,0,r0
|
|
||||||
nop ! ld.b r2,0,r63 ! TAKum03020
|
|
||||||
ld.b r3,1,r1
|
|
||||||
st.b r2,0,r0
|
|
||||||
pta/l L2_3,tr0
|
|
||||||
ld.b r6,-1,r6
|
|
||||||
st.b r2,1,r1
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
/* 4 .. 7 byte memcpy */
|
|
||||||
LDUAL (r3, 0, r0, r1)
|
|
||||||
pta L4_7, tr0
|
|
||||||
ldlo.l r6, -4, r7
|
|
||||||
or r0, r1, r0
|
|
||||||
sthi.l r2, 3, r0
|
|
||||||
ldhi.l r6, -1, r6
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
/* 8 .. 15 byte memcpy */
|
|
||||||
LDUAQ (r3, 0, r0, r1)
|
|
||||||
pta L8_15, tr0
|
|
||||||
ldlo.q r6, -8, r7
|
|
||||||
or r0, r1, r0
|
|
||||||
sthi.q r2, 7, r0
|
|
||||||
ldhi.q r6, -1, r6
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
/* 16 .. 24 byte memcpy */
|
|
||||||
LDUAQ (r3, 0, r0, r1)
|
|
||||||
LDUAQ (r3, 8, r8, r9)
|
|
||||||
or r0, r1, r0
|
|
||||||
sthi.q r2, 7, r0
|
|
||||||
or r8, r9, r8
|
|
||||||
sthi.q r2, 15, r8
|
|
||||||
ldlo.q r6, -8, r7
|
|
||||||
ldhi.q r6, -1, r6
|
|
||||||
stlo.q r2, 8, r8
|
|
||||||
stlo.q r2, 0, r0
|
|
||||||
or r6, r7, r6
|
|
||||||
sthi.q r5, -1, r6
|
|
||||||
stlo.q r5, -8, r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
Large:
|
|
||||||
! ld.b r2, 0, r63 ! TAKum03020
|
|
||||||
pta/l Loop_ua, tr1
|
|
||||||
ori r3, -8, r7
|
|
||||||
sub r2, r7, r22
|
|
||||||
sub r3, r2, r6
|
|
||||||
add r2, r4, r5
|
|
||||||
ldlo.q r3, 0, r0
|
|
||||||
addi r5, -16, r5
|
|
||||||
movi 64+8, r27 ! could subtract r7 from that.
|
|
||||||
stlo.q r2, 0, r0
|
|
||||||
sthi.q r2, 7, r0
|
|
||||||
ldx.q r22, r6, r0
|
|
||||||
bgtu/l r27, r4, tr1
|
|
||||||
|
|
||||||
addi r5, -48, r27
|
|
||||||
pta/l Loop_line, tr0
|
|
||||||
addi r6, 64, r36
|
|
||||||
addi r6, -24, r19
|
|
||||||
addi r6, -16, r20
|
|
||||||
addi r6, -8, r21
|
|
||||||
|
|
||||||
Loop_line:
|
|
||||||
! ldx.q r22, r36, r63 ! TAKum03020
|
|
||||||
alloco r22, 32
|
|
||||||
synco
|
|
||||||
addi r22, 32, r22
|
|
||||||
ldx.q r22, r19, r23
|
|
||||||
sthi.q r22, -25, r0
|
|
||||||
ldx.q r22, r20, r24
|
|
||||||
ldx.q r22, r21, r25
|
|
||||||
stlo.q r22, -32, r0
|
|
||||||
ldx.q r22, r6, r0
|
|
||||||
sthi.q r22, -17, r23
|
|
||||||
sthi.q r22, -9, r24
|
|
||||||
sthi.q r22, -1, r25
|
|
||||||
stlo.q r22, -24, r23
|
|
||||||
stlo.q r22, -16, r24
|
|
||||||
stlo.q r22, -8, r25
|
|
||||||
bgeu r27, r22, tr0
|
|
||||||
|
|
||||||
Loop_ua:
|
|
||||||
addi r22, 8, r22
|
|
||||||
sthi.q r22, -1, r0
|
|
||||||
stlo.q r22, -8, r0
|
|
||||||
ldx.q r22, r6, r0
|
|
||||||
bgtu/l r5, r22, tr1
|
|
||||||
|
|
||||||
add r3, r4, r7
|
|
||||||
ldlo.q r7, -8, r1
|
|
||||||
sthi.q r22, 7, r0
|
|
||||||
ldhi.q r7, -1, r7
|
|
||||||
ptabs r18,tr1
|
|
||||||
stlo.q r22, 0, r0
|
|
||||||
or r1, r7, r1
|
|
||||||
sthi.q r5, 15, r1
|
|
||||||
stlo.q r5, 8, r1
|
|
||||||
blink tr1, r63
|
|
||||||
copy_user_memcpy_end:
|
|
||||||
nop
|
|
|
@ -1,202 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
|
|
||||||
/* Modified by SuperH, Inc. September 2003 */
|
|
||||||
!
|
|
||||||
! Fast SH memcpy
|
|
||||||
!
|
|
||||||
! by Toshiyasu Morita (tm@netcom.com)
|
|
||||||
! hacked by J"orn Rernnecke (joern.rennecke@superh.com) ("o for o-umlaut)
|
|
||||||
! SH5 code Copyright 2002 SuperH Ltd.
|
|
||||||
!
|
|
||||||
! Entry: ARG0: destination pointer
|
|
||||||
! ARG1: source pointer
|
|
||||||
! ARG2: byte count
|
|
||||||
!
|
|
||||||
! Exit: RESULT: destination pointer
|
|
||||||
! any other registers in the range r0-r7: trashed
|
|
||||||
!
|
|
||||||
! Notes: Usually one wants to do small reads and write a longword, but
|
|
||||||
! unfortunately it is difficult in some cases to concatanate bytes
|
|
||||||
! into a longword on the SH, so this does a longword read and small
|
|
||||||
! writes.
|
|
||||||
!
|
|
||||||
! This implementation makes two assumptions about how it is called:
|
|
||||||
!
|
|
||||||
! 1.: If the byte count is nonzero, the address of the last byte to be
|
|
||||||
! copied is unsigned greater than the address of the first byte to
|
|
||||||
! be copied. This could be easily swapped for a signed comparison,
|
|
||||||
! but the algorithm used needs some comparison.
|
|
||||||
!
|
|
||||||
! 2.: When there are two or three bytes in the last word of an 11-or-more
|
|
||||||
! bytes memory chunk to b copied, the rest of the word can be read
|
|
||||||
! without side effects.
|
|
||||||
! This could be easily changed by increasing the minimum size of
|
|
||||||
! a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2,
|
|
||||||
! however, this would cost a few extra cyles on average.
|
|
||||||
! For SHmedia, the assumption is that any quadword can be read in its
|
|
||||||
! enirety if at least one byte is included in the copy.
|
|
||||||
!
|
|
||||||
|
|
||||||
.section .text..SHmedia32,"ax"
|
|
||||||
.globl memcpy
|
|
||||||
.type memcpy, @function
|
|
||||||
.align 5
|
|
||||||
|
|
||||||
memcpy:
|
|
||||||
|
|
||||||
#define LDUAQ(P,O,D0,D1) ldlo.q P,O,D0; ldhi.q P,O+7,D1
|
|
||||||
#define STUAQ(P,O,D0,D1) stlo.q P,O,D0; sthi.q P,O+7,D1
|
|
||||||
#define LDUAL(P,O,D0,D1) ldlo.l P,O,D0; ldhi.l P,O+3,D1
|
|
||||||
#define STUAL(P,O,D0,D1) stlo.l P,O,D0; sthi.l P,O+3,D1
|
|
||||||
|
|
||||||
ld.b r3,0,r63
|
|
||||||
pta/l Large,tr0
|
|
||||||
movi 25,r0
|
|
||||||
bgeu/u r4,r0,tr0
|
|
||||||
nsb r4,r0
|
|
||||||
shlli r0,5,r0
|
|
||||||
movi (L1-L0+63*32 + 1) & 0xffff,r1
|
|
||||||
sub r1, r0, r0
|
|
||||||
L0: ptrel r0,tr0
|
|
||||||
add r2,r4,r5
|
|
||||||
ptabs r18,tr1
|
|
||||||
add r3,r4,r6
|
|
||||||
blink tr0,r63
|
|
||||||
|
|
||||||
/* Rearranged to make cut2 safe */
|
|
||||||
.balign 8
|
|
||||||
L4_7: /* 4..7 byte memcpy cntd. */
|
|
||||||
stlo.l r2, 0, r0
|
|
||||||
or r6, r7, r6
|
|
||||||
sthi.l r5, -1, r6
|
|
||||||
stlo.l r5, -4, r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
.balign 8
|
|
||||||
L1: /* 0 byte memcpy */
|
|
||||||
nop
|
|
||||||
blink tr1,r63
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
L2_3: /* 2 or 3 byte memcpy cntd. */
|
|
||||||
st.b r5,-1,r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
/* 1 byte memcpy */
|
|
||||||
ld.b r3,0,r0
|
|
||||||
st.b r2,0,r0
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
L8_15: /* 8..15 byte memcpy cntd. */
|
|
||||||
stlo.q r2, 0, r0
|
|
||||||
or r6, r7, r6
|
|
||||||
sthi.q r5, -1, r6
|
|
||||||
stlo.q r5, -8, r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
/* 2 or 3 byte memcpy */
|
|
||||||
ld.b r3,0,r0
|
|
||||||
ld.b r2,0,r63
|
|
||||||
ld.b r3,1,r1
|
|
||||||
st.b r2,0,r0
|
|
||||||
pta/l L2_3,tr0
|
|
||||||
ld.b r6,-1,r6
|
|
||||||
st.b r2,1,r1
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
/* 4 .. 7 byte memcpy */
|
|
||||||
LDUAL (r3, 0, r0, r1)
|
|
||||||
pta L4_7, tr0
|
|
||||||
ldlo.l r6, -4, r7
|
|
||||||
or r0, r1, r0
|
|
||||||
sthi.l r2, 3, r0
|
|
||||||
ldhi.l r6, -1, r6
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
/* 8 .. 15 byte memcpy */
|
|
||||||
LDUAQ (r3, 0, r0, r1)
|
|
||||||
pta L8_15, tr0
|
|
||||||
ldlo.q r6, -8, r7
|
|
||||||
or r0, r1, r0
|
|
||||||
sthi.q r2, 7, r0
|
|
||||||
ldhi.q r6, -1, r6
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
/* 16 .. 24 byte memcpy */
|
|
||||||
LDUAQ (r3, 0, r0, r1)
|
|
||||||
LDUAQ (r3, 8, r8, r9)
|
|
||||||
or r0, r1, r0
|
|
||||||
sthi.q r2, 7, r0
|
|
||||||
or r8, r9, r8
|
|
||||||
sthi.q r2, 15, r8
|
|
||||||
ldlo.q r6, -8, r7
|
|
||||||
ldhi.q r6, -1, r6
|
|
||||||
stlo.q r2, 8, r8
|
|
||||||
stlo.q r2, 0, r0
|
|
||||||
or r6, r7, r6
|
|
||||||
sthi.q r5, -1, r6
|
|
||||||
stlo.q r5, -8, r6
|
|
||||||
blink tr1,r63
|
|
||||||
|
|
||||||
Large:
|
|
||||||
ld.b r2, 0, r63
|
|
||||||
pta/l Loop_ua, tr1
|
|
||||||
ori r3, -8, r7
|
|
||||||
sub r2, r7, r22
|
|
||||||
sub r3, r2, r6
|
|
||||||
add r2, r4, r5
|
|
||||||
ldlo.q r3, 0, r0
|
|
||||||
addi r5, -16, r5
|
|
||||||
movi 64+8, r27 // could subtract r7 from that.
|
|
||||||
stlo.q r2, 0, r0
|
|
||||||
sthi.q r2, 7, r0
|
|
||||||
ldx.q r22, r6, r0
|
|
||||||
bgtu/l r27, r4, tr1
|
|
||||||
|
|
||||||
addi r5, -48, r27
|
|
||||||
pta/l Loop_line, tr0
|
|
||||||
addi r6, 64, r36
|
|
||||||
addi r6, -24, r19
|
|
||||||
addi r6, -16, r20
|
|
||||||
addi r6, -8, r21
|
|
||||||
|
|
||||||
Loop_line:
|
|
||||||
ldx.q r22, r36, r63
|
|
||||||
alloco r22, 32
|
|
||||||
addi r22, 32, r22
|
|
||||||
ldx.q r22, r19, r23
|
|
||||||
sthi.q r22, -25, r0
|
|
||||||
ldx.q r22, r20, r24
|
|
||||||
ldx.q r22, r21, r25
|
|
||||||
stlo.q r22, -32, r0
|
|
||||||
ldx.q r22, r6, r0
|
|
||||||
sthi.q r22, -17, r23
|
|
||||||
sthi.q r22, -9, r24
|
|
||||||
sthi.q r22, -1, r25
|
|
||||||
stlo.q r22, -24, r23
|
|
||||||
stlo.q r22, -16, r24
|
|
||||||
stlo.q r22, -8, r25
|
|
||||||
bgeu r27, r22, tr0
|
|
||||||
|
|
||||||
Loop_ua:
|
|
||||||
addi r22, 8, r22
|
|
||||||
sthi.q r22, -1, r0
|
|
||||||
stlo.q r22, -8, r0
|
|
||||||
ldx.q r22, r6, r0
|
|
||||||
bgtu/l r5, r22, tr1
|
|
||||||
|
|
||||||
add r3, r4, r7
|
|
||||||
ldlo.q r7, -8, r1
|
|
||||||
sthi.q r22, 7, r0
|
|
||||||
ldhi.q r7, -1, r7
|
|
||||||
ptabs r18,tr1
|
|
||||||
stlo.q r22, 0, r0
|
|
||||||
or r1, r7, r1
|
|
||||||
sthi.q r5, 15, r1
|
|
||||||
stlo.q r5, 8, r1
|
|
||||||
blink tr1, r63
|
|
||||||
|
|
||||||
.size memcpy,.-memcpy
|
|
|
@ -1,92 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/* Cloned and hacked for uClibc by Paul Mundt, December 2003 */
|
|
||||||
/* Modified by SuperH, Inc. September 2003 */
|
|
||||||
!
|
|
||||||
! Fast SH memset
|
|
||||||
!
|
|
||||||
! by Toshiyasu Morita (tm@netcom.com)
|
|
||||||
!
|
|
||||||
! SH5 code by J"orn Rennecke (joern.rennecke@superh.com)
|
|
||||||
! Copyright 2002 SuperH Ltd.
|
|
||||||
!
|
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
||||||
#define SHHI shlld
|
|
||||||
#define SHLO shlrd
|
|
||||||
#else
|
|
||||||
#define SHHI shlrd
|
|
||||||
#define SHLO shlld
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.section .text..SHmedia32,"ax"
|
|
||||||
.globl memset
|
|
||||||
.type memset, @function
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
|
|
||||||
memset:
|
|
||||||
pta/l multiquad, tr0
|
|
||||||
andi r2, 7, r22
|
|
||||||
ptabs r18, tr2
|
|
||||||
mshflo.b r3,r3,r3
|
|
||||||
add r4, r22, r23
|
|
||||||
mperm.w r3, r63, r3 // Fill pattern now in every byte of r3
|
|
||||||
|
|
||||||
movi 8, r9
|
|
||||||
bgtu/u r23, r9, tr0 // multiquad
|
|
||||||
|
|
||||||
beqi/u r4, 0, tr2 // Return with size 0 - ensures no mem accesses
|
|
||||||
ldlo.q r2, 0, r7
|
|
||||||
shlli r4, 2, r4
|
|
||||||
movi -1, r8
|
|
||||||
SHHI r8, r4, r8
|
|
||||||
SHHI r8, r4, r8
|
|
||||||
mcmv r7, r8, r3
|
|
||||||
stlo.q r2, 0, r3
|
|
||||||
blink tr2, r63
|
|
||||||
|
|
||||||
multiquad:
|
|
||||||
pta/l lastquad, tr0
|
|
||||||
stlo.q r2, 0, r3
|
|
||||||
shlri r23, 3, r24
|
|
||||||
add r2, r4, r5
|
|
||||||
beqi/u r24, 1, tr0 // lastquad
|
|
||||||
pta/l loop, tr1
|
|
||||||
sub r2, r22, r25
|
|
||||||
andi r5, -8, r20 // calculate end address and
|
|
||||||
addi r20, -7*8, r8 // loop end address; This might overflow, so we need
|
|
||||||
// to use a different test before we start the loop
|
|
||||||
bge/u r24, r9, tr1 // loop
|
|
||||||
st.q r25, 8, r3
|
|
||||||
st.q r20, -8, r3
|
|
||||||
shlri r24, 1, r24
|
|
||||||
beqi/u r24, 1, tr0 // lastquad
|
|
||||||
st.q r25, 16, r3
|
|
||||||
st.q r20, -16, r3
|
|
||||||
beqi/u r24, 2, tr0 // lastquad
|
|
||||||
st.q r25, 24, r3
|
|
||||||
st.q r20, -24, r3
|
|
||||||
lastquad:
|
|
||||||
sthi.q r5, -1, r3
|
|
||||||
blink tr2,r63
|
|
||||||
|
|
||||||
loop:
|
|
||||||
!!! alloco r25, 32 // QQQ comment out for short-term fix to SHUK #3895.
|
|
||||||
// QQQ commenting out is locically correct, but sub-optimal
|
|
||||||
// QQQ Sean McGoogan - 4th April 2003.
|
|
||||||
st.q r25, 8, r3
|
|
||||||
st.q r25, 16, r3
|
|
||||||
st.q r25, 24, r3
|
|
||||||
st.q r25, 32, r3
|
|
||||||
addi r25, 32, r25
|
|
||||||
bgeu/l r8, r25, tr1 // loop
|
|
||||||
|
|
||||||
st.q r20, -40, r3
|
|
||||||
st.q r20, -32, r3
|
|
||||||
st.q r20, -24, r3
|
|
||||||
st.q r20, -16, r3
|
|
||||||
st.q r20, -8, r3
|
|
||||||
sthi.q r5, -1, r3
|
|
||||||
blink tr2,r63
|
|
||||||
|
|
||||||
.size memset,.-memset
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2003 Richard Curnow, SuperH UK Limited
|
|
||||||
*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
panic_handler(unsigned long panicPC, unsigned long panicSSR,
|
|
||||||
unsigned long panicEXPEVT)
|
|
||||||
{
|
|
||||||
/* Never return from the panic handler */
|
|
||||||
for (;;) ;
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
.global __sdivsi3
|
|
||||||
.global __sdivsi3_1
|
|
||||||
.global __sdivsi3_2
|
|
||||||
.section .text..SHmedia32,"ax"
|
|
||||||
.align 2
|
|
||||||
|
|
||||||
/* inputs: r4,r5 */
|
|
||||||
/* clobbered: r1,r18,r19,r20,r21,r25,tr0 */
|
|
||||||
/* result in r0 */
|
|
||||||
__sdivsi3:
|
|
||||||
__sdivsi3_1:
|
|
||||||
ptb __div_table,tr0
|
|
||||||
gettr tr0,r20
|
|
||||||
|
|
||||||
__sdivsi3_2:
|
|
||||||
nsb r5, r1
|
|
||||||
shlld r5, r1, r25 /* normalize; [-2 ..1, 1..2) in s2.62 */
|
|
||||||
shari r25, 58, r21 /* extract 5(6) bit index (s2.4 with hole -1..1) */
|
|
||||||
/* bubble */
|
|
||||||
ldx.ub r20, r21, r19 /* u0.8 */
|
|
||||||
shari r25, 32, r25 /* normalize to s2.30 */
|
|
||||||
shlli r21, 1, r21
|
|
||||||
muls.l r25, r19, r19 /* s2.38 */
|
|
||||||
ldx.w r20, r21, r21 /* s2.14 */
|
|
||||||
ptabs r18, tr0
|
|
||||||
shari r19, 24, r19 /* truncate to s2.14 */
|
|
||||||
sub r21, r19, r19 /* some 11 bit inverse in s1.14 */
|
|
||||||
muls.l r19, r19, r21 /* u0.28 */
|
|
||||||
sub r63, r1, r1
|
|
||||||
addi r1, 92, r1
|
|
||||||
muls.l r25, r21, r18 /* s2.58 */
|
|
||||||
shlli r19, 45, r19 /* multiply by two and convert to s2.58 */
|
|
||||||
/* bubble */
|
|
||||||
sub r19, r18, r18
|
|
||||||
shari r18, 28, r18 /* some 22 bit inverse in s1.30 */
|
|
||||||
muls.l r18, r25, r0 /* s2.60 */
|
|
||||||
muls.l r18, r4, r25 /* s32.30 */
|
|
||||||
/* bubble */
|
|
||||||
shari r0, 16, r19 /* s-16.44 */
|
|
||||||
muls.l r19, r18, r19 /* s-16.74 */
|
|
||||||
shari r25, 63, r0
|
|
||||||
shari r4, 14, r18 /* s19.-14 */
|
|
||||||
shari r19, 30, r19 /* s-16.44 */
|
|
||||||
muls.l r19, r18, r19 /* s15.30 */
|
|
||||||
xor r21, r0, r21 /* You could also use the constant 1 << 27. */
|
|
||||||
add r21, r25, r21
|
|
||||||
sub r21, r19, r21
|
|
||||||
shard r21, r1, r21
|
|
||||||
sub r21, r0, r0
|
|
||||||
blink tr0, r63
|
|
||||||
|
|
||||||
/* This table has been generated by divtab.c .
|
|
||||||
Defects for bias -330:
|
|
||||||
Max defect: 6.081536e-07 at -1.000000e+00
|
|
||||||
Min defect: 2.849516e-08 at 1.030651e+00
|
|
||||||
Max 2nd step defect: 9.606539e-12 at -1.000000e+00
|
|
||||||
Min 2nd step defect: 0.000000e+00 at 0.000000e+00
|
|
||||||
Defect at 1: 1.238659e-07
|
|
||||||
Defect at -2: 1.061708e-07 */
|
|
||||||
|
|
||||||
.balign 2
|
|
||||||
.type __div_table,@object
|
|
||||||
.size __div_table,128
|
|
||||||
/* negative division constants */
|
|
||||||
.word -16638
|
|
||||||
.word -17135
|
|
||||||
.word -17737
|
|
||||||
.word -18433
|
|
||||||
.word -19103
|
|
||||||
.word -19751
|
|
||||||
.word -20583
|
|
||||||
.word -21383
|
|
||||||
.word -22343
|
|
||||||
.word -23353
|
|
||||||
.word -24407
|
|
||||||
.word -25582
|
|
||||||
.word -26863
|
|
||||||
.word -28382
|
|
||||||
.word -29965
|
|
||||||
.word -31800
|
|
||||||
/* negative division factors */
|
|
||||||
.byte 66
|
|
||||||
.byte 70
|
|
||||||
.byte 75
|
|
||||||
.byte 81
|
|
||||||
.byte 87
|
|
||||||
.byte 93
|
|
||||||
.byte 101
|
|
||||||
.byte 109
|
|
||||||
.byte 119
|
|
||||||
.byte 130
|
|
||||||
.byte 142
|
|
||||||
.byte 156
|
|
||||||
.byte 172
|
|
||||||
.byte 192
|
|
||||||
.byte 214
|
|
||||||
.byte 241
|
|
||||||
.skip 16
|
|
||||||
.global __div_table
|
|
||||||
__div_table:
|
|
||||||
.skip 16
|
|
||||||
/* positive division factors */
|
|
||||||
.byte 241
|
|
||||||
.byte 214
|
|
||||||
.byte 192
|
|
||||||
.byte 172
|
|
||||||
.byte 156
|
|
||||||
.byte 142
|
|
||||||
.byte 130
|
|
||||||
.byte 119
|
|
||||||
.byte 109
|
|
||||||
.byte 101
|
|
||||||
.byte 93
|
|
||||||
.byte 87
|
|
||||||
.byte 81
|
|
||||||
.byte 75
|
|
||||||
.byte 70
|
|
||||||
.byte 66
|
|
||||||
/* positive division constants */
|
|
||||||
.word 31801
|
|
||||||
.word 29966
|
|
||||||
.word 28383
|
|
||||||
.word 26864
|
|
||||||
.word 25583
|
|
||||||
.word 24408
|
|
||||||
.word 23354
|
|
||||||
.word 22344
|
|
||||||
.word 21384
|
|
||||||
.word 20584
|
|
||||||
.word 19752
|
|
||||||
.word 19104
|
|
||||||
.word 18434
|
|
||||||
.word 17738
|
|
||||||
.word 17136
|
|
||||||
.word 16639
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче