summaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/Kconfig20
-rw-r--r--arch/riscv/Kconfig.socs13
-rw-r--r--arch/riscv/Makefile17
-rw-r--r--arch/riscv/boot/dts/Makefile2
-rw-r--r--arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi2
-rw-r--r--arch/riscv/boot/dts/anlogic/Makefile2
-rw-r--r--arch/riscv/boot/dts/anlogic/dr1v90-mlkpai-fs01.dts28
-rw-r--r--arch/riscv/boot/dts/anlogic/dr1v90.dtsi100
-rw-r--r--arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts96
-rw-r--r--arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts10
-rw-r--r--arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts5
-rw-r--r--arch/riscv/boot/dts/sophgo/cv180x.dtsi42
-rw-r--r--arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts5
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts5
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts36
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts24
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts36
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042.dtsi112
-rw-r--r--arch/riscv/boot/dts/spacemit/Makefile2
-rw-r--r--arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts172
-rw-r--r--arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts79
-rw-r--r--arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts90
-rw-r--r--arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts52
-rw-r--r--arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi465
-rw-r--r--arch/riscv/boot/dts/spacemit/k1.dtsi122
-rw-r--r--arch/riscv/boot/dts/starfive/Makefile3
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-common.dtsi19
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts27
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts27
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts9
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts1
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi13
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-orangepi-rv.dts76
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts27
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite-emmc.dts22
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dts20
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi161
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi24
-rw-r--r--arch/riscv/boot/dts/tenstorrent/Makefile2
-rw-r--r--arch/riscv/boot/dts/tenstorrent/blackhole-card.dts14
-rw-r--r--arch/riscv/boot/dts/tenstorrent/blackhole.dtsi108
-rw-r--r--arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts67
-rw-r--r--arch/riscv/boot/dts/thead/th1520.dtsi72
-rw-r--r--arch/riscv/configs/defconfig3
-rw-r--r--arch/riscv/include/asm/arch_hweight.h24
-rw-r--r--arch/riscv/include/asm/asm.h6
-rw-r--r--arch/riscv/include/asm/bitops.h32
-rw-r--r--arch/riscv/include/asm/bug.h10
-rw-r--r--arch/riscv/include/asm/checksum.h13
-rw-r--r--arch/riscv/include/asm/cmpxchg.h12
-rw-r--r--arch/riscv/include/asm/hwcap.h2
-rw-r--r--arch/riscv/include/asm/hwprobe.h2
-rw-r--r--arch/riscv/include/asm/insn-def.h87
-rw-r--r--arch/riscv/include/asm/kvm_host.h6
-rw-r--r--arch/riscv/include/asm/kvm_tlb.h1
-rw-r--r--arch/riscv/include/asm/kvm_vcpu_sbi.h5
-rw-r--r--arch/riscv/include/asm/kvm_vmid.h1
-rw-r--r--arch/riscv/include/asm/pgtable-bits.h37
-rw-r--r--arch/riscv/include/asm/pgtable.h158
-rw-r--r--arch/riscv/include/asm/uaccess.h8
-rw-r--r--arch/riscv/include/asm/vector.h1
-rw-r--r--arch/riscv/include/asm/vendor_extensions/mips.h6
-rw-r--r--arch/riscv/include/asm/vendorid_list.h2
-rw-r--r--arch/riscv/include/uapi/asm/hwprobe.h3
-rw-r--r--arch/riscv/include/uapi/asm/kvm.h3
-rw-r--r--arch/riscv/kernel/cpufeature.c2
-rw-r--r--arch/riscv/kernel/kgdb.c4
-rw-r--r--arch/riscv/kernel/module-sections.c8
-rw-r--r--arch/riscv/kernel/ptrace.c24
-rw-r--r--arch/riscv/kernel/sbi.c6
-rw-r--r--arch/riscv/kernel/smpboot.c15
-rw-r--r--arch/riscv/kernel/stacktrace.c21
-rw-r--r--arch/riscv/kernel/sys_hwprobe.c7
-rw-r--r--arch/riscv/kernel/tests/Kconfig.debug2
-rw-r--r--arch/riscv/kernel/tests/kprobes/Makefile4
-rw-r--r--arch/riscv/kernel/tests/kprobes/test-kprobes.c5
-rw-r--r--arch/riscv/kernel/vector.c2
-rw-r--r--arch/riscv/kvm/Kconfig1
-rw-r--r--arch/riscv/kvm/Makefile1
-rw-r--r--arch/riscv/kvm/aia_imsic.c18
-rw-r--r--arch/riscv/kvm/main.c14
-rw-r--r--arch/riscv/kvm/mmu.c30
-rw-r--r--arch/riscv/kvm/tlb.c30
-rw-r--r--arch/riscv/kvm/vcpu.c8
-rw-r--r--arch/riscv/kvm/vcpu_insn.c22
-rw-r--r--arch/riscv/kvm/vcpu_sbi.c10
-rw-r--r--arch/riscv/kvm/vcpu_sbi_base.c28
-rw-r--r--arch/riscv/kvm/vcpu_sbi_forward.c34
-rw-r--r--arch/riscv/kvm/vcpu_sbi_replace.c32
-rw-r--r--arch/riscv/kvm/vcpu_sbi_system.c4
-rw-r--r--arch/riscv/kvm/vcpu_sbi_v01.c3
-rw-r--r--arch/riscv/kvm/vmid.c23
-rw-r--r--arch/riscv/lib/csum.c53
-rw-r--r--arch/riscv/mm/init.c4
-rw-r--r--arch/riscv/mm/pgtable.c22
-rw-r--r--arch/riscv/mm/ptdump.c2
-rw-r--r--arch/riscv/net/bpf_jit_comp64.c11
97 files changed, 2773 insertions, 328 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 22cda9c452d2..6b39f37f769a 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -142,11 +142,13 @@ config RISCV
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP_FILTER
+ select HAVE_ARCH_SOFT_DIRTY if 64BIT && MMU && RISCV_ISA_SVRSW60T59B
select HAVE_ARCH_THREAD_STRUCT_WHITELIST
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU
select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if 64BIT && MMU
select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD
+ select HAVE_ARCH_USERFAULTFD_WP if 64BIT && MMU && USERFAULTFD && RISCV_ISA_SVRSW60T59B
select HAVE_ARCH_VMAP_STACK if MMU && 64BIT
select HAVE_ASM_MODVERSIONS
select HAVE_CONTEXT_TRACKING_USER
@@ -198,7 +200,7 @@ config RISCV
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS
- select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
+ select HOTPLUG_PARALLEL if HOTPLUG_CPU
select IRQ_DOMAIN
select IRQ_FORCED_THREADING
select KASAN_VMALLOC if KASAN
@@ -367,7 +369,7 @@ config RISCV_NONSTANDARD_CACHE_OPS
systems to handle cache management.
config AS_HAS_INSN
- def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
+ def_bool $(as-instr,.insn 0x100000f)
config AS_HAS_OPTION_ARCH
# https://github.com/llvm/llvm-project/commit/9e8ed3403c191ab9c4903e8eeb8f732ff8a43cb4
@@ -849,6 +851,20 @@ config RISCV_ISA_ZICBOP
If you don't know what to do here, say Y.
+config RISCV_ISA_SVRSW60T59B
+ bool "Svrsw60t59b extension support for using PTE bits 60 and 59"
+ depends on MMU && 64BIT
+ depends on RISCV_ALTERNATIVE
+ default y
+ help
+ Adds support to dynamically detect the presence of the Svrsw60t59b
+ extension and enable its usage.
+
+ The Svrsw60t59b extension allows to free the PTE reserved bits 60
+ and 59 for software to use.
+
+ If you don't know what to do here, say Y.
+
config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI
def_bool y
# https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 848e7149e443..d621b85dd63b 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -7,6 +7,11 @@ config ARCH_ANDES
help
This enables support for Andes SoC platform hardware.
+config ARCH_ANLOGIC
+ bool "Anlogic SoCs"
+ help
+ This enables support for Anlogic SoC platform hardware.
+
config ARCH_ESWIN
bool "ESWIN SoCs"
help
@@ -63,6 +68,14 @@ config ARCH_SUNXI
This enables support for Allwinner sun20i platform hardware,
including boards based on the D1 and D1s SoCs.
+config ARCH_TENSTORRENT
+ bool "Tenstorrent SoCs"
+ help
+ This enables support for Tenstorrent SoC platforms.
+ Current support is for Blackhole P100 and P150 PCIe cards.
+ The Blackhole SoC contains four RISC-V CPU tiles each
+ consisting of 4x SiFive X280 cores.
+
config ARCH_THEAD
bool "T-HEAD RISC-V SoCs"
depends on MMU && !XIP_KERNEL
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index ecf2fcce2d92..4c6de57f65ef 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -134,21 +134,6 @@ endif
CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS)
# Default target when executing plain make
-boot := arch/riscv/boot
-ifeq ($(CONFIG_XIP_KERNEL),y)
-KBUILD_IMAGE := $(boot)/xipImage
-else
-ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN_K210),yy)
-KBUILD_IMAGE := $(boot)/loader.bin
-else
-ifeq ($(CONFIG_EFI_ZBOOT),)
-KBUILD_IMAGE := $(boot)/Image.gz
-else
-KBUILD_IMAGE := $(boot)/vmlinuz.efi
-endif
-endif
-endif
-
boot := arch/riscv/boot
boot-image-y := Image
boot-image-$(CONFIG_KERNEL_BZIP2) := Image.bz2
@@ -159,7 +144,7 @@ boot-image-$(CONFIG_KERNEL_LZO) := Image.lzo
boot-image-$(CONFIG_KERNEL_ZSTD) := Image.zst
boot-image-$(CONFIG_KERNEL_XZ) := Image.xz
ifdef CONFIG_RISCV_M_MODE
-boot-image-$(CONFIG_ARCH_CANAAN) := loader.bin
+boot-image-$(CONFIG_SOC_CANAAN_K210) := loader.bin
endif
boot-image-$(CONFIG_EFI_ZBOOT) := vmlinuz.efi
boot-image-$(CONFIG_XIP_KERNEL) := xipImage
diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index 3763d199c70a..69d8751fb17c 100644
--- a/arch/riscv/boot/dts/Makefile
+++ b/arch/riscv/boot/dts/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
subdir-y += allwinner
subdir-y += andes
+subdir-y += anlogic
subdir-y += canaan
subdir-y += eswin
subdir-y += microchip
@@ -9,4 +10,5 @@ subdir-y += sifive
subdir-y += sophgo
subdir-y += spacemit
subdir-y += starfive
+subdir-y += tenstorrent
subdir-y += thead
diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
index 6367112e614a..a7442a508433 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
@@ -28,7 +28,7 @@
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
"zifencei", "zihpm", "xtheadvector";
- thead,vlenb = <128>;
+ thead,vlenb = <16>;
#cooling-cells = <2>;
cpu0_intc: interrupt-controller {
diff --git a/arch/riscv/boot/dts/anlogic/Makefile b/arch/riscv/boot/dts/anlogic/Makefile
new file mode 100644
index 000000000000..87f3b2f418cf
--- /dev/null
+++ b/arch/riscv/boot/dts/anlogic/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_ANLOGIC) += dr1v90-mlkpai-fs01.dtb
diff --git a/arch/riscv/boot/dts/anlogic/dr1v90-mlkpai-fs01.dts b/arch/riscv/boot/dts/anlogic/dr1v90-mlkpai-fs01.dts
new file mode 100644
index 000000000000..597407655efd
--- /dev/null
+++ b/arch/riscv/boot/dts/anlogic/dr1v90-mlkpai-fs01.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2025 Junhui Liu <junhui.liu@pigmoral.tech>
+ */
+
+#include "dr1v90.dtsi"
+
+/ {
+ model = "Milianke MLKPAI-FS01";
+ compatible = "milianke,mlkpai-fs01", "anlogic,dr1v90";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x20000000>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/anlogic/dr1v90.dtsi b/arch/riscv/boot/dts/anlogic/dr1v90.dtsi
new file mode 100644
index 000000000000..a5d0765ade32
--- /dev/null
+++ b/arch/riscv/boot/dts/anlogic/dr1v90.dtsi
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2025 Junhui Liu <junhui.liu@pigmoral.tech>
+ */
+
+/dts-v1/;
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ model = "Anlogic DR1V90";
+ compatible = "anlogic,dr1v90";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <800000000>;
+
+ cpu@0 {
+ compatible = "nuclei,ux900", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ device_type = "cpu";
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ reg = <0>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb", "zbc",
+ "zbkc", "zbs", "zicntr", "zicsr", "zifencei",
+ "zihintpause", "zihpm";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ aclint_mswi: interrupt-controller@68031000 {
+ compatible = "anlogic,dr1v90-aclint-mswi", "nuclei,ux900-aclint-mswi";
+ reg = <0x0 0x68031000 0x0 0x4000>;
+ interrupts-extended = <&cpu0_intc 3>;
+ };
+
+ aclint_mtimer: timer@68035000 {
+ compatible = "anlogic,dr1v90-aclint-mtimer", "nuclei,ux900-aclint-mtimer";
+ reg = <0x0 0x68035000 0x0 0x8000>;
+ reg-names = "mtimecmp";
+ interrupts-extended = <&cpu0_intc 7>;
+ };
+
+ aclint_sswi: interrupt-controller@6803d000 {
+ compatible = "anlogic,dr1v90-aclint-sswi", "nuclei,ux900-aclint-sswi";
+ reg = <0x0 0x6803d000 0x0 0x3000>;
+ #interrupt-cells = <0>;
+ interrupt-controller;
+ interrupts-extended = <&cpu0_intc 1>;
+ };
+
+ plic: interrupt-controller@6c000000 {
+ compatible = "anlogic,dr1v90-plic", "sifive,plic-1.0.0";
+ reg = <0x0 0x6c000000 0x0 0x4000000>;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
+ riscv,ndev = <150>;
+ };
+
+ uart0: serial@f8400000 {
+ compatible = "anlogic,dr1v90-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xf8400000 0x0 0x1000>;
+ clock-frequency = <50000000>;
+ interrupts = <71>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+
+ uart1: serial@f8401000 {
+ compatible = "anlogic,dr1v90-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xf8401000 0x0 0x1000>;
+ clock-frequency = <50000000>;
+ interrupts = <72>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
index 55e30f3636df..f44ad8e6f4e4 100644
--- a/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
+++ b/arch/riscv/boot/dts/microchip/mpfs-beaglev-fire.dts
@@ -79,6 +79,26 @@
};
+&gpio0 {
+ interrupts = <13>, <14>, <15>, <16>,
+ <17>, <18>, <19>, <20>,
+ <21>, <22>, <23>, <24>,
+ <25>, <26>;
+ ngpios = <14>;
+ status = "okay";
+};
+
+&gpio1 {
+ interrupts = <27>, <28>, <29>, <30>,
+ <31>, <32>, <33>, <34>,
+ <35>, <36>, <37>, <38>,
+ <39>, <40>, <41>, <42>,
+ <43>, <44>, <45>, <46>,
+ <47>, <48>, <49>, <50>;
+ ngpios = <24>;
+ status = "okay";
+};
+
&gpio2 {
interrupts = <53>, <53>, <53>, <53>,
<53>, <53>, <53>, <53>,
@@ -199,6 +219,82 @@
status = "okay";
};
+&qspi {
+ status = "okay";
+ cs-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>, <&gpio0 12 GPIO_ACTIVE_LOW>;
+ num-cs = <2>;
+
+ adc@0 {
+ compatible = "microchip,mcp3464r";
+ reg = <0>; /* CE0 */
+ spi-cpol;
+ spi-cpha;
+ spi-max-frequency = <5000000>;
+ microchip,hw-device-address = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ channel@0 {
+ /* CH0 to AGND */
+ reg = <0>;
+ label = "CH0";
+ };
+
+ channel@1 {
+ /* CH1 to AGND */
+ reg = <1>;
+ label = "CH1";
+ };
+
+ channel@2 {
+ /* CH2 to AGND */
+ reg = <2>;
+ label = "CH2";
+ };
+
+ channel@3 {
+ /* CH3 to AGND */
+ reg = <3>;
+ label = "CH3";
+ };
+
+ channel@4 {
+ /* CH4 to AGND */
+ reg = <4>;
+ label = "CH4";
+ };
+
+ channel@5 {
+ /* CH5 to AGND */
+ reg = <5>;
+ label = "CH5";
+ };
+
+ channel@6 {
+ /* CH6 to AGND */
+ reg = <6>;
+ label = "CH6";
+ };
+
+ channel@7 {
+ /* CH7 is connected to AGND */
+ reg = <7>;
+ label = "CH7";
+ };
+ };
+
+ mmc@1 {
+ compatible = "mmc-spi-slot";
+ reg = <1>;
+ gpios = <&gpio2 31 1>;
+ voltage-ranges = <3300 3300>;
+ spi-max-frequency = <5000000>;
+ disable-wp;
+ };
+};
+
+
&syscontroller {
microchip,bitstream-flash = <&sys_ctrl_flash>;
status = "okay";
diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
index 03ce2cee4e97..850fa1d25be7 100644
--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
@@ -47,6 +47,16 @@
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
+ fan1 {
+ compatible = "pwm-fan";
+ pwms = <&pwm1 2 7812500 0>;
+ };
+
+ fan2 {
+ compatible = "pwm-fan";
+ pwms = <&pwm1 3 7812500 0>;
+ };
+
led-controller-1 {
compatible = "pwm-leds";
diff --git a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
index 9feb520eaec4..0e6d79e6e3a4 100644
--- a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
+++ b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
@@ -100,3 +100,8 @@
pinctrl-names = "default";
status = "okay";
};
+
+&usb {
+ dr_mode = "host";
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/sophgo/cv180x.dtsi b/arch/riscv/boot/dts/sophgo/cv180x.dtsi
index ccdb45498653..1b2b1969a648 100644
--- a/arch/riscv/boot/dts/sophgo/cv180x.dtsi
+++ b/arch/riscv/boot/dts/sophgo/cv180x.dtsi
@@ -25,6 +25,32 @@
#size-cells = <1>;
ranges;
+ syscon: syscon@3000000 {
+ compatible = "sophgo,cv1800b-top-syscon",
+ "syscon", "simple-mfd";
+ reg = <0x03000000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ usbphy: phy@48 {
+ compatible = "sophgo,cv1800b-usb2-phy";
+ reg = <0x48 0x4>;
+ #phy-cells = <0>;
+ clocks = <&clk CLK_USB_125M>,
+ <&clk CLK_USB_33K>,
+ <&clk CLK_USB_12M>;
+ clock-names = "app", "stb", "lpm";
+ resets = <&rst RST_COMBO_PHY0>;
+ };
+
+ dmamux: dma-router@154 {
+ compatible = "sophgo,cv1800b-dmamux";
+ reg = <0x154 0x8>, <0x298 0x4>;
+ #dma-cells = <2>;
+ dma-masters = <&dmac>;
+ };
+ };
+
rst: reset-controller@3003000 {
compatible = "sophgo,cv1800b-reset";
reg = <0x3003000 0x1000>;
@@ -406,6 +432,22 @@
status = "disabled";
};
+ usb: usb@4340000 {
+ compatible = "sophgo,cv1800b-usb";
+ reg = <0x04340000 0x10000>;
+ clocks = <&clk CLK_AXI4_USB>, <&clk CLK_APB_USB>;
+ clock-names = "otg", "utmi";
+ g-np-tx-fifo-size = <32>;
+ g-rx-fifo-size = <536>;
+ g-tx-fifo-size = <768 512 512 384 128 128>;
+ interrupts = <SOC_PERIPHERAL_IRQ(14) IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&usbphy>;
+ phy-names = "usb2-phy";
+ resets = <&rst RST_USB>;
+ reset-names = "dwc2";
+ status = "disabled";
+ };
+
rtc@5025000 {
compatible = "sophgo,cv1800b-rtc", "syscon";
reg = <0x5025000 0x2000>;
diff --git a/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts b/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts
index 4a5835fa9e96..aedf79f47407 100644
--- a/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts
+++ b/arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts
@@ -86,3 +86,8 @@
&uart0 {
status = "okay";
};
+
+&usb {
+ dr_mode = "host";
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts b/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts
index 86a712b953a5..b1853770d017 100644
--- a/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts
@@ -93,3 +93,8 @@
pinctrl-names = "default";
status = "okay";
};
+
+&usb {
+ dr_mode = "host";
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts
index 3320bc1dd2c6..b116dfa904cd 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts
@@ -164,6 +164,18 @@
};
};
+&pcie_rc0 {
+ status = "okay";
+};
+
+&pcie_rc1 {
+ status = "okay";
+};
+
+&pcie_rc2 {
+ status = "okay";
+};
+
&pinctrl {
emmc_cfg: sdhci-emmc-cfg {
sdhci-emmc-wp-pins {
@@ -238,6 +250,30 @@
status = "okay";
};
+&spifmc0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
+&spifmc1 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
&uart0 {
pinctrl-0 = <&uart0_cfg>;
pinctrl-names = "default";
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts
index 46980e41b886..b2ceae2d8829 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts
@@ -152,6 +152,18 @@
};
};
+&pcie_rc0 {
+ status = "okay";
+};
+
+&pcie_rc1 {
+ status = "okay";
+};
+
+&pcie_rc2 {
+ status = "okay";
+};
+
&pinctrl {
emmc_cfg: sdhci-emmc-cfg {
sdhci-emmc-wp-pins {
@@ -226,6 +238,18 @@
status = "okay";
};
+&spifmc1 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
&uart0 {
pinctrl-0 = <&uart0_cfg>;
pinctrl-names = "default";
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
index ef3a602172b1..54d8386bf9c0 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
@@ -128,6 +128,18 @@
};
};
+&pcie_rc0 {
+ status = "okay";
+};
+
+&pcie_rc2 {
+ status = "okay";
+};
+
+&pcie_rc3 {
+ status = "okay";
+};
+
&sd {
pinctrl-0 = <&sd_cfg>;
pinctrl-names = "default";
@@ -138,6 +150,30 @@
status = "okay";
};
+&spifmc0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
+&spifmc1 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
&uart0 {
pinctrl-0 = <&uart0_cfg>;
pinctrl-names = "default";
diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
index c5e49709b308..ec99da39150f 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi
+++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
@@ -68,6 +68,30 @@
interrupt-parent = <&intc>;
ranges;
+ spifmc0: spi@7000180000 {
+ compatible = "sophgo,sg2042-spifmc-nor";
+ reg = <0x70 0x00180000 0x0 0x1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkgen GATE_CLK_AHB_SF>;
+ interrupt-parent = <&intc>;
+ interrupts = <108 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&rstgen RST_SF0>;
+ status = "disabled";
+ };
+
+ spifmc1: spi@7002180000 {
+ compatible = "sophgo,sg2042-spifmc-nor";
+ reg = <0x70 0x02180000 0x0 0x1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkgen GATE_CLK_AHB_SF>;
+ interrupt-parent = <&intc>;
+ interrupts = <109 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&rstgen RST_SF1>;
+ status = "disabled";
+ };
+
i2c0: i2c@7030005000 {
compatible = "snps,designware-i2c";
reg = <0x70 0x30005000 0x0 0x1000>;
@@ -240,6 +264,94 @@
#clock-cells = <1>;
};
+ pcie_rc0: pcie@7060000000 {
+ compatible = "sophgo,sg2042-pcie-host";
+ device_type = "pci";
+ reg = <0x70 0x60000000 0x0 0x00800000>,
+ <0x40 0x00000000 0x0 0x00001000>;
+ reg-names = "reg", "cfg";
+ linux,pci-domain = <0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0x0 0x00000000 0x40 0xc0000000 0x0 0x00400000>,
+ <0x42000000 0x0 0xd0000000 0x40 0xd0000000 0x0 0x10000000>,
+ <0x02000000 0x0 0xe0000000 0x40 0xe0000000 0x0 0x20000000>,
+ <0x43000000 0x42 0x00000000 0x42 0x00000000 0x2 0x00000000>,
+ <0x03000000 0x41 0x00000000 0x41 0x00000000 0x1 0x00000000>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x1f1c>;
+ device-id = <0x2042>;
+ cdns,no-bar-match-nbits = <48>;
+ msi-parent = <&msi>;
+ status = "disabled";
+ };
+
+ pcie_rc1: pcie@7060800000 {
+ compatible = "sophgo,sg2042-pcie-host";
+ device_type = "pci";
+ reg = <0x70 0x60800000 0x0 0x00800000>,
+ <0x44 0x00000000 0x0 0x00001000>;
+ reg-names = "reg", "cfg";
+ linux,pci-domain = <1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0x0 0x00000000 0x44 0xc0400000 0x0 0x00400000>,
+ <0x42000000 0x0 0xd0000000 0x44 0xd0000000 0x0 0x10000000>,
+ <0x02000000 0x0 0xe0000000 0x44 0xe0000000 0x0 0x20000000>,
+ <0x43000000 0x46 0x00000000 0x46 0x00000000 0x2 0x00000000>,
+ <0x03000000 0x45 0x00000000 0x45 0x00000000 0x1 0x00000000>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x1f1c>;
+ device-id = <0x2042>;
+ cdns,no-bar-match-nbits = <48>;
+ msi-parent = <&msi>;
+ status = "disabled";
+ };
+
+ pcie_rc2: pcie@7062000000 {
+ compatible = "sophgo,sg2042-pcie-host";
+ device_type = "pci";
+ reg = <0x70 0x62000000 0x0 0x00800000>,
+ <0x48 0x00000000 0x0 0x00001000>;
+ reg-names = "reg", "cfg";
+ linux,pci-domain = <2>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0x0 0x00000000 0x48 0xc0800000 0x0 0x00400000>,
+ <0x42000000 0x0 0xd0000000 0x48 0xd0000000 0x0 0x10000000>,
+ <0x02000000 0x0 0xe0000000 0x48 0xe0000000 0x0 0x20000000>,
+ <0x03000000 0x49 0x00000000 0x49 0x00000000 0x1 0x00000000>,
+ <0x43000000 0x4a 0x00000000 0x4a 0x00000000 0x2 0x00000000>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x1f1c>;
+ device-id = <0x2042>;
+ cdns,no-bar-match-nbits = <48>;
+ msi-parent = <&msi>;
+ status = "disabled";
+ };
+
+ pcie_rc3: pcie@7062800000 {
+ compatible = "sophgo,sg2042-pcie-host";
+ device_type = "pci";
+ reg = <0x70 0x62800000 0x0 0x00800000>,
+ <0x4c 0x00000000 0x0 0x00001000>;
+ reg-names = "reg", "cfg";
+ linux,pci-domain = <3>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0x0 0x00000000 0x4c 0xc0c00000 0x0 0x00400000>,
+ <0x42000000 0x0 0xf8000000 0x4c 0xf8000000 0x0 0x04000000>,
+ <0x02000000 0x0 0xfc000000 0x4c 0xfc000000 0x0 0x04000000>,
+ <0x43000000 0x4e 0x00000000 0x4e 0x00000000 0x2 0x00000000>,
+ <0x03000000 0x4d 0x00000000 0x4d 0x00000000 0x1 0x00000000>;
+ bus-range = <0x0 0xff>;
+ vendor-id = <0x1f1c>;
+ device-id = <0x2042>;
+ cdns,no-bar-match-nbits = <48>;
+ msi-parent = <&msi>;
+ status = "disabled";
+ };
+
clint_mswi: interrupt-controller@7094000000 {
compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi";
reg = <0x00000070 0x94000000 0x00000000 0x00004000>;
diff --git a/arch/riscv/boot/dts/spacemit/Makefile b/arch/riscv/boot/dts/spacemit/Makefile
index 152832644870..95889e7269d1 100644
--- a/arch/riscv/boot/dts/spacemit/Makefile
+++ b/arch/riscv/boot/dts/spacemit/Makefile
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_SPACEMIT) += k1-bananapi-f3.dtb
dtb-$(CONFIG_ARCH_SPACEMIT) += k1-milkv-jupiter.dtb
+dtb-$(CONFIG_ARCH_SPACEMIT) += k1-musepi-pro.dtb
+dtb-$(CONFIG_ARCH_SPACEMIT) += k1-orangepi-r2s.dtb
dtb-$(CONFIG_ARCH_SPACEMIT) += k1-orangepi-rv2.dtb
diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index 2aaaff77831e..02f218a16318 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -14,6 +14,8 @@
ethernet0 = &eth0;
ethernet1 = &eth1;
serial0 = &uart0;
+ i2c2 = &i2c2;
+ i2c8 = &i2c8;
};
chosen {
@@ -30,6 +32,25 @@
default-state = "on";
};
};
+
+ reg_dc_in: dc-in-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_in_12v";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_vcc_4v: vcc-4v {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_4v";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ vin-supply = <&reg_dc_in>;
+ };
};
&emmc {
@@ -92,6 +113,157 @@
status = "okay";
};
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_cfg>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_0_cfg>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ vcc-supply = <&buck3_1v8>; /* EEPROM_VCC1V8 */
+ pagesize = <16>;
+ read-only;
+ size = <256>;
+
+ nvmem-layout {
+ compatible = "onie,tlv-layout";
+
+ mac-address {
+ #nvmem-cell-cells = <1>;
+ };
+
+ num-macs {
+ };
+
+ serial-number {
+ };
+ };
+ };
+};
+
+&i2c8 {
+ pinctrl-0 = <&i2c8_cfg>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ pmic@41 {
+ compatible = "spacemit,p1";
+ reg = <0x41>;
+ interrupts = <64>;
+ vin-supply = <&reg_vcc_4v>;
+
+ regulators {
+ buck1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ buck2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ buck3_1v8: buck3 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ buck4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ buck5 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ buck6 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-ramp-delay = <5000>;
+ regulator-always-on;
+ };
+
+ aldo1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ };
+
+ aldo2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ aldo3 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ aldo4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ dldo1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ };
+
+ dldo2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ dldo3 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ dldo4 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-always-on;
+ };
+
+ dldo5 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ };
+
+ dldo6 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-always-on;
+ };
+
+ dldo7 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3400000>;
+ };
+ };
+ };
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_2_cfg>;
diff --git a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts
new file mode 100644
index 000000000000..29e333b670cf
--- /dev/null
+++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name>
+ * Copyright (C) 2025 SpacemiT, Inc
+ * Copyright (C) 2025 Troy Mitchell <troy.mitchell@linux.spacemit.com>
+ */
+
+/dts-v1/;
+
+#include "k1.dtsi"
+#include "k1-pinctrl.dtsi"
+
+/ {
+ model = "SpacemiT MusePi Pro";
+ compatible = "spacemit,musepi-pro", "spacemit,k1";
+
+ aliases {
+ ethernet0 = &eth0;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led1 {
+ label = "sys-led";
+ gpios = <&gpio K1_GPIO(96) GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+ };
+};
+
+&emmc {
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ non-removable;
+ no-sd;
+ no-sdio;
+ status = "okay";
+};
+
+&eth0 {
+ phy-handle = <&rgmii0>;
+ phy-mode = "rgmii-id";
+ pinctrl-0 = <&gmac0_cfg>;
+ pinctrl-names = "default";
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+ status = "okay";
+
+ mdio-bus {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <100000>;
+
+ rgmii0: phy@1 {
+ reg = <0x1>;
+ };
+ };
+};
+
+&pdma {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-0 = <&uart0_2_cfg>;
+ pinctrl-names = "default";
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts
new file mode 100644
index 000000000000..58098c4a2aab
--- /dev/null
+++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker@rootcommit.com>
+ */
+
+/dts-v1/;
+
+#include "k1.dtsi"
+#include "k1-pinctrl.dtsi"
+
+/ {
+ model = "OrangePi R2S";
+ compatible = "xunlong,orangepi-r2s", "spacemit,k1";
+
+ aliases {
+ serial0 = &uart0;
+ ethernet0 = &eth0;
+ ethernet1 = &eth1;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+};
+
+&emmc {
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ non-removable;
+ no-sd;
+ no-sdio;
+ status = "okay";
+};
+
+&eth0 {
+ phy-handle = <&rgmii0>;
+ phy-mode = "rgmii-id";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_cfg>;
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+ status = "okay";
+
+ mdio-bus {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <100000>;
+
+ rgmii0: phy@1 {
+ reg = <0x1>;
+ };
+ };
+};
+
+&eth1 {
+ phy-handle = <&rgmii1>;
+ phy-mode = "rgmii-id";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1_cfg>;
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <250>;
+ status = "okay";
+
+ mdio-bus {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ reset-gpios = <&gpio K1_GPIO(115) GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <100000>;
+
+ rgmii1: phy@1 {
+ reg = <0x1>;
+ };
+ };
+};
+
+&pdma {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_2_cfg>;
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
index 337240ebb7b7..41dc8e35e6eb 100644
--- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
@@ -15,6 +15,8 @@
aliases {
serial0 = &uart0;
+ ethernet0 = &eth0;
+ ethernet1 = &eth1;
};
chosen {
@@ -33,6 +35,56 @@
};
};
+&eth0 {
+ phy-handle = <&rgmii0>;
+ phy-mode = "rgmii-id";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_cfg>;
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+ status = "okay";
+
+ mdio-bus {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ reset-gpios = <&gpio K1_GPIO(110) GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <100000>;
+
+ rgmii0: phy@1 {
+ reg = <0x1>;
+ };
+ };
+};
+
+&eth1 {
+ phy-handle = <&rgmii1>;
+ phy-mode = "rgmii-id";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1_cfg>;
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <250>;
+ status = "okay";
+
+ mdio-bus {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ reset-gpios = <&gpio K1_GPIO(115) GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <100000>;
+
+ rgmii1: phy@1 {
+ reg = <0x1>;
+ };
+ };
+};
+
+&pdma {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_2_cfg>;
diff --git a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
index aff19c86d5ff..e922e05ff856 100644
--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
@@ -59,11 +59,472 @@
};
};
+ i2c2_0_cfg: i2c2-0-cfg {
+ i2c2-0-pins {
+ pinmux = <K1_PADCONF(84, 4)>, /* I2C2_SCL */
+ <K1_PADCONF(85, 4)>; /* I2C2_SDA */
+ };
+ };
+
+ i2c8_cfg: i2c8-cfg {
+ i2c8-0-pins {
+ pinmux = <K1_PADCONF(93, 0)>, /* PWR_SCL */
+ <K1_PADCONF(94, 0)>; /* PWR_SDA */
+ };
+ };
+
+ qspi_cfg: qspi-cfg {
+ qspi-pins {
+ pinmux = <K1_PADCONF(98, 0)>, /* QSPI_DATA3 */
+ <K1_PADCONF(99, 0)>, /* QSPI_DATA2 */
+ <K1_PADCONF(100, 0)>, /* QSPI_DATA1 */
+ <K1_PADCONF(101, 0)>, /* QSPI_DATA0 */
+ <K1_PADCONF(102, 0)>; /* QSPI_CLK */
+
+ bias-disable;
+ drive-strength = <19>;
+ power-source = <3300>;
+ };
+
+ qspi-cs1-pins {
+ pinmux = <K1_PADCONF(103, 0)>; /* QSPI_CS1 */
+ bias-pull-up = <0>;
+ drive-strength = <19>;
+ power-source = <3300>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart0_0_cfg: uart0-0-cfg {
+ uart0-0-pins {
+ pinmux = <K1_PADCONF(104, 3)>, /* uart0_txd */
+ <K1_PADCONF(105, 3)>; /* uart0_rxd */
+ power-source = <3300>;
+ bias-pull-up = <0>;
+ drive-strength = <19>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart0_1_cfg: uart0-1-cfg {
+ uart0-1-pins {
+ pinmux = <K1_PADCONF(108, 1)>, /* uart0_txd */
+ <K1_PADCONF(80, 3)>; /* uart0_rxd */
+ power-source = <3300>;
+ bias-pull-up = <0>;
+ drive-strength = <19>;
+ };
+ };
+
+ /omit-if-no-ref/
uart0_2_cfg: uart0-2-cfg {
uart0-2-pins {
- pinmux = <K1_PADCONF(68, 2)>,
- <K1_PADCONF(69, 2)>;
+ pinmux = <K1_PADCONF(68, 2)>, /* uart0_txd */
+ <K1_PADCONF(69, 2)>; /* uart0_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart2_0_cfg: uart2-0-cfg {
+ uart2-0-pins {
+ pinmux = <K1_PADCONF(21, 1)>, /* uart2_txd */
+ <K1_PADCONF(22, 1)>; /* uart2_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart2_0_cts_rts_cfg: uart2-0-cts-rts-cfg {
+ uart2-0-pins {
+ pinmux = <K1_PADCONF(23, 1)>, /* uart2_cts */
+ <K1_PADCONF(24, 1)>; /* uart2_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart3_0_cfg: uart3-0-cfg {
+ uart3-0-pins {
+ pinmux = <K1_PADCONF(81, 2)>, /* uart3_txd */
+ <K1_PADCONF(82, 2)>; /* uart3_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart3_0_cts_rts_cfg: uart3-0-cts-rts-cfg {
+ uart3-0-pins {
+ pinmux = <K1_PADCONF(83, 2)>, /* uart3_cts */
+ <K1_PADCONF(84, 2)>; /* uart3_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart3_1_cfg: uart3-1-cfg {
+ uart3-1-pins {
+ pinmux = <K1_PADCONF(18, 2)>, /* uart3_txd */
+ <K1_PADCONF(19, 2)>; /* uart3_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart3_1_cts_rts_cfg: uart3-1-cts-rts-cfg {
+ uart3-1-pins {
+ pinmux = <K1_PADCONF(20, 2)>, /* uart3_cts */
+ <K1_PADCONF(21, 2)>; /* uart3_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart3_2_cfg: uart3-2-cfg {
+ uart3-2-pins {
+ pinmux = <K1_PADCONF(53, 4)>, /* uart3_txd */
+ <K1_PADCONF(54, 4)>; /* uart3_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart3_2_cts_rts_cfg: uart3-2-cts-rts-cfg {
+ uart3-2-pins {
+ pinmux = <K1_PADCONF(55, 4)>, /* uart3_cts */
+ <K1_PADCONF(56, 4)>; /* uart3_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_0_cfg: uart4-0-cfg {
+ uart4-0-pins {
+ pinmux = <K1_PADCONF(100, 4)>, /* uart4_txd */
+ <K1_PADCONF(101, 4)>; /* uart4_rxd */
+ power-source = <3300>;
+ bias-pull-up = <0>;
+ drive-strength = <19>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_1_cfg: uart4-1-cfg {
+ uart4-1-pins {
+ pinmux = <K1_PADCONF(83, 3)>, /* uart4_txd */
+ <K1_PADCONF(84, 3)>; /* uart4_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_1_cts_rts_cfg: uart4-1-cts-rts-cfg {
+ uart4-1-pins {
+ pinmux = <K1_PADCONF(81, 3)>, /* uart4_cts */
+ <K1_PADCONF(82, 3)>; /* uart4_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_2_cfg: uart4-2-cfg {
+ uart4-2-pins {
+ pinmux = <K1_PADCONF(23, 2)>, /* uart4_txd */
+ <K1_PADCONF(24, 2)>; /* uart4_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_3_cfg: uart4-3-cfg {
+ uart4-3-pins {
+ pinmux = <K1_PADCONF(33, 2)>, /* uart4_txd */
+ <K1_PADCONF(34, 2)>; /* uart4_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_3_cts_rts_cfg: uart4-3-cts-rts-cfg {
+ uart4-3-pins {
+ pinmux = <K1_PADCONF(35, 2)>, /* uart4_cts */
+ <K1_PADCONF(36, 2)>; /* uart4_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_4_cfg: uart4-4-cfg {
+ uart4-4-pins {
+ pinmux = <K1_PADCONF(111, 4)>, /* uart4_txd */
+ <K1_PADCONF(112, 4)>; /* uart4_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart4_4_cts_rts_cfg: uart4-4-cts-rts-cfg {
+ uart4-4-pins {
+ pinmux = <K1_PADCONF(113, 4)>, /* uart4_cts */
+ <K1_PADCONF(114, 4)>; /* uart4_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart5_0_cfg: uart5-0-cfg {
+ uart5-0-pins {
+ pinmux = <K1_PADCONF(102, 3)>, /* uart5_txd */
+ <K1_PADCONF(103, 3)>; /* uart5_rxd */
+ power-source = <3300>;
+ bias-pull-up = <0>;
+ drive-strength = <19>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart5_1_cfg: uart5-1-cfg {
+ uart5-1-pins {
+ pinmux = <K1_PADCONF(25, 2)>, /* uart5_txd */
+ <K1_PADCONF(26, 2)>; /* uart5_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart5_1_cts_rts_cfg: uart5-1-cts-rts-cfg {
+ uart5-1-pins {
+ pinmux = <K1_PADCONF(27, 2)>, /* uart5_cts */
+ <K1_PADCONF(28, 2)>; /* uart5_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart5_2_cfg: uart5-2-cfg {
+ uart5-2-pins {
+ pinmux = <K1_PADCONF(42, 2)>, /* uart5_txd */
+ <K1_PADCONF(43, 2)>; /* uart5_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart5_2_cts_rts_cfg: uart5-2-cts-rts-cfg {
+ uart5-2-pins {
+ pinmux = <K1_PADCONF(44, 2)>, /* uart5_cts */
+ <K1_PADCONF(45, 2)>; /* uart5_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart5_3_cfg: uart5-3-cfg {
+ uart5-3-pins {
+ pinmux = <K1_PADCONF(70, 4)>, /* uart5_txd */
+ <K1_PADCONF(71, 4)>; /* uart5_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart5_3_cts_rts_cfg: uart5-3-cts-rts-cfg {
+ uart5-3-pins {
+ pinmux = <K1_PADCONF(72, 4)>, /* uart5_cts */
+ <K1_PADCONF(73, 4)>; /* uart5_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart6_0_cfg: uart6-0-cfg {
+ uart6-0-pins {
+ pinmux = <K1_PADCONF(86, 2)>, /* uart6_txd */
+ <K1_PADCONF(87, 2)>; /* uart6_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart6_0_cts_rts_cfg: uart6-0-cts-rts-cfg {
+ uart6-0-pins {
+ pinmux = <K1_PADCONF(85, 2)>, /* uart6_cts */
+ <K1_PADCONF(90, 2)>; /* uart6_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart6_1_cfg: uart6-1-cfg {
+ uart6-1-pins {
+ pinmux = <K1_PADCONF(0, 2)>, /* uart6_txd */
+ <K1_PADCONF(1, 2)>; /* uart6_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart6_1_cts_rts_cfg: uart6-1-cts-rts-cfg {
+ uart6-1-pins {
+ pinmux = <K1_PADCONF(2, 2)>, /* uart6_cts */
+ <K1_PADCONF(3, 2)>; /* uart6_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart6_2_cfg: uart6-2-cfg {
+ uart6-2-pins {
+ pinmux = <K1_PADCONF(56, 2)>, /* uart6_txd */
+ <K1_PADCONF(57, 2)>; /* uart6_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart7_0_cfg: uart7-0-cfg {
+ uart7-0-pins {
+ pinmux = <K1_PADCONF(88, 2)>, /* uart7_txd */
+ <K1_PADCONF(89, 2)>; /* uart7_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart7_1_cfg: uart7-1-cfg {
+ uart7-1-pins {
+ pinmux = <K1_PADCONF(4, 2)>, /* uart7_txd */
+ <K1_PADCONF(5, 2)>; /* uart7_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart7_1_cts_rts_cfg: uart7-1-cts-rts-cfg {
+ uart7-1-pins {
+ pinmux = <K1_PADCONF(6, 2)>, /* uart7_cts */
+ <K1_PADCONF(7, 2)>; /* uart7_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart8_0_cfg: uart8-0-cfg {
+ uart8-0-pins {
+ pinmux = <K1_PADCONF(82, 4)>, /* uart8_txd */
+ <K1_PADCONF(83, 4)>; /* uart8_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart8_1_cfg: uart8-1-cfg {
+ uart8-1-pins {
+ pinmux = <K1_PADCONF(8, 2)>, /* uart8_txd */
+ <K1_PADCONF(9, 2)>; /* uart8_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart8_1_cts_rts_cfg: uart8-1-cts-rts-cfg {
+ uart8-1-pins {
+ pinmux = <K1_PADCONF(10, 2)>, /* uart8_cts */
+ <K1_PADCONF(11, 2)>; /* uart8_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart8_2_cfg: uart8-2-cfg {
+ uart8-2-pins {
+ pinmux = <K1_PADCONF(75, 4)>, /* uart8_txd */
+ <K1_PADCONF(76, 4)>; /* uart8_rxd */
+ power-source = <3300>;
+ bias-pull-up = <0>;
+ drive-strength = <19>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart8_2_cts_rts_cfg: uart8-2-cts-rts-cfg {
+ uart8-2-pins {
+ pinmux = <K1_PADCONF(77, 4)>, /* uart8_cts */
+ <K1_PADCONF(78, 4)>; /* uart8_rts */
+ power-source = <3300>;
+ bias-pull-up = <0>;
+ drive-strength = <19>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart9_0_cfg: uart9-0-cfg {
+ uart9-0-pins {
+ pinmux = <K1_PADCONF(12, 2)>, /* uart9_txd */
+ <K1_PADCONF(13, 2)>; /* uart9_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart9_1_cfg: uart9-1-cfg {
+ uart9-1-pins {
+ pinmux = <K1_PADCONF(116, 3)>, /* uart9_txd */
+ <K1_PADCONF(117, 3)>; /* uart9_rxd */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+
+ /omit-if-no-ref/
+ uart9_1_cts_rts_cfg: uart9-1-cts-rts-cfg {
+ uart9-1-pins {
+ pinmux = <K1_PADCONF(110, 3)>, /* uart9_cts */
+ <K1_PADCONF(115, 3)>; /* uart9_rts */
+ bias-pull-up = <0>;
+ drive-strength = <32>;
+ };
+ };
+ /omit-if-no-ref/
+ uart9_2_cfg: uart9-2-cfg {
+ uart9-2-pins {
+ pinmux = <K1_PADCONF(72, 2)>, /* uart9_txd */
+ <K1_PADCONF(73, 2)>; /* uart9_rxd */
bias-pull-up = <0>;
drive-strength = <32>;
};
diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
index 6cdcd80a7c83..7818ca4979b6 100644
--- a/arch/riscv/boot/dts/spacemit/k1.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
@@ -358,6 +358,71 @@
#reset-cells = <1>;
};
+ i2c0: i2c@d4010800 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd4010800 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI0>,
+ <&syscon_apbc CLK_TWSI0_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <36>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@d4011000 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd4011000 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI1>,
+ <&syscon_apbc CLK_TWSI1_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <37>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@d4012000 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd4012000 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI2>,
+ <&syscon_apbc CLK_TWSI2_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <38>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@d4012800 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd4012800 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI4>,
+ <&syscon_apbc CLK_TWSI4_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <40>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@d4013800 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd4013800 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI5>,
+ <&syscon_apbc CLK_TWSI5_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <41>;
+ status = "disabled";
+ };
+
syscon_apbc: system-controller@d4015000 {
compatible = "spacemit,k1-syscon-apbc";
reg = <0x0 0xd4015000 0x0 0x1000>;
@@ -369,6 +434,19 @@
#reset-cells = <1>;
};
+ i2c6: i2c@d4018800 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd4018800 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI6>,
+ <&syscon_apbc CLK_TWSI6_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <70>;
+ status = "disabled";
+ };
+
gpio: gpio@d4019000 {
compatible = "spacemit,k1-gpio";
reg = <0x0 0xd4019000 0x0 0x100>;
@@ -459,6 +537,32 @@
status = "disabled";
};
+ i2c7: i2c@d401d000 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd401d000 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI7>,
+ <&syscon_apbc CLK_TWSI7_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <18>;
+ status = "disabled";
+ };
+
+ i2c8: i2c@d401d800 {
+ compatible = "spacemit,k1-i2c";
+ reg = <0x0 0xd401d800 0x0 0x38>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&syscon_apbc CLK_TWSI8>,
+ <&syscon_apbc CLK_TWSI8_BUS>;
+ clock-names = "func", "bus";
+ clock-frequency = <400000>;
+ interrupts = <19>;
+ status = "disabled";
+ };
+
pinctrl: pinctrl@d401e000 {
compatible = "spacemit,k1-pinctrl";
reg = <0x0 0xd401e000 0x0 0x400>;
@@ -643,6 +747,8 @@
#reset-cells = <1>;
};
+ /* sec_i2c3: 0xf0614000, not available from Linux */
+
camera-bus {
compatible = "simple-bus";
ranges;
@@ -797,6 +903,22 @@
status = "disabled";
};
+ qspi: spi@d420c000 {
+ compatible = "spacemit,k1-qspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0xd420c000 0x0 0x1000>,
+ <0x0 0xb8000000 0x0 0xc00000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ clocks = <&syscon_apmu CLK_QSPI_BUS>,
+ <&syscon_apmu CLK_QSPI>;
+ clock-names = "qspi_en", "qspi";
+ resets = <&syscon_apmu RESET_QSPI>,
+ <&syscon_apmu RESET_QSPI_BUS>;
+ interrupts = <117>;
+ status = "disabled";
+ };
+
/* sec_uart1: 0xf0612000, not available from Linux */
};
diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile
index 62b659f89ba7..3dd1f05283f7 100644
--- a/arch/riscv/boot/dts/starfive/Makefile
+++ b/arch/riscv/boot/dts/starfive/Makefile
@@ -12,6 +12,9 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-deepcomputing-fml13v01.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-mars.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-marscm-emmc.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-marscm-lite.dtb
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-orangepi-rv.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-pine64-star64.dtb
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-lite.dtb
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-lite-emmc.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
diff --git a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
index 5dc15e48b74b..8cfe8033305d 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
@@ -281,14 +281,8 @@
assigned-clock-rates = <50000000>;
bus-width = <8>;
bootph-pre-ram;
- cap-mmc-highspeed;
- mmc-ddr-1_8v;
- mmc-hs200-1_8v;
- cap-mmc-hw-reset;
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins>;
- vmmc-supply = <&vcc_3v3>;
- vqmmc-supply = <&emmc_vdd>;
status = "okay";
};
@@ -298,8 +292,6 @@
assigned-clock-rates = <50000000>;
bus-width = <4>;
bootph-pre-ram;
- cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
- disable-wp;
cap-sd-highspeed;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
@@ -444,17 +436,6 @@
};
mmc0_pins: mmc0-0 {
- rst-pins {
- pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
- GPOEN_ENABLE,
- GPI_NONE)>;
- bias-pull-up;
- drive-strength = <12>;
- input-disable;
- input-schmitt-disable;
- slew-rate = <0>;
- };
-
mmc-pins {
pinmux = <PINMUX(PAD_SD0_CLK, 0)>,
<PINMUX(PAD_SD0_CMD, 0)>,
diff --git a/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts b/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts
index f2857d021d68..d8db9ed4474d 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts
@@ -11,6 +11,33 @@
compatible = "deepcomputing,fml13v01", "starfive,jh7110";
};
+&mmc0 {
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_vdd>;
+};
+
+&mmc0_pins {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+};
+
+&mmc1 {
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
+ disable-wp;
+};
+
&pcie1 {
perst-gpios = <&sysgpio 21 GPIO_ACTIVE_LOW>;
phys = <&pciephy1>;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index fdaf6b4557da..21873612d993 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -22,6 +22,33 @@
status = "okay";
};
+&mmc0 {
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_vdd>;
+};
+
+&mmc0_pins {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+};
+
+&mmc1 {
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
+ disable-wp;
+};
+
&pcie0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts
index e568537af2c4..ce95496263af 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-emmc.dts
@@ -10,3 +10,12 @@
model = "Milk-V Mars CM";
compatible = "milkv,marscm-emmc", "starfive,jh7110";
};
+
+&mmc0 {
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_vdd>;
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts
index 6c40d0ec4011..63aa94d65ab5 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm-lite.dts
@@ -14,6 +14,7 @@
&mmc0 {
bus-width = <4>;
cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
+ disable-wp;
};
&mmc0_pins {
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi
index 25b70af564ee..025471061d43 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi
@@ -40,6 +40,19 @@
status = "disabled";
};
+&mmc0_pins {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+};
+
&mmc1 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-orangepi-rv.dts b/arch/riscv/boot/dts/starfive/jh7110-orangepi-rv.dts
new file mode 100644
index 000000000000..053c35992ec3
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7110-orangepi-rv.dts
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2025 Icenowy Zheng <uwu@icenowy.me>
+ */
+
+/dts-v1/;
+#include "jh7110-common.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi RV";
+ compatible = "xunlong,orangepi-rv", "starfive,jh7110";
+
+ /* This regulator is always on by hardware */
+ reg_vcc3v3_pcie: regulator-vcc3v3-pcie {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3-pcie";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ wifi_pwrseq: wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&sysgpio 62 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&gmac0 {
+ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
+ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
+ starfive,tx-use-rgmii-clk;
+ status = "okay";
+};
+
+&mmc0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cap-sd-highspeed;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ vmmc-supply = <&reg_vcc3v3_pcie>;
+ vqmmc-supply = <&vcc_3v3>;
+ status = "okay";
+
+ ap6256: wifi@1 {
+ compatible = "brcm,bcm43456-fmac", "brcm,bcm4329-fmac";
+ reg = <1>;
+ /* TODO: out-of-band IRQ on GPIO21, lacking pinctrl support */
+ };
+};
+
+&mmc1 {
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_HIGH>;
+};
+
+&pcie0 {
+ status = "okay";
+};
+
+&pcie1 {
+ status = "okay";
+};
+
+&phy0 {
+ rx-internal-delay-ps = <1500>;
+ tx-internal-delay-ps = <1500>;
+ motorcomm,rx-clk-drv-microamp = <3970>;
+ motorcomm,rx-data-drv-microamp = <2910>;
+ motorcomm,tx-clk-adj-enabled;
+ motorcomm,tx-clk-10-inverted;
+ motorcomm,tx-clk-100-inverted;
+ motorcomm,tx-clk-1000-inverted;
+};
+
+&pwmdac {
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
index 31e825be2065..aec7ae3d1f5b 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -44,6 +44,33 @@
status = "okay";
};
+&mmc0 {
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_vdd>;
+};
+
+&mmc0_pins {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+};
+
+&mmc1 {
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
+ disable-wp;
+};
+
&pcie1 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite-emmc.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite-emmc.dts
new file mode 100644
index 000000000000..e27a662d4022
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite-emmc.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2025 StarFive Technology Co., Ltd.
+ * Copyright (C) 2025 Hal Feng <hal.feng@starfivetech.com>
+ */
+
+/dts-v1/;
+#include "jh7110-starfive-visionfive-2-lite.dtsi"
+
+/ {
+ model = "StarFive VisionFive 2 Lite eMMC";
+ compatible = "starfive,visionfive-2-lite-emmc", "starfive,jh7110s";
+};
+
+&mmc0 {
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_vdd>;
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dts b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dts
new file mode 100644
index 000000000000..b96eea4fa7d5
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2025 StarFive Technology Co., Ltd.
+ * Copyright (C) 2025 Hal Feng <hal.feng@starfivetech.com>
+ */
+
+/dts-v1/;
+#include "jh7110-starfive-visionfive-2-lite.dtsi"
+
+/ {
+ model = "StarFive VisionFive 2 Lite";
+ compatible = "starfive,visionfive-2-lite", "starfive,jh7110s";
+};
+
+&mmc0 {
+ bus-width = <4>;
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_HIGH>;
+ disable-wp;
+ cap-sd-highspeed;
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi
new file mode 100644
index 000000000000..f8797a666dbf
--- /dev/null
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Copyright (C) 2025 StarFive Technology Co., Ltd.
+ * Copyright (C) 2025 Hal Feng <hal.feng@starfivetech.com>
+ */
+
+/dts-v1/;
+#include "jh7110-common.dtsi"
+
+/ {
+ vcc_3v3_pcie: regulator-vcc-3v3-pcie {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&sysgpio 27 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc_3v3_pcie";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&cpu_opp {
+ /delete-node/ opp-375000000;
+ /delete-node/ opp-500000000;
+ /delete-node/ opp-750000000;
+ /delete-node/ opp-1500000000;
+
+ opp-312500000 {
+ opp-hz = /bits/ 64 <312500000>;
+ opp-microvolt = <800000>;
+ };
+ opp-417000000 {
+ opp-hz = /bits/ 64 <417000000>;
+ opp-microvolt = <800000>;
+ };
+ opp-625000000 {
+ opp-hz = /bits/ 64 <625000000>;
+ opp-microvolt = <800000>;
+ };
+ opp-1250000000 {
+ opp-hz = /bits/ 64 <1250000000>;
+ opp-microvolt = <1000000>;
+ };
+};
+
+&gmac0 {
+ starfive,tx-use-rgmii-clk;
+ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
+ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&mmc1 {
+ max-frequency = <50000000>;
+ keep-power-in-suspend;
+ non-removable;
+};
+
+&pcie1 {
+ vpcie3v3-supply = <&vcc_3v3_pcie>;
+ status = "okay";
+};
+
+&phy0 {
+ motorcomm,tx-clk-adj-enabled;
+ motorcomm,tx-clk-100-inverted;
+ motorcomm,tx-clk-1000-inverted;
+ motorcomm,rx-clk-drv-microamp = <3970>;
+ motorcomm,rx-data-drv-microamp = <2910>;
+ rx-internal-delay-ps = <1500>;
+ tx-internal-delay-ps = <1500>;
+};
+
+&pwm {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+};
+
+&syscrg {
+ assigned-clock-rates = <0>, <0>, <0>, <0>, <500000000>, <1250000000>;
+};
+
+&sysgpio {
+ uart1_pins: uart1-0 {
+ tx-pins {
+ pinmux = <GPIOMUX(22, GPOUT_SYS_UART1_TX,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+
+ rx-pins {
+ pinmux = <GPIOMUX(23, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_UART1_RX)>;
+ bias-pull-up;
+ drive-strength = <2>;
+ input-enable;
+ input-schmitt-enable;
+ slew-rate = <0>;
+ };
+
+ cts-pins {
+ pinmux = <GPIOMUX(24, GPOUT_LOW,
+ GPOEN_DISABLE,
+ GPI_SYS_UART1_CTS)>;
+ input-enable;
+ };
+
+ rts-pins {
+ pinmux = <GPIOMUX(25, GPOUT_SYS_UART1_RTS,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ input-enable;
+ };
+ };
+
+ usb0_pins: usb0-0 {
+ power-pins {
+ pinmux = <GPIOMUX(26, GPOUT_HIGH,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ input-disable;
+ };
+
+ switch-pins {
+ pinmux = <GPIOMUX(62, GPOUT_LOW,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ input-disable;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
+
+&usb0 {
+ dr_mode = "host";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins>;
+ status = "okay";
+};
+
+&usb_cdns3 {
+ phys = <&usbphy0>, <&pciephy0>;
+ phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy";
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
index 5f14afb2c24d..edc8f4588133 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -38,9 +38,33 @@
};
&mmc0 {
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_vdd>;
non-removable;
};
+&mmc0_pins {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+ GPOEN_ENABLE,
+ GPI_NONE)>;
+ bias-pull-up;
+ drive-strength = <12>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+};
+
+&mmc1 {
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
+ disable-wp;
+};
+
&pcie0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/tenstorrent/Makefile b/arch/riscv/boot/dts/tenstorrent/Makefile
new file mode 100644
index 000000000000..2c81faaba462
--- /dev/null
+++ b/arch/riscv/boot/dts/tenstorrent/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_TENSTORRENT) += blackhole-card.dtb
diff --git a/arch/riscv/boot/dts/tenstorrent/blackhole-card.dts b/arch/riscv/boot/dts/tenstorrent/blackhole-card.dts
new file mode 100644
index 000000000000..f53667ce73a9
--- /dev/null
+++ b/arch/riscv/boot/dts/tenstorrent/blackhole-card.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/dts-v1/;
+
+#include "blackhole.dtsi"
+
+/ {
+ model = "Tenstorrent Blackhole";
+ compatible = "tenstorrent,blackhole-card", "tenstorrent,blackhole";
+
+ memory@400030000000 {
+ device_type = "memory";
+ reg = <0x4000 0x30000000 0x1 0x00000000>;
+ };
+};
diff --git a/arch/riscv/boot/dts/tenstorrent/blackhole.dtsi b/arch/riscv/boot/dts/tenstorrent/blackhole.dtsi
new file mode 100644
index 000000000000..6408810d8d80
--- /dev/null
+++ b/arch/riscv/boot/dts/tenstorrent/blackhole.dtsi
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright 2025 Tenstorrent AI ULC
+/dts-v1/;
+
+/ {
+ compatible = "tenstorrent,blackhole";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <50000000>;
+
+ cpu@0 {
+ compatible = "sifive,x280", "sifive,rocket0", "riscv";
+ device_type = "cpu";
+ reg = <0>;
+ mmu-type = "riscv,sv57";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr",
+ "zifencei", "zfh", "zba", "zbb", "sscofpmf";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ cpu@1 {
+ compatible = "sifive,x280", "sifive,rocket0", "riscv";
+ device_type = "cpu";
+ reg = <1>;
+ mmu-type = "riscv,sv57";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr",
+ "zifencei", "zfh", "zba", "zbb", "sscofpmf";
+
+ cpu1_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ cpu@2 {
+ compatible = "sifive,x280", "sifive,rocket0", "riscv";
+ device_type = "cpu";
+ reg = <2>;
+ mmu-type = "riscv,sv57";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr",
+ "zifencei", "zfh", "zba", "zbb", "sscofpmf";
+
+ cpu2_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ cpu@3 {
+ compatible = "sifive,x280", "sifive,rocket0", "riscv";
+ device_type = "cpu";
+ reg = <3>;
+ mmu-type = "riscv,sv57";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "zicsr",
+ "zifencei", "zfh", "zba", "zbb", "sscofpmf";
+
+ cpu3_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ clint0: timer@2000000 {
+ compatible = "tenstorrent,blackhole-clint", "sifive,clint0";
+ reg = <0x0 0x2000000 0x0 0x10000>;
+ interrupts-extended = <&cpu0_intc 0x3>, <&cpu0_intc 0x7>,
+ <&cpu1_intc 0x3>, <&cpu1_intc 0x7>,
+ <&cpu2_intc 0x3>, <&cpu2_intc 0x7>,
+ <&cpu3_intc 0x3>, <&cpu3_intc 0x7>;
+ };
+
+ plic0: interrupt-controller@c000000 {
+ compatible = "tenstorrent,blackhole-plic", "sifive,plic-1.0.0";
+ reg = <0x0 0x0c000000 0x0 0x04000000>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
+ <&cpu1_intc 11>, <&cpu1_intc 9>,
+ <&cpu2_intc 11>, <&cpu2_intc 9>,
+ <&cpu3_intc 11>, <&cpu3_intc 9>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ riscv,ndev = <128>;
+ };
+ };
+};
diff --git a/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts b/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts
index 4020c727f09e..c58c2085ca92 100644
--- a/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts
+++ b/arch/riscv/boot/dts/thead/th1520-lichee-pi-4a.dts
@@ -28,9 +28,76 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+ thermal-zones {
+ cpu-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <1000>;
+ thermal-sensors = <&pvt 0>;
+
+ trips {
+ fan_config0: fan-trip0 {
+ temperature = <39000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+
+ fan_config1: fan-trip1 {
+ temperature = <50000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+
+ fan_config2: fan-trip2 {
+ temperature = <60000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map-active-0 {
+ cooling-device = <&fan 1 1>;
+ trip = <&fan_config0>;
+ };
+
+ map-active-1 {
+ cooling-device = <&fan 2 2>;
+ trip = <&fan_config1>;
+ };
+
+ map-active-2 {
+ cooling-device = <&fan 3 3>;
+ trip = <&fan_config2>;
+ };
+ };
+ };
+ };
+
+ fan: pwm-fan {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fan_pins>;
+ compatible = "pwm-fan";
+ #cooling-cells = <2>;
+ pwms = <&pwm 1 10000000 0>;
+ cooling-levels = <0 66 196 255>;
+ };
+
};
&padctrl0_apsys {
+ fan_pins: fan-0 {
+ pwm1-pins {
+ pins = "GPIO3_3"; /* PWM1 */
+ function = "pwm";
+ bias-disable;
+ drive-strength = <25>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
uart0_pins: uart0-0 {
tx-pins {
pins = "UART0_TXD";
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index e680d1a7c821..bd5d33840884 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -24,8 +24,11 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
riscv,isa-base = "rv64i";
- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
- "zifencei", "zihpm";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "ziccrse", "zicntr", "zicsr",
+ "zifencei", "zihpm", "zfh",
+ "xtheadvector";
+ thead,vlenb = <16>;
reg = <0>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
@@ -48,8 +51,11 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
riscv,isa-base = "rv64i";
- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
- "zifencei", "zihpm";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "ziccrse", "zicntr", "zicsr",
+ "zifencei", "zihpm", "zfh",
+ "xtheadvector";
+ thead,vlenb = <16>;
reg = <1>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
@@ -72,8 +78,11 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
riscv,isa-base = "rv64i";
- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
- "zifencei", "zihpm";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "ziccrse", "zicntr", "zicsr",
+ "zifencei", "zihpm", "zfh",
+ "xtheadvector";
+ thead,vlenb = <16>;
reg = <2>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
@@ -96,8 +105,11 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
riscv,isa-base = "rv64i";
- riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
- "zifencei", "zihpm";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "ziccrse", "zicntr", "zicsr",
+ "zifencei", "zihpm", "zfh",
+ "xtheadvector";
+ thead,vlenb = <16>;
reg = <3>;
i-cache-block-size = <64>;
i-cache-size = <65536>;
@@ -277,6 +289,12 @@
<&cpu3_intc 3>, <&cpu3_intc 7>;
};
+ rst_vi: reset-controller@ffe4040100 {
+ compatible = "thead,th1520-reset-vi";
+ reg = <0xff 0xe4040100 0x0 0x8>;
+ #reset-cells = <1>;
+ };
+
spi0: spi@ffe700c000 {
compatible = "thead,th1520-spi", "snps,dw-apb-ssi";
reg = <0xff 0xe700c000 0x0 0x1000>;
@@ -502,6 +520,25 @@
status = "disabled";
};
+ pwm: pwm@ffec01c000 {
+ compatible = "thead,th1520-pwm";
+ reg = <0xff 0xec01c000 0x0 0x4000>;
+ clocks = <&clk CLK_PWM>;
+ #pwm-cells = <3>;
+ };
+
+ rst_misc: reset-controller@ffec02c000 {
+ compatible = "thead,th1520-reset-misc";
+ reg = <0xff 0xec02c000 0x0 0x18>;
+ #reset-cells = <1>;
+ };
+
+ rst_vp: reset-controller@ffecc30000 {
+ compatible = "thead,th1520-reset-vp";
+ reg = <0xff 0xecc30000 0x0 0x14>;
+ #reset-cells = <1>;
+ };
+
clk: clock-controller@ffef010000 {
compatible = "thead,th1520-clk-ap";
reg = <0xff 0xef010000 0x0 0x1000>;
@@ -509,6 +546,18 @@
#clock-cells = <1>;
};
+ rst_ap: reset-controller@ffef014000 {
+ compatible = "thead,th1520-reset-ap";
+ reg = <0xff 0xef014000 0x0 0x1000>;
+ #reset-cells = <1>;
+ };
+
+ rst_dsp: reset-controller@ffef040028 {
+ compatible = "thead,th1520-reset-dsp";
+ reg = <0xff 0xef040028 0x0 0x4>;
+ #reset-cells = <1>;
+ };
+
gpu: gpu@ffef400000 {
compatible = "thead,th1520-gpu", "img,img-bxm-4-64",
"img,img-rogue";
@@ -681,6 +730,13 @@
};
};
+ rst_ao: reset-controller@fffff44000 {
+ compatible = "thead,th1520-reset-ao";
+ reg = <0xff 0xfff44000 0x0 0x2000>;
+ #reset-cells = <1>;
+ status = "reserved";
+ };
+
padctrl_aosys: pinctrl@fffff4a000 {
compatible = "thead,th1520-pinctrl";
reg = <0xff 0xfff4a000 0x0 0x2000>;
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index fc2725cbca18..cd736a1d657e 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -23,12 +23,14 @@ CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_PROFILING=y
CONFIG_ARCH_ANDES=y
+CONFIG_ARCH_ANLOGIC=y
CONFIG_ARCH_MICROCHIP=y
CONFIG_ARCH_SIFIVE=y
CONFIG_ARCH_SOPHGO=y
CONFIG_ARCH_SPACEMIT=y
CONFIG_SOC_STARFIVE=y
CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_TENSTORRENT=y
CONFIG_ARCH_THEAD=y
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_CANAAN=y
@@ -158,6 +160,7 @@ CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_I2C_MV64XXX=m
CONFIG_SPI=y
CONFIG_SPI_CADENCE_QUADSPI=m
+CONFIG_SPI_FSL_QUADSPI=m
CONFIG_SPI_PL022=m
CONFIG_SPI_SIFIVE=y
CONFIG_SPI_SUN6I=y
diff --git a/arch/riscv/include/asm/arch_hweight.h b/arch/riscv/include/asm/arch_hweight.h
index 0e7cdbbec8ef..f3c0831beefc 100644
--- a/arch/riscv/include/asm/arch_hweight.h
+++ b/arch/riscv/include/asm/arch_hweight.h
@@ -19,10 +19,10 @@
static __always_inline unsigned int __arch_hweight32(unsigned int w)
{
-#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB)
- asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- : : : : legacy);
+ if (!(IS_ENABLED(CONFIG_RISCV_ISA_ZBB) &&
+ IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) &&
+ riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)))
+ return __sw_hweight32(w);
asm (".option push\n"
".option arch,+zbb\n"
@@ -31,10 +31,6 @@ static __always_inline unsigned int __arch_hweight32(unsigned int w)
: "=r" (w) : "r" (w) :);
return w;
-
-legacy:
-#endif
- return __sw_hweight32(w);
}
static inline unsigned int __arch_hweight16(unsigned int w)
@@ -50,10 +46,10 @@ static inline unsigned int __arch_hweight8(unsigned int w)
#if BITS_PER_LONG == 64
static __always_inline unsigned long __arch_hweight64(__u64 w)
{
-#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB)
- asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- : : : : legacy);
+ if (!(IS_ENABLED(CONFIG_RISCV_ISA_ZBB) &&
+ IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) &&
+ riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)))
+ return __sw_hweight64(w);
asm (".option push\n"
".option arch,+zbb\n"
@@ -62,10 +58,6 @@ static __always_inline unsigned long __arch_hweight64(__u64 w)
: "=r" (w) : "r" (w) :);
return w;
-
-legacy:
-#endif
- return __sw_hweight64(w);
}
#else /* BITS_PER_LONG == 64 */
static inline unsigned long __arch_hweight64(__u64 w)
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index ac28066bb564..e9e8ba83e632 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -12,6 +12,12 @@
#define __ASM_STR(x) #x
#endif
+#ifdef CONFIG_AS_HAS_INSN
+#define ASM_INSN_I(__x) ".insn " __x
+#else
+#define ASM_INSN_I(__x) ".4byte " __x
+#endif
+
#if __riscv_xlen == 64
#define __REG_SEL(a, b) __ASM_STR(a)
#elif __riscv_xlen == 32
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index 77880677b06e..238092125c11 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -47,9 +47,8 @@
static __always_inline __attribute_const__ unsigned long variable__ffs(unsigned long word)
{
- asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- : : : : legacy);
+ if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB))
+ return generic___ffs(word);
asm volatile (".option push\n"
".option arch,+zbb\n"
@@ -58,9 +57,6 @@ static __always_inline __attribute_const__ unsigned long variable__ffs(unsigned
: "=r" (word) : "r" (word) :);
return word;
-
-legacy:
- return generic___ffs(word);
}
/**
@@ -76,9 +72,8 @@ legacy:
static __always_inline __attribute_const__ unsigned long variable__fls(unsigned long word)
{
- asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- : : : : legacy);
+ if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB))
+ return generic___fls(word);
asm volatile (".option push\n"
".option arch,+zbb\n"
@@ -87,9 +82,6 @@ static __always_inline __attribute_const__ unsigned long variable__fls(unsigned
: "=r" (word) : "r" (word) :);
return BITS_PER_LONG - 1 - word;
-
-legacy:
- return generic___fls(word);
}
/**
@@ -105,9 +97,8 @@ legacy:
static __always_inline __attribute_const__ int variable_ffs(int x)
{
- asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- : : : : legacy);
+ if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB))
+ return generic_ffs(x);
if (!x)
return 0;
@@ -119,9 +110,6 @@ static __always_inline __attribute_const__ int variable_ffs(int x)
: "=r" (x) : "r" (x) :);
return x + 1;
-
-legacy:
- return generic_ffs(x);
}
/**
@@ -137,9 +125,8 @@ legacy:
static __always_inline int variable_fls(unsigned int x)
{
- asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- : : : : legacy);
+ if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBB))
+ return generic_fls(x);
if (!x)
return 0;
@@ -151,9 +138,6 @@ static __always_inline int variable_fls(unsigned int x)
: "=r" (x) : "r" (x) :);
return 32 - x;
-
-legacy:
- return generic_fls(x);
}
/**
diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
index 4c03e20ad11f..6f581b84d8fc 100644
--- a/arch/riscv/include/asm/bug.h
+++ b/arch/riscv/include/asm/bug.h
@@ -60,28 +60,28 @@ typedef u32 bug_insn_t;
".org 2b + " size "\n\t" \
".popsection" \
-#define __BUG_FLAGS(flags) \
+#define __BUG_FLAGS(cond_str, flags) \
do { \
__asm__ __volatile__ ( \
ARCH_WARN_ASM("%0", "%1", "%2", "%3") \
: \
- : "i" (__FILE__), "i" (__LINE__), \
+ : "i" (WARN_CONDITION_STR(cond_str) __FILE__), "i" (__LINE__), \
"i" (flags), \
"i" (sizeof(struct bug_entry))); \
} while (0)
#else /* CONFIG_GENERIC_BUG */
-#define __BUG_FLAGS(flags) do { \
+#define __BUG_FLAGS(cond_str, flags) do { \
__asm__ __volatile__ ("ebreak\n"); \
} while (0)
#endif /* CONFIG_GENERIC_BUG */
#define BUG() do { \
- __BUG_FLAGS(0); \
+ __BUG_FLAGS("", 0); \
unreachable(); \
} while (0)
-#define __WARN_FLAGS(flags) __BUG_FLAGS(BUGFLAG_WARNING|(flags))
+#define __WARN_FLAGS(cond_str, flags) __BUG_FLAGS(cond_str, BUGFLAG_WARNING|(flags))
#define ARCH_WARN_REACHABLE
diff --git a/arch/riscv/include/asm/checksum.h b/arch/riscv/include/asm/checksum.h
index da378856f1d5..945cce34be92 100644
--- a/arch/riscv/include/asm/checksum.h
+++ b/arch/riscv/include/asm/checksum.h
@@ -49,16 +49,11 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
* ZBB only saves three instructions on 32-bit and five on 64-bit so not
* worth checking if supported without Alternatives.
*/
- if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) {
+ if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) &&
+ IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) &&
+ riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) {
unsigned long fold_temp;
- asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- :
- :
- :
- : no_zbb);
-
if (IS_ENABLED(CONFIG_32BIT)) {
asm(".option push \n\
.option arch,+zbb \n\
@@ -81,7 +76,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
return (__force __sum16)(csum >> 16);
}
-no_zbb:
+
#ifndef CONFIG_32BIT
csum += ror64(csum, 32);
csum >>= 32;
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 122e1485d39a..8712cf9c69dc 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -373,9 +373,10 @@ static __always_inline void __cmpwait(volatile void *ptr,
u32 *__ptr32b;
ulong __s, __val, __mask;
- asm goto(ALTERNATIVE("j %l[no_zawrs]", "nop",
- 0, RISCV_ISA_EXT_ZAWRS, 1)
- : : : : no_zawrs);
+ if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZAWRS)) {
+ ALT_RISCV_PAUSE();
+ return;
+ }
switch (size) {
case 1:
@@ -437,11 +438,6 @@ static __always_inline void __cmpwait(volatile void *ptr,
default:
BUILD_BUG();
}
-
- return;
-
-no_zawrs:
- ALT_RISCV_PAUSE();
}
#define __cmpwait_relaxed(ptr, val) \
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index affd63e11b0a..dfe57b215e6c 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -106,6 +106,8 @@
#define RISCV_ISA_EXT_ZAAMO 97
#define RISCV_ISA_EXT_ZALRSC 98
#define RISCV_ISA_EXT_ZICBOP 99
+#define RISCV_ISA_EXT_SVRSW60T59B 100
+#define RISCV_ISA_EXT_ZALASR 101
#define RISCV_ISA_EXT_XLINUXENVCFG 127
diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
index 58f8dda73259..8c572a464719 100644
--- a/arch/riscv/include/asm/hwprobe.h
+++ b/arch/riscv/include/asm/hwprobe.h
@@ -8,7 +8,7 @@
#include <uapi/asm/hwprobe.h>
-#define RISCV_HWPROBE_MAX_KEY 14
+#define RISCV_HWPROBE_MAX_KEY 15
static inline bool riscv_hwprobe_key_is_valid(__s64 key)
{
diff --git a/arch/riscv/include/asm/insn-def.h b/arch/riscv/include/asm/insn-def.h
index c9cfcea52cbb..7c6daf116756 100644
--- a/arch/riscv/include/asm/insn-def.h
+++ b/arch/riscv/include/asm/insn-def.h
@@ -179,6 +179,7 @@
#define RV___RS1(v) __RV_REG(v)
#define RV___RS2(v) __RV_REG(v)
+#define RV_OPCODE_AMO RV_OPCODE(47)
#define RV_OPCODE_MISC_MEM RV_OPCODE(15)
#define RV_OPCODE_OP_IMM RV_OPCODE(19)
#define RV_OPCODE_SYSTEM RV_OPCODE(115)
@@ -208,6 +209,84 @@
__ASM_STR(.error "hlv.d requires 64-bit support")
#endif
+#define LB_AQ(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(26), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define LB_AQRL(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(27), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define LH_AQ(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(26), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define LH_AQRL(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(27), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define LW_AQ(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(26), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define LW_AQRL(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(27), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define SB_RL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(29), \
+ __RD(0), RS1(addr), RS2(src))
+
+#define SB_AQRL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(0), FUNC7(31), \
+ __RD(0), RS1(addr), RS2(src))
+
+#define SH_RL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(29), \
+ __RD(0), RS1(addr), RS2(src))
+
+#define SH_AQRL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(1), FUNC7(31), \
+ __RD(0), RS1(addr), RS2(src))
+
+#define SW_RL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(29), \
+ __RD(0), RS1(addr), RS2(src))
+
+#define SW_AQRL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(2), FUNC7(31), \
+ __RD(0), RS1(addr), RS2(src))
+
+#ifdef CONFIG_64BIT
+#define LD_AQ(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(26), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define LD_AQRL(dest, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(27), \
+ RD(dest), RS1(addr), __RS2(0))
+
+#define SD_RL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(29), \
+ __RD(0), RS1(addr), RS2(src))
+
+#define SD_AQRL(src, addr) \
+ INSN_R(OPCODE_AMO, FUNC3(3), FUNC7(31), \
+ __RD(0), RS1(addr), RS2(src))
+#else
+#define LD_AQ(dest, addr) \
+ __ASM_STR(.error "ld.aq requires 64-bit support")
+
+#define LD_AQRL(dest, addr) \
+ __ASM_STR(.error "ld.aqrl requires 64-bit support")
+
+#define SD_RL(dest, addr) \
+ __ASM_STR(.error "sd.rl requires 64-bit support")
+
+#define SD_AQRL(dest, addr) \
+ __ASM_STR(.error "sd.aqrl requires 64-bit support")
+#endif
+
#define SINVAL_VMA(vaddr, asid) \
INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(11), \
__RD(0), RS1(vaddr), RS2(asid))
@@ -256,10 +335,10 @@
INSN_S(OPCODE_OP_IMM, FUNC3(6), __RS2(3), \
SIMM12((offset) & 0xfe0), RS1(base))
-#define RISCV_PAUSE ".4byte 0x100000f"
-#define ZAWRS_WRS_NTO ".4byte 0x00d00073"
-#define ZAWRS_WRS_STO ".4byte 0x01d00073"
-#define RISCV_NOP4 ".4byte 0x00000013"
+#define RISCV_PAUSE ASM_INSN_I("0x100000f")
+#define ZAWRS_WRS_NTO ASM_INSN_I("0x00d00073")
+#define ZAWRS_WRS_STO ASM_INSN_I("0x01d00073")
+#define RISCV_NOP4 ASM_INSN_I("0x00000013")
#define RISCV_INSN_NOP4 _AC(0x00000013, U)
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 4d794573e3db..24585304c02b 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -59,6 +59,9 @@
BIT(IRQ_VS_TIMER) | \
BIT(IRQ_VS_EXT))
+#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
+ KVM_DIRTY_LOG_INITIALLY_SET)
+
struct kvm_vm_stat {
struct kvm_vm_stat_generic generic;
};
@@ -327,4 +330,7 @@ bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu);
+/* Flags representing implementation specific details */
+DECLARE_STATIC_KEY_FALSE(kvm_riscv_vsstage_tlb_no_gpa);
+
#endif /* __RISCV_KVM_HOST_H__ */
diff --git a/arch/riscv/include/asm/kvm_tlb.h b/arch/riscv/include/asm/kvm_tlb.h
index 38a2f933ad3a..a0e7099bcb85 100644
--- a/arch/riscv/include/asm/kvm_tlb.h
+++ b/arch/riscv/include/asm/kvm_tlb.h
@@ -49,6 +49,7 @@ void kvm_riscv_local_hfence_vvma_gva(unsigned long vmid,
unsigned long gva, unsigned long gvsz,
unsigned long order);
void kvm_riscv_local_hfence_vvma_all(unsigned long vmid);
+void kvm_riscv_local_tlb_sanitize(struct kvm_vcpu *vcpu);
void kvm_riscv_tlb_flush_process(struct kvm_vcpu *vcpu);
diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
index 3497489e04db..c1a7e3b40d9c 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
@@ -69,7 +69,9 @@ struct kvm_vcpu_sbi_extension {
unsigned long reg_size, const void *reg_val);
};
-void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_riscv_vcpu_sbi_forward_handler(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ struct kvm_vcpu_sbi_return *retdata);
void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
struct kvm_run *run,
u32 type, u64 flags);
@@ -105,6 +107,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_susp;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_fwft;
+extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_mpxy;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
diff --git a/arch/riscv/include/asm/kvm_vmid.h b/arch/riscv/include/asm/kvm_vmid.h
index ab98e1434fb7..db61b0525a8d 100644
--- a/arch/riscv/include/asm/kvm_vmid.h
+++ b/arch/riscv/include/asm/kvm_vmid.h
@@ -22,6 +22,5 @@ unsigned long kvm_riscv_gstage_vmid_bits(void);
int kvm_riscv_gstage_vmid_init(struct kvm *kvm);
bool kvm_riscv_gstage_vmid_ver_changed(struct kvm_vmid *vmid);
void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu);
-void kvm_riscv_gstage_vmid_sanitize(struct kvm_vcpu *vcpu);
#endif
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index 179bd4afece4..b422d9691e60 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -19,6 +19,43 @@
#define _PAGE_SOFT (3 << 8) /* Reserved for software */
#define _PAGE_SPECIAL (1 << 8) /* RSW: 0x1 */
+
+#ifdef CONFIG_MEM_SOFT_DIRTY
+
+/* ext_svrsw60t59b: bit 59 for soft-dirty tracking */
+#define _PAGE_SOFT_DIRTY \
+ ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \
+ (1UL << 59) : 0)
+/*
+ * Bit 3 is always zero for swap entry computation, so we
+ * can borrow it for swap page soft-dirty tracking.
+ */
+#define _PAGE_SWP_SOFT_DIRTY \
+ ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \
+ _PAGE_EXEC : 0)
+#else
+#define _PAGE_SOFT_DIRTY 0
+#define _PAGE_SWP_SOFT_DIRTY 0
+#endif /* CONFIG_MEM_SOFT_DIRTY */
+
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+
+/* ext_svrsw60t59b: Bit(60) for uffd-wp tracking */
+#define _PAGE_UFFD_WP \
+ ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \
+ (1UL << 60) : 0)
+/*
+ * Bit 4 is not involved into swap entry computation, so we
+ * can borrow it for swap page uffd-wp tracking.
+ */
+#define _PAGE_SWP_UFFD_WP \
+ ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \
+ _PAGE_USER : 0)
+#else
+#define _PAGE_UFFD_WP 0
+#define _PAGE_SWP_UFFD_WP 0
+#endif
+
#define _PAGE_TABLE _PAGE_PRESENT
/*
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 5a08eb5fe99f..8bd36ac842eb 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -417,6 +417,41 @@ static inline pte_t pte_wrprotect(pte_t pte)
return __pte(pte_val(pte) & ~(_PAGE_WRITE));
}
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+#define pgtable_supports_uffd_wp() \
+ riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)
+
+static inline bool pte_uffd_wp(pte_t pte)
+{
+ return !!(pte_val(pte) & _PAGE_UFFD_WP);
+}
+
+static inline pte_t pte_mkuffd_wp(pte_t pte)
+{
+ return pte_wrprotect(__pte(pte_val(pte) | _PAGE_UFFD_WP));
+}
+
+static inline pte_t pte_clear_uffd_wp(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~(_PAGE_UFFD_WP));
+}
+
+static inline bool pte_swp_uffd_wp(pte_t pte)
+{
+ return !!(pte_val(pte) & _PAGE_SWP_UFFD_WP);
+}
+
+static inline pte_t pte_swp_mkuffd_wp(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SWP_UFFD_WP);
+}
+
+static inline pte_t pte_swp_clear_uffd_wp(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~(_PAGE_SWP_UFFD_WP));
+}
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
+
/* static inline pte_t pte_mkread(pte_t pte) */
static inline pte_t pte_mkwrite_novma(pte_t pte)
@@ -428,7 +463,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
static inline pte_t pte_mkdirty(pte_t pte)
{
- return __pte(pte_val(pte) | _PAGE_DIRTY);
+ return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
}
static inline pte_t pte_mkclean(pte_t pte)
@@ -456,6 +491,42 @@ static inline pte_t pte_mkhuge(pte_t pte)
return pte;
}
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
+#define pgtable_supports_soft_dirty() \
+ (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && \
+ riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B))
+
+static inline bool pte_soft_dirty(pte_t pte)
+{
+ return !!(pte_val(pte) & _PAGE_SOFT_DIRTY);
+}
+
+static inline pte_t pte_mksoft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
+}
+
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY));
+}
+
+static inline bool pte_swp_soft_dirty(pte_t pte)
+{
+ return !!(pte_val(pte) & _PAGE_SWP_SOFT_DIRTY);
+}
+
+static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
+}
+
+static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
+{
+ return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY));
+}
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
+
#ifdef CONFIG_RISCV_ISA_SVNAPOT
#define pte_leaf_size(pte) (pte_napot(pte) ? \
napot_cont_size(napot_cont_order(pte)) :\
@@ -496,8 +567,13 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
struct vm_area_struct *vma, unsigned long address,
pte_t *ptep, unsigned int nr)
{
- asm goto(ALTERNATIVE("nop", "j %l[svvptc]", 0, RISCV_ISA_EXT_SVVPTC, 1)
- : : : : svvptc);
+ /*
+ * Svvptc guarantees that the new valid pte will be visible within
+ * a bounded timeframe, so when the uarch does not cache invalid
+ * entries, we don't have to do anything.
+ */
+ if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC))
+ return;
/*
* The kernel assumes that TLBs don't cache invalid entries, but
@@ -509,12 +585,6 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
while (nr--)
local_flush_tlb_page(address + nr * PAGE_SIZE);
-svvptc:;
- /*
- * Svvptc guarantees that the new valid pte will be visible within
- * a bounded timeframe, so when the uarch does not cache invalid
- * entries, we don't have to do anything.
- */
}
#define update_mmu_cache(vma, addr, ptep) \
update_mmu_cache_range(NULL, vma, addr, ptep, 1)
@@ -805,6 +875,72 @@ static inline pud_t pud_mkspecial(pud_t pud)
}
#endif
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+static inline bool pmd_uffd_wp(pmd_t pmd)
+{
+ return pte_uffd_wp(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_mkuffd_wp(pmd_t pmd)
+{
+ return pte_pmd(pte_mkuffd_wp(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_clear_uffd_wp(pmd_t pmd)
+{
+ return pte_pmd(pte_clear_uffd_wp(pmd_pte(pmd)));
+}
+
+static inline bool pmd_swp_uffd_wp(pmd_t pmd)
+{
+ return pte_swp_uffd_wp(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_swp_mkuffd_wp(pmd_t pmd)
+{
+ return pte_pmd(pte_swp_mkuffd_wp(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_swp_clear_uffd_wp(pmd_t pmd)
+{
+ return pte_pmd(pte_swp_clear_uffd_wp(pmd_pte(pmd)));
+}
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
+
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
+static inline bool pmd_soft_dirty(pmd_t pmd)
+{
+ return pte_soft_dirty(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
+{
+ return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
+{
+ return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
+}
+
+#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
+static inline bool pmd_swp_soft_dirty(pmd_t pmd)
+{
+ return pte_swp_soft_dirty(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
+{
+ return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
+{
+ return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd)));
+}
+#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
+
static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
pmd_t *pmdp, pmd_t pmd)
{
@@ -1003,7 +1139,9 @@ static inline pud_t pud_modify(pud_t pud, pgprot_t newprot)
*
* Format of swap PTE:
* bit 0: _PAGE_PRESENT (zero)
- * bit 1 to 3: _PAGE_LEAF (zero)
+ * bit 1 to 2: (zero)
+ * bit 3: _PAGE_SWP_SOFT_DIRTY
+ * bit 4: _PAGE_SWP_UFFD_WP
* bit 5: _PAGE_PROT_NONE (zero)
* bit 6: exclusive marker
* bits 7 to 11: swap type
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index f5f4f7f85543..36bba6720c26 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -437,10 +437,10 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
__clear_user(untagged_addr(to), n) : n;
}
-#define __get_kernel_nofault(dst, src, type, err_label) \
+#define arch_get_kernel_nofault(dst, src, type, err_label) \
__get_user_nocheck(*((type *)(dst)), (__force __user type *)(src), err_label)
-#define __put_kernel_nofault(dst, src, type, err_label) \
+#define arch_put_kernel_nofault(dst, src, type, err_label) \
__put_user_nocheck(*((type *)(src)), (__force __user type *)(dst), err_label)
static __must_check __always_inline bool user_access_begin(const void __user *ptr, size_t len)
@@ -460,10 +460,10 @@ static inline void user_access_restore(unsigned long enabled) { }
* We want the unsafe accessors to always be inlined and use
* the error labels - thus the macro games.
*/
-#define unsafe_put_user(x, ptr, label) \
+#define arch_unsafe_put_user(x, ptr, label) \
__put_user_nocheck(x, (ptr), label)
-#define unsafe_get_user(x, ptr, label) do { \
+#define arch_unsafe_get_user(x, ptr, label) do { \
__inttype(*(ptr)) __gu_val; \
__get_user_nocheck(__gu_val, (ptr), label); \
(x) = (__force __typeof__(*(ptr)))__gu_val; \
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index b61786d43c20..e7aa449368ad 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -51,6 +51,7 @@ void put_cpu_vector_context(void);
void riscv_v_thread_free(struct task_struct *tsk);
void __init riscv_v_setup_ctx_cache(void);
void riscv_v_thread_alloc(struct task_struct *tsk);
+void __init update_regset_vector_info(unsigned long size);
static inline u32 riscv_v_flags(void)
{
diff --git a/arch/riscv/include/asm/vendor_extensions/mips.h b/arch/riscv/include/asm/vendor_extensions/mips.h
index ea8ca747d691..ffeb12dc17a3 100644
--- a/arch/riscv/include/asm/vendor_extensions/mips.h
+++ b/arch/riscv/include/asm/vendor_extensions/mips.h
@@ -30,8 +30,8 @@ extern struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_mips;
* allowing any subsequent instructions to fetch.
*/
-#define MIPS_PAUSE ".4byte 0x00501013\n\t"
-#define MIPS_EHB ".4byte 0x00301013\n\t"
-#define MIPS_IHB ".4byte 0x00101013\n\t"
+#define MIPS_PAUSE ASM_INSN_I("0x00501013\n\t")
+#define MIPS_EHB ASM_INSN_I("0x00301013\n\t")
+#define MIPS_IHB ASM_INSN_I("0x00101013\n\t")
#endif // _ASM_RISCV_VENDOR_EXTENSIONS_MIPS_H
diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
index 3b09874d7a6d..7f5030ee1fcf 100644
--- a/arch/riscv/include/asm/vendorid_list.h
+++ b/arch/riscv/include/asm/vendorid_list.h
@@ -7,8 +7,8 @@
#define ANDES_VENDOR_ID 0x31e
#define MICROCHIP_VENDOR_ID 0x029
+#define MIPS_VENDOR_ID 0x127
#define SIFIVE_VENDOR_ID 0x489
#define THEAD_VENDOR_ID 0x5b7
-#define MIPS_VENDOR_ID 0x722
#endif
diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index 5d30a4fae37a..1edea2331b8b 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -82,6 +82,8 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_EXT_ZAAMO (1ULL << 56)
#define RISCV_HWPROBE_EXT_ZALRSC (1ULL << 57)
#define RISCV_HWPROBE_EXT_ZABHA (1ULL << 58)
+#define RISCV_HWPROBE_EXT_ZALASR (1ULL << 59)
+#define RISCV_HWPROBE_EXT_ZICBOP (1ULL << 60)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
@@ -107,6 +109,7 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE 12
#define RISCV_HWPROBE_KEY_VENDOR_EXT_SIFIVE_0 13
#define RISCV_HWPROBE_KEY_VENDOR_EXT_MIPS_0 14
+#define RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE 15
/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
/* Flags */
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 759a4852c09a..54f3ad7ed2e4 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -23,6 +23,8 @@
#define KVM_INTERRUPT_SET -1U
#define KVM_INTERRUPT_UNSET -2U
+#define KVM_EXIT_FAIL_ENTRY_NO_VSFILE (1ULL << 0)
+
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
};
@@ -211,6 +213,7 @@ enum KVM_RISCV_SBI_EXT_ID {
KVM_RISCV_SBI_EXT_STA,
KVM_RISCV_SBI_EXT_SUSP,
KVM_RISCV_SBI_EXT_FWFT,
+ KVM_RISCV_SBI_EXT_MPXY,
KVM_RISCV_SBI_EXT_MAX,
};
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 72ca768f4e91..b057362f8fb5 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -472,6 +472,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(zaamo, RISCV_ISA_EXT_ZAAMO),
__RISCV_ISA_EXT_DATA(zabha, RISCV_ISA_EXT_ZABHA),
__RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS),
+ __RISCV_ISA_EXT_DATA(zalasr, RISCV_ISA_EXT_ZALASR),
__RISCV_ISA_EXT_DATA(zalrsc, RISCV_ISA_EXT_ZALRSC),
__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
__RISCV_ISA_EXT_DATA_VALIDATE(zfa, RISCV_ISA_EXT_ZFA, riscv_ext_f_depends),
@@ -539,6 +540,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),
__RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT),
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
+ __RISCV_ISA_EXT_DATA(svrsw60t59b, RISCV_ISA_EXT_SVRSW60T59B),
__RISCV_ISA_EXT_DATA(svvptc, RISCV_ISA_EXT_SVVPTC),
};
diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c
index 9f3db3503dab..15fec5d1e6de 100644
--- a/arch/riscv/kernel/kgdb.c
+++ b/arch/riscv/kernel/kgdb.c
@@ -265,10 +265,10 @@ void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer,
{
if (!strncmp(remcom_in_buffer, gdb_xfer_read_target,
sizeof(gdb_xfer_read_target)))
- strcpy(remcom_out_buffer, riscv_gdb_stub_target_desc);
+ strscpy(remcom_out_buffer, riscv_gdb_stub_target_desc, BUFMAX);
else if (!strncmp(remcom_in_buffer, gdb_xfer_read_cpuxml,
sizeof(gdb_xfer_read_cpuxml)))
- strcpy(remcom_out_buffer, riscv_gdb_stub_cpuxml);
+ strscpy(remcom_out_buffer, riscv_gdb_stub_cpuxml, BUFMAX);
}
static inline void kgdb_arch_update_addr(struct pt_regs *regs,
diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c
index 75551ac6504c..1675cbad8619 100644
--- a/arch/riscv/kernel/module-sections.c
+++ b/arch/riscv/kernel/module-sections.c
@@ -119,6 +119,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
unsigned int num_plts = 0;
unsigned int num_gots = 0;
Elf_Rela *scratch = NULL;
+ Elf_Rela *new_scratch;
size_t scratch_size = 0;
int i;
@@ -168,9 +169,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
scratch_size_needed = (num_scratch_relas + num_relas) * sizeof(*scratch);
if (scratch_size_needed > scratch_size) {
scratch_size = scratch_size_needed;
- scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL);
- if (!scratch)
+ new_scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL);
+ if (!new_scratch) {
+ kvfree(scratch);
return -ENOMEM;
+ }
+ scratch = new_scratch;
}
for (size_t j = 0; j < num_relas; j++)
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 8e86305831ea..e6272d74572f 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -153,6 +153,17 @@ static int riscv_vr_set(struct task_struct *target,
0, riscv_v_vsize);
return ret;
}
+
+static int riscv_vr_active(struct task_struct *target, const struct user_regset *regset)
+{
+ if (!(has_vector() || has_xtheadvector()))
+ return -ENODEV;
+
+ if (!riscv_v_vstate_query(task_pt_regs(target)))
+ return 0;
+
+ return regset->n;
+}
#endif
#ifdef CONFIG_RISCV_ISA_SUPM
@@ -184,7 +195,7 @@ static int tagged_addr_ctrl_set(struct task_struct *target,
}
#endif
-static const struct user_regset riscv_user_regset[] = {
+static struct user_regset riscv_user_regset[] __ro_after_init = {
[REGSET_X] = {
USER_REGSET_NOTE_TYPE(PRSTATUS),
.n = ELF_NGREG,
@@ -207,11 +218,10 @@ static const struct user_regset riscv_user_regset[] = {
[REGSET_V] = {
USER_REGSET_NOTE_TYPE(RISCV_VECTOR),
.align = 16,
- .n = ((32 * RISCV_MAX_VLENB) +
- sizeof(struct __riscv_v_regset_state)) / sizeof(__u32),
.size = sizeof(__u32),
.regset_get = riscv_vr_get,
.set = riscv_vr_set,
+ .active = riscv_vr_active,
},
#endif
#ifdef CONFIG_RISCV_ISA_SUPM
@@ -233,6 +243,14 @@ static const struct user_regset_view riscv_user_native_view = {
.n = ARRAY_SIZE(riscv_user_regset),
};
+#ifdef CONFIG_RISCV_ISA_V
+void __init update_regset_vector_info(unsigned long size)
+{
+ riscv_user_regset[REGSET_V].n = (size + sizeof(struct __riscv_v_regset_state)) /
+ sizeof(__u32);
+}
+#endif
+
struct pt_regs_offset {
const char *name;
int offset;
diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
index 5e8cde055264..c443337056ab 100644
--- a/arch/riscv/kernel/sbi.c
+++ b/arch/riscv/kernel/sbi.c
@@ -648,9 +648,9 @@ int sbi_debug_console_read(char *bytes, unsigned int num_bytes)
void __init sbi_init(void)
{
+ bool srst_power_off = false;
int ret;
- sbi_set_power_off();
ret = sbi_get_spec_version();
if (ret > 0)
sbi_spec_version = ret;
@@ -683,6 +683,7 @@ void __init sbi_init(void)
sbi_probe_extension(SBI_EXT_SRST)) {
pr_info("SBI SRST extension detected\n");
register_platform_power_off(sbi_srst_power_off);
+ srst_power_off = true;
sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot;
sbi_srst_reboot_nb.priority = 192;
register_restart_handler(&sbi_srst_reboot_nb);
@@ -702,4 +703,7 @@ void __init sbi_init(void)
__sbi_send_ipi = __sbi_send_ipi_v01;
__sbi_rfence = __sbi_rfence_v01;
}
+
+ if (!srst_power_off)
+ sbi_set_power_off();
}
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index 601a321e0f17..d85916a3660c 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -39,7 +39,9 @@
#include "head.h"
+#ifndef CONFIG_HOTPLUG_PARALLEL
static DECLARE_COMPLETION(cpu_running);
+#endif
void __init smp_prepare_cpus(unsigned int max_cpus)
{
@@ -179,6 +181,12 @@ static int start_secondary_cpu(int cpu, struct task_struct *tidle)
return -EOPNOTSUPP;
}
+#ifdef CONFIG_HOTPLUG_PARALLEL
+int arch_cpuhp_kick_ap_alive(unsigned int cpu, struct task_struct *tidle)
+{
+ return start_secondary_cpu(cpu, tidle);
+}
+#else
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
int ret = 0;
@@ -199,6 +207,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
return ret;
}
+#endif
void __init smp_cpus_done(unsigned int max_cpus)
{
@@ -225,6 +234,10 @@ asmlinkage __visible void smp_callin(void)
mmgrab(mm);
current->active_mm = mm;
+#ifdef CONFIG_HOTPLUG_PARALLEL
+ cpuhp_ap_sync_alive();
+#endif
+
store_cpu_topology(curr_cpuid);
notify_cpu_starting(curr_cpuid);
@@ -243,7 +256,9 @@ asmlinkage __visible void smp_callin(void)
*/
local_flush_icache_all();
local_flush_tlb_all();
+#ifndef CONFIG_HOTPLUG_PARALLEL
complete(&cpu_running);
+#endif
/*
* Disable preemption before enabling interrupts, so we don't try to
* schedule a CPU that hasn't actually started yet.
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index 3fe9e6edef8f..b41b6255751c 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -16,6 +16,22 @@
#ifdef CONFIG_FRAME_POINTER
+/*
+ * This disables KASAN checking when reading a value from another task's stack,
+ * since the other task could be running on another CPU and could have poisoned
+ * the stack in the meantime.
+ */
+#define READ_ONCE_TASK_STACK(task, x) \
+({ \
+ unsigned long val; \
+ unsigned long addr = x; \
+ if ((task) == current) \
+ val = READ_ONCE(addr); \
+ else \
+ val = READ_ONCE_NOCHECK(addr); \
+ val; \
+})
+
extern asmlinkage void handle_exception(void);
extern unsigned long ret_from_exception_end;
@@ -69,8 +85,9 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
fp = frame->ra;
pc = regs->ra;
} else {
- fp = frame->fp;
- pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
+ fp = READ_ONCE_TASK_STACK(task, frame->fp);
+ pc = READ_ONCE_TASK_STACK(task, frame->ra);
+ pc = ftrace_graph_ret_addr(current, &graph_idx, pc,
&frame->ra);
if (pc >= (unsigned long)handle_exception &&
pc < (unsigned long)&ret_from_exception_end) {
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 199d13f86f31..0f701ace3bb9 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -109,6 +109,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
EXT_KEY(ZAAMO);
EXT_KEY(ZABHA);
EXT_KEY(ZACAS);
+ EXT_KEY(ZALASR);
EXT_KEY(ZALRSC);
EXT_KEY(ZAWRS);
EXT_KEY(ZBA);
@@ -122,6 +123,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
EXT_KEY(ZCB);
EXT_KEY(ZCMOP);
EXT_KEY(ZICBOM);
+ EXT_KEY(ZICBOP);
EXT_KEY(ZICBOZ);
EXT_KEY(ZICNTR);
EXT_KEY(ZICOND);
@@ -302,6 +304,11 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
pair->value = riscv_cbom_block_size;
break;
+ case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
+ pair->value = 0;
+ if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
+ pair->value = riscv_cbop_block_size;
+ break;
case RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS:
pair->value = user_max_virt_addr();
break;
diff --git a/arch/riscv/kernel/tests/Kconfig.debug b/arch/riscv/kernel/tests/Kconfig.debug
index 5db4df44279e..40f8dafffa0a 100644
--- a/arch/riscv/kernel/tests/Kconfig.debug
+++ b/arch/riscv/kernel/tests/Kconfig.debug
@@ -31,7 +31,7 @@ config RISCV_MODULE_LINKING_KUNIT
If unsure, say N.
config RISCV_KPROBES_KUNIT
- bool "KUnit test for riscv kprobes" if !KUNIT_ALL_TESTS
+ tristate "KUnit test for riscv kprobes" if !KUNIT_ALL_TESTS
depends on KUNIT
depends on KPROBES
default KUNIT_ALL_TESTS
diff --git a/arch/riscv/kernel/tests/kprobes/Makefile b/arch/riscv/kernel/tests/kprobes/Makefile
index 4cb6c66a98e8..df7256f62313 100644
--- a/arch/riscv/kernel/tests/kprobes/Makefile
+++ b/arch/riscv/kernel/tests/kprobes/Makefile
@@ -1 +1,3 @@
-obj-y += test-kprobes.o test-kprobes-asm.o
+obj-$(CONFIG_RISCV_KPROBES_KUNIT) += kprobes_riscv_kunit.o
+
+kprobes_riscv_kunit-objs := test-kprobes.o test-kprobes-asm.o
diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes.c b/arch/riscv/kernel/tests/kprobes/test-kprobes.c
index 6f6cdfbf5a95..664535ca0a98 100644
--- a/arch/riscv/kernel/tests/kprobes/test-kprobes.c
+++ b/arch/riscv/kernel/tests/kprobes/test-kprobes.c
@@ -49,8 +49,11 @@ static struct kunit_case kprobes_testcases[] = {
};
static struct kunit_suite kprobes_test_suite = {
- .name = "kprobes_test_riscv",
+ .name = "kprobes_riscv",
.test_cases = kprobes_testcases,
};
kunit_test_suites(&kprobes_test_suite);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("KUnit test for riscv kprobes");
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 901e67adf576..3ed071dab9d8 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -66,6 +66,8 @@ void __init riscv_v_setup_ctx_cache(void)
if (!(has_vector() || has_xtheadvector()))
return;
+ update_regset_vector_info(riscv_v_vsize);
+
riscv_v_user_cachep = kmem_cache_create_usercopy("riscv_vector_ctx",
riscv_v_vsize, 16, SLAB_PANIC,
0, riscv_v_vsize, NULL);
diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig
index c50328212917..77379f77840a 100644
--- a/arch/riscv/kvm/Kconfig
+++ b/arch/riscv/kvm/Kconfig
@@ -23,7 +23,6 @@ config KVM
select HAVE_KVM_IRQCHIP
select HAVE_KVM_IRQ_ROUTING
select HAVE_KVM_MSI
- select HAVE_KVM_VCPU_ASYNC_IOCTL
select HAVE_KVM_READONLY_MEM
select HAVE_KVM_DIRTY_RING_ACQ_REL
select KVM_COMMON
diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile
index 07197395750e..3b8afb038b35 100644
--- a/arch/riscv/kvm/Makefile
+++ b/arch/riscv/kvm/Makefile
@@ -27,6 +27,7 @@ kvm-y += vcpu_onereg.o
kvm-$(CONFIG_RISCV_PMU_SBI) += vcpu_pmu.o
kvm-y += vcpu_sbi.o
kvm-y += vcpu_sbi_base.o
+kvm-y += vcpu_sbi_forward.o
kvm-y += vcpu_sbi_fwft.o
kvm-y += vcpu_sbi_hsm.o
kvm-$(CONFIG_RISCV_PMU_SBI) += vcpu_sbi_pmu.o
diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
index fda0346f0ea1..e597e86491c3 100644
--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -689,8 +689,20 @@ bool kvm_riscv_vcpu_aia_imsic_has_interrupt(struct kvm_vcpu *vcpu)
*/
read_lock_irqsave(&imsic->vsfile_lock, flags);
- if (imsic->vsfile_cpu > -1)
- ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
+ if (imsic->vsfile_cpu > -1) {
+ /*
+ * This function is typically called from kvm_vcpu_block() via
+ * kvm_arch_vcpu_runnable() upon WFI trap. The kvm_vcpu_block()
+ * can be preempted and the blocking VCPU might resume on a
+ * different CPU. This means it is possible that current CPU
+ * does not match the imsic->vsfile_cpu hence this function
+ * must check imsic->vsfile_cpu before accessing HGEIP CSR.
+ */
+ if (imsic->vsfile_cpu != vcpu->cpu)
+ ret = true;
+ else
+ ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
+ }
read_unlock_irqrestore(&imsic->vsfile_lock, flags);
return ret;
@@ -802,7 +814,7 @@ int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
/* For HW acceleration mode, we can't continue */
if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_HWACCEL) {
run->fail_entry.hardware_entry_failure_reason =
- CSR_HSTATUS;
+ KVM_EXIT_FAIL_ENTRY_NO_VSFILE;
run->fail_entry.cpu = vcpu->cpu;
run->exit_reason = KVM_EXIT_FAIL_ENTRY;
return 0;
diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c
index 77dc1655b442..45536af521f0 100644
--- a/arch/riscv/kvm/main.c
+++ b/arch/riscv/kvm/main.c
@@ -15,6 +15,18 @@
#include <asm/kvm_nacl.h>
#include <asm/sbi.h>
+DEFINE_STATIC_KEY_FALSE(kvm_riscv_vsstage_tlb_no_gpa);
+
+static void kvm_riscv_setup_vendor_features(void)
+{
+ /* Andes AX66: split two-stage TLBs */
+ if (riscv_cached_mvendorid(0) == ANDES_VENDOR_ID &&
+ (riscv_cached_marchid(0) & 0xFFFF) == 0x8A66) {
+ static_branch_enable(&kvm_riscv_vsstage_tlb_no_gpa);
+ kvm_info("VS-stage TLB does not cache guest physical address and VMID\n");
+ }
+}
+
long kvm_arch_dev_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -160,6 +172,8 @@ static int __init riscv_kvm_init(void)
kvm_info("AIA available with %d guest external interrupts\n",
kvm_riscv_aia_nr_hgei);
+ kvm_riscv_setup_vendor_features();
+
kvm_register_perf_callbacks(NULL);
rc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c
index 525fb5a330c0..4ab06697bfc0 100644
--- a/arch/riscv/kvm/mmu.c
+++ b/arch/riscv/kvm/mmu.c
@@ -161,8 +161,11 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
* allocated dirty_bitmap[], dirty pages will be tracked while
* the memory slot is write protected.
*/
- if (change != KVM_MR_DELETE && new->flags & KVM_MEM_LOG_DIRTY_PAGES)
+ if (change != KVM_MR_DELETE && new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
+ if (kvm_dirty_log_manual_protect_and_init_set(kvm))
+ return;
mmu_wp_memory_region(kvm, new->id);
+ }
}
int kvm_arch_prepare_memory_region(struct kvm *kvm,
@@ -171,7 +174,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
enum kvm_mr_change change)
{
hva_t hva, reg_end, size;
- gpa_t base_gpa;
bool writable;
int ret = 0;
@@ -190,15 +192,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
hva = new->userspace_addr;
size = new->npages << PAGE_SHIFT;
reg_end = hva + size;
- base_gpa = new->base_gfn << PAGE_SHIFT;
writable = !(new->flags & KVM_MEM_READONLY);
mmap_read_lock(current->mm);
/*
* A memory region could potentially cover multiple VMAs, and
- * any holes between them, so iterate over all of them to find
- * out if we can map any of them right now.
+ * any holes between them, so iterate over all of them.
*
* +--------------------------------------------+
* +---------------+----------------+ +----------------+
@@ -209,7 +209,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
*/
do {
struct vm_area_struct *vma;
- hva_t vm_start, vm_end;
+ hva_t vm_end;
vma = find_vma_intersection(current->mm, hva, reg_end);
if (!vma)
@@ -225,36 +225,18 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
}
/* Take the intersection of this VMA with the memory region */
- vm_start = max(hva, vma->vm_start);
vm_end = min(reg_end, vma->vm_end);
if (vma->vm_flags & VM_PFNMAP) {
- gpa_t gpa = base_gpa + (vm_start - hva);
- phys_addr_t pa;
-
- pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
- pa += vm_start - vma->vm_start;
-
/* IO region dirty page logging not allowed */
if (new->flags & KVM_MEM_LOG_DIRTY_PAGES) {
ret = -EINVAL;
goto out;
}
-
- ret = kvm_riscv_mmu_ioremap(kvm, gpa, pa, vm_end - vm_start,
- writable, false);
- if (ret)
- break;
}
hva = vm_end;
} while (hva < reg_end);
- if (change == KVM_MR_FLAGS_ONLY)
- goto out;
-
- if (ret)
- kvm_riscv_mmu_iounmap(kvm, base_gpa, size);
-
out:
mmap_read_unlock(current->mm);
return ret;
diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c
index 3c5a70a2b927..ff1aeac4eb8e 100644
--- a/arch/riscv/kvm/tlb.c
+++ b/arch/riscv/kvm/tlb.c
@@ -158,6 +158,36 @@ void kvm_riscv_local_hfence_vvma_all(unsigned long vmid)
csr_write(CSR_HGATP, hgatp);
}
+void kvm_riscv_local_tlb_sanitize(struct kvm_vcpu *vcpu)
+{
+ unsigned long vmid;
+
+ if (!kvm_riscv_gstage_vmid_bits() ||
+ vcpu->arch.last_exit_cpu == vcpu->cpu)
+ return;
+
+ /*
+ * On RISC-V platforms with hardware VMID support, we share same
+ * VMID for all VCPUs of a particular Guest/VM. This means we might
+ * have stale G-stage TLB entries on the current Host CPU due to
+ * some other VCPU of the same Guest which ran previously on the
+ * current Host CPU.
+ *
+ * To cleanup stale TLB entries, we simply flush all G-stage TLB
+ * entries by VMID whenever underlying Host CPU changes for a VCPU.
+ */
+
+ vmid = READ_ONCE(vcpu->kvm->arch.vmid.vmid);
+ kvm_riscv_local_hfence_gvma_vmid_all(vmid);
+
+ /*
+ * Flush VS-stage TLB entries for implementation where VS-stage
+ * TLB does not cahce guest physical address and VMID.
+ */
+ if (static_branch_unlikely(&kvm_riscv_vsstage_tlb_no_gpa))
+ kvm_riscv_local_hfence_vvma_all(vmid);
+}
+
void kvm_riscv_fence_i_process(struct kvm_vcpu *vcpu)
{
kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_FENCE_I_RCVD);
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index bccb919ca615..a55a95da54d0 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -212,7 +212,7 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
{
- return (kvm_riscv_vcpu_has_interrupts(vcpu, -1UL) &&
+ return (kvm_riscv_vcpu_has_interrupts(vcpu, -1ULL) &&
!kvm_riscv_vcpu_stopped(vcpu) && !vcpu->arch.pause);
}
@@ -238,8 +238,8 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
}
-long kvm_arch_vcpu_async_ioctl(struct file *filp,
- unsigned int ioctl, unsigned long arg)
+long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl,
+ unsigned long arg)
{
struct kvm_vcpu *vcpu = filp->private_data;
void __user *argp = (void __user *)arg;
@@ -968,7 +968,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
* Note: This should be done after G-stage VMID has been
* updated using kvm_riscv_gstage_vmid_ver_changed()
*/
- kvm_riscv_gstage_vmid_sanitize(vcpu);
+ kvm_riscv_local_tlb_sanitize(vcpu);
trace_kvm_entry(vcpu);
diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c
index de1f96ea6225..4d89b94128ae 100644
--- a/arch/riscv/kvm/vcpu_insn.c
+++ b/arch/riscv/kvm/vcpu_insn.c
@@ -298,6 +298,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
return (rc <= 0) ? rc : 1;
}
+static bool is_load_guest_page_fault(unsigned long scause)
+{
+ /**
+ * If a g-stage page fault occurs, the direct approach
+ * is to let the g-stage page fault handler handle it
+ * naturally, however, calling the g-stage page fault
+ * handler here seems rather strange.
+ * Considering this is a corner case, we can directly
+ * return to the guest and re-execute the same PC, this
+ * will trigger a g-stage page fault again and then the
+ * regular g-stage page fault handler will populate
+ * g-stage page table.
+ */
+ return (scause == EXC_LOAD_GUEST_PAGE_FAULT);
+}
+
/**
* kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap
*
@@ -323,6 +339,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
ct->sepc,
&utrap);
if (utrap.scause) {
+ if (is_load_guest_page_fault(utrap.scause))
+ return 1;
utrap.sepc = ct->sepc;
kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
return 1;
@@ -378,6 +396,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run,
insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc,
&utrap);
if (utrap.scause) {
+ if (is_load_guest_page_fault(utrap.scause))
+ return 1;
/* Redirect trap if we failed to read instruction */
utrap.sepc = ct->sepc;
kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
@@ -504,6 +524,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run,
insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc,
&utrap);
if (utrap.scause) {
+ if (is_load_guest_page_fault(utrap.scause))
+ return 1;
/* Redirect trap if we failed to read instruction */
utrap.sepc = ct->sepc;
kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index 1b13623380e1..46ab7b989432 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -83,6 +83,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = {
.ext_ptr = &vcpu_sbi_ext_fwft,
},
{
+ .ext_idx = KVM_RISCV_SBI_EXT_MPXY,
+ .ext_ptr = &vcpu_sbi_ext_mpxy,
+ },
+ {
.ext_idx = KVM_RISCV_SBI_EXT_EXPERIMENTAL,
.ext_ptr = &vcpu_sbi_ext_experimental,
},
@@ -120,7 +124,9 @@ static bool riscv_vcpu_supports_sbi_ext(struct kvm_vcpu *vcpu, int idx)
return sext && scontext->ext_status[sext->ext_idx] != KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE;
}
-void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
+int kvm_riscv_vcpu_sbi_forward_handler(struct kvm_vcpu *vcpu,
+ struct kvm_run *run,
+ struct kvm_vcpu_sbi_return *retdata)
{
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
@@ -137,6 +143,8 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->riscv_sbi.args[5] = cp->a5;
run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
run->riscv_sbi.ret[1] = 0;
+ retdata->uexit = true;
+ return 0;
}
void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
diff --git a/arch/riscv/kvm/vcpu_sbi_base.c b/arch/riscv/kvm/vcpu_sbi_base.c
index 5bc570b984f4..06fdd5f69364 100644
--- a/arch/riscv/kvm/vcpu_sbi_base.c
+++ b/arch/riscv/kvm/vcpu_sbi_base.c
@@ -41,8 +41,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
* For experimental/vendor extensions
* forward it to the userspace
*/
- kvm_riscv_vcpu_sbi_forward(vcpu, run);
- retdata->uexit = true;
+ return kvm_riscv_vcpu_sbi_forward_handler(vcpu, run, retdata);
} else {
sbi_ext = kvm_vcpu_sbi_find_ext(vcpu, cp->a0);
*out_val = sbi_ext && sbi_ext->probe ?
@@ -71,28 +70,3 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base = {
.extid_end = SBI_EXT_BASE,
.handler = kvm_sbi_ext_base_handler,
};
-
-static int kvm_sbi_ext_forward_handler(struct kvm_vcpu *vcpu,
- struct kvm_run *run,
- struct kvm_vcpu_sbi_return *retdata)
-{
- /*
- * Both SBI experimental and vendor extensions are
- * unconditionally forwarded to userspace.
- */
- kvm_riscv_vcpu_sbi_forward(vcpu, run);
- retdata->uexit = true;
- return 0;
-}
-
-const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental = {
- .extid_start = SBI_EXT_EXPERIMENTAL_START,
- .extid_end = SBI_EXT_EXPERIMENTAL_END,
- .handler = kvm_sbi_ext_forward_handler,
-};
-
-const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor = {
- .extid_start = SBI_EXT_VENDOR_START,
- .extid_end = SBI_EXT_VENDOR_END,
- .handler = kvm_sbi_ext_forward_handler,
-};
diff --git a/arch/riscv/kvm/vcpu_sbi_forward.c b/arch/riscv/kvm/vcpu_sbi_forward.c
new file mode 100644
index 000000000000..5a3c75eb23c5
--- /dev/null
+++ b/arch/riscv/kvm/vcpu_sbi_forward.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Ventana Micro Systems Inc.
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_vcpu_sbi.h>
+#include <asm/sbi.h>
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental = {
+ .extid_start = SBI_EXT_EXPERIMENTAL_START,
+ .extid_end = SBI_EXT_EXPERIMENTAL_END,
+ .handler = kvm_riscv_vcpu_sbi_forward_handler,
+};
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor = {
+ .extid_start = SBI_EXT_VENDOR_START,
+ .extid_end = SBI_EXT_VENDOR_END,
+ .handler = kvm_riscv_vcpu_sbi_forward_handler,
+};
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn = {
+ .extid_start = SBI_EXT_DBCN,
+ .extid_end = SBI_EXT_DBCN,
+ .default_disabled = true,
+ .handler = kvm_riscv_vcpu_sbi_forward_handler,
+};
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_mpxy = {
+ .extid_start = SBI_EXT_MPXY,
+ .extid_end = SBI_EXT_MPXY,
+ .default_disabled = true,
+ .handler = kvm_riscv_vcpu_sbi_forward_handler,
+};
diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c
index b490ed1428a6..506a510b6bff 100644
--- a/arch/riscv/kvm/vcpu_sbi_replace.c
+++ b/arch/riscv/kvm/vcpu_sbi_replace.c
@@ -185,35 +185,3 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = {
.extid_end = SBI_EXT_SRST,
.handler = kvm_sbi_ext_srst_handler,
};
-
-static int kvm_sbi_ext_dbcn_handler(struct kvm_vcpu *vcpu,
- struct kvm_run *run,
- struct kvm_vcpu_sbi_return *retdata)
-{
- struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
- unsigned long funcid = cp->a6;
-
- switch (funcid) {
- case SBI_EXT_DBCN_CONSOLE_WRITE:
- case SBI_EXT_DBCN_CONSOLE_READ:
- case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
- /*
- * The SBI debug console functions are unconditionally
- * forwarded to the userspace.
- */
- kvm_riscv_vcpu_sbi_forward(vcpu, run);
- retdata->uexit = true;
- break;
- default:
- retdata->err_val = SBI_ERR_NOT_SUPPORTED;
- }
-
- return 0;
-}
-
-const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn = {
- .extid_start = SBI_EXT_DBCN,
- .extid_end = SBI_EXT_DBCN,
- .default_disabled = true,
- .handler = kvm_sbi_ext_dbcn_handler,
-};
diff --git a/arch/riscv/kvm/vcpu_sbi_system.c b/arch/riscv/kvm/vcpu_sbi_system.c
index 359be90b0fc5..c6f7e609ac79 100644
--- a/arch/riscv/kvm/vcpu_sbi_system.c
+++ b/arch/riscv/kvm/vcpu_sbi_system.c
@@ -47,9 +47,7 @@ static int kvm_sbi_ext_susp_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
kvm_riscv_vcpu_sbi_request_reset(vcpu, cp->a1, cp->a2);
/* userspace provides the suspend implementation */
- kvm_riscv_vcpu_sbi_forward(vcpu, run);
- retdata->uexit = true;
- break;
+ return kvm_riscv_vcpu_sbi_forward_handler(vcpu, run, retdata);
default:
retdata->err_val = SBI_ERR_NOT_SUPPORTED;
break;
diff --git a/arch/riscv/kvm/vcpu_sbi_v01.c b/arch/riscv/kvm/vcpu_sbi_v01.c
index 368dfddd23d9..188d5ea5b3b8 100644
--- a/arch/riscv/kvm/vcpu_sbi_v01.c
+++ b/arch/riscv/kvm/vcpu_sbi_v01.c
@@ -32,8 +32,7 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
* The CONSOLE_GETCHAR/CONSOLE_PUTCHAR SBI calls cannot be
* handled in kernel so we forward these to user-space
*/
- kvm_riscv_vcpu_sbi_forward(vcpu, run);
- retdata->uexit = true;
+ ret = kvm_riscv_vcpu_sbi_forward_handler(vcpu, run, retdata);
break;
case SBI_EXT_0_1_SET_TIMER:
#if __riscv_xlen == 32
diff --git a/arch/riscv/kvm/vmid.c b/arch/riscv/kvm/vmid.c
index abb1c2bf2542..cf34d448289d 100644
--- a/arch/riscv/kvm/vmid.c
+++ b/arch/riscv/kvm/vmid.c
@@ -122,26 +122,3 @@ void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu)
kvm_for_each_vcpu(i, v, vcpu->kvm)
kvm_make_request(KVM_REQ_UPDATE_HGATP, v);
}
-
-void kvm_riscv_gstage_vmid_sanitize(struct kvm_vcpu *vcpu)
-{
- unsigned long vmid;
-
- if (!kvm_riscv_gstage_vmid_bits() ||
- vcpu->arch.last_exit_cpu == vcpu->cpu)
- return;
-
- /*
- * On RISC-V platforms with hardware VMID support, we share same
- * VMID for all VCPUs of a particular Guest/VM. This means we might
- * have stale G-stage TLB entries on the current Host CPU due to
- * some other VCPU of the same Guest which ran previously on the
- * current Host CPU.
- *
- * To cleanup stale TLB entries, we simply flush all G-stage TLB
- * entries by VMID whenever underlying Host CPU changes for a VCPU.
- */
-
- vmid = READ_ONCE(vcpu->kvm->arch.vmid.vmid);
- kvm_riscv_local_hfence_gvma_vmid_all(vmid);
-}
diff --git a/arch/riscv/lib/csum.c b/arch/riscv/lib/csum.c
index 9408f50ca59a..75bd0abffd63 100644
--- a/arch/riscv/lib/csum.c
+++ b/arch/riscv/lib/csum.c
@@ -40,20 +40,11 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
uproto = (__force unsigned int)htonl(proto);
sum += uproto;
- if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) {
+ if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) &&
+ IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) &&
+ riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) {
unsigned long fold_temp;
- /*
- * Zbb is likely available when the kernel is compiled with Zbb
- * support, so nop when Zbb is available and jump when Zbb is
- * not available.
- */
- asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- :
- :
- :
- : no_zbb);
asm(".option push \n\
.option arch,+zbb \n\
rori %[fold_temp], %[sum], 32 \n\
@@ -66,7 +57,7 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
: [sum] "+r" (sum), [fold_temp] "=&r" (fold_temp));
return (__force __sum16)(sum >> 16);
}
-no_zbb:
+
sum += ror64(sum, 32);
sum >>= 32;
return csum_fold((__force __wsum)sum);
@@ -152,21 +143,11 @@ do_csum_with_alignment(const unsigned char *buff, int len)
csum = do_csum_common(ptr, end, data);
#ifdef CC_HAS_ASM_GOTO_TIED_OUTPUT
- if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) {
+ if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) &&
+ IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) &&
+ riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) {
unsigned long fold_temp;
- /*
- * Zbb is likely available when the kernel is compiled with Zbb
- * support, so nop when Zbb is available and jump when Zbb is
- * not available.
- */
- asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- :
- :
- :
- : no_zbb);
-
#ifdef CONFIG_32BIT
asm_goto_output(".option push \n\
.option arch,+zbb \n\
@@ -204,7 +185,7 @@ do_csum_with_alignment(const unsigned char *buff, int len)
end:
return csum >> 16;
}
-no_zbb:
+
#endif /* CC_HAS_ASM_GOTO_TIED_OUTPUT */
#ifndef CONFIG_32BIT
csum += ror64(csum, 32);
@@ -234,21 +215,11 @@ do_csum_no_alignment(const unsigned char *buff, int len)
end = (const unsigned long *)(buff + len);
csum = do_csum_common(ptr, end, data);
- if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) {
+ if (IS_ENABLED(CONFIG_RISCV_ISA_ZBB) &&
+ IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB) &&
+ riscv_has_extension_likely(RISCV_ISA_EXT_ZBB)) {
unsigned long fold_temp;
- /*
- * Zbb is likely available when the kernel is compiled with Zbb
- * support, so nop when Zbb is available and jump when Zbb is
- * not available.
- */
- asm goto(ALTERNATIVE("j %l[no_zbb]", "nop", 0,
- RISCV_ISA_EXT_ZBB, 1)
- :
- :
- :
- : no_zbb);
-
#ifdef CONFIG_32BIT
asm (".option push \n\
.option arch,+zbb \n\
@@ -274,7 +245,7 @@ do_csum_no_alignment(const unsigned char *buff, int len)
#endif /* !CONFIG_32BIT */
return csum >> 16;
}
-no_zbb:
+
#ifndef CONFIG_32BIT
csum += ror64(csum, 32);
csum >>= 32;
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index d85efe74a4b6..addb8a9305be 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -441,7 +441,7 @@ static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va)
static phys_addr_t __meminit alloc_pte_late(uintptr_t va)
{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0);
+ struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
/*
* We do not know which mm the PTE page is associated to at this point.
@@ -526,7 +526,7 @@ static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va)
static phys_addr_t __meminit alloc_pmd_late(uintptr_t va)
{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 0);
+ struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
/* See comment in alloc_pte_late() regarding NULL passed the ctor */
BUG_ON(!ptdesc || !pagetable_pmd_ctor(NULL, ptdesc));
diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c
index 8b6c0a112a8d..807c0a0de182 100644
--- a/arch/riscv/mm/pgtable.c
+++ b/arch/riscv/mm/pgtable.c
@@ -9,8 +9,16 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep,
pte_t entry, int dirty)
{
- asm goto(ALTERNATIVE("nop", "j %l[svvptc]", 0, RISCV_ISA_EXT_SVVPTC, 1)
- : : : : svvptc);
+ if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC)) {
+ if (!pte_same(ptep_get(ptep), entry)) {
+ __set_pte_at(vma->vm_mm, ptep, entry);
+ /* Here only not svadu is impacted */
+ flush_tlb_page(vma, address);
+ return true;
+ }
+
+ return false;
+ }
if (!pte_same(ptep_get(ptep), entry))
__set_pte_at(vma->vm_mm, ptep, entry);
@@ -19,16 +27,6 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
* the case that the PTE changed and the spurious fault case.
*/
return true;
-
-svvptc:
- if (!pte_same(ptep_get(ptep), entry)) {
- __set_pte_at(vma->vm_mm, ptep, entry);
- /* Here only not svadu is impacted */
- flush_tlb_page(vma, address);
- return true;
- }
-
- return false;
}
int ptep_test_and_clear_young(struct vm_area_struct *vma,
diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
index 3b51690cc876..34299c2b231f 100644
--- a/arch/riscv/mm/ptdump.c
+++ b/arch/riscv/mm/ptdump.c
@@ -21,7 +21,7 @@
#define pt_dump_seq_puts(m, fmt) \
({ \
if (m) \
- seq_printf(m, fmt); \
+ seq_puts(m, fmt); \
})
/*
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index 45cbc7c6fe49..5f9457e910e8 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -852,17 +852,19 @@ static int gen_jump_or_nops(void *target, void *ip, u32 *insns, bool is_call)
return emit_jump_and_link(is_call ? RV_REG_T0 : RV_REG_ZERO, rvoff, false, &ctx);
}
-int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
- void *old_addr, void *new_addr)
+int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
+ enum bpf_text_poke_type new_t, void *old_addr,
+ void *new_addr)
{
u32 old_insns[RV_FENTRY_NINSNS], new_insns[RV_FENTRY_NINSNS];
- bool is_call = poke_type == BPF_MOD_CALL;
+ bool is_call;
int ret;
if (!is_kernel_text((unsigned long)ip) &&
!is_bpf_text_address((unsigned long)ip))
return -ENOTSUPP;
+ is_call = old_t == BPF_MOD_CALL;
ret = gen_jump_or_nops(old_addr, ip, old_insns, is_call);
if (ret)
return ret;
@@ -870,6 +872,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
if (memcmp(ip, old_insns, RV_FENTRY_NBYTES))
return -EFAULT;
+ is_call = new_t == BPF_MOD_CALL;
ret = gen_jump_or_nops(new_addr, ip, new_insns, is_call);
if (ret)
return ret;
@@ -1131,7 +1134,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
store_args(nr_arg_slots, args_off, ctx);
/* skip to actual body of traced function */
- if (flags & BPF_TRAMP_F_SKIP_FRAME)
+ if (flags & BPF_TRAMP_F_ORIG_STACK)
orig_call += RV_FENTRY_NINSNS * 4;
if (flags & BPF_TRAMP_F_CALL_ORIG) {