summaryrefslogtreecommitdiffstats
path: root/arch/sh/boot
diff options
context:
space:
mode:
authorJinke Han <jinkehan@didiglobal.com>2026-09-08 15:37:42 +0800
committerIngo Molnar <mingo@kernel.org>2026-09-17 09:48:42 +0200
commita5f7a5bb3b7f28ba7e4fa246775b29a0e5537255 (patch)
tree73fef824f9a846cf935869d0dbc5070ef6e2f741 /arch/sh/boot
downloadlinux-stable-a5f7a5bb3b7f28ba7e4fa246775b29a0e5537255.tar.gz
linux-stable-a5f7a5bb3b7f28ba7e4fa246775b29a0e5537255.zip
x86/kprobes: Fix crash when probing CS CALL instructionsgrafted
When using eBPF to probe CS CALL instructions within a function, a crash can be triggered. The eBPF tool probes offset 257 of the __hrtimer_run_queues() function: <__hrtimer_run_queues+249>: nopl 0x0(%rax,%rax,1) <__hrtimer_run_queues+254>: mov %r14,%rdi <__hrtimer_run_queues+257>: cs call <__x86_indirect_thunk_r12> <__hrtimer_run_queues+263>: mov %eax,%r12d <__hrtimer_run_queues+266>: xchg %ax,%ax <__hrtimer_run_queues+268>: mov %r13,%rdi Which triggers this crash: BUG: unable to handle page fault for address: 00000000000f41c9 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 0 P4D 0 Oops: 0002 [#1] SMP NOPTI CPU: 1 PID: 0 Comm: swapper/1 Kdump: loaded Tainted: P RIP: 0010:__hrtimer_run_queues+0x106/0x230 Note that __hrtimer_run_queues+0x106 is __hrtimer_run_queues+262, which is at the 6th byte of the above CS CALL instruction. Since the CS CALL instruction occupies 6 bytes, the exception occurred in the middle of that call instruction. The root cause is that when using eBPF tools to probe in the middle of a function, a kprobe with INT3 is used as the underlying implementation. During single-step emulation of the original CALL instruction, int3_emulate_call() assumes that the probed CALL instruction is 5 bytes long. However, the actual CS-prefixed CALL instruction occupies 6 bytes, so it constructs an incorrect exception return address. When the CPU returns from the kprobe handler, the next instruction to be executed is at the address of the last byte of that CS CALL instruction. Coincidentally, starting from that address, the CPU fetches and decodes a completely different instruction, which ultimately triggers a kernel crash. Fix the issue by using the actual instruction length obtained from the instruction decoder when constructing the exception return address, rather than relying on the hardcoded CALL_INSN_SIZE macro. [ mingo: Refined the changelog ] Fixes: 6256e668b7af ("x86/kprobes: Use int3 instead of debug trap for single-step") Suggested-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Jinke Han <jinkehan@didiglobal.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Acked-by: Yafang Shao <laoar.shao@gmail.com> Acked-by: Borislav Petkov <bp@alien8.de> Cc: Peter Zijlstra <peterz@infradead.org> Link: https://patch.msgid.link/20260908073742.GA10517@didi-ThinkCentre-M920t-N000
Diffstat (limited to 'arch/sh/boot')
-rw-r--r--arch/sh/boot/.gitignore5
-rw-r--r--arch/sh/boot/Makefile115
-rw-r--r--arch/sh/boot/compressed/.gitignore2
-rw-r--r--arch/sh/boot/compressed/Makefile57
-rw-r--r--arch/sh/boot/compressed/ashiftrt.S2
-rw-r--r--arch/sh/boot/compressed/ashldi3.c2
-rw-r--r--arch/sh/boot/compressed/ashlsi3.S2
-rw-r--r--arch/sh/boot/compressed/ashrsi3.S2
-rw-r--r--arch/sh/boot/compressed/head_32.S126
-rw-r--r--arch/sh/boot/compressed/head_64.S159
-rw-r--r--arch/sh/boot/compressed/lshrsi3.S2
-rw-r--r--arch/sh/boot/compressed/misc.c141
-rw-r--r--arch/sh/boot/compressed/misc.h9
-rw-r--r--arch/sh/boot/compressed/vmlinux.scr10
-rw-r--r--arch/sh/boot/dts/Makefile2
-rw-r--r--arch/sh/boot/dts/j2_mimas_v2.dts97
-rw-r--r--arch/sh/boot/romimage/Makefile30
-rw-r--r--arch/sh/boot/romimage/head.S85
-rw-r--r--arch/sh/boot/romimage/mmcif-sh7724.c78
-rw-r--r--arch/sh/boot/romimage/vmlinux.scr8
20 files changed, 934 insertions, 0 deletions
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
new file mode 100644
index 000000000..6603bbbc9
--- /dev/null
+++ b/arch/sh/boot/.gitignore
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+zImage
+vmlinux*
+uImage*
+!vmlinux.scr
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
new file mode 100644
index 000000000..1f5d2df3c
--- /dev/null
+++ b/arch/sh/boot/Makefile
@@ -0,0 +1,115 @@
+#
+# arch/sh/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1999 Stuart Menefy
+#
+
+#
+# Assign safe dummy values if these variables are not defined,
+# in order to suppress error message.
+#
+CONFIG_PAGE_OFFSET ?= 0x80000000
+CONFIG_MEMORY_START ?= 0x0c000000
+CONFIG_BOOT_LINK_OFFSET ?= 0x00800000
+CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000
+CONFIG_ENTRY_OFFSET ?= 0x00001000
+CONFIG_PHYSICAL_START ?= $(CONFIG_MEMORY_START)
+
+suffix_y := bin
+suffix_$(CONFIG_KERNEL_GZIP) := gz
+suffix_$(CONFIG_KERNEL_BZIP2) := bz2
+suffix_$(CONFIG_KERNEL_LZMA) := lzma
+suffix_$(CONFIG_KERNEL_XZ) := xz
+suffix_$(CONFIG_KERNEL_LZO) := lzo
+
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
+ uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin \
+ vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
+ vmlinux.bin.xz vmlinux.bin.lzo
+subdir- := compressed romimage
+
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
+$(obj)/romImage: $(obj)/romimage/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
+
+$(obj)/romimage/vmlinux: $(obj)/zImage FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/romimage $@
+
+KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_PHYSICAL_START) & 0x1fffffff]')
+
+KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_PAGE_OFFSET) + \
+ $(KERNEL_MEMORY) + \
+ $(CONFIG_ZERO_PAGE_OFFSET)]')
+
+KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_PAGE_OFFSET) + \
+ $(KERNEL_MEMORY) + \
+ $(CONFIG_ZERO_PAGE_OFFSET) + $(CONFIG_ENTRY_OFFSET)]')
+
+UIMAGE_LOADADDR = $(KERNEL_LOAD)
+UIMAGE_ENTRYADDR = $(KERNEL_ENTRY)
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,bzip2)
+
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzma)
+
+$(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,xzkern)
+
+$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzo)
+
+$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2 FORCE
+ $(call if_changed,uimage,bzip2)
+
+$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
+ $(call if_changed,uimage,gzip)
+
+$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE
+ $(call if_changed,uimage,lzma)
+
+$(obj)/uImage.xz: $(obj)/vmlinux.bin.xz FORCE
+ $(call if_changed,uimage,xz)
+
+$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo FORCE
+ $(call if_changed,uimage,lzo)
+
+$(obj)/uImage.bin: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,uimage,none)
+
+OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
+$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+
+OBJCOPYFLAGS_uImage.srec := -I binary -O srec
+$(obj)/uImage.srec: $(obj)/uImage FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/uImage: $(obj)/uImage.$(suffix_y)
+ @ln -sf $(notdir $<) $@
+ @echo ' Image $@ is ready'
+
+export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
+ CONFIG_PHYSICAL_START CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET \
+ KERNEL_MEMORY suffix_y
diff --git a/arch/sh/boot/compressed/.gitignore b/arch/sh/boot/compressed/.gitignore
new file mode 100644
index 000000000..cd16663bc
--- /dev/null
+++ b/arch/sh/boot/compressed/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+vmlinux.bin.*
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
new file mode 100644
index 000000000..58df49177
--- /dev/null
+++ b/arch/sh/boot/compressed/Makefile
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+OBJECTS := head_32.o misc.o piggy.o \
+ ashiftrt.o ashldi3.o ashrsi3.o ashlsi3.o lshrsi3.o
+
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
+ vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo $(OBJECTS)
+
+#
+# IMAGE_OFFSET is the load offset of the compression loader
+#
+ifeq ($(CONFIG_32BIT),y)
+IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_MEMORY_START) + \
+ $(CONFIG_BOOT_LINK_OFFSET)]')
+else
+IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_PAGE_OFFSET) + \
+ $(KERNEL_MEMORY) + \
+ $(CONFIG_BOOT_LINK_OFFSET)]')
+endif
+
+ccflags-remove-$(CONFIG_MCOUNT) += -pg
+
+LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(IMAGE_OFFSET) -e startup \
+ -T $(obj)/../../kernel/vmlinux.lds
+
+KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
+
+$(obj)/vmlinux: $(addprefix $(obj)/, $(OBJECTS)) FORCE
+ $(call if_changed,ld)
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,bzip2_with_size)
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzma_with_size)
+$(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,xzkern_with_size)
+$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzo_with_size)
+
+OBJCOPYFLAGS += -R .empty_zero_page
+
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE
+ $(call if_changed,ld)
diff --git a/arch/sh/boot/compressed/ashiftrt.S b/arch/sh/boot/compressed/ashiftrt.S
new file mode 100644
index 000000000..0f3b291a3
--- /dev/null
+++ b/arch/sh/boot/compressed/ashiftrt.S
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include "../../lib/ashiftrt.S"
diff --git a/arch/sh/boot/compressed/ashldi3.c b/arch/sh/boot/compressed/ashldi3.c
new file mode 100644
index 000000000..7c1212170
--- /dev/null
+++ b/arch/sh/boot/compressed/ashldi3.c
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "../../../../lib/ashldi3.c"
diff --git a/arch/sh/boot/compressed/ashlsi3.S b/arch/sh/boot/compressed/ashlsi3.S
new file mode 100644
index 000000000..e354262b2
--- /dev/null
+++ b/arch/sh/boot/compressed/ashlsi3.S
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include "../../lib/ashlsi3.S"
diff --git a/arch/sh/boot/compressed/ashrsi3.S b/arch/sh/boot/compressed/ashrsi3.S
new file mode 100644
index 000000000..e564be9a4
--- /dev/null
+++ b/arch/sh/boot/compressed/ashrsi3.S
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include "../../lib/ashrsi3.S"
diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
new file mode 100644
index 000000000..7bb168133
--- /dev/null
+++ b/arch/sh/boot/compressed/head_32.S
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * linux/arch/sh/boot/compressed/head.S
+ *
+ * Copyright (C) 1999 Stuart Menefy
+ * Copyright (C) 2003 SUGIOKA Toshinobu
+ */
+
+.text
+
+#include <asm/page.h>
+
+ .global startup
+startup:
+ /* Load initial status register */
+ mov.l init_sr, r1
+ ldc r1, sr
+
+ /* Move myself to proper location if necessary */
+ mova 1f, r0
+ mov.l 1f, r2
+ cmp/eq r2, r0
+ bt clear_bss
+ sub r0, r2
+ mov.l bss_start_addr, r0
+ mov #0xffffffe0, r1
+ and r1, r0 ! align cache line
+ mov.l text_start_addr, r3
+ mov r0, r1
+ sub r2, r1
+3:
+ mov.l @r1, r4
+ mov.l @(4,r1), r5
+ mov.l @(8,r1), r6
+ mov.l @(12,r1), r7
+ mov.l @(16,r1), r8
+ mov.l @(20,r1), r9
+ mov.l @(24,r1), r10
+ mov.l @(28,r1), r11
+ mov.l r4, @r0
+ mov.l r5, @(4,r0)
+ mov.l r6, @(8,r0)
+ mov.l r7, @(12,r0)
+ mov.l r8, @(16,r0)
+ mov.l r9, @(20,r0)
+ mov.l r10, @(24,r0)
+ mov.l r11, @(28,r0)
+#ifdef CONFIG_CPU_SH4
+ ocbwb @r0
+#endif
+ cmp/hi r3, r0
+ add #-32, r0
+ bt/s 3b
+ add #-32, r1
+ mov.l 2f, r0
+ jmp @r0
+ nop
+
+ .align 2
+1: .long 1b
+2: .long clear_bss
+text_start_addr:
+ .long startup
+
+ /* Clear BSS */
+clear_bss:
+ mov.l end_addr, r1
+ mov.l bss_start_addr, r2
+ mov #0, r0
+l1:
+ mov.l r0, @-r1
+ cmp/eq r1,r2
+ bf l1
+
+ /* Set the initial pointer. */
+ mov.l init_stack_addr, r0
+ mov.l @r0, r15
+
+ /* Decompress the kernel */
+ mov.l decompress_kernel_addr, r0
+ jsr @r0
+ nop
+
+ /* Jump to the start of the decompressed kernel */
+ mov.l kernel_start_addr, r0
+ jmp @r0
+ nop
+
+ .align 2
+bss_start_addr:
+ .long __bss_start
+end_addr:
+ .long _end
+init_sr:
+ .long 0x500000F0 /* Privileged mode, Bank=0, Block=1, IMASK=0xF */
+kexec_magic:
+ .long 0x400000F0 /* magic used by kexec to parse zImage format */
+init_stack_addr:
+ .long stack_start
+decompress_kernel_addr:
+ .long decompress_kernel
+kernel_start_addr:
+#ifdef CONFIG_32BIT
+ .long ___pa(_text+PAGE_SIZE)
+#else
+ .long _text+PAGE_SIZE
+#endif
+
+ .align 9
+fake_headers_as_bzImage:
+ .word 0
+ .ascii "HdrS" ! header signature
+ .word 0x0202 ! header version number (>= 0x0105)
+ ! or else old loadlin-1.5 will fail)
+ .word 0 ! default_switch
+ .word 0 ! SETUPSEG
+ .word 0x1000
+ .word 0 ! pointing to kernel version string
+ .byte 0 ! = 0, old one (LILO, Loadlin,
+ ! 0xTV: T=0 for LILO
+ ! V = version
+ .byte 1 ! Load flags bzImage=1
+ .word 0x8000 ! size to move, when setup is not
+ .long 0x100000 ! 0x100000 = default for big kernel
+ .long 0 ! address of loaded ramdisk image
+ .long 0 # its size in bytes
diff --git a/arch/sh/boot/compressed/head_64.S b/arch/sh/boot/compressed/head_64.S
new file mode 100644
index 000000000..9993113c6
--- /dev/null
+++ b/arch/sh/boot/compressed/head_64.S
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ *
+ * arch/shmedia/boot/compressed/head.S
+ *
+ * Copied from
+ * arch/shmedia/kernel/head.S
+ * which carried the copyright:
+ * Copyright (C) 2000, 2001 Paolo Alberelli
+ *
+ * Modification for compressed loader:
+ * Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com)
+ */
+#include <asm/cache.h>
+#include <asm/tlb.h>
+#include <cpu/mmu_context.h>
+#include <cpu/registers.h>
+
+/*
+ * Fixed TLB entries to identity map the beginning of RAM
+ */
+#define MMUIR_TEXT_H 0x0000000000000003 | CONFIG_MEMORY_START
+ /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUIR_TEXT_L 0x000000000000009a | CONFIG_MEMORY_START
+ /* 512 Mb, Cacheable (Write-back), execute, Not User, Ph. Add. */
+
+#define MMUDR_CACHED_H 0x0000000000000003 | CONFIG_MEMORY_START
+ /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUDR_CACHED_L 0x000000000000015a | CONFIG_MEMORY_START
+ /* 512 Mb, Cacheable (Write-back), read/write, Not User, Ph. Add. */
+
+#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */
+#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */
+
+#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* OCE + OCI + WB */
+#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */
+
+ .text
+
+ .global startup
+startup:
+ /*
+ * Prevent speculative fetch on device memory due to
+ * uninitialized target registers.
+ * This must be executed before the first branch.
+ */
+ ptabs/u r63, tr0
+ ptabs/u r63, tr1
+ ptabs/u r63, tr2
+ ptabs/u r63, tr3
+ ptabs/u r63, tr4
+ ptabs/u r63, tr5
+ ptabs/u r63, tr6
+ ptabs/u r63, tr7
+ synci
+
+ /*
+ * Set initial TLB entries for cached and uncached regions.
+ * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't !
+ */
+ /* Clear ITLBs */
+ pta 1f, tr1
+ movi ITLB_FIXED, r21
+ movi ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
+1: putcfg r21, 0, r63 /* Clear MMUIR[n].PTEH.V */
+ addi r21, TLB_STEP, r21
+ bne r21, r22, tr1
+
+ /* Clear DTLBs */
+ pta 1f, tr1
+ movi DTLB_FIXED, r21
+ movi DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
+1: putcfg r21, 0, r63 /* Clear MMUDR[n].PTEH.V */
+ addi r21, TLB_STEP, r21
+ bne r21, r22, tr1
+
+ /* Map one big (512Mb) page for ITLB */
+ movi ITLB_FIXED, r21
+ movi MMUIR_TEXT_L, r22 /* PTEL first */
+ putcfg r21, 1, r22 /* Set MMUIR[0].PTEL */
+ movi MMUIR_TEXT_H, r22 /* PTEH last */
+ putcfg r21, 0, r22 /* Set MMUIR[0].PTEH */
+
+ /* Map one big CACHED (512Mb) page for DTLB */
+ movi DTLB_FIXED, r21
+ movi MMUDR_CACHED_L, r22 /* PTEL first */
+ putcfg r21, 1, r22 /* Set MMUDR[0].PTEL */
+ movi MMUDR_CACHED_H, r22 /* PTEH last */
+ putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */
+
+ /* 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
+ synci
+
+ /* 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
+ synco
+
+ /*
+ * Enable the MMU.
+ * From here-on code can be non-PIC.
+ */
+ movi SR_HARMLESS | SR_ENABLE_MMU, r22
+ putcon r22, SSR
+ movi 1f, r22
+ putcon r22, SPC
+ synco
+ rte /* And now go into the hyperspace ... */
+1: /* ... that's the next instruction ! */
+
+ /* Set initial stack pointer */
+ movi datalabel stack_start, r0
+ ld.l r0, 0, r15
+
+ /*
+ * Clear bss
+ */
+ pt 1f, tr1
+ movi datalabel __bss_start, r22
+ movi datalabel _end, r23
+1: st.l r22, 0, r63
+ addi r22, 4, r22
+ bne r22, r23, tr1
+
+ /*
+ * Decompress the kernel.
+ */
+ pt decompress_kernel, tr0
+ blink tr0, r18
+
+ /*
+ * Disable the MMU.
+ */
+ movi SR_HARMLESS, r22
+ putcon r22, SSR
+ movi 1f, r22
+ putcon r22, SPC
+ synco
+ rte /* And now go into the hyperspace ... */
+1: /* ... that's the next instruction ! */
+
+ /* Jump into the decompressed kernel */
+ movi datalabel (CONFIG_MEMORY_START + 0x2000)+1, r19
+ ptabs r19, tr0
+ blink tr0, r18
+
+ /* Shouldn't return here, but just in case, loop forever */
+ pt 1f, tr0
+1: blink tr0, r63
diff --git a/arch/sh/boot/compressed/lshrsi3.S b/arch/sh/boot/compressed/lshrsi3.S
new file mode 100644
index 000000000..5a8281b7e
--- /dev/null
+++ b/arch/sh/boot/compressed/lshrsi3.S
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include "../../lib/lshrsi3.S"
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
new file mode 100644
index 000000000..3690379cc
--- /dev/null
+++ b/arch/sh/boot/compressed/misc.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ */
+
+#include <linux/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+#include "misc.h"
+
+/*
+ * gzip declarations
+ */
+
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset ((s), 0, (n))
+
+extern char input_data[];
+extern int input_len;
+static unsigned char *output;
+
+static void error(char *m);
+
+int puts(const char *);
+
+extern int _text; /* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#ifdef CONFIG_HAVE_KERNEL_BZIP2
+#define HEAP_SIZE 0x400000
+#else
+#define HEAP_SIZE 0x10000
+#endif
+
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+#ifdef CONFIG_KERNEL_XZ
+#include "../../../../lib/decompress_unxz.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+int puts(const char *s)
+{
+ /* This should be updated to use the sh-sci routines */
+ return 0;
+}
+
+void* memset(void* s, int c, size_t n)
+{
+ int i;
+ char *ss = (char*)s;
+
+ for (i=0;i<n;i++) ss[i] = c;
+ return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+ size_t __n)
+{
+ int i;
+ char *d = (char *)__dest, *s = (char *)__src;
+
+ for (i=0;i<__n;i++) d[i] = s[i];
+ return __dest;
+}
+
+static void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+const unsigned long __stack_chk_guard = 0x000a0dff;
+
+void __stack_chk_fail(void)
+{
+ error("stack-protector: Kernel stack is corrupted\n");
+}
+
+/* Needed because vmlinux.lds.h references this */
+void ftrace_stub(void)
+{
+}
+void arch_ftrace_ops_list_func(void)
+{
+}
+
+#define stackalign 4
+
+#define STACK_SIZE (4096)
+long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+ unsigned long output_addr;
+
+ output_addr = __pa((unsigned long)&_text+PAGE_SIZE);
+#if defined(CONFIG_29BIT)
+ output_addr |= P2SEG;
+#endif
+
+ output = (unsigned char *)output_addr;
+ free_mem_ptr = (unsigned long)&_end;
+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+ puts("Uncompressing Linux... ");
+ __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
+ puts("Ok, booting the kernel.\n");
+}
diff --git a/arch/sh/boot/compressed/misc.h b/arch/sh/boot/compressed/misc.h
new file mode 100644
index 000000000..2b4534faa
--- /dev/null
+++ b/arch/sh/boot/compressed/misc.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef MISC_H
+#define MISC_H
+
+void arch_ftrace_ops_list_func(void);
+void decompress_kernel(void);
+void ftrace_stub(void);
+
+#endif /* MISC_H */
diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr
new file mode 100644
index 000000000..dd292b4b9
--- /dev/null
+++ b/arch/sh/boot/compressed/vmlinux.scr
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ .rodata..compressed : ALIGN(8) {
+ input_len = .;
+ LONG(input_data_end - input_data) input_data = .;
+ *(.data)
+ output_len = . - 4;
+ input_data_end = .;
+ }
+}
diff --git a/arch/sh/boot/dts/Makefile b/arch/sh/boot/dts/Makefile
new file mode 100644
index 000000000..d109978a5
--- /dev/null
+++ b/arch/sh/boot/dts/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .dtb.o, $(CONFIG_BUILTIN_DTB_NAME))
diff --git a/arch/sh/boot/dts/j2_mimas_v2.dts b/arch/sh/boot/dts/j2_mimas_v2.dts
new file mode 100644
index 000000000..faf884f53
--- /dev/null
+++ b/arch/sh/boot/dts/j2_mimas_v2.dts
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+/ {
+ compatible = "jcore,j2-soc";
+ model = "J2 FPGA SoC on Mimas v2 board";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&aic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "jcore,j2";
+ reg = <0>;
+ clock-frequency = <50000000>;
+ d-cache-size = <8192>;
+ i-cache-size = <8192>;
+ d-cache-block-size = <16>;
+ i-cache-block-size = <16>;
+ };
+ };
+
+ memory@10000000 {
+ device_type = "memory";
+ reg = <0x10000000 0x4000000>;
+ };
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &spi0;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ soc@abcd0000 {
+ compatible = "simple-bus";
+ ranges = <0 0xabcd0000 0x100000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aic: interrupt-controller@200 {
+ compatible = "jcore,aic1";
+ reg = <0x200 0x10>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ cache-controller@c0 {
+ compatible = "jcore,cache";
+ reg = <0xc0 4>;
+ };
+
+ timer@200 {
+ compatible = "jcore,pit";
+ reg = <0x200 0x30>;
+ interrupts = <0x48>;
+ };
+
+ spi0: spi@40 {
+ compatible = "jcore,spi2";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <0x40 0x8>;
+
+ sdcard@0 {
+ compatible = "mmc-spi-slot";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+ voltage-ranges = <3200 3400>;
+ mode = <0>;
+ };
+ };
+
+ uart0: serial@100 {
+ clock-frequency = <125000000>;
+ compatible = "xlnx,xps-uartlite-1.00.a";
+ current-speed = <19200>;
+ xlnx,use-parity = <0>;
+ xlnx,data-bits = <8>;
+ device_type = "serial";
+ interrupts = <0x12>;
+ port-number = <0>;
+ reg = <0x100 0x10>;
+ };
+ };
+};
diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile
new file mode 100644
index 000000000..17b03df0a
--- /dev/null
+++ b/arch/sh/boot/romimage/Makefile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# linux/arch/sh/boot/romimage/Makefile
+#
+# create an romImage file suitable for burning to flash/mmc from zImage
+#
+
+targets := vmlinux head.o zeropage.bin piggy.o
+load-y := 0
+
+mmcif-load-$(CONFIG_CPU_SUBTYPE_SH7724) := 0xe5200000 # ILRAM
+mmcif-obj-$(CONFIG_CPU_SUBTYPE_SH7724) := $(obj)/mmcif-sh7724.o
+load-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-load-y)
+obj-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-obj-y)
+
+LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(load-y) -e romstart \
+ -T $(obj)/../../kernel/vmlinux.lds
+
+$(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE
+ $(call if_changed,ld)
+
+OBJCOPYFLAGS += -j .empty_zero_page
+
+$(obj)/zeropage.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE
+ $(call if_changed,ld)
diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S
new file mode 100644
index 000000000..81a0652a3
--- /dev/null
+++ b/arch/sh/boot/romimage/head.S
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * linux/arch/sh/boot/romimage/head.S
+ *
+ * Board specific setup code, executed before zImage loader
+ */
+
+.text
+ #include <asm/page.h>
+
+ .global romstart
+romstart:
+ /* include board specific setup code */
+#include <mach/romimage.h>
+
+#ifdef CONFIG_ROMIMAGE_MMCIF
+ /* load the romImage to above the empty zero page */
+ mov.l empty_zero_page_dst, r4
+ mov.l empty_zero_page_dst_adj, r5
+ add r5, r4
+ mov.l bytes_to_load, r5
+ mov.l loader_function, r7
+ jsr @r7
+ mov r4, r15
+
+ mov.l empty_zero_page_dst, r4
+ mov.l empty_zero_page_dst_adj, r5
+ add r5, r4
+ mov.l loaded_code_offs, r5
+ add r5, r4
+ jmp @r4
+ nop
+
+ .balign 4
+empty_zero_page_dst_adj:
+ .long PAGE_SIZE
+bytes_to_load:
+ .long end_data - romstart
+loader_function:
+ .long mmcif_loader
+loaded_code_offs:
+ .long loaded_code - romstart
+loaded_code:
+#endif /* CONFIG_ROMIMAGE_MMCIF */
+
+ /* copy the empty_zero_page contents to where vmlinux expects it */
+ mova extra_data_pos, r0
+ mov.l extra_data_size, r1
+ add r1, r0
+ mov.l empty_zero_page_dst, r1
+ mov #(PAGE_SHIFT - 4), r4
+ mov #1, r3
+ shld r4, r3 /* r3 = PAGE_SIZE / 16 */
+
+1:
+ mov.l @r0, r4
+ mov.l @(4, r0), r5
+ mov.l @(8, r0), r6
+ mov.l @(12, r0), r7
+ add #16,r0
+ mov.l r4, @r1
+ mov.l r5, @(4, r1)
+ mov.l r6, @(8, r1)
+ mov.l r7, @(12, r1)
+ dt r3
+ add #16,r1
+ bf 1b
+
+ /* jump to the zImage entry point located after the zero page data */
+ mov #PAGE_SHIFT, r4
+ mov #1, r1
+ shld r4, r1
+ mova extra_data_pos, r0
+ add r1, r0
+ mov.l extra_data_size, r1
+ add r1, r0
+ jmp @r0
+ nop
+
+ .align 2
+empty_zero_page_dst:
+ .long _text
+extra_data_pos:
+extra_data_size:
+ .long zero_page_pos - extra_data_pos
diff --git a/arch/sh/boot/romimage/mmcif-sh7724.c b/arch/sh/boot/romimage/mmcif-sh7724.c
new file mode 100644
index 000000000..d30123d85
--- /dev/null
+++ b/arch/sh/boot/romimage/mmcif-sh7724.c
@@ -0,0 +1,78 @@
+/*
+ * sh7724 MMCIF loader
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * 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.
+ */
+
+#include <linux/platform_data/sh_mmcif.h>
+#include <mach/romimage.h>
+
+#define MMCIF_BASE (void __iomem *)0xa4ca0000
+
+#define MSTPCR2 0xa4150038
+#define PTWCR 0xa4050146
+#define PTXCR 0xa4050148
+#define PSELA 0xa405014e
+#define PSELE 0xa4050156
+#define HIZCRC 0xa405015c
+#define DRVCRA 0xa405018a
+
+enum {
+ MMCIF_PROGRESS_ENTER,
+ MMCIF_PROGRESS_INIT,
+ MMCIF_PROGRESS_LOAD,
+ MMCIF_PROGRESS_DONE
+};
+
+/* SH7724 specific MMCIF loader
+ *
+ * loads the romImage from an MMC card starting from block 512
+ * use the following line to write the romImage to an MMC card
+ * # dd if=arch/sh/boot/romImage of=/dev/sdx bs=512 seek=512
+ */
+asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes)
+{
+ mmcif_update_progress(MMCIF_PROGRESS_ENTER);
+
+ /* enable clock to the MMCIF hardware block */
+ __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2);
+
+ /* setup pins D7-D0 */
+ __raw_writew(0x0000, PTWCR);
+
+ /* setup pins MMC_CLK, MMC_CMD */
+ __raw_writew(__raw_readw(PTXCR) & ~0x000f, PTXCR);
+
+ /* select D3-D0 pin function */
+ __raw_writew(__raw_readw(PSELA) & ~0x2000, PSELA);
+
+ /* select D7-D4 pin function */
+ __raw_writew(__raw_readw(PSELE) & ~0x3000, PSELE);
+
+ /* disable Hi-Z for the MMC pins */
+ __raw_writew(__raw_readw(HIZCRC) & ~0x0620, HIZCRC);
+
+ /* high drive capability for MMC pins */
+ __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA);
+
+ mmcif_update_progress(MMCIF_PROGRESS_INIT);
+
+ /* setup MMCIF hardware */
+ sh_mmcif_boot_init(MMCIF_BASE);
+
+ mmcif_update_progress(MMCIF_PROGRESS_LOAD);
+
+ /* load kernel via MMCIF interface */
+ sh_mmcif_boot_do_read(MMCIF_BASE, 512,
+ (no_bytes + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS,
+ buf);
+
+ /* disable clock to the MMCIF hardware block */
+ __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2);
+
+ mmcif_update_progress(MMCIF_PROGRESS_DONE);
+}
diff --git a/arch/sh/boot/romimage/vmlinux.scr b/arch/sh/boot/romimage/vmlinux.scr
new file mode 100644
index 000000000..590394e2f
--- /dev/null
+++ b/arch/sh/boot/romimage/vmlinux.scr
@@ -0,0 +1,8 @@
+SECTIONS
+{
+ .text : {
+ zero_page_pos = .;
+ *(.data)
+ end_data = .;
+ }
+}