* [PATCH v2 0/9] Kendryte k210 SoC boards support
@ 2020-03-12 5:10 Damien Le Moal
2020-03-12 5:10 ` [PATCH v2 1/9] riscv: Unaligned load/store handling for M_MODE Damien Le Moal
` (8 more replies)
0 siblings, 9 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:10 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
This series adds support to boot nommu Linux on Kendryte K210 SoC based
boards. This is all based on initial work done by Christoph Hellwig.
Patch 1 adds unaligned load/store trap handlers for M-mode.
Patch 2 enables a builtin DTB to allow passing a device tree to the
kernel when the board bootchain is not able to pass one. This option
can be used only for NOMMU kernels for now
Patch 3 introduces an early SoC initialization enabling very early
hardware initialization not possible with device tree entries pointing
to drivers. This is used in patch 6 which introduces a sysctl driver for
the K210 SoC. The early SoC initialization is used to enable the
additional 2MB of SRAM normally reserved to the SoC AI chip.
Patch 4 to 9 add necessary Kconfig changes, a defconfig, a generic
device tree suitable for many K210 boards and compilation of a bootable
image file (bin file) that can be used to flash on K210 board ROM.
Finally, patch 9 disables PMP initialization for K210 SoCs.
This series was tested on the Kendryte KD233 development board, the
Sipeed MAIX dan dock board and the Sipeed MAIXDUINO board. The userspace
used was built using a modified buildroot tree for the toolchain part
and an unmodified busybox tree for the initramfs image (embedded in the
kernel as a cpio file). The folowwing github project contains the
modified buildroot tree:
https://github.com/damien-lemoal/riscv64-nommu-buildroot
This is based on work from Christoph Hellwig, with additional changes
and updates to the latest upstream versions for buildroot and uClibc.
Precompiled versions of the toolchain (gcc 9.2) and initramfs file tree
and cpio file can be found in this project under the directory:
buildroot/riscv64-uclibc-nommu/
Flashing the file arch/riscv/boot/loader.bin to a board can be done
using the Sipeed kflash.py tool with the command:
kflash.py/kflash.py -p /dev/ttyUSB0 -b 1500000 -t loader.bin
The kflash.py tool can be found here:
https://github.com/sipeed/kflash.py
For reference, using the Sipeed MAIXDUINO board, here is the boot
output:
[INFO] Rebooting...
--- forcing DTR inactive
--- forcing RTS inactive
--- Miniterm on /dev/ttyUSB0 115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
[ 0.000000] Linux version 5.6.0-rc1-00011-ga2b5be1c4374 (damien@yyy) (gcc version 8.2.0 (Buildroot 2018.11-rc2-00003-ga0787e9)) #610 SMP Wed Feb 12 18:53:50 JST 2020
[ 0.000000] earlycon: sifive0 at MMIO 0x0000000038000000 (options '')
[ 0.000000] printk: bootconsole [sifive0] enabled
[ 0.000000] initrd not found or empty - disabling initrd
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000080000000-0x00000000807fffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080000000-0x00000000807fffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000807fffff]
[ 0.000000] elf_hwcap is 0x112d
[ 0.000000] percpu: max_distance=0x18000 too large for vmalloc space 0x0
[ 0.000000] percpu: Embedded 12 pages/cpu s18272 r0 d30880 u49152
[ 0.000000] Built 1 zonelists, mobility grouping off. Total pages: 2020
[ 0.000000] Kernel command line: earlycon console=ttySIF0
[ 0.000000] Dentry cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.000000] Sorting __ex_table...
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 6328K/8192K available (924K kernel code, 110K rwdata, 164K rodata, 321K init, 91K bss, 1864K reserved, 0K cma-reserved)
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
[ 0.000000] plic: mapped 65 interrupts with 2 handlers for 4 contexts.
[ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0]
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x3990be68b, max_idle_ns: 881590404272 ns
[ 0.000014] sched_clock: 64 bits at 7MHz, resolution 128ns, wraps every 4398046511054ns
[ 0.008232] Console: colour dummy device 80x25
[ 0.012474] Calibrating delay loop (skipped), value calculated using timer frequency.. 15.60 BogoMIPS (lpj=31200)
[ 0.022678] pid_max: default: 4096 minimum: 301
[ 0.027288] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.034414] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.044796] rcu: Hierarchical SRCU implementation.
[ 0.049602] smp: Bringing up secondary CPUs ...
[ 0.054746] smp: Brought up 1 node, 2 CPUs
[ 0.059093] devtmpfs: initialized
[ 0.065523] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.074544] futex hash table entries: 16 (order: -2, 1024 bytes, linear)
[ 0.082512] Kendryte K210 SoC sysctl
[ 0.096010] clocksource: Switched to clocksource riscv_clocksource
[ 0.178581] workingset: timestamp_bits=62 max_order=11 bucket_order=0
[ 0.185846] 38000000.serial: ttySIF0 at MMIO 0x38000000 (irq = 1, base_baud = 0) is a SiFive UART v0
[ 0.194344] printk: console [ttySIF0] enabled
[ 0.194344] printk: console [ttySIF0] enabled
[ 0.202929] printk: bootconsole [sifive0] disabled
[ 0.202929] printk: bootconsole [sifive0] disabled
[ 0.214853] random: get_random_bytes called from 0x0000000080055178 with crng_init=0
[ 0.223606] devtmpfs: mounted
[ 0.226861] Freeing unused kernel memory: 320K
[ 0.230574] This architecture does not have kernel memory protection.
[ 0.236987] Run /sbin/init as init process
[ 0.241181] Run /etc/init as init process
[ 0.245178] Run /bin/init as init process
-----------------------------
| Kendryte K210 NOMMU Linux |
-----------------------------
Mounting /proc
Starting shell
BusyBox v1.32.0.git (2020-02-12 17:51:45 JST) hush - the humble shell
Enter 'help' for a list of built-in commands.
/ # cat /proc/cpuinfo
processor : 0
hart : 0
isa : rv64imafdc
processor : 1
hart : 1
isa : rv64imafdc
/ #
/ # ls -l /
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 bin
drwxr-xr-x 2 0 0 0 Jan 1 00:00 dev
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 etc
dr-xr-xr-x 58 0 0 0 Jan 1 00:00 proc
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 root
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 sbin
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 sys
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 tmp
drwxrwxr-x 4 1000 1000 0 Feb 12 2020 usr
/ #
/ # cat /proc/vmstat
nr_free_pages 1148
...
/ #
The K210 SoC has more devices (GPIO, SD-card, LCD, etc) that likely can
be enabled and used. For this, the sysctl driver will need further
improvements as each device uses a different clock. To share the fun,
supporting these is left as an exercise for the hobbyist and hackers
interested in this SoC/boards :)
Christoph Hellwig (2):
riscv: Add Kendryte K210 SoC support
riscv: create a loader.bin boot image for Kendryte SoC
Damien Le Moal (7):
riscv: Unaligned load/store handling for M_MODE
riscv: Add BUILTIN_DTB support
riscv: Add SOC early init support
riscv: Select required drivers for Kendryte SOC
riscv: Add Kendryte K210 device tree
riscv: Kendryte K210 default config
riscv: Do not initialize PMP on Kendryte SoC
arch/riscv/Kbuild | 1 +
arch/riscv/Kconfig | 19 ++
arch/riscv/Kconfig.socs | 10 +
arch/riscv/Makefile | 6 +-
arch/riscv/boot/Makefile | 3 +
arch/riscv/boot/dts/Makefile | 5 +
arch/riscv/boot/dts/kendryte/Makefile | 2 +
arch/riscv/boot/dts/kendryte/k210.dts | 23 ++
arch/riscv/boot/dts/kendryte/k210.dtsi | 117 ++++++++
arch/riscv/configs/nommu_k210_defconfig | 68 +++++
arch/riscv/include/asm/soc.h | 23 ++
arch/riscv/kernel/Makefile | 3 +-
arch/riscv/kernel/head.S | 9 +-
arch/riscv/kernel/setup.c | 6 +
arch/riscv/kernel/soc.c | 28 ++
arch/riscv/kernel/traps.c | 27 +-
arch/riscv/kernel/traps_misaligned.c | 370 ++++++++++++++++++++++++
arch/riscv/kernel/vmlinux.lds.S | 6 +
arch/riscv/mm/init.c | 4 +
drivers/soc/Kconfig | 1 +
drivers/soc/Makefile | 1 +
drivers/soc/kendryte/Kconfig | 14 +
drivers/soc/kendryte/Makefile | 3 +
drivers/soc/kendryte/k210-sysctl.c | 245 ++++++++++++++++
include/dt-bindings/clock/k210-clk.h | 20 ++
25 files changed, 1006 insertions(+), 8 deletions(-)
create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
create mode 100644 arch/riscv/configs/nommu_k210_defconfig
create mode 100644 arch/riscv/include/asm/soc.h
create mode 100644 arch/riscv/kernel/soc.c
create mode 100644 arch/riscv/kernel/traps_misaligned.c
create mode 100644 drivers/soc/kendryte/Kconfig
create mode 100644 drivers/soc/kendryte/Makefile
create mode 100644 drivers/soc/kendryte/k210-sysctl.c
create mode 100644 include/dt-bindings/clock/k210-clk.h
--
2.24.1
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 1/9] riscv: Unaligned load/store handling for M_MODE
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
@ 2020-03-12 5:10 ` Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 2/9] riscv: Add BUILTIN_DTB support Damien Le Moal
` (7 subsequent siblings)
8 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:10 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
Add handlers for unaligned load and store traps that may be generated
by applications. Code heavily inspired from the OpenSBI project.
Handling of the unaligned access traps is suitable for applications
compiled with or without compressed instructions and is independent of
the kernel CONFIG_RISCV_ISA_C option value.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Anup Patel <anup.patel@wdc.com>
---
arch/riscv/kernel/Makefile | 2 +-
arch/riscv/kernel/traps.c | 27 +-
arch/riscv/kernel/traps_misaligned.c | 370 +++++++++++++++++++++++++++
3 files changed, 395 insertions(+), 4 deletions(-)
create mode 100644 arch/riscv/kernel/traps_misaligned.c
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index f40205cb9a22..97d0c35f8b37 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -28,7 +28,7 @@ obj-y += stacktrace.o
obj-y += cacheinfo.o
obj-$(CONFIG_MMU) += vdso.o vdso/
-obj-$(CONFIG_RISCV_M_MODE) += clint.o
+obj-$(CONFIG_RISCV_M_MODE) += clint.o traps_misaligned.o
obj-$(CONFIG_FPU) += fpu.o
obj-$(CONFIG_SMP) += smpboot.o
obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index ffb3d94bf0cc..13e55459d7b0 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -97,12 +97,33 @@ DO_ERROR_INFO(do_trap_insn_fault,
SIGSEGV, SEGV_ACCERR, "instruction access fault");
DO_ERROR_INFO(do_trap_insn_illegal,
SIGILL, ILL_ILLOPC, "illegal instruction");
-DO_ERROR_INFO(do_trap_load_misaligned,
- SIGBUS, BUS_ADRALN, "load address misaligned");
DO_ERROR_INFO(do_trap_load_fault,
SIGSEGV, SEGV_ACCERR, "load access fault");
+#ifndef CONFIG_RISCV_M_MODE
+DO_ERROR_INFO(do_trap_load_misaligned,
+ SIGBUS, BUS_ADRALN, "Oops - load address misaligned");
DO_ERROR_INFO(do_trap_store_misaligned,
- SIGBUS, BUS_ADRALN, "store (or AMO) address misaligned");
+ SIGBUS, BUS_ADRALN, "Oops - store (or AMO) address misaligned");
+#else
+int handle_misaligned_load(struct pt_regs *regs);
+int handle_misaligned_store(struct pt_regs *regs);
+
+asmlinkage void do_trap_load_misaligned(struct pt_regs *regs)
+{
+ if (!handle_misaligned_load(regs))
+ return;
+ do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
+ "Oops - load address misaligned");
+}
+
+asmlinkage void do_trap_store_misaligned(struct pt_regs *regs)
+{
+ if (!handle_misaligned_store(regs))
+ return;
+ do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
+ "Oops - store (or AMO) address misaligned");
+}
+#endif
DO_ERROR_INFO(do_trap_store_fault,
SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
DO_ERROR_INFO(do_trap_ecall_u,
diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
new file mode 100644
index 000000000000..46c4dafe3ba0
--- /dev/null
+++ b/arch/riscv/kernel/traps_misaligned.c
@@ -0,0 +1,370 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/csr.h>
+
+#define INSN_MATCH_LB 0x3
+#define INSN_MASK_LB 0x707f
+#define INSN_MATCH_LH 0x1003
+#define INSN_MASK_LH 0x707f
+#define INSN_MATCH_LW 0x2003
+#define INSN_MASK_LW 0x707f
+#define INSN_MATCH_LD 0x3003
+#define INSN_MASK_LD 0x707f
+#define INSN_MATCH_LBU 0x4003
+#define INSN_MASK_LBU 0x707f
+#define INSN_MATCH_LHU 0x5003
+#define INSN_MASK_LHU 0x707f
+#define INSN_MATCH_LWU 0x6003
+#define INSN_MASK_LWU 0x707f
+#define INSN_MATCH_SB 0x23
+#define INSN_MASK_SB 0x707f
+#define INSN_MATCH_SH 0x1023
+#define INSN_MASK_SH 0x707f
+#define INSN_MATCH_SW 0x2023
+#define INSN_MASK_SW 0x707f
+#define INSN_MATCH_SD 0x3023
+#define INSN_MASK_SD 0x707f
+
+#define INSN_MATCH_FLW 0x2007
+#define INSN_MASK_FLW 0x707f
+#define INSN_MATCH_FLD 0x3007
+#define INSN_MASK_FLD 0x707f
+#define INSN_MATCH_FLQ 0x4007
+#define INSN_MASK_FLQ 0x707f
+#define INSN_MATCH_FSW 0x2027
+#define INSN_MASK_FSW 0x707f
+#define INSN_MATCH_FSD 0x3027
+#define INSN_MASK_FSD 0x707f
+#define INSN_MATCH_FSQ 0x4027
+#define INSN_MASK_FSQ 0x707f
+
+#define INSN_MATCH_C_LD 0x6000
+#define INSN_MASK_C_LD 0xe003
+#define INSN_MATCH_C_SD 0xe000
+#define INSN_MASK_C_SD 0xe003
+#define INSN_MATCH_C_LW 0x4000
+#define INSN_MASK_C_LW 0xe003
+#define INSN_MATCH_C_SW 0xc000
+#define INSN_MASK_C_SW 0xe003
+#define INSN_MATCH_C_LDSP 0x6002
+#define INSN_MASK_C_LDSP 0xe003
+#define INSN_MATCH_C_SDSP 0xe002
+#define INSN_MASK_C_SDSP 0xe003
+#define INSN_MATCH_C_LWSP 0x4002
+#define INSN_MASK_C_LWSP 0xe003
+#define INSN_MATCH_C_SWSP 0xc002
+#define INSN_MASK_C_SWSP 0xe003
+
+#define INSN_MATCH_C_FLD 0x2000
+#define INSN_MASK_C_FLD 0xe003
+#define INSN_MATCH_C_FLW 0x6000
+#define INSN_MASK_C_FLW 0xe003
+#define INSN_MATCH_C_FSD 0xa000
+#define INSN_MASK_C_FSD 0xe003
+#define INSN_MATCH_C_FSW 0xe000
+#define INSN_MASK_C_FSW 0xe003
+#define INSN_MATCH_C_FLDSP 0x2002
+#define INSN_MASK_C_FLDSP 0xe003
+#define INSN_MATCH_C_FSDSP 0xa002
+#define INSN_MASK_C_FSDSP 0xe003
+#define INSN_MATCH_C_FLWSP 0x6002
+#define INSN_MASK_C_FLWSP 0xe003
+#define INSN_MATCH_C_FSWSP 0xe002
+#define INSN_MASK_C_FSWSP 0xe003
+
+#define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4)
+
+#if defined(CONFIG_64BIT)
+#define LOG_REGBYTES 3
+#define XLEN 64
+#else
+#define LOG_REGBYTES 2
+#define XLEN 32
+#endif
+#define REGBYTES (1 << LOG_REGBYTES)
+#define XLEN_MINUS_16 ((XLEN) - 16)
+
+#define SH_RD 7
+#define SH_RS1 15
+#define SH_RS2 20
+#define SH_RS2C 2
+
+#define RV_X(x, s, n) (((x) >> (s)) & ((1 << (n)) - 1))
+#define RVC_LW_IMM(x) ((RV_X(x, 6, 1) << 2) | \
+ (RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 5, 1) << 6))
+#define RVC_LD_IMM(x) ((RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 5, 2) << 6))
+#define RVC_LWSP_IMM(x) ((RV_X(x, 4, 3) << 2) | \
+ (RV_X(x, 12, 1) << 5) | \
+ (RV_X(x, 2, 2) << 6))
+#define RVC_LDSP_IMM(x) ((RV_X(x, 5, 2) << 3) | \
+ (RV_X(x, 12, 1) << 5) | \
+ (RV_X(x, 2, 3) << 6))
+#define RVC_SWSP_IMM(x) ((RV_X(x, 9, 4) << 2) | \
+ (RV_X(x, 7, 2) << 6))
+#define RVC_SDSP_IMM(x) ((RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 7, 3) << 6))
+#define RVC_RS1S(insn) (8 + RV_X(insn, SH_RD, 3))
+#define RVC_RS2S(insn) (8 + RV_X(insn, SH_RS2C, 3))
+#define RVC_RS2(insn) RV_X(insn, SH_RS2C, 5)
+
+#define SHIFT_RIGHT(x, y) \
+ ((y) < 0 ? ((x) << -(y)) : ((x) >> (y)))
+
+#define REG_MASK \
+ ((1 << (5 + LOG_REGBYTES)) - (1 << LOG_REGBYTES))
+
+#define REG_OFFSET(insn, pos) \
+ (SHIFT_RIGHT((insn), (pos) - LOG_REGBYTES) & REG_MASK)
+
+#define REG_PTR(insn, pos, regs) \
+ (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
+
+#define GET_RM(insn) (((insn) >> 12) & 7)
+
+#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs))
+#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs))
+#define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs))
+#define GET_RS2S(insn, regs) (*REG_PTR(RVC_RS2S(insn), 0, regs))
+#define GET_RS2C(insn, regs) (*REG_PTR(insn, SH_RS2C, regs))
+#define GET_SP(regs) (*REG_PTR(2, 0, regs))
+#define SET_RD(insn, regs, val) (*REG_PTR(insn, SH_RD, regs) = (val))
+#define IMM_I(insn) ((s32)(insn) >> 20)
+#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
+ (s32)(((insn) >> 7) & 0x1f))
+#define MASK_FUNCT3 0x7000
+
+#define GET_PRECISION(insn) (((insn) >> 25) & 3)
+#define GET_RM(insn) (((insn) >> 12) & 7)
+#define PRECISION_S 0
+#define PRECISION_D 1
+
+#define STR(x) XSTR(x)
+#define XSTR(x) #x
+
+#define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type, insn) \
+static inline type load_##type(const type *addr) \
+{ \
+ type val; \
+ asm (#insn " %0, %1" \
+ : "=&r" (val) : "m" (*addr)); \
+ return val; \
+}
+
+#define DECLARE_UNPRIVILEGED_STORE_FUNCTION(type, insn) \
+static inline void store_##type(type *addr, type val) \
+{ \
+ asm volatile (#insn " %0, %1\n" \
+ : : "r" (val), "m" (*addr)); \
+}
+
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u8, lbu)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u16, lhu)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s8, lb)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s16, lh)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s32, lw)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u8, sb)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u16, sh)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u32, sw)
+#if defined(CONFIG_64BIT)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lwu)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u64, ld)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u64, sd)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, ld)
+#else
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lw)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, lw)
+
+static inline u64 load_u64(const u64 *addr)
+{
+ return load_u32((u32 *)addr)
+ + ((u64)load_u32((u32 *)addr + 1) << 32);
+}
+
+static inline void store_u64(u64 *addr, u64 val)
+{
+ store_u32((u32 *)addr, val);
+ store_u32((u32 *)addr + 1, val >> 32);
+}
+#endif
+
+static inline ulong get_insn(ulong mepc)
+{
+ register ulong __mepc asm ("a2") = mepc;
+ ulong val, rvc_mask = 3, tmp;
+
+ asm ("and %[tmp], %[addr], 2\n"
+ "bnez %[tmp], 1f\n"
+#if defined(CONFIG_64BIT)
+ STR(LWU) " %[insn], (%[addr])\n"
+#else
+ STR(LW) " %[insn], (%[addr])\n"
+#endif
+ "and %[tmp], %[insn], %[rvc_mask]\n"
+ "beq %[tmp], %[rvc_mask], 2f\n"
+ "sll %[insn], %[insn], %[xlen_minus_16]\n"
+ "srl %[insn], %[insn], %[xlen_minus_16]\n"
+ "j 2f\n"
+ "1:\n"
+ "lhu %[insn], (%[addr])\n"
+ "and %[tmp], %[insn], %[rvc_mask]\n"
+ "bne %[tmp], %[rvc_mask], 2f\n"
+ "lhu %[tmp], 2(%[addr])\n"
+ "sll %[tmp], %[tmp], 16\n"
+ "add %[insn], %[insn], %[tmp]\n"
+ "2:"
+ : [insn] "=&r" (val), [tmp] "=&r" (tmp)
+ : [addr] "r" (__mepc), [rvc_mask] "r" (rvc_mask),
+ [xlen_minus_16] "i" (XLEN_MINUS_16));
+
+ return val;
+}
+
+union reg_data {
+ u8 data_bytes[8];
+ ulong data_ulong;
+ u64 data_u64;
+};
+
+int handle_misaligned_load(struct pt_regs *regs)
+{
+ union reg_data val;
+ unsigned long epc = regs->epc;
+ unsigned long insn = get_insn(epc);
+ unsigned long addr = csr_read(mtval);
+ int i, fp = 0, shift = 0, len = 0;
+
+ regs->epc = 0;
+
+ if ((insn & INSN_MASK_LW) == INSN_MATCH_LW) {
+ len = 4;
+ shift = 8 * (sizeof(unsigned long) - len);
+#if defined(CONFIG_64BIT)
+ } else if ((insn & INSN_MASK_LD) == INSN_MATCH_LD) {
+ len = 8;
+ shift = 8 * (sizeof(unsigned long) - len);
+ } else if ((insn & INSN_MASK_LWU) == INSN_MATCH_LWU) {
+ len = 4;
+#endif
+ } else if ((insn & INSN_MASK_FLD) == INSN_MATCH_FLD) {
+ fp = 1;
+ len = 8;
+ } else if ((insn & INSN_MASK_FLW) == INSN_MATCH_FLW) {
+ fp = 1;
+ len = 4;
+ } else if ((insn & INSN_MASK_LH) == INSN_MATCH_LH) {
+ len = 2;
+ shift = 8 * (sizeof(unsigned long) - len);
+ } else if ((insn & INSN_MASK_LHU) == INSN_MATCH_LHU) {
+ len = 2;
+#if defined(CONFIG_64BIT)
+ } else if ((insn & INSN_MASK_C_LD) == INSN_MATCH_C_LD) {
+ len = 8;
+ shift = 8 * (sizeof(unsigned long) - len);
+ insn = RVC_RS2S(insn) << SH_RD;
+ } else if ((insn & INSN_MASK_C_LDSP) == INSN_MATCH_C_LDSP &&
+ ((insn >> SH_RD) & 0x1f)) {
+ len = 8;
+ shift = 8 * (sizeof(unsigned long) - len);
+#endif
+ } else if ((insn & INSN_MASK_C_LW) == INSN_MATCH_C_LW) {
+ len = 4;
+ shift = 8 * (sizeof(unsigned long) - len);
+ insn = RVC_RS2S(insn) << SH_RD;
+ } else if ((insn & INSN_MASK_C_LWSP) == INSN_MATCH_C_LWSP &&
+ ((insn >> SH_RD) & 0x1f)) {
+ len = 4;
+ shift = 8 * (sizeof(unsigned long) - len);
+ } else if ((insn & INSN_MASK_C_FLD) == INSN_MATCH_C_FLD) {
+ fp = 1;
+ len = 8;
+ insn = RVC_RS2S(insn) << SH_RD;
+ } else if ((insn & INSN_MASK_C_FLDSP) == INSN_MATCH_C_FLDSP) {
+ fp = 1;
+ len = 8;
+#if defined(CONFIG_32BIT)
+ } else if ((insn & INSN_MASK_C_FLW) == INSN_MATCH_C_FLW) {
+ fp = 1;
+ len = 4;
+ insn = RVC_RS2S(insn) << SH_RD;
+ } else if ((insn & INSN_MASK_C_FLWSP) == INSN_MATCH_C_FLWSP) {
+ fp = 1;
+ len = 4;
+#endif
+ } else {
+ regs->epc = epc;
+ return -1;
+ }
+
+ val.data_u64 = 0;
+ for (i = 0; i < len; i++)
+ val.data_bytes[i] = load_u8((void *)(addr + i));
+
+ if (fp)
+ return -1;
+ SET_RD(insn, regs, val.data_ulong << shift >> shift);
+
+ regs->epc = epc + INSN_LEN(insn);
+
+ return 0;
+}
+
+int handle_misaligned_store(struct pt_regs *regs)
+{
+ union reg_data val;
+ unsigned long epc = regs->epc;
+ unsigned long insn = get_insn(epc);
+ unsigned long addr = csr_read(mtval);
+ int i, len = 0;
+
+ regs->epc = 0;
+
+ val.data_ulong = GET_RS2(insn, regs);
+
+ if ((insn & INSN_MASK_SW) == INSN_MATCH_SW) {
+ len = 4;
+#if defined(CONFIG_64BIT)
+ } else if ((insn & INSN_MASK_SD) == INSN_MATCH_SD) {
+ len = 8;
+#endif
+ } else if ((insn & INSN_MASK_SH) == INSN_MATCH_SH) {
+ len = 2;
+#if defined(CONFIG_64BIT)
+ } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) {
+ len = 8;
+ val.data_ulong = GET_RS2S(insn, regs);
+ } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP &&
+ ((insn >> SH_RD) & 0x1f)) {
+ len = 8;
+ val.data_ulong = GET_RS2C(insn, regs);
+#endif
+ } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) {
+ len = 4;
+ val.data_ulong = GET_RS2S(insn, regs);
+ } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP &&
+ ((insn >> SH_RD) & 0x1f)) {
+ len = 4;
+ val.data_ulong = GET_RS2C(insn, regs);
+ } else {
+ regs->epc = epc;
+ return -1;
+ }
+
+ for (i = 0; i < len; i++)
+ store_u8((void *)(addr + i), val.data_bytes[i]);
+
+ regs->epc = epc + INSN_LEN(insn);
+
+ return 0;
+}
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 2/9] riscv: Add BUILTIN_DTB support
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
2020-03-12 5:10 ` [PATCH v2 1/9] riscv: Unaligned load/store handling for M_MODE Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 20:03 ` Atish Patra
2020-03-12 5:11 ` [PATCH v2 3/9] riscv: Add SOC early init support Damien Le Moal
` (6 subsequent siblings)
8 siblings, 1 reply; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
For the NOMMU case, enable a kernel builtin dtb to allow direct kernel
loading without a bootloader. This option also allows booting on boards
not capable of providing a device tree to the bootloader.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
arch/riscv/Kbuild | 1 +
arch/riscv/Kconfig | 19 +++++++++++++++++++
arch/riscv/boot/dts/Makefile | 4 ++++
arch/riscv/kernel/setup.c | 6 ++++++
arch/riscv/mm/init.c | 4 ++++
5 files changed, 34 insertions(+)
diff --git a/arch/riscv/Kbuild b/arch/riscv/Kbuild
index d1d0aa70fdf1..988804e430e4 100644
--- a/arch/riscv/Kbuild
+++ b/arch/riscv/Kbuild
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y += kernel/ mm/ net/
+obj-$(CONFIG_USE_BUILTIN_DTB) += boot/dts/
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 1a3b5a5276be..025f5ba1dd68 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -355,6 +355,25 @@ config CMDLINE_FORCE
endchoice
+config USE_BUILTIN_DTB
+ bool "Use builtin DTB"
+ depends on !MMU
+ help
+ Link a device tree blob for particular hardware into the kernel,
+ suppressing use of the DTB pointer provided by the bootloader.
+ This option should only be used with hardware or bootloaders that
+ are not capable of providing a DTB to the kernel, or for
+ experimental hardware without stable device tree bindings.
+
+config BUILTIN_DTB_SOURCE
+ string "Source file for builtin DTB"
+ default ""
+ depends on USE_BUILTIN_DTB
+ help
+ Base name (without suffix, relative to arch/riscv/boot/dts) for
+ the a DTS file that will be used to produce the DTB linked into
+ the kernel.
+
endmenu
menu "Power management options"
diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index dcc3ada78455..0bf2669aa12d 100644
--- a/arch/riscv/boot/dts/Makefile
+++ b/arch/riscv/boot/dts/Makefile
@@ -1,2 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
+ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
+obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
+else
subdir-y += sifive
+endif
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 0a6d415b0a5a..3e89be9d888c 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -68,7 +68,13 @@ void __init setup_arch(char **cmdline_p)
setup_bootmem();
paging_init();
+
+#if IS_ENABLED(CONFIG_USE_BUILTIN_DTB)
+ unflatten_and_copy_device_tree();
+#else
unflatten_device_tree();
+#endif
+
clint_init_boot_cpu();
#ifdef CONFIG_SWIOTLB
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index fab855963c73..51f1ee0a24a6 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -480,7 +480,11 @@ static void __init setup_vm_final(void)
#else
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
{
+#if IS_ENABLED(CONFIG_USE_BUILTIN_DTB)
+ dtb_early_va = __dtb_start;
+#else
dtb_early_va = (void *)dtb_pa;
+#endif
}
static inline void setup_vm_final(void)
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
2020-03-12 5:10 ` [PATCH v2 1/9] riscv: Unaligned load/store handling for M_MODE Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 2/9] riscv: Add BUILTIN_DTB support Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 18:21 ` Sean Anderson
` (2 more replies)
2020-03-12 5:11 ` [PATCH v2 4/9] riscv: Add Kendryte K210 SoC support Damien Le Moal
` (5 subsequent siblings)
8 siblings, 3 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
Add a mechanism for early SoC initialization for platforms that need
additional hardware initialization not possible through the regular
device tree and drivers mechanism. With this, a SoC specific
initialization function can be called very early, before DTB parsing
is done by parse_dtb() in Linux RISC-V kernel setup code.
This can be very useful for early hardware initialization for No-MMU
kernels booted directly in M-mode because it is quite likely that no
other booting stage exist prior to the No-MMU kernel.
Example use of a SoC early initialization is as follows:
static void vendor_abc_early_init(const void *fdt)
{
/*
* some early init code here that can use simple matches
* against the flat device tree file.
*/
}
SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
This early initialization function is executed only if the flat device
tree for the board has a 'compatible = "vendor,abc"' entry;
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
---
arch/riscv/include/asm/soc.h | 23 +++++++++++++++++++++++
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/head.S | 1 +
arch/riscv/kernel/soc.c | 28 ++++++++++++++++++++++++++++
arch/riscv/kernel/vmlinux.lds.S | 6 ++++++
5 files changed, 59 insertions(+)
create mode 100644 arch/riscv/include/asm/soc.h
create mode 100644 arch/riscv/kernel/soc.c
diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h
new file mode 100644
index 000000000000..9b8c332cbe76
--- /dev/null
+++ b/arch/riscv/include/asm/soc.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#ifndef _ASM_RISCV_SOC_H
+#define _ASM_RISCV_SOC_H
+
+#include <linux/of.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+
+#define SOC_EARLY_INIT_DECLARE(compat, fn) \
+ static const struct of_device_id __soc_early_init \
+ __used __section(__soc_early_init_table) \
+ = { .compatible = compat, .data = fn }
+
+void soc_early_init(void);
+
+extern unsigned long __soc_early_init_table_start;
+extern unsigned long __soc_early_init_table_end;
+
+#endif
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 97d0c35f8b37..e4a22999dbc6 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -10,6 +10,7 @@ endif
extra-y += head.o
extra-y += vmlinux.lds
+obj-y += soc.o
obj-y += cpu.o
obj-y += cpufeature.o
obj-y += entry.o
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 85f2073e7fe4..52ed11b4fda6 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -131,6 +131,7 @@ clear_bss_done:
call kasan_early_init
#endif
/* Start the kernel */
+ call soc_early_init
call parse_dtb
tail start_kernel
diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c
new file mode 100644
index 000000000000..0b3b3dc9ad0f
--- /dev/null
+++ b/arch/riscv/kernel/soc.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+#include <linux/init.h>
+#include <linux/libfdt.h>
+#include <asm/pgtable.h>
+#include <asm/soc.h>
+
+/*
+ * This is called extremly early, before parse_dtb(), to allow initializing
+ * SoC hardware before memory or any device driver initialization.
+ */
+void __init soc_early_init(void)
+{
+ void (*early_fn)(const void *fdt);
+ const struct of_device_id *s;
+ const void *fdt = dtb_early_va;
+
+ for (s = (void *)&__soc_early_init_table_start;
+ (void *)s < (void *)&__soc_early_init_table_end; s++) {
+ if (!fdt_node_check_compatible(fdt, 0, s->compatible)) {
+ early_fn = s->data;
+ early_fn(fdt);
+ return;
+ }
+ }
+}
diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
index 1e0193ded420..32b160942f40 100644
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -24,6 +24,12 @@ SECTIONS
HEAD_TEXT_SECTION
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
+ . = ALIGN(8);
+ __soc_early_init_table : {
+ __soc_early_init_table_start = .;
+ KEEP(*(__soc_early_init_table))
+ __soc_early_init_table_end = .;
+ }
/* we have to discard exit text and such at runtime, not link time */
.exit.text :
{
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 4/9] riscv: Add Kendryte K210 SoC support
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
` (2 preceding siblings ...)
2020-03-12 5:11 ` [PATCH v2 3/9] riscv: Add SOC early init support Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 18:19 ` Sean Anderson
2020-03-12 5:11 ` [PATCH v2 5/9] riscv: Select required drivers for Kendryte SOC Damien Le Moal
` (4 subsequent siblings)
8 siblings, 1 reply; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
From: Christoph Hellwig <hch@lst.de>
Add support for the Kendryte K210 RISC-V SoC. For now, this support
only provides a simple sysctl driver allowing to setup the CPU and
uart clock. This support is enabled through the new Kconfig option
SOC_KENDRYTE and defines the config option CONFIG_K210_SYSCTL
to enable the K210 SoC sysctl driver compilation.
The sysctl driver also registers an early SoC initialization function
allowing enabling the general purpose use of the 2MB of SRAM normally
reserved for the SoC AI engine. This initialization function is
automatically called before the dt early initialization using the flat
dt root node compatible property matching the value "kendryte,k210".
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
---
arch/riscv/Kconfig.socs | 6 +
drivers/soc/Kconfig | 1 +
drivers/soc/Makefile | 1 +
drivers/soc/kendryte/Kconfig | 14 ++
drivers/soc/kendryte/Makefile | 3 +
drivers/soc/kendryte/k210-sysctl.c | 245 +++++++++++++++++++++++++++++
6 files changed, 270 insertions(+)
create mode 100644 drivers/soc/kendryte/Kconfig
create mode 100644 drivers/soc/kendryte/Makefile
create mode 100644 drivers/soc/kendryte/k210-sysctl.c
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 3078b2de0b2d..69071578e181 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -34,4 +34,10 @@ config SOC_VIRT
help
This enables support for QEMU Virt Machine.
+config SOC_KENDRYTE
+ bool "Kendryte K210 SoC"
+ depends on !MMU
+ help
+ This enables support for Kendryte K210 SoC platform hardware.
+
endmenu
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 1778f8c62861..425ab6f7e375 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -22,5 +22,6 @@ source "drivers/soc/ux500/Kconfig"
source "drivers/soc/versatile/Kconfig"
source "drivers/soc/xilinx/Kconfig"
source "drivers/soc/zte/Kconfig"
+source "drivers/soc/kendryte/Kconfig"
endmenu
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 8b49d782a1ab..af58063bb989 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_PLAT_VERSATILE) += versatile/
obj-y += xilinx/
obj-$(CONFIG_ARCH_ZX) += zte/
+obj-$(CONFIG_SOC_KENDRYTE) += kendryte/
diff --git a/drivers/soc/kendryte/Kconfig b/drivers/soc/kendryte/Kconfig
new file mode 100644
index 000000000000..49785b1b0217
--- /dev/null
+++ b/drivers/soc/kendryte/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if SOC_KENDRYTE
+
+config K210_SYSCTL
+ bool "Kendryte K210 system controller"
+ default y
+ depends on RISCV
+ help
+ Enables controlling the K210 various clocks and to enable
+ general purpose use of the extra 2MB of SRAM normally
+ reserved for the AI engine.
+
+endif
diff --git a/drivers/soc/kendryte/Makefile b/drivers/soc/kendryte/Makefile
new file mode 100644
index 000000000000..002d9ce95c0d
--- /dev/null
+++ b/drivers/soc/kendryte/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_K210_SYSCTL) += k210-sysctl.o
diff --git a/drivers/soc/kendryte/k210-sysctl.c b/drivers/soc/kendryte/k210-sysctl.c
new file mode 100644
index 000000000000..7d4ecd954af0
--- /dev/null
+++ b/drivers/soc/kendryte/k210-sysctl.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Christoph Hellwig.
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ */
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <asm/soc.h>
+
+#define K210_SYSCTL_CLK0_FREQ 26000000UL
+
+/* Registers base address */
+#define K210_SYSCTL_SYSCTL_BASE_ADDR 0x50440000ULL
+
+/* Registers */
+#define K210_SYSCTL_PLL0 0x08
+#define K210_SYSCTL_PLL1 0x0c
+/* clkr: 4bits, clkf1: 6bits, clkod: 4bits, bwadj: 4bits */
+#define PLL_RESET (1 << 20)
+#define PLL_PWR (1 << 21)
+#define PLL_INTFB (1 << 22)
+#define PLL_BYPASS (1 << 23)
+#define PLL_TEST (1 << 24)
+#define PLL_OUT_EN (1 << 25)
+#define PLL_TEST_EN (1 << 26)
+#define K210_SYSCTL_PLL_LOCK 0x18
+#define PLL0_LOCK1 (1 << 0)
+#define PLL0_LOCK2 (1 << 1)
+#define PLL0_SLIP_CLEAR (1 << 2)
+#define PLL0_TEST_CLK_OUT (1 << 3)
+#define PLL1_LOCK1 (1 << 8)
+#define PLL1_LOCK2 (1 << 9)
+#define PLL1_SLIP_CLEAR (1 << 10)
+#define PLL1_TEST_CLK_OUT (1 << 11)
+#define PLL2_LOCK1 (1 << 16)
+#define PLL2_LOCK2 (1 << 16)
+#define PLL2_SLIP_CLEAR (1 << 18)
+#define PLL2_TEST_CLK_OUT (1 << 19)
+#define K210_SYSCTL_CLKSEL0 0x20
+#define CLKSEL_ACLK (1 << 0)
+#define K210_SYSCTL_CLKEN_CENT 0x28
+#define CLKEN_CPU (1 << 0)
+#define CLKEN_SRAM0 (1 << 1)
+#define CLKEN_SRAM1 (1 << 2)
+#define CLKEN_APB0 (1 << 3)
+#define CLKEN_APB1 (1 << 4)
+#define CLKEN_APB2 (1 << 5)
+#define K210_SYSCTL_CLKEN_PERI 0x2c
+#define CLKEN_ROM (1 << 0)
+#define CLKEN_DMA (1 << 1)
+#define CLKEN_AI (1 << 2)
+#define CLKEN_DVP (1 << 3)
+#define CLKEN_FFT (1 << 4)
+#define CLKEN_GPIO (1 << 5)
+#define CLKEN_SPI0 (1 << 6)
+#define CLKEN_SPI1 (1 << 7)
+#define CLKEN_SPI2 (1 << 8)
+#define CLKEN_SPI3 (1 << 9)
+#define CLKEN_I2S0 (1 << 10)
+#define CLKEN_I2S1 (1 << 11)
+#define CLKEN_I2S2 (1 << 12)
+#define CLKEN_I2C0 (1 << 13)
+#define CLKEN_I2C1 (1 << 14)
+#define CLKEN_I2C2 (1 << 15)
+#define CLKEN_UART1 (1 << 16)
+#define CLKEN_UART2 (1 << 17)
+#define CLKEN_UART3 (1 << 18)
+#define CLKEN_AES (1 << 19)
+#define CLKEN_FPIO (1 << 20)
+#define CLKEN_TIMER0 (1 << 21)
+#define CLKEN_TIMER1 (1 << 22)
+#define CLKEN_TIMER2 (1 << 23)
+#define CLKEN_WDT0 (1 << 24)
+#define CLKEN_WDT1 (1 << 25)
+#define CLKEN_SHA (1 << 26)
+#define CLKEN_OTP (1 << 27)
+#define CLKEN_RTC (1 << 29)
+
+struct k210_sysctl {
+ void __iomem *regs;
+ struct clk_hw hw;
+};
+
+static void k210_set_bits(u32 val, void __iomem *reg)
+{
+ writel(readl(reg) | val, reg);
+}
+
+static void k210_clear_bits(u32 val, void __iomem *reg)
+{
+ writel(readl(reg) & ~val, reg);
+}
+
+static void k210_pll1_enable(void __iomem *regs)
+{
+ u32 val;
+
+ val = readl(regs + K210_SYSCTL_PLL1);
+ val &= ~0xfffff;
+ val |= (59 << 4) | (3 << 10) | (59 << 15);
+ writel(val, regs + K210_SYSCTL_PLL1);
+
+ k210_clear_bits(PLL_BYPASS, regs + K210_SYSCTL_PLL1);
+ k210_set_bits(PLL_PWR, regs + K210_SYSCTL_PLL1);
+
+ /*
+ * Reset the pll. The magic NOPs come from the Kendryte reference SDK.
+ */
+ k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
+ k210_set_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
+ nop();
+ nop();
+ k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
+
+ for (;;) {
+ val = readl(regs + K210_SYSCTL_PLL_LOCK);
+ if (val & PLL1_LOCK2)
+ break;
+ writel(val | PLL1_SLIP_CLEAR, regs + K210_SYSCTL_PLL_LOCK);
+ }
+
+ k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL1);
+}
+
+static unsigned long k210_sysctl_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct k210_sysctl *s = container_of(hw, struct k210_sysctl, hw);
+ u32 clksel0, pll0;
+ u64 pll0_freq, clkr0, clkf0, clkod0;
+
+ /*
+ * If the clock selector is not set, use the base frequency.
+ * Otherwise, use PLL0 frequency with a frequency divisor.
+ */
+ clksel0 = readl(s->regs + K210_SYSCTL_CLKSEL0);
+ if (!(clksel0 & CLKSEL_ACLK))
+ return K210_SYSCTL_CLK0_FREQ;
+
+ /*
+ * Get PLL0 frequency:
+ * freq = base frequency * clkf0 / (clkr0 * clkod0)
+ */
+ pll0 = readl(s->regs + K210_SYSCTL_PLL0);
+ clkr0 = 1 + (pll0 & 0x0000000f);
+ clkf0 = 1 + ((pll0 & 0x000003f0) >> 4);
+ clkod0 = 1 + ((pll0 & 0x00003c00) >> 10);
+ pll0_freq = clkf0 * K210_SYSCTL_CLK0_FREQ / (clkr0 * clkod0);
+
+ /* Get the frequency divisor from the clock selector */
+ return pll0_freq / (2ULL << ((clksel0 & 0x00000006) >> 1));
+}
+
+static const struct clk_ops k210_sysctl_clk_ops = {
+ .recalc_rate = k210_sysctl_clk_recalc_rate,
+};
+
+static const struct clk_init_data k210_clk_init_data = {
+ .name = "k210-sysctl-pll1",
+ .ops = &k210_sysctl_clk_ops,
+};
+
+static int k210_sysctl_probe(struct platform_device *pdev)
+{
+ struct k210_sysctl *s;
+ int error;
+
+ pr_info("Kendryte K210 SoC sysctl\n");
+
+ s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ s->regs = devm_ioremap_resource(&pdev->dev,
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
+ if (IS_ERR(s->regs))
+ return PTR_ERR(s->regs);
+
+ s->hw.init = &k210_clk_init_data;
+ error = devm_clk_hw_register(&pdev->dev, &s->hw);
+ if (error) {
+ dev_err(&pdev->dev, "failed to register clk");
+ return error;
+ }
+
+ error = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
+ &s->hw);
+ if (error) {
+ dev_err(&pdev->dev, "adding clk provider failed\n");
+ return error;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id k210_sysctl_of_match[] = {
+ { .compatible = "kendryte,k210-sysctl", },
+ {}
+};
+
+static struct platform_driver k210_sysctl_driver = {
+ .driver = {
+ .name = "k210-sysctl",
+ .of_match_table = k210_sysctl_of_match,
+ },
+ .probe = k210_sysctl_probe,
+};
+
+static int __init k210_sysctl_init(void)
+{
+ return platform_driver_register(&k210_sysctl_driver);
+}
+core_initcall(k210_sysctl_init);
+
+/*
+ * This needs to be called very early during initialization, given that
+ * PLL1 needs to be enabled to be able to use all SRAM.
+ */
+static void __init k210_soc_early_init(const void *fdt)
+{
+ void __iomem *regs;
+
+ regs = ioremap(K210_SYSCTL_SYSCTL_BASE_ADDR, 0x1000);
+ if (!regs)
+ panic("K210 sysctl ioremap");
+
+ /* Enable PLL1 to make the KPU SRAM useable */
+ k210_pll1_enable(regs);
+
+ k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL0);
+
+ k210_set_bits(CLKEN_CPU | CLKEN_SRAM0 | CLKEN_SRAM1,
+ regs + K210_SYSCTL_CLKEN_CENT);
+ k210_set_bits(CLKEN_ROM | CLKEN_TIMER0 | CLKEN_RTC,
+ regs + K210_SYSCTL_CLKEN_PERI);
+
+ k210_set_bits(CLKSEL_ACLK, regs + K210_SYSCTL_CLKSEL0);
+
+ iounmap(regs);
+}
+SOC_EARLY_INIT_DECLARE("kendryte,k210", k210_soc_early_init);
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 5/9] riscv: Select required drivers for Kendryte SOC
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
` (3 preceding siblings ...)
2020-03-12 5:11 ` [PATCH v2 4/9] riscv: Add Kendryte K210 SoC support Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 6/9] riscv: Add Kendryte K210 device tree Damien Le Moal
` (3 subsequent siblings)
8 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
This patch selects drivers required for the Kendryte K210 SOC.
Since K210 SoC based boards do not provide a device tree, this patch
also enables the BUILTIN_DTB option.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
---
arch/riscv/Kconfig.socs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 69071578e181..a843100124ae 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -37,6 +37,10 @@ config SOC_VIRT
config SOC_KENDRYTE
bool "Kendryte K210 SoC"
depends on !MMU
+ select BUILTIN_DTB
+ select SERIAL_SIFIVE if TTY
+ select SERIAL_SIFIVE_CONSOLE if TTY
+ select SIFIVE_PLIC
help
This enables support for Kendryte K210 SoC platform hardware.
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 6/9] riscv: Add Kendryte K210 device tree
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
` (4 preceding siblings ...)
2020-03-12 5:11 ` [PATCH v2 5/9] riscv: Select required drivers for Kendryte SOC Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 18:16 ` Sean Anderson
2020-03-12 5:11 ` [PATCH v2 7/9] riscv: Kendryte K210 default config Damien Le Moal
` (2 subsequent siblings)
8 siblings, 1 reply; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
Add a generic device tree for Kendryte K210 SoC based boards. This (for
now) very simple device tree works for the Kendryte KD233 development
board, the Sipeed MAIX M1 Dan Dock board and the Sipeed MAIXDUINO board.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
arch/riscv/boot/dts/Makefile | 1 +
arch/riscv/boot/dts/kendryte/Makefile | 2 +
arch/riscv/boot/dts/kendryte/k210.dts | 23 +++++
arch/riscv/boot/dts/kendryte/k210.dtsi | 117 +++++++++++++++++++++++++
include/dt-bindings/clock/k210-clk.h | 20 +++++
5 files changed, 163 insertions(+)
create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
create mode 100644 include/dt-bindings/clock/k210-clk.h
diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index 0bf2669aa12d..87815557f2db 100644
--- a/arch/riscv/boot/dts/Makefile
+++ b/arch/riscv/boot/dts/Makefile
@@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
else
subdir-y += sifive
+subdir-y += kendryte
endif
diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
new file mode 100644
index 000000000000..815444e69e89
--- /dev/null
+++ b/arch/riscv/boot/dts/kendryte/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
new file mode 100644
index 000000000000..0d1f28fce6b2
--- /dev/null
+++ b/arch/riscv/boot/dts/kendryte/k210.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+
+/dts-v1/;
+
+#include "k210.dtsi"
+
+/ {
+ model = "Kendryte K210 generic";
+ compatible = "kendryte,k210";
+
+ chosen {
+ bootargs = "earlycon console=ttySIF0";
+ stdout-path = "serial0";
+ };
+};
+
+&uarths0 {
+ status = "okay";
+};
+
diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
new file mode 100644
index 000000000000..88f28a3fd337
--- /dev/null
+++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+#include <dt-bindings/clock/k210-clk.h>
+
+/ {
+ /*
+ * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
+ * wide, and the upper half of all addresses is ignored.
+ */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "kendryte,k210";
+
+ aliases {
+ serial0 = &uarths0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <7800000>;
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ compatible = "kendryte,k210", "sifive,rocket0", "riscv";
+ riscv,isa = "rv64imafdc";
+ mmu-type = "none";
+ i-cache-size = <0x8000>;
+ i-cache-block-size = <64>;
+ d-cache-size = <0x8000>;
+ d-cache-block-size = <64>;
+ clocks = <&sysctl K210_CLK_CPU>;
+ clock-frequency = <390000000>;
+ cpu0_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ reg = <1>;
+ compatible = "kendryte,k210", "sifive,rocket0", "riscv";
+ riscv,isa = "rv64imafdc";
+ mmu-type = "none";
+ i-cache-size = <0x8000>;
+ i-cache-block-size = <64>; /* bogus */
+ d-cache-size = <0x8000>;
+ d-cache-block-size = <64>; /* bogus */
+ clocks = <&sysctl K210_CLK_CPU>;
+ clock-frequency = <390000000>;
+ cpu1_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
+ };
+
+ sram: memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x400000>,
+ <0x80400000 0x200000>,
+ <0x80600000 0x200000>;
+ reg-names = "sram0", "sram1", "aisram";
+ };
+
+ clocks {
+ in0: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "kendryte,k210-soc", "simple-bus";
+ ranges;
+ interrupt-parent = <&plic0>;
+
+ sysctl: sysctl@50440000 {
+ compatible = "kendryte,k210-sysctl", "syscon";
+ reg = <0x50440000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ clint0: interrupt-controller@2000000 {
+ compatible = "riscv,clint0";
+ reg = <0x2000000 0xC000>;
+ interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>;
+ clocks = <&sysctl K210_CLK_ACLK>;
+ };
+
+ plic0: interrupt-controller@c000000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "kendryte,k210-plic0", "riscv,plic0";
+ reg = <0xC000000 0x4000000>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
+ <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
+ riscv,ndev = <65>;
+ riscv,max-priority = <7>;
+ };
+
+ uarths0: serial@38000000 {
+ compatible = "kendryte,k210-uarths", "sifive,uart0";
+ reg = <0x38000000 0x1000>;
+ interrupts = <33>;
+ clocks = <&sysctl K210_CLK_CPU>;
+ };
+ };
+};
diff --git a/include/dt-bindings/clock/k210-clk.h b/include/dt-bindings/clock/k210-clk.h
new file mode 100644
index 000000000000..5a2fd64d1a49
--- /dev/null
+++ b/include/dt-bindings/clock/k210-clk.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com>
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ */
+#ifndef K210_CLK_H
+#define K210_CLK_H
+
+/*
+ * Arbitrary identifiers for clocks.
+ * The structure is: in0 -> pll0 -> aclk -> cpu
+ *
+ * Since we use the hardware defaults for now, set all these to the same clock.
+ */
+#define K210_CLK_PLL0 0
+#define K210_CLK_PLL1 0
+#define K210_CLK_ACLK 0
+#define K210_CLK_CPU 0
+
+#endif /* K210_CLK_H */
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 7/9] riscv: Kendryte K210 default config
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
` (5 preceding siblings ...)
2020-03-12 5:11 ` [PATCH v2 6/9] riscv: Add Kendryte K210 device tree Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 19:03 ` Atish Patra
2020-03-12 5:11 ` [PATCH v2 8/9] riscv: create a loader.bin boot image for Kendryte SoC Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 9/9] riscv: Do not initialize PMP on " Damien Le Moal
8 siblings, 1 reply; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
This patch adds a defconfig file to build No-MMU kernels meant for
boards based on the Kendryte K210 SoC.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
---
arch/riscv/configs/nommu_k210_defconfig | 68 +++++++++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 arch/riscv/configs/nommu_k210_defconfig
diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig
new file mode 100644
index 000000000000..00ded8f0bc55
--- /dev/null
+++ b/arch/riscv/configs/nommu_k210_defconfig
@@ -0,0 +1,68 @@
+# CONFIG_CPU_ISOLATION is not set
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="k210.cpio"
+CONFIG_INITRAMFS_FORCE=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+# CONFIG_BOOT_CONFIG is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_SYSFS_SYSCALL is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+# CONFIG_IO_URING is not set
+# CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_MEMBARRIER is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+# CONFIG_SLAB_MERGE_DEFAULT is not set
+# CONFIG_MMU is not set
+CONFIG_SOC_KENDRYTE=y
+CONFIG_MAXPHYSMEM_2GB=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_CMDLINE="earlycon console=ttySIF0"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_USE_BUILTIN_DTB=y
+CONFIG_BUILTIN_DTB_SOURCE="kendryte/k210"
+# CONFIG_BLOCK is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_COREDUMP is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_LDISC_AUTOLOAD is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_LSM="[]"
+CONFIG_PRINTK_TIME=y
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 8/9] riscv: create a loader.bin boot image for Kendryte SoC
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
` (6 preceding siblings ...)
2020-03-12 5:11 ` [PATCH v2 7/9] riscv: Kendryte K210 default config Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 9/9] riscv: Do not initialize PMP on " Damien Le Moal
8 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
From: Christoph Hellwig <hch@lst.de>
Create the loader.bin bootable image file that can be loaded into
Kendryte K210 based boards using the kflash.py tool with the command:
kflash.py/kflash.py -t arch/riscv/boot/loader.bin
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
---
arch/riscv/Makefile | 6 +++---
arch/riscv/boot/Makefile | 3 +++
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 259cb53d7f20..fb6e37db836d 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -85,12 +85,12 @@ PHONY += vdso_install
vdso_install:
$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
-ifeq ($(CONFIG_RISCV_M_MODE),y)
-KBUILD_IMAGE := $(boot)/loader
+ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_KENDRYTE),yy)
+KBUILD_IMAGE := $(boot)/loader.bin
else
KBUILD_IMAGE := $(boot)/Image.gz
endif
-BOOT_TARGETS := Image Image.gz loader
+BOOT_TARGETS := Image Image.gz loader loader.bin
all: $(notdir $(KBUILD_IMAGE))
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
index 36db8145f9f4..3530c59b3ea7 100644
--- a/arch/riscv/boot/Makefile
+++ b/arch/riscv/boot/Makefile
@@ -41,6 +41,9 @@ $(obj)/Image.lzma: $(obj)/Image FORCE
$(obj)/Image.lzo: $(obj)/Image FORCE
$(call if_changed,lzo)
+$(obj)/loader.bin: $(obj)/loader FORCE
+ $(call if_changed,objcopy)
+
install:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/Image System.map "$(INSTALL_PATH)"
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
` (7 preceding siblings ...)
2020-03-12 5:11 ` [PATCH v2 8/9] riscv: create a loader.bin boot image for Kendryte SoC Damien Le Moal
@ 2020-03-12 5:11 ` Damien Le Moal
2020-03-12 15:20 ` Sean Anderson
8 siblings, 1 reply; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:11 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
Commit c68a9032299e ("riscv: set pmp configuration if kernel is running
in M-mode") added PMP initialization to M-Mode. While this patch is
valid for any SoC following the ratified riscv specifications, the
Kendryte K210 SoC is based on earlier unstable specifications and does
not seem to support PMP initialization (the SoC crashes if CSR_PMPADDR0
or CSR_PMPCFG0 are accessed).
Since all physical memory access works fine on this SoC without any
explicit PMP initialization, avoid the SoC crash by not touching the
PMP CSRs.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
arch/riscv/kernel/head.S | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 52ed11b4fda6..1a5defdc33d2 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -58,11 +58,17 @@ _start_kernel:
/* Reset all registers except ra, a0, a1 */
call reset_regs
- /* Setup a PMP to permit access to all of memory. */
+ /*
+ * For M-mode, setup PMP to permit access to all of memory.
+ * This should however not be done for the Kendryte K210 SoC as this
+ * causes a crash (this SoC follows older unstable specification).
+ */
+#ifndef CONFIG_SOC_KENDRYTE
li a0, -1
csrw CSR_PMPADDR0, a0
li a0, (PMP_A_NAPOT | PMP_R | PMP_W | PMP_X)
csrw CSR_PMPCFG0, a0
+#endif
/*
* The hartid in a0 is expected later on, and we have no firmware
--
2.24.1
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 5:11 ` [PATCH v2 9/9] riscv: Do not initialize PMP on " Damien Le Moal
@ 2020-03-12 15:20 ` Sean Anderson
2020-03-12 18:10 ` Atish Patra
0 siblings, 1 reply; 36+ messages in thread
From: Sean Anderson @ 2020-03-12 15:20 UTC (permalink / raw)
To: linux-riscv
On 3/12/20 1:11 AM, Damien Le Moal wrote:
> Commit c68a9032299e ("riscv: set pmp configuration if kernel is running
> in M-mode") added PMP initialization to M-Mode. While this patch is
> valid for any SoC following the ratified riscv specifications, the
> Kendryte K210 SoC is based on earlier unstable specifications and does
> not seem to support PMP initialization (the SoC crashes if CSR_PMPADDR0
> or CSR_PMPCFG0 are accessed).
The PMP bit has its polarity inverted in the v1.9 specification, and is
called the SUM or Supervisor User Memory Access bit.
--Sean
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 15:20 ` Sean Anderson
@ 2020-03-12 18:10 ` Atish Patra
2020-03-12 18:14 ` Sean Anderson
2020-03-13 5:25 ` Damien Le Moal
0 siblings, 2 replies; 36+ messages in thread
From: Atish Patra @ 2020-03-12 18:10 UTC (permalink / raw)
To: Sean Anderson; +Cc: linux-riscv, Palmer Dabbelt, Damien Le Moal
On Thu, Mar 12, 2020 at 8:20 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 3/12/20 1:11 AM, Damien Le Moal wrote:
> > Commit c68a9032299e ("riscv: set pmp configuration if kernel is running
> > in M-mode") added PMP initialization to M-Mode. While this patch is
> > valid for any SoC following the ratified riscv specifications, the
> > Kendryte K210 SoC is based on earlier unstable specifications and does
> > not seem to support PMP initialization (the SoC crashes if CSR_PMPADDR0
> > or CSR_PMPCFG0 are accessed).
>
> The PMP bit has its polarity inverted in the v1.9 specification, and is
> called the SUM or Supervisor User Memory Access bit.
>
> --Sean
>
I don't think supporting old specs in Linux is a good idea. As per the
patch guideline
for RISC-V Linux, patches for only "frozen" or "ratified"
specifications are allowed.
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 18:10 ` Atish Patra
@ 2020-03-12 18:14 ` Sean Anderson
2020-03-12 18:29 ` Atish Patra
2020-03-13 5:25 ` Damien Le Moal
1 sibling, 1 reply; 36+ messages in thread
From: Sean Anderson @ 2020-03-12 18:14 UTC (permalink / raw)
To: Atish Patra; +Cc: linux-riscv, Palmer Dabbelt, Damien Le Moal
> I don't think supporting old specs in Linux is a good idea. As per the
> patch guideline
> for RISC-V Linux, patches for only "frozen" or "ratified"
> specifications are allowed.
>
Well this CPU follows the v1.9 spec. It's real hardware, if it is to be
be supported, then the 1.9 spec needs to be as well.
--Sean
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 6/9] riscv: Add Kendryte K210 device tree
2020-03-12 5:11 ` [PATCH v2 6/9] riscv: Add Kendryte K210 device tree Damien Le Moal
@ 2020-03-12 18:16 ` Sean Anderson
2020-03-13 5:29 ` Damien Le Moal
0 siblings, 1 reply; 36+ messages in thread
From: Sean Anderson @ 2020-03-12 18:16 UTC (permalink / raw)
To: Damien Le Moal, linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
On 3/12/20 1:11 AM, Damien Le Moal wrote:
> Add a generic device tree for Kendryte K210 SoC based boards. This (for
> now) very simple device tree works for the Kendryte KD233 development
> board, the Sipeed MAIX M1 Dan Dock board and the Sipeed MAIXDUINO board.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> ---
> arch/riscv/boot/dts/Makefile | 1 +
> arch/riscv/boot/dts/kendryte/Makefile | 2 +
> arch/riscv/boot/dts/kendryte/k210.dts | 23 +++++
> arch/riscv/boot/dts/kendryte/k210.dtsi | 117 +++++++++++++++++++++++++
> include/dt-bindings/clock/k210-clk.h | 20 +++++
> 5 files changed, 163 insertions(+)
> create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
> create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
> create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
> create mode 100644 include/dt-bindings/clock/k210-clk.h
>
> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
> index 0bf2669aa12d..87815557f2db 100644
> --- a/arch/riscv/boot/dts/Makefile
> +++ b/arch/riscv/boot/dts/Makefile
> @@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
> obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
> else
> subdir-y += sifive
> +subdir-y += kendryte
> endif
> diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
> new file mode 100644
> index 000000000000..815444e69e89
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
> new file mode 100644
> index 000000000000..0d1f28fce6b2
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dts
> @@ -0,0 +1,23 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +/dts-v1/;
> +
> +#include "k210.dtsi"
> +
> +/ {
> + model = "Kendryte K210 generic";
> + compatible = "kendryte,k210";
> +
> + chosen {
> + bootargs = "earlycon console=ttySIF0";
> + stdout-path = "serial0";
> + };
> +};
> +
> +&uarths0 {
> + status = "okay";
> +};
> +
> diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
> new file mode 100644
> index 000000000000..88f28a3fd337
> --- /dev/null
> +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
> @@ -0,0 +1,117 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +#include <dt-bindings/clock/k210-clk.h>
> +
> +/ {
> + /*
> + * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
> + * wide, and the upper half of all addresses is ignored.
> + */
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "kendryte,k210";
> +
> + aliases {
> + serial0 = &uarths0;
> + };
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + timebase-frequency = <7800000>;
> + cpu0: cpu@0 {
> + device_type = "cpu";
> + reg = <0>;
> + compatible = "kendryte,k210", "sifive,rocket0", "riscv";
> + riscv,isa = "rv64imafdc";
> + mmu-type = "none";
> + i-cache-size = <0x8000>;
> + i-cache-block-size = <64>;
> + d-cache-size = <0x8000>;
> + d-cache-block-size = <64>;
> + clocks = <&sysctl K210_CLK_CPU>;
> + clock-frequency = <390000000>;
> + cpu0_intc: interrupt-controller {
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + compatible = "riscv,cpu-intc";
> + };
> + };
> + cpu1: cpu@1 {
> + device_type = "cpu";
> + reg = <1>;
> + compatible = "kendryte,k210", "sifive,rocket0", "riscv";
> + riscv,isa = "rv64imafdc";
> + mmu-type = "none";
Perhaps add a comment? The mmu is still sv39, even if the kernel is NOMMU.
> + i-cache-size = <0x8000>;
> + i-cache-block-size = <64>; /* bogus */
These comments should be removed to match the bindings above.
> + d-cache-size = <0x8000>;
> + d-cache-block-size = <64>; /* bogus */
> + clocks = <&sysctl K210_CLK_CPU>;
> + clock-frequency = <390000000>;
> + cpu1_intc: interrupt-controller {
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + compatible = "riscv,cpu-intc";
> + };
> + };
> + };
> +
> + sram: memory@80000000 {
> + device_type = "memory";
> + reg = <0x80000000 0x400000>,
> + <0x80400000 0x200000>,
> + <0x80600000 0x200000>;
> + reg-names = "sram0", "sram1", "aisram";
> + };
> +
> + clocks {
> + in0: oscillator {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <26000000>;
> + };
> + };
> +
> + soc {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "kendryte,k210-soc", "simple-bus";
> + ranges;
> + interrupt-parent = <&plic0>;
> +
> + sysctl: sysctl@50440000 {
> + compatible = "kendryte,k210-sysctl", "syscon";
> + reg = <0x50440000 0x1000>;
> + #clock-cells = <1>;
> + };
Still think this should be modeled as an mfd.
> +
> + clint0: interrupt-controller@2000000 {
> + compatible = "riscv,clint0";
> + reg = <0x2000000 0xC000>;
> + interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>;
> + clocks = <&sysctl K210_CLK_ACLK>;
> + };
> +
> + plic0: interrupt-controller@c000000 {
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + compatible = "kendryte,k210-plic0", "riscv,plic0";
> + reg = <0xC000000 0x4000000>;
> + interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
> + <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
> + riscv,ndev = <65>;
> + riscv,max-priority = <7>;
> + };
> +
> + uarths0: serial@38000000 {
> + compatible = "kendryte,k210-uarths", "sifive,uart0";
> + reg = <0x38000000 0x1000>;
> + interrupts = <33>;
> + clocks = <&sysctl K210_CLK_CPU>;
> + };
> + };
> +};
> diff --git a/include/dt-bindings/clock/k210-clk.h b/include/dt-bindings/clock/k210-clk.h
> new file mode 100644
> index 000000000000..5a2fd64d1a49
> --- /dev/null
> +++ b/include/dt-bindings/clock/k210-clk.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com>
> + * Copyright (c) 2020 Western Digital Corporation or its affiliates.
> + */
> +#ifndef K210_CLK_H
> +#define K210_CLK_H
> +
> +/*
> + * Arbitrary identifiers for clocks.
> + * The structure is: in0 -> pll0 -> aclk -> cpu
> + *
> + * Since we use the hardware defaults for now, set all these to the same clock.
> + */
> +#define K210_CLK_PLL0 0
> +#define K210_CLK_PLL1 0
> +#define K210_CLK_ACLK 0
> +#define K210_CLK_CPU 0
> +
> +#endif /* K210_CLK_H */
>
--Sean
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 4/9] riscv: Add Kendryte K210 SoC support
2020-03-12 5:11 ` [PATCH v2 4/9] riscv: Add Kendryte K210 SoC support Damien Le Moal
@ 2020-03-12 18:19 ` Sean Anderson
2020-03-13 5:43 ` Damien Le Moal
0 siblings, 1 reply; 36+ messages in thread
From: Sean Anderson @ 2020-03-12 18:19 UTC (permalink / raw)
To: Damien Le Moal, linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
On 3/12/20 1:11 AM, Damien Le Moal wrote:
> From: Christoph Hellwig <hch@lst.de>
>
> Add support for the Kendryte K210 RISC-V SoC. For now, this support
> only provides a simple sysctl driver allowing to setup the CPU and
> uart clock. This support is enabled through the new Kconfig option
> SOC_KENDRYTE and defines the config option CONFIG_K210_SYSCTL
> to enable the K210 SoC sysctl driver compilation.
>
> The sysctl driver also registers an early SoC initialization function
> allowing enabling the general purpose use of the 2MB of SRAM normally
> reserved for the SoC AI engine. This initialization function is
> automatically called before the dt early initialization using the flat
> dt root node compatible property matching the value "kendryte,k210".
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> ---
> arch/riscv/Kconfig.socs | 6 +
> drivers/soc/Kconfig | 1 +
> drivers/soc/Makefile | 1 +
> drivers/soc/kendryte/Kconfig | 14 ++
> drivers/soc/kendryte/Makefile | 3 +
> drivers/soc/kendryte/k210-sysctl.c | 245 +++++++++++++++++++++++++++++
> 6 files changed, 270 insertions(+)
> create mode 100644 drivers/soc/kendryte/Kconfig
> create mode 100644 drivers/soc/kendryte/Makefile
> create mode 100644 drivers/soc/kendryte/k210-sysctl.c
>
> diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
> index 3078b2de0b2d..69071578e181 100644
> --- a/arch/riscv/Kconfig.socs
> +++ b/arch/riscv/Kconfig.socs
> @@ -34,4 +34,10 @@ config SOC_VIRT
> help
> This enables support for QEMU Virt Machine.
>
> +config SOC_KENDRYTE
> + bool "Kendryte K210 SoC"
> + depends on !MMU
> + help
> + This enables support for Kendryte K210 SoC platform hardware.
> +
> endmenu
> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> index 1778f8c62861..425ab6f7e375 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -22,5 +22,6 @@ source "drivers/soc/ux500/Kconfig"
> source "drivers/soc/versatile/Kconfig"
> source "drivers/soc/xilinx/Kconfig"
> source "drivers/soc/zte/Kconfig"
> +source "drivers/soc/kendryte/Kconfig"
>
> endmenu
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 8b49d782a1ab..af58063bb989 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -28,3 +28,4 @@ obj-$(CONFIG_ARCH_U8500) += ux500/
> obj-$(CONFIG_PLAT_VERSATILE) += versatile/
> obj-y += xilinx/
> obj-$(CONFIG_ARCH_ZX) += zte/
> +obj-$(CONFIG_SOC_KENDRYTE) += kendryte/
> diff --git a/drivers/soc/kendryte/Kconfig b/drivers/soc/kendryte/Kconfig
> new file mode 100644
> index 000000000000..49785b1b0217
> --- /dev/null
> +++ b/drivers/soc/kendryte/Kconfig
> @@ -0,0 +1,14 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +if SOC_KENDRYTE
> +
> +config K210_SYSCTL
> + bool "Kendryte K210 system controller"
> + default y
> + depends on RISCV
> + help
> + Enables controlling the K210 various clocks and to enable
> + general purpose use of the extra 2MB of SRAM normally
> + reserved for the AI engine.
> +
> +endif
> diff --git a/drivers/soc/kendryte/Makefile b/drivers/soc/kendryte/Makefile
> new file mode 100644
> index 000000000000..002d9ce95c0d
> --- /dev/null
> +++ b/drivers/soc/kendryte/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_K210_SYSCTL) += k210-sysctl.o
> diff --git a/drivers/soc/kendryte/k210-sysctl.c b/drivers/soc/kendryte/k210-sysctl.c
> new file mode 100644
> index 000000000000..7d4ecd954af0
> --- /dev/null
> +++ b/drivers/soc/kendryte/k210-sysctl.c
> @@ -0,0 +1,245 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 Christoph Hellwig.
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + */
> +#include <linux/types.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <asm/soc.h>
> +
> +#define K210_SYSCTL_CLK0_FREQ 26000000UL
> +
> +/* Registers base address */
> +#define K210_SYSCTL_SYSCTL_BASE_ADDR 0x50440000ULL
> +
> +/* Registers */
> +#define K210_SYSCTL_PLL0 0x08
> +#define K210_SYSCTL_PLL1 0x0c
> +/* clkr: 4bits, clkf1: 6bits, clkod: 4bits, bwadj: 4bits */
> +#define PLL_RESET (1 << 20)
I think the preferred style is to use BIT(20), etc.
> +#define PLL_PWR (1 << 21)
> +#define PLL_INTFB (1 << 22)
> +#define PLL_BYPASS (1 << 23)
> +#define PLL_TEST (1 << 24)
> +#define PLL_OUT_EN (1 << 25)
> +#define PLL_TEST_EN (1 << 26)
> +#define K210_SYSCTL_PLL_LOCK 0x18
Can you use GENMASK here?
> +#define PLL0_LOCK1 (1 << 0)
> +#define PLL0_LOCK2 (1 << 1)
> +#define PLL0_SLIP_CLEAR (1 << 2)
> +#define PLL0_TEST_CLK_OUT (1 << 3)
> +#define PLL1_LOCK1 (1 << 8)
> +#define PLL1_LOCK2 (1 << 9)
> +#define PLL1_SLIP_CLEAR (1 << 10)
> +#define PLL1_TEST_CLK_OUT (1 << 11)
> +#define PLL2_LOCK1 (1 << 16)
> +#define PLL2_LOCK2 (1 << 16)
> +#define PLL2_SLIP_CLEAR (1 << 18)
> +#define PLL2_TEST_CLK_OUT (1 << 19)
> +#define K210_SYSCTL_CLKSEL0 0x20
> +#define CLKSEL_ACLK (1 << 0)
> +#define K210_SYSCTL_CLKEN_CENT 0x28
> +#define CLKEN_CPU (1 << 0)
> +#define CLKEN_SRAM0 (1 << 1)
> +#define CLKEN_SRAM1 (1 << 2)
> +#define CLKEN_APB0 (1 << 3)
> +#define CLKEN_APB1 (1 << 4)
> +#define CLKEN_APB2 (1 << 5)
> +#define K210_SYSCTL_CLKEN_PERI 0x2c
> +#define CLKEN_ROM (1 << 0)
> +#define CLKEN_DMA (1 << 1)
> +#define CLKEN_AI (1 << 2)
> +#define CLKEN_DVP (1 << 3)
> +#define CLKEN_FFT (1 << 4)
> +#define CLKEN_GPIO (1 << 5)
> +#define CLKEN_SPI0 (1 << 6)
> +#define CLKEN_SPI1 (1 << 7)
> +#define CLKEN_SPI2 (1 << 8)
> +#define CLKEN_SPI3 (1 << 9)
> +#define CLKEN_I2S0 (1 << 10)
> +#define CLKEN_I2S1 (1 << 11)
> +#define CLKEN_I2S2 (1 << 12)
> +#define CLKEN_I2C0 (1 << 13)
> +#define CLKEN_I2C1 (1 << 14)
> +#define CLKEN_I2C2 (1 << 15)
> +#define CLKEN_UART1 (1 << 16)
> +#define CLKEN_UART2 (1 << 17)
> +#define CLKEN_UART3 (1 << 18)
> +#define CLKEN_AES (1 << 19)
> +#define CLKEN_FPIO (1 << 20)
> +#define CLKEN_TIMER0 (1 << 21)
> +#define CLKEN_TIMER1 (1 << 22)
> +#define CLKEN_TIMER2 (1 << 23)
> +#define CLKEN_WDT0 (1 << 24)
> +#define CLKEN_WDT1 (1 << 25)
> +#define CLKEN_SHA (1 << 26)
> +#define CLKEN_OTP (1 << 27)
> +#define CLKEN_RTC (1 << 29)
> +
> +struct k210_sysctl {
> + void __iomem *regs;
> + struct clk_hw hw;
> +};
> +
> +static void k210_set_bits(u32 val, void __iomem *reg)
> +{
> + writel(readl(reg) | val, reg);
> +}
> +
> +static void k210_clear_bits(u32 val, void __iomem *reg)
> +{
> + writel(readl(reg) & ~val, reg);
> +}
> +
> +static void k210_pll1_enable(void __iomem *regs)
> +{
> + u32 val;
> +
> + val = readl(regs + K210_SYSCTL_PLL1);
> + val &= ~0xfffff;
> + val |= (59 << 4) | (3 << 10) | (59 << 15);
Again, can this be done with GENMASK and FIELD_PREP?
> + writel(val, regs + K210_SYSCTL_PLL1);
> +
> + k210_clear_bits(PLL_BYPASS, regs + K210_SYSCTL_PLL1);
> + k210_set_bits(PLL_PWR, regs + K210_SYSCTL_PLL1);
> +
> + /*
> + * Reset the pll. The magic NOPs come from the Kendryte reference SDK.
> + */
> + k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> + k210_set_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> + nop();
> + nop();
> + k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> +
> + for (;;) {
> + val = readl(regs + K210_SYSCTL_PLL_LOCK);
> + if (val & PLL1_LOCK2)
> + break;
> + writel(val | PLL1_SLIP_CLEAR, regs + K210_SYSCTL_PLL_LOCK);
> + }
> +
> + k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL1);
> +}
> +
> +static unsigned long k210_sysctl_clk_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct k210_sysctl *s = container_of(hw, struct k210_sysctl, hw);
> + u32 clksel0, pll0;
> + u64 pll0_freq, clkr0, clkf0, clkod0;
> +
> + /*
> + * If the clock selector is not set, use the base frequency.
> + * Otherwise, use PLL0 frequency with a frequency divisor.
> + */
> + clksel0 = readl(s->regs + K210_SYSCTL_CLKSEL0);
> + if (!(clksel0 & CLKSEL_ACLK))
> + return K210_SYSCTL_CLK0_FREQ;
> +
> + /*
> + * Get PLL0 frequency:
> + * freq = base frequency * clkf0 / (clkr0 * clkod0)
> + */
> + pll0 = readl(s->regs + K210_SYSCTL_PLL0);
> + clkr0 = 1 + (pll0 & 0x0000000f);
> + clkf0 = 1 + ((pll0 & 0x000003f0) >> 4);
> + clkod0 = 1 + ((pll0 & 0x00003c00) >> 10);
Same thing here, use FIELD_GET instead please.
> + pll0_freq = clkf0 * K210_SYSCTL_CLK0_FREQ / (clkr0 * clkod0);
> +
> + /* Get the frequency divisor from the clock selector */
> + return pll0_freq / (2ULL << ((clksel0 & 0x00000006) >> 1));
> +}
> +
> +static const struct clk_ops k210_sysctl_clk_ops = {
> + .recalc_rate = k210_sysctl_clk_recalc_rate,
> +};
> +
> +static const struct clk_init_data k210_clk_init_data = {
> + .name = "k210-sysctl-pll1",
> + .ops = &k210_sysctl_clk_ops,
> +};
> +
> +static int k210_sysctl_probe(struct platform_device *pdev)
> +{
> + struct k210_sysctl *s;
> + int error;
> +
> + pr_info("Kendryte K210 SoC sysctl\n");
> +
> + s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
> + if (!s)
> + return -ENOMEM;
> +
> + s->regs = devm_ioremap_resource(&pdev->dev,
> + platform_get_resource(pdev, IORESOURCE_MEM, 0));
> + if (IS_ERR(s->regs))
> + return PTR_ERR(s->regs);
> +
> + s->hw.init = &k210_clk_init_data;
> + error = devm_clk_hw_register(&pdev->dev, &s->hw);
> + if (error) {
> + dev_err(&pdev->dev, "failed to register clk");
> + return error;
> + }
> +
> + error = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
> + &s->hw);
> + if (error) {
> + dev_err(&pdev->dev, "adding clk provider failed\n");
> + return error;
> + }
> +
> + return 0;
> +}
> +
> +static const struct of_device_id k210_sysctl_of_match[] = {
> + { .compatible = "kendryte,k210-sysctl", },
> + {}
> +};
> +
> +static struct platform_driver k210_sysctl_driver = {
> + .driver = {
> + .name = "k210-sysctl",
> + .of_match_table = k210_sysctl_of_match,
> + },
> + .probe = k210_sysctl_probe,
> +};
> +
> +static int __init k210_sysctl_init(void)
> +{
> + return platform_driver_register(&k210_sysctl_driver);
> +}
> +core_initcall(k210_sysctl_init);
> +
> +/*
> + * This needs to be called very early during initialization, given that
> + * PLL1 needs to be enabled to be able to use all SRAM.
> + */
> +static void __init k210_soc_early_init(const void *fdt)
> +{
> + void __iomem *regs;
> +
> + regs = ioremap(K210_SYSCTL_SYSCTL_BASE_ADDR, 0x1000);
> + if (!regs)
> + panic("K210 sysctl ioremap");
> +
> + /* Enable PLL1 to make the KPU SRAM useable */
> + k210_pll1_enable(regs);
> +
> + k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL0);
> +
> + k210_set_bits(CLKEN_CPU | CLKEN_SRAM0 | CLKEN_SRAM1,
> + regs + K210_SYSCTL_CLKEN_CENT);
> + k210_set_bits(CLKEN_ROM | CLKEN_TIMER0 | CLKEN_RTC,
> + regs + K210_SYSCTL_CLKEN_PERI);
> +
> + k210_set_bits(CLKSEL_ACLK, regs + K210_SYSCTL_CLKSEL0);
> +
> + iounmap(regs);
> +}
> +SOC_EARLY_INIT_DECLARE("kendryte,k210", k210_soc_early_init);
>
--Sean
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-12 5:11 ` [PATCH v2 3/9] riscv: Add SOC early init support Damien Le Moal
@ 2020-03-12 18:21 ` Sean Anderson
2020-03-13 5:52 ` Damien Le Moal
2020-03-12 19:50 ` Atish Patra
2020-03-12 20:53 ` Atish Patra
2 siblings, 1 reply; 36+ messages in thread
From: Sean Anderson @ 2020-03-12 18:21 UTC (permalink / raw)
To: Damien Le Moal, linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
On 3/12/20 1:11 AM, Damien Le Moal wrote:
> Add a mechanism for early SoC initialization for platforms that need
> additional hardware initialization not possible through the regular
> device tree and drivers mechanism. With this, a SoC specific
> initialization function can be called very early, before DTB parsing
> is done by parse_dtb() in Linux RISC-V kernel setup code.
Why does it need to be called that early (e.g. before parsing dtb)?
>
> This can be very useful for early hardware initialization for No-MMU
> kernels booted directly in M-mode because it is quite likely that no
> other booting stage exist prior to the No-MMU kernel.
>
> Example use of a SoC early initialization is as follows:
>
> static void vendor_abc_early_init(const void *fdt)
> {
> /*
> * some early init code here that can use simple matches
> * against the flat device tree file.
> */
> }
> SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
>
> This early initialization function is executed only if the flat device
> tree for the board has a 'compatible = "vendor,abc"' entry;
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Signed-off-by: Anup Patel <anup.patel@wdc.com>
> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
--Sean
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 18:14 ` Sean Anderson
@ 2020-03-12 18:29 ` Atish Patra
2020-03-12 18:49 ` Sean Anderson
0 siblings, 1 reply; 36+ messages in thread
From: Atish Patra @ 2020-03-12 18:29 UTC (permalink / raw)
To: Sean Anderson; +Cc: linux-riscv, Palmer Dabbelt, Damien Le Moal
On Thu, Mar 12, 2020 at 11:14 AM Sean Anderson <seanga2@gmail.com> wrote:
>
>
> > I don't think supporting old specs in Linux is a good idea. As per the
> > patch guideline
> > for RISC-V Linux, patches for only "frozen" or "ratified"
> > specifications are allowed.
> >
>
> Well this CPU follows the v1.9 spec. It's real hardware, if it is to be
> be supported, then the 1.9 spec needs to be as well.
>
As RISC-V is an open ISA and it's continuously evolving, there will be
some hardware
that will implement old specifications or non-backward compatible features.
I fear the number of hardware with such features/implementations will
grow in the future.
If Linux is going to support all of them, it may be a maintenance nightmare.
> --Sean
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 18:29 ` Atish Patra
@ 2020-03-12 18:49 ` Sean Anderson
2020-03-12 19:12 ` Atish Patra
2020-03-13 5:40 ` Anup Patel
0 siblings, 2 replies; 36+ messages in thread
From: Sean Anderson @ 2020-03-12 18:49 UTC (permalink / raw)
To: Atish Patra; +Cc: linux-riscv, Palmer Dabbelt, Damien Le Moal
On 3/12/20 2:29 PM, Atish Patra wrote:
> On Thu, Mar 12, 2020 at 11:14 AM Sean Anderson <seanga2@gmail.com> wrote:
>>
>>
>>> I don't think supporting old specs in Linux is a good idea. As per the
>>> patch guideline
>>> for RISC-V Linux, patches for only "frozen" or "ratified"
>>> specifications are allowed.
>>>
>>
>> Well this CPU follows the v1.9 spec. It's real hardware, if it is to be
>> be supported, then the 1.9 spec needs to be as well.
>>
>
> As RISC-V is an open ISA and it's continuously evolving, there will be
> some hardware
> that will implement old specifications or non-backward compatible features.
> I fear the number of hardware with such features/implementations will
> grow in the future.
> If Linux is going to support all of them, it may be a maintenance nightmare.
I agree. There is also no standard way to communicate the implemented
privileged spec level e.g. in the device tree. The base integer
instruction set version can be specified in the riscv,isa property, such
as
riscv,isa = "rv64i2p1..."
However, there is no "extension" for the privileged specification.
A method to specify this would be helpful, especially since the
bootloader may need to enable the MMU before loading Linux since there
is no way to enable it from S-mode until v1.10.
On the other hand, there is relatively little changed from v1.9 to the
current revision. The following list has the differences from the
current spec:
* The PMP has flipped polarity
* The mcounteren CSRs are split
* sfence.vma is sfence.vm (though this should be handled by the sbi
anyway)
* satp has a different name, and mode no longer exists in the top four
bits. Since these bits used to be part of ASID, it's fine to write the
mode to those bits. If linux never switches from (e.g.) sv39 to
something else, there will be no observed difference either.
Everything else is mostly forwards-compatible, as far as I can tell.
That is, assuming new behaviour on old hardware won't cause problems.
A sufficiently smart kernel could even detect the version at runtime by
intentionally triggering behaviour which is illegal depending on the
privileged version, and then checking for an exception.
--Sean
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 7/9] riscv: Kendryte K210 default config
2020-03-12 5:11 ` [PATCH v2 7/9] riscv: Kendryte K210 default config Damien Le Moal
@ 2020-03-12 19:03 ` Atish Patra
2020-03-13 5:52 ` Damien Le Moal
0 siblings, 1 reply; 36+ messages in thread
From: Atish Patra @ 2020-03-12 19:03 UTC (permalink / raw)
To: Damien Le Moal; +Cc: linux-riscv, Anup Patel, Palmer Dabbelt
On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
>
> This patch adds a defconfig file to build No-MMU kernels meant for
> boards based on the Kendryte K210 SoC.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Reviewed-by: Anup Patel <anup@brainfault.org>
> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> ---
> arch/riscv/configs/nommu_k210_defconfig | 68 +++++++++++++++++++++++++
> 1 file changed, 68 insertions(+)
> create mode 100644 arch/riscv/configs/nommu_k210_defconfig
>
> diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig
> new file mode 100644
> index 000000000000..00ded8f0bc55
> --- /dev/null
> +++ b/arch/riscv/configs/nommu_k210_defconfig
> @@ -0,0 +1,68 @@
> +# CONFIG_CPU_ISOLATION is not set
> +CONFIG_LOG_BUF_SHIFT=15
> +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12
> +CONFIG_BLK_DEV_INITRD=y
> +CONFIG_INITRAMFS_SOURCE="k210.cpio"
I don't think it is a common practice to provide a default rootfs file
in defconfig if it is not
part of the kernel. I may be wrong but I have not seen an example before.
It is expected that developers will generate their own rootfs and
modify it here.
It may also raise compiler errors for auto builders in absence of k210.cpio.
> +CONFIG_INITRAMFS_FORCE=y
> +# CONFIG_RD_BZIP2 is not set
> +# CONFIG_RD_LZMA is not set
> +# CONFIG_RD_XZ is not set
> +# CONFIG_RD_LZO is not set
> +# CONFIG_RD_LZ4 is not set
> +# CONFIG_BOOT_CONFIG is not set
> +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
> +# CONFIG_SYSFS_SYSCALL is not set
> +# CONFIG_FHANDLE is not set
> +# CONFIG_BASE_FULL is not set
> +# CONFIG_EPOLL is not set
> +# CONFIG_SIGNALFD is not set
> +# CONFIG_TIMERFD is not set
> +# CONFIG_EVENTFD is not set
> +# CONFIG_AIO is not set
> +# CONFIG_IO_URING is not set
> +# CONFIG_ADVISE_SYSCALLS is not set
> +# CONFIG_MEMBARRIER is not set
> +# CONFIG_KALLSYMS is not set
> +CONFIG_EMBEDDED=y
> +# CONFIG_VM_EVENT_COUNTERS is not set
> +# CONFIG_COMPAT_BRK is not set
> +CONFIG_SLOB=y
> +# CONFIG_SLAB_MERGE_DEFAULT is not set
> +# CONFIG_MMU is not set
> +CONFIG_SOC_KENDRYTE=y
> +CONFIG_MAXPHYSMEM_2GB=y
> +CONFIG_SMP=y
> +CONFIG_NR_CPUS=2
> +CONFIG_CMDLINE="earlycon console=ttySIF0"
> +CONFIG_CMDLINE_FORCE=y
> +CONFIG_USE_BUILTIN_DTB=y
> +CONFIG_BUILTIN_DTB_SOURCE="kendryte/k210"
> +# CONFIG_BLOCK is not set
> +CONFIG_BINFMT_FLAT=y
> +# CONFIG_COREDUMP is not set
> +CONFIG_DEVTMPFS=y
> +CONFIG_DEVTMPFS_MOUNT=y
> +# CONFIG_FW_LOADER is not set
> +# CONFIG_ALLOW_DEV_COREDUMP is not set
> +# CONFIG_INPUT_KEYBOARD is not set
> +# CONFIG_INPUT_MOUSE is not set
> +# CONFIG_SERIO is not set
> +# CONFIG_LEGACY_PTYS is not set
> +# CONFIG_LDISC_AUTOLOAD is not set
> +# CONFIG_DEVMEM is not set
> +# CONFIG_HW_RANDOM is not set
> +# CONFIG_HWMON is not set
> +# CONFIG_VGA_CONSOLE is not set
> +# CONFIG_HID is not set
> +# CONFIG_USB_SUPPORT is not set
> +# CONFIG_VIRTIO_MENU is not set
> +# CONFIG_DNOTIFY is not set
> +# CONFIG_INOTIFY_USER is not set
> +# CONFIG_MISC_FILESYSTEMS is not set
> +CONFIG_LSM="[]"
> +CONFIG_PRINTK_TIME=y
> +# CONFIG_DEBUG_MISC is not set
> +# CONFIG_SCHED_DEBUG is not set
> +# CONFIG_RCU_TRACE is not set
> +# CONFIG_FTRACE is not set
> +# CONFIG_RUNTIME_TESTING_MENU is not set
> --
> 2.24.1
>
>
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 18:49 ` Sean Anderson
@ 2020-03-12 19:12 ` Atish Patra
2020-03-12 20:09 ` Sean Anderson
2020-03-13 6:03 ` Damien Le Moal
2020-03-13 5:40 ` Anup Patel
1 sibling, 2 replies; 36+ messages in thread
From: Atish Patra @ 2020-03-12 19:12 UTC (permalink / raw)
To: Sean Anderson; +Cc: linux-riscv, Palmer Dabbelt, Damien Le Moal
On Thu, Mar 12, 2020 at 11:49 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 3/12/20 2:29 PM, Atish Patra wrote:
> > On Thu, Mar 12, 2020 at 11:14 AM Sean Anderson <seanga2@gmail.com> wrote:
> >>
> >>
> >>> I don't think supporting old specs in Linux is a good idea. As per the
> >>> patch guideline
> >>> for RISC-V Linux, patches for only "frozen" or "ratified"
> >>> specifications are allowed.
> >>>
> >>
> >> Well this CPU follows the v1.9 spec. It's real hardware, if it is to be
> >> be supported, then the 1.9 spec needs to be as well.
> >>
> >
> > As RISC-V is an open ISA and it's continuously evolving, there will be
> > some hardware
> > that will implement old specifications or non-backward compatible features.
> > I fear the number of hardware with such features/implementations will
> > grow in the future.
> > If Linux is going to support all of them, it may be a maintenance nightmare.
>
> I agree. There is also no standard way to communicate the implemented
> privileged spec level e.g. in the device tree. The base integer
> instruction set version can be specified in the riscv,isa property, such
> as
>
> riscv,isa = "rv64i2p1..."
>
> However, there is no "extension" for the privileged specification.
> A method to specify this would be helpful, especially since the
> bootloader may need to enable the MMU before loading Linux since there
> is no way to enable it from S-mode until v1.10.
>
> On the other hand, there is relatively little changed from v1.9 to the
> current revision. The following list has the differences from the
> current spec:
>
> * The PMP has flipped polarity
> * The mcounteren CSRs are split
> * sfence.vma is sfence.vm (though this should be handled by the sbi
> anyway)
> * satp has a different name, and mode no longer exists in the top four
> bits. Since these bits used to be part of ASID, it's fine to write the
> mode to those bits. If linux never switches from (e.g.) sv39 to
> something else, there will be no observed difference either.
>
> Everything else is mostly forwards-compatible, as far as I can tell.
> That is, assuming new behaviour on old hardware won't cause problems.
>
Even if the changes are minimal and we can easily hide under macro magic,
it will create a bad precedent for the future. What if somebody sends
a patch for
a non-standard extension and cites kendryte support as an example.
> A sufficiently smart kernel could even detect the version at runtime by
> intentionally triggering behaviour which is illegal depending on the
> privileged version, and then checking for an exception.
>
That's the maintenance nightmare I was talking about. For kendryte, it
is only few incompatible changes
in privilege specification but what if some hardware implements a
variation of hypervisor spec or vector extension.
> --Sean
>
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-12 5:11 ` [PATCH v2 3/9] riscv: Add SOC early init support Damien Le Moal
2020-03-12 18:21 ` Sean Anderson
@ 2020-03-12 19:50 ` Atish Patra
2020-03-12 20:53 ` Atish Patra
2 siblings, 0 replies; 36+ messages in thread
From: Atish Patra @ 2020-03-12 19:50 UTC (permalink / raw)
To: Damien Le Moal; +Cc: linux-riscv, Anup Patel, Palmer Dabbelt
On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
>
> Add a mechanism for early SoC initialization for platforms that need
> additional hardware initialization not possible through the regular
> device tree and drivers mechanism. With this, a SoC specific
> initialization function can be called very early, before DTB parsing
> is done by parse_dtb() in Linux RISC-V kernel setup code.
>
> This can be very useful for early hardware initialization for No-MMU
> kernels booted directly in M-mode because it is quite likely that no
> other booting stage exist prior to the No-MMU kernel.
>
> Example use of a SoC early initialization is as follows:
>
> static void vendor_abc_early_init(const void *fdt)
> {
> /*
> * some early init code here that can use simple matches
> * against the flat device tree file.
> */
> }
> SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
>
> This early initialization function is executed only if the flat device
> tree for the board has a 'compatible = "vendor,abc"' entry;
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Signed-off-by: Anup Patel <anup.patel@wdc.com>
> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> ---
> arch/riscv/include/asm/soc.h | 23 +++++++++++++++++++++++
> arch/riscv/kernel/Makefile | 1 +
> arch/riscv/kernel/head.S | 1 +
> arch/riscv/kernel/soc.c | 28 ++++++++++++++++++++++++++++
> arch/riscv/kernel/vmlinux.lds.S | 6 ++++++
> 5 files changed, 59 insertions(+)
> create mode 100644 arch/riscv/include/asm/soc.h
> create mode 100644 arch/riscv/kernel/soc.c
>
> diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h
> new file mode 100644
> index 000000000000..9b8c332cbe76
> --- /dev/null
> +++ b/arch/riscv/include/asm/soc.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +#ifndef _ASM_RISCV_SOC_H
> +#define _ASM_RISCV_SOC_H
> +
> +#include <linux/of.h>
> +#include <linux/linkage.h>
> +#include <linux/types.h>
> +
> +#define SOC_EARLY_INIT_DECLARE(compat, fn) \
> + static const struct of_device_id __soc_early_init \
> + __used __section(__soc_early_init_table) \
> + = { .compatible = compat, .data = fn }
> +
> +void soc_early_init(void);
> +
> +extern unsigned long __soc_early_init_table_start;
> +extern unsigned long __soc_early_init_table_end;
> +
> +#endif
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 97d0c35f8b37..e4a22999dbc6 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -10,6 +10,7 @@ endif
> extra-y += head.o
> extra-y += vmlinux.lds
>
> +obj-y += soc.o
> obj-y += cpu.o
> obj-y += cpufeature.o
> obj-y += entry.o
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 85f2073e7fe4..52ed11b4fda6 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -131,6 +131,7 @@ clear_bss_done:
> call kasan_early_init
> #endif
> /* Start the kernel */
> + call soc_early_init
> call parse_dtb
> tail start_kernel
>
> diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c
> new file mode 100644
> index 000000000000..0b3b3dc9ad0f
> --- /dev/null
> +++ b/arch/riscv/kernel/soc.c
> @@ -0,0 +1,28 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +#include <linux/init.h>
> +#include <linux/libfdt.h>
> +#include <asm/pgtable.h>
> +#include <asm/soc.h>
> +
> +/*
> + * This is called extremly early, before parse_dtb(), to allow initializing
> + * SoC hardware before memory or any device driver initialization.
> + */
> +void __init soc_early_init(void)
> +{
> + void (*early_fn)(const void *fdt);
> + const struct of_device_id *s;
> + const void *fdt = dtb_early_va;
> +
> + for (s = (void *)&__soc_early_init_table_start;
> + (void *)s < (void *)&__soc_early_init_table_end; s++) {
> + if (!fdt_node_check_compatible(fdt, 0, s->compatible)) {
> + early_fn = s->data;
> + early_fn(fdt);
> + return;
> + }
> + }
> +}
> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> index 1e0193ded420..32b160942f40 100644
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -24,6 +24,12 @@ SECTIONS
> HEAD_TEXT_SECTION
> INIT_TEXT_SECTION(PAGE_SIZE)
> INIT_DATA_SECTION(16)
> + . = ALIGN(8);
> + __soc_early_init_table : {
> + __soc_early_init_table_start = .;
> + KEEP(*(__soc_early_init_table))
> + __soc_early_init_table_end = .;
> + }
> /* we have to discard exit text and such at runtime, not link time */
> .exit.text :
> {
> --
> 2.24.1
>
>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 2/9] riscv: Add BUILTIN_DTB support
2020-03-12 5:11 ` [PATCH v2 2/9] riscv: Add BUILTIN_DTB support Damien Le Moal
@ 2020-03-12 20:03 ` Atish Patra
0 siblings, 0 replies; 36+ messages in thread
From: Atish Patra @ 2020-03-12 20:03 UTC (permalink / raw)
To: Damien Le Moal; +Cc: linux-riscv, Anup Patel, Palmer Dabbelt
On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
>
> For the NOMMU case, enable a kernel builtin dtb to allow direct kernel
> loading without a bootloader. This option also allows booting on boards
> not capable of providing a device tree to the bootloader.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> ---
> arch/riscv/Kbuild | 1 +
> arch/riscv/Kconfig | 19 +++++++++++++++++++
> arch/riscv/boot/dts/Makefile | 4 ++++
> arch/riscv/kernel/setup.c | 6 ++++++
> arch/riscv/mm/init.c | 4 ++++
> 5 files changed, 34 insertions(+)
>
> diff --git a/arch/riscv/Kbuild b/arch/riscv/Kbuild
> index d1d0aa70fdf1..988804e430e4 100644
> --- a/arch/riscv/Kbuild
> +++ b/arch/riscv/Kbuild
> @@ -1,3 +1,4 @@
> # SPDX-License-Identifier: GPL-2.0-only
>
> obj-y += kernel/ mm/ net/
> +obj-$(CONFIG_USE_BUILTIN_DTB) += boot/dts/
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 1a3b5a5276be..025f5ba1dd68 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -355,6 +355,25 @@ config CMDLINE_FORCE
>
> endchoice
>
> +config USE_BUILTIN_DTB
> + bool "Use builtin DTB"
> + depends on !MMU
> + help
> + Link a device tree blob for particular hardware into the kernel,
> + suppressing use of the DTB pointer provided by the bootloader.
> + This option should only be used with hardware or bootloaders that
> + are not capable of providing a DTB to the kernel, or for
> + experimental hardware without stable device tree bindings.
> +
> +config BUILTIN_DTB_SOURCE
> + string "Source file for builtin DTB"
> + default ""
> + depends on USE_BUILTIN_DTB
> + help
> + Base name (without suffix, relative to arch/riscv/boot/dts) for
> + the a DTS file that will be used to produce the DTB linked into
> + the kernel.
> +
> endmenu
>
> menu "Power management options"
> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
> index dcc3ada78455..0bf2669aa12d 100644
> --- a/arch/riscv/boot/dts/Makefile
> +++ b/arch/riscv/boot/dts/Makefile
> @@ -1,2 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0
> +ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
> +obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
> +else
> subdir-y += sifive
> +endif
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 0a6d415b0a5a..3e89be9d888c 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -68,7 +68,13 @@ void __init setup_arch(char **cmdline_p)
>
> setup_bootmem();
> paging_init();
> +
> +#if IS_ENABLED(CONFIG_USE_BUILTIN_DTB)
> + unflatten_and_copy_device_tree();
> +#else
> unflatten_device_tree();
> +#endif
> +
> clint_init_boot_cpu();
>
> #ifdef CONFIG_SWIOTLB
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index fab855963c73..51f1ee0a24a6 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -480,7 +480,11 @@ static void __init setup_vm_final(void)
> #else
> asmlinkage void __init setup_vm(uintptr_t dtb_pa)
> {
> +#if IS_ENABLED(CONFIG_USE_BUILTIN_DTB)
> + dtb_early_va = __dtb_start;
> +#else
> dtb_early_va = (void *)dtb_pa;
> +#endif
> }
>
> static inline void setup_vm_final(void)
> --
> 2.24.1
>
>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 19:12 ` Atish Patra
@ 2020-03-12 20:09 ` Sean Anderson
2020-03-13 6:03 ` Damien Le Moal
1 sibling, 0 replies; 36+ messages in thread
From: Sean Anderson @ 2020-03-12 20:09 UTC (permalink / raw)
To: Atish Patra; +Cc: linux-riscv, Palmer Dabbelt, Damien Le Moal
On 3/12/20 3:12 PM, Atish Patra wrote:
> On Thu, Mar 12, 2020 at 11:49 AM Sean Anderson <seanga2@gmail.com> wrote:
>>
>> On 3/12/20 2:29 PM, Atish Patra wrote:
>>> On Thu, Mar 12, 2020 at 11:14 AM Sean Anderson <seanga2@gmail.com> wrote:
>>>>
>>>>
>>>>> I don't think supporting old specs in Linux is a good idea. As per the
>>>>> patch guideline
>>>>> for RISC-V Linux, patches for only "frozen" or "ratified"
>>>>> specifications are allowed.
>>>>>
>>>>
>>>> Well this CPU follows the v1.9 spec. It's real hardware, if it is to be
>>>> be supported, then the 1.9 spec needs to be as well.
>>>>
>>>
>>> As RISC-V is an open ISA and it's continuously evolving, there will be
>>> some hardware
>>> that will implement old specifications or non-backward compatible features.
>>> I fear the number of hardware with such features/implementations will
>>> grow in the future.
>>> If Linux is going to support all of them, it may be a maintenance nightmare.
>>
>> I agree. There is also no standard way to communicate the implemented
>> privileged spec level e.g. in the device tree. The base integer
>> instruction set version can be specified in the riscv,isa property, such
>> as
>>
>> riscv,isa = "rv64i2p1..."
>>
>> However, there is no "extension" for the privileged specification.
>> A method to specify this would be helpful, especially since the
>> bootloader may need to enable the MMU before loading Linux since there
>> is no way to enable it from S-mode until v1.10.
>>
>> On the other hand, there is relatively little changed from v1.9 to the
>> current revision. The following list has the differences from the
>> current spec:
>>
>> * The PMP has flipped polarity
>> * The mcounteren CSRs are split
>> * sfence.vma is sfence.vm (though this should be handled by the sbi
>> anyway)
>> * satp has a different name, and mode no longer exists in the top four
>> bits. Since these bits used to be part of ASID, it's fine to write the
>> mode to those bits. If linux never switches from (e.g.) sv39 to
>> something else, there will be no observed difference either.
>>
>> Everything else is mostly forwards-compatible, as far as I can tell.
>> That is, assuming new behaviour on old hardware won't cause problems.
>>
> Even if the changes are minimal and we can easily hide under macro magic,
> it will create a bad precedent for the future. What if somebody sends
> a patch for
> a non-standard extension and cites kendryte support as an example.
I think there are substantial differences between a non-standard
extension, and what we would need for the K210. First, the changes we
would need are for the official specification. At the time this chip was
designed, this was *the* authritative privileged spec. I think if a
hardware vendor makes the effort to comply with the specification as it
exists at the time, then we should support that.
In addition, the incompatibilities are within the core boot process.
Most non-standard extensions will be optional extras which can be
completely ignored. For example, the GAP8 processor has a non-standard
extension which adds some instructions for complex number arithmetic
(and other operations). These instructions have no effect on the usual
boot process, and (if there was an MMU) Linux could run fine on that
board with no knowledge of these extensions.
Lastly, these non-standard instructions can be documented in a standard
way through the isa version string. This incompatibility in the spec has
no standard way to be documented.
>> A sufficiently smart kernel could even detect the version at runtime by
>> intentionally triggering behaviour which is illegal depending on the
>> privileged version, and then checking for an exception.
>>
> That's the maintenance nightmare I was talking about. For kendryte, it
> is only few incompatible changes
> in privilege specification but what if some hardware implements a
> variation of hypervisor spec or vector extension.
Hopefully that will not happen, but I think given the long development
period of the vector spec, it is inevitable that a chip will be released
with some subtle (or not-so-subtle) incompatibilities. As far as I can
tell, the restriction on non-ratified extensions is to prevent work
towards experimental specifications which may never have real hardware
which uses them. However, I think if real hardware is incompatible small
but fundamental way, then we should make the effort to support it,
especially when the patches already exist.
--Sean
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-12 5:11 ` [PATCH v2 3/9] riscv: Add SOC early init support Damien Le Moal
2020-03-12 18:21 ` Sean Anderson
2020-03-12 19:50 ` Atish Patra
@ 2020-03-12 20:53 ` Atish Patra
2020-03-13 6:42 ` Damien Le Moal
2 siblings, 1 reply; 36+ messages in thread
From: Atish Patra @ 2020-03-12 20:53 UTC (permalink / raw)
To: Damien Le Moal; +Cc: linux-riscv, Anup Patel, Palmer Dabbelt
On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
>
> Add a mechanism for early SoC initialization for platforms that need
> additional hardware initialization not possible through the regular
> device tree and drivers mechanism. With this, a SoC specific
> initialization function can be called very early, before DTB parsing
> is done by parse_dtb() in Linux RISC-V kernel setup code.
>
> This can be very useful for early hardware initialization for No-MMU
> kernels booted directly in M-mode because it is quite likely that no
> other booting stage exist prior to the No-MMU kernel.
>
> Example use of a SoC early initialization is as follows:
>
> static void vendor_abc_early_init(const void *fdt)
> {
> /*
> * some early init code here that can use simple matches
> * against the flat device tree file.
> */
> }
> SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
>
> This early initialization function is executed only if the flat device
> tree for the board has a 'compatible = "vendor,abc"' entry;
>
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> Signed-off-by: Anup Patel <anup.patel@wdc.com>
> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> ---
> arch/riscv/include/asm/soc.h | 23 +++++++++++++++++++++++
> arch/riscv/kernel/Makefile | 1 +
> arch/riscv/kernel/head.S | 1 +
> arch/riscv/kernel/soc.c | 28 ++++++++++++++++++++++++++++
> arch/riscv/kernel/vmlinux.lds.S | 6 ++++++
> 5 files changed, 59 insertions(+)
> create mode 100644 arch/riscv/include/asm/soc.h
> create mode 100644 arch/riscv/kernel/soc.c
>
> diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h
> new file mode 100644
> index 000000000000..9b8c332cbe76
> --- /dev/null
> +++ b/arch/riscv/include/asm/soc.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +
> +#ifndef _ASM_RISCV_SOC_H
> +#define _ASM_RISCV_SOC_H
> +
> +#include <linux/of.h>
> +#include <linux/linkage.h>
> +#include <linux/types.h>
> +
> +#define SOC_EARLY_INIT_DECLARE(compat, fn) \
> + static const struct of_device_id __soc_early_init \
> + __used __section(__soc_early_init_table) \
> + = { .compatible = compat, .data = fn }
> +
There may be some future kendryte board or some other RISC-V board
which want to use SOC_EARLY_INIT_DECLARE.
There should be a name parameter as well which allows multiple usage
of SOC_EARLY_INIT_DECLARE.
> +void soc_early_init(void);
> +
> +extern unsigned long __soc_early_init_table_start;
> +extern unsigned long __soc_early_init_table_end;
> +
> +#endif
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index 97d0c35f8b37..e4a22999dbc6 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -10,6 +10,7 @@ endif
> extra-y += head.o
> extra-y += vmlinux.lds
>
> +obj-y += soc.o
> obj-y += cpu.o
> obj-y += cpufeature.o
> obj-y += entry.o
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 85f2073e7fe4..52ed11b4fda6 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -131,6 +131,7 @@ clear_bss_done:
> call kasan_early_init
> #endif
> /* Start the kernel */
> + call soc_early_init
> call parse_dtb
> tail start_kernel
>
> diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c
> new file mode 100644
> index 000000000000..0b3b3dc9ad0f
> --- /dev/null
> +++ b/arch/riscv/kernel/soc.c
> @@ -0,0 +1,28 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> + */
> +#include <linux/init.h>
> +#include <linux/libfdt.h>
> +#include <asm/pgtable.h>
> +#include <asm/soc.h>
> +
> +/*
> + * This is called extremly early, before parse_dtb(), to allow initializing
> + * SoC hardware before memory or any device driver initialization.
> + */
> +void __init soc_early_init(void)
> +{
> + void (*early_fn)(const void *fdt);
> + const struct of_device_id *s;
> + const void *fdt = dtb_early_va;
> +
> + for (s = (void *)&__soc_early_init_table_start;
> + (void *)s < (void *)&__soc_early_init_table_end; s++) {
> + if (!fdt_node_check_compatible(fdt, 0, s->compatible)) {
> + early_fn = s->data;
> + early_fn(fdt);
> + return;
> + }
> + }
> +}
> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> index 1e0193ded420..32b160942f40 100644
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -24,6 +24,12 @@ SECTIONS
> HEAD_TEXT_SECTION
> INIT_TEXT_SECTION(PAGE_SIZE)
> INIT_DATA_SECTION(16)
> + . = ALIGN(8);
> + __soc_early_init_table : {
> + __soc_early_init_table_start = .;
> + KEEP(*(__soc_early_init_table))
> + __soc_early_init_table_end = .;
> + }
> /* we have to discard exit text and such at runtime, not link time */
> .exit.text :
> {
> --
> 2.24.1
>
>
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 18:10 ` Atish Patra
2020-03-12 18:14 ` Sean Anderson
@ 2020-03-13 5:25 ` Damien Le Moal
2020-03-13 5:47 ` Atish Patra
1 sibling, 1 reply; 36+ messages in thread
From: Damien Le Moal @ 2020-03-13 5:25 UTC (permalink / raw)
To: atishp, seanga2; +Cc: linux-riscv, palmer
On Thu, 2020-03-12 at 11:10 -0700, Atish Patra wrote:
> On Thu, Mar 12, 2020 at 8:20 AM Sean Anderson <seanga2@gmail.com> wrote:
> > On 3/12/20 1:11 AM, Damien Le Moal wrote:
> > > Commit c68a9032299e ("riscv: set pmp configuration if kernel is running
> > > in M-mode") added PMP initialization to M-Mode. While this patch is
> > > valid for any SoC following the ratified riscv specifications, the
> > > Kendryte K210 SoC is based on earlier unstable specifications and does
> > > not seem to support PMP initialization (the SoC crashes if CSR_PMPADDR0
> > > or CSR_PMPCFG0 are accessed).
> >
> > The PMP bit has its polarity inverted in the v1.9 specification, and is
> > called the SUM or Supervisor User Memory Access bit.
> >
> > --Sean
> >
> I don't think supporting old specs in Linux is a good idea. As per the
> patch guideline
> for RISC-V Linux, patches for only "frozen" or "ratified"
> specifications are allowed.
Yes, I agree on this point. However, this should be taken a little more
lightly in my opinion. As long as we do not try to run the K210 with
MMU turned on, this is the only known tiny deviation from the current
ratified privileged specs v1.11. Since this is really a small one, I am
inclined to consider this in the same way as a hardware bug, for which
software exceptions are perfectly acceptable in the kernel. There are
tons of "quirk" bits defined for ratified specifications such as NVMe
or AHCI for example, due to hardware bugs. Even though the hardware
intend to follow the specifications, quirks are sometimes necessary as
work-around for hardware implementation bugs which are far more
difficult to fix than software.
Of course there are limits to this and sometimes, the decision has to
be "go fix your hardware". In this case, I do not think we are at that
level of seriousness, again assuming we never run with MMU on (because
then we would need to implement support for the 1.9 specs, and that
would seriously mess things up).
Without this fix, the K210 cannot boot, at all. So if this small change
is refused, we may as well just give up on the entire effort. That
would really be too bad since the K210 boards are really cheap and
would enable a lot of hobbyist and students to start playing with Linux
on RISC-V...
In the end, I think this is Palmer's decision. I gave my 2 cents above.
If there is too much push-back on this, I will stop the effort because
I do not see how to work around this one within 1.11 specs.
Cheers.
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 6/9] riscv: Add Kendryte K210 device tree
2020-03-12 18:16 ` Sean Anderson
@ 2020-03-13 5:29 ` Damien Le Moal
0 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-13 5:29 UTC (permalink / raw)
To: linux-riscv, palmer, seanga2; +Cc: Anup Patel
On Thu, 2020-03-12 at 14:16 -0400, Sean Anderson wrote:
> On 3/12/20 1:11 AM, Damien Le Moal wrote:
> > Add a generic device tree for Kendryte K210 SoC based boards. This (for
> > now) very simple device tree works for the Kendryte KD233 development
> > board, the Sipeed MAIX M1 Dan Dock board and the Sipeed MAIXDUINO board.
> >
> > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> > ---
> > arch/riscv/boot/dts/Makefile | 1 +
> > arch/riscv/boot/dts/kendryte/Makefile | 2 +
> > arch/riscv/boot/dts/kendryte/k210.dts | 23 +++++
> > arch/riscv/boot/dts/kendryte/k210.dtsi | 117 +++++++++++++++++++++++++
> > include/dt-bindings/clock/k210-clk.h | 20 +++++
> > 5 files changed, 163 insertions(+)
> > create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
> > create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
> > create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
> > create mode 100644 include/dt-bindings/clock/k210-clk.h
> >
> > diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
> > index 0bf2669aa12d..87815557f2db 100644
> > --- a/arch/riscv/boot/dts/Makefile
> > +++ b/arch/riscv/boot/dts/Makefile
> > @@ -3,4 +3,5 @@ ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
> > obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
> > else
> > subdir-y += sifive
> > +subdir-y += kendryte
> > endif
> > diff --git a/arch/riscv/boot/dts/kendryte/Makefile b/arch/riscv/boot/dts/kendryte/Makefile
> > new file mode 100644
> > index 000000000000..815444e69e89
> > --- /dev/null
> > +++ b/arch/riscv/boot/dts/kendryte/Makefile
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +dtb-$(CONFIG_SOC_KENDRYTE) += k210.dtb
> > diff --git a/arch/riscv/boot/dts/kendryte/k210.dts b/arch/riscv/boot/dts/kendryte/k210.dts
> > new file mode 100644
> > index 000000000000..0d1f28fce6b2
> > --- /dev/null
> > +++ b/arch/riscv/boot/dts/kendryte/k210.dts
> > @@ -0,0 +1,23 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "k210.dtsi"
> > +
> > +/ {
> > + model = "Kendryte K210 generic";
> > + compatible = "kendryte,k210";
> > +
> > + chosen {
> > + bootargs = "earlycon console=ttySIF0";
> > + stdout-path = "serial0";
> > + };
> > +};
> > +
> > +&uarths0 {
> > + status = "okay";
> > +};
> > +
> > diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi
> > new file mode 100644
> > index 000000000000..88f28a3fd337
> > --- /dev/null
> > +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi
> > @@ -0,0 +1,117 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
> > + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> > + */
> > +#include <dt-bindings/clock/k210-clk.h>
> > +
> > +/ {
> > + /*
> > + * Although the K210 is a 64-bit CPU, the address bus is only 32-bits
> > + * wide, and the upper half of all addresses is ignored.
> > + */
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + compatible = "kendryte,k210";
> > +
> > + aliases {
> > + serial0 = &uarths0;
> > + };
> > +
> > + cpus {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > + timebase-frequency = <7800000>;
> > + cpu0: cpu@0 {
> > + device_type = "cpu";
> > + reg = <0>;
> > + compatible = "kendryte,k210", "sifive,rocket0", "riscv";
> > + riscv,isa = "rv64imafdc";
> > + mmu-type = "none";
> > + i-cache-size = <0x8000>;
> > + i-cache-block-size = <64>;
> > + d-cache-size = <0x8000>;
> > + d-cache-block-size = <64>;
> > + clocks = <&sysctl K210_CLK_CPU>;
> > + clock-frequency = <390000000>;
> > + cpu0_intc: interrupt-controller {
> > + #interrupt-cells = <1>;
> > + interrupt-controller;
> > + compatible = "riscv,cpu-intc";
> > + };
> > + };
> > + cpu1: cpu@1 {
> > + device_type = "cpu";
> > + reg = <1>;
> > + compatible = "kendryte,k210", "sifive,rocket0", "riscv";
> > + riscv,isa = "rv64imafdc";
> > + mmu-type = "none";
>
> Perhaps add a comment? The mmu is still sv39, even if the kernel is NOMMU.
Yes, will do. I want to keep this entry as "none" because we cannot
support the 1.9 spec MMU. So yes, clarifying this point will be good.
>
> > + i-cache-size = <0x8000>;
> > + i-cache-block-size = <64>; /* bogus */
>
> These comments should be removed to match the bindings above.
Oops. Yes. Missed that one :)
>
> > + d-cache-size = <0x8000>;
> > + d-cache-block-size = <64>; /* bogus */
> > + clocks = <&sysctl K210_CLK_CPU>;
> > + clock-frequency = <390000000>;
> > + cpu1_intc: interrupt-controller {
> > + #interrupt-cells = <1>;
> > + interrupt-controller;
> > + compatible = "riscv,cpu-intc";
> > + };
> > + };
> > + };
> > +
> > + sram: memory@80000000 {
> > + device_type = "memory";
> > + reg = <0x80000000 0x400000>,
> > + <0x80400000 0x200000>,
> > + <0x80600000 0x200000>;
> > + reg-names = "sram0", "sram1", "aisram";
> > + };
> > +
> > + clocks {
> > + in0: oscillator {
> > + compatible = "fixed-clock";
> > + #clock-cells = <0>;
> > + clock-frequency = <26000000>;
> > + };
> > + };
> > +
> > + soc {
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + compatible = "kendryte,k210-soc", "simple-bus";
> > + ranges;
> > + interrupt-parent = <&plic0>;
> > +
> > + sysctl: sysctl@50440000 {
> > + compatible = "kendryte,k210-sysctl", "syscon";
> > + reg = <0x50440000 0x1000>;
> > + #clock-cells = <1>;
> > + };
>
> Still think this should be modeled as an mfd.
Yes. Absolutely. That will be needed for adding support for GPIO, SD
card etc. However, I do not want to do this now and leave this work for
another series on top of this one. Would you agree with this approach ?
>
> > +
> > + clint0: interrupt-controller@2000000 {
> > + compatible = "riscv,clint0";
> > + reg = <0x2000000 0xC000>;
> > + interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>;
> > + clocks = <&sysctl K210_CLK_ACLK>;
> > + };
> > +
> > + plic0: interrupt-controller@c000000 {
> > + #interrupt-cells = <1>;
> > + interrupt-controller;
> > + compatible = "kendryte,k210-plic0", "riscv,plic0";
> > + reg = <0xC000000 0x4000000>;
> > + interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 0xffffffff>,
> > + <&cpu1_intc 11>, <&cpu1_intc 0xffffffff>;
> > + riscv,ndev = <65>;
> > + riscv,max-priority = <7>;
> > + };
> > +
> > + uarths0: serial@38000000 {
> > + compatible = "kendryte,k210-uarths", "sifive,uart0";
> > + reg = <0x38000000 0x1000>;
> > + interrupts = <33>;
> > + clocks = <&sysctl K210_CLK_CPU>;
> > + };
> > + };
> > +};
> > diff --git a/include/dt-bindings/clock/k210-clk.h b/include/dt-bindings/clock/k210-clk.h
> > new file mode 100644
> > index 000000000000..5a2fd64d1a49
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/k210-clk.h
> > @@ -0,0 +1,20 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com>
> > + * Copyright (c) 2020 Western Digital Corporation or its affiliates.
> > + */
> > +#ifndef K210_CLK_H
> > +#define K210_CLK_H
> > +
> > +/*
> > + * Arbitrary identifiers for clocks.
> > + * The structure is: in0 -> pll0 -> aclk -> cpu
> > + *
> > + * Since we use the hardware defaults for now, set all these to the same clock.
> > + */
> > +#define K210_CLK_PLL0 0
> > +#define K210_CLK_PLL1 0
> > +#define K210_CLK_ACLK 0
> > +#define K210_CLK_CPU 0
> > +
> > +#endif /* K210_CLK_H */
> >
>
> --Sean
>
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 18:49 ` Sean Anderson
2020-03-12 19:12 ` Atish Patra
@ 2020-03-13 5:40 ` Anup Patel
1 sibling, 0 replies; 36+ messages in thread
From: Anup Patel @ 2020-03-13 5:40 UTC (permalink / raw)
To: Sean Anderson; +Cc: linux-riscv, Palmer Dabbelt, Damien Le Moal, Atish Patra
On Fri, Mar 13, 2020 at 12:19 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 3/12/20 2:29 PM, Atish Patra wrote:
> > On Thu, Mar 12, 2020 at 11:14 AM Sean Anderson <seanga2@gmail.com> wrote:
> >>
> >>
> >>> I don't think supporting old specs in Linux is a good idea. As per the
> >>> patch guideline
> >>> for RISC-V Linux, patches for only "frozen" or "ratified"
> >>> specifications are allowed.
> >>>
> >>
> >> Well this CPU follows the v1.9 spec. It's real hardware, if it is to be
> >> be supported, then the 1.9 spec needs to be as well.
> >>
> >
> > As RISC-V is an open ISA and it's continuously evolving, there will be
> > some hardware
> > that will implement old specifications or non-backward compatible features.
> > I fear the number of hardware with such features/implementations will
> > grow in the future.
> > If Linux is going to support all of them, it may be a maintenance nightmare.
>
> I agree. There is also no standard way to communicate the implemented
> privileged spec level e.g. in the device tree. The base integer
> instruction set version can be specified in the riscv,isa property, such
> as
>
> riscv,isa = "rv64i2p1..."
>
> However, there is no "extension" for the privileged specification.
> A method to specify this would be helpful, especially since the
> bootloader may need to enable the MMU before loading Linux since there
> is no way to enable it from S-mode until v1.10.
>
> On the other hand, there is relatively little changed from v1.9 to the
> current revision. The following list has the differences from the
> current spec:
>
> * The PMP has flipped polarity
> * The mcounteren CSRs are split
> * sfence.vma is sfence.vm (though this should be handled by the sbi
> anyway)
> * satp has a different name, and mode no longer exists in the top four
> bits. Since these bits used to be part of ASID, it's fine to write the
> mode to those bits. If linux never switches from (e.g.) sv39 to
> something else, there will be no observed difference either.
>
> Everything else is mostly forwards-compatible, as far as I can tell.
> That is, assuming new behaviour on old hardware won't cause problems.
>
> A sufficiently smart kernel could even detect the version at runtime by
> intentionally triggering behaviour which is illegal depending on the
> privileged version, and then checking for an exception.
As-per Linux RISC-V patch acceptance policy, patches for "Frozen" or
"Ratified" spec will only be accepted. The KVM RISC-V and Vector
support patches are on-hold for same reason.
(Refer, Documentation/riscv/patch-acceptance.rst)
The amount of change is not the question here it more about policy.
Linux RISC-V NOMMU kernel has carefully avoided this policy issues
by only touching CSRs in a way which is compliant with the latest "Ratified"
v1.11 spec.
Regards,
Anup
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 4/9] riscv: Add Kendryte K210 SoC support
2020-03-12 18:19 ` Sean Anderson
@ 2020-03-13 5:43 ` Damien Le Moal
0 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-13 5:43 UTC (permalink / raw)
To: linux-riscv, palmer, seanga2; +Cc: Anup Patel
On Thu, 2020-03-12 at 14:19 -0400, Sean Anderson wrote:
> On 3/12/20 1:11 AM, Damien Le Moal wrote:
> > From: Christoph Hellwig <hch@lst.de>
> >
> > Add support for the Kendryte K210 RISC-V SoC. For now, this support
> > only provides a simple sysctl driver allowing to setup the CPU and
> > uart clock. This support is enabled through the new Kconfig option
> > SOC_KENDRYTE and defines the config option CONFIG_K210_SYSCTL
> > to enable the K210 SoC sysctl driver compilation.
> >
> > The sysctl driver also registers an early SoC initialization function
> > allowing enabling the general purpose use of the 2MB of SRAM normally
> > reserved for the SoC AI engine. This initialization function is
> > automatically called before the dt early initialization using the flat
> > dt root node compatible property matching the value "kendryte,k210".
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> > Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> > ---
> > arch/riscv/Kconfig.socs | 6 +
> > drivers/soc/Kconfig | 1 +
> > drivers/soc/Makefile | 1 +
> > drivers/soc/kendryte/Kconfig | 14 ++
> > drivers/soc/kendryte/Makefile | 3 +
> > drivers/soc/kendryte/k210-sysctl.c | 245 +++++++++++++++++++++++++++++
> > 6 files changed, 270 insertions(+)
> > create mode 100644 drivers/soc/kendryte/Kconfig
> > create mode 100644 drivers/soc/kendryte/Makefile
> > create mode 100644 drivers/soc/kendryte/k210-sysctl.c
> >
> > diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
> > index 3078b2de0b2d..69071578e181 100644
> > --- a/arch/riscv/Kconfig.socs
> > +++ b/arch/riscv/Kconfig.socs
> > @@ -34,4 +34,10 @@ config SOC_VIRT
> > help
> > This enables support for QEMU Virt Machine.
> >
> > +config SOC_KENDRYTE
> > + bool "Kendryte K210 SoC"
> > + depends on !MMU
> > + help
> > + This enables support for Kendryte K210 SoC platform hardware.
> > +
> > endmenu
> > diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> > index 1778f8c62861..425ab6f7e375 100644
> > --- a/drivers/soc/Kconfig
> > +++ b/drivers/soc/Kconfig
> > @@ -22,5 +22,6 @@ source "drivers/soc/ux500/Kconfig"
> > source "drivers/soc/versatile/Kconfig"
> > source "drivers/soc/xilinx/Kconfig"
> > source "drivers/soc/zte/Kconfig"
> > +source "drivers/soc/kendryte/Kconfig"
> >
> > endmenu
> > diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> > index 8b49d782a1ab..af58063bb989 100644
> > --- a/drivers/soc/Makefile
> > +++ b/drivers/soc/Makefile
> > @@ -28,3 +28,4 @@ obj-$(CONFIG_ARCH_U8500) += ux500/
> > obj-$(CONFIG_PLAT_VERSATILE) += versatile/
> > obj-y += xilinx/
> > obj-$(CONFIG_ARCH_ZX) += zte/
> > +obj-$(CONFIG_SOC_KENDRYTE) += kendryte/
> > diff --git a/drivers/soc/kendryte/Kconfig b/drivers/soc/kendryte/Kconfig
> > new file mode 100644
> > index 000000000000..49785b1b0217
> > --- /dev/null
> > +++ b/drivers/soc/kendryte/Kconfig
> > @@ -0,0 +1,14 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +if SOC_KENDRYTE
> > +
> > +config K210_SYSCTL
> > + bool "Kendryte K210 system controller"
> > + default y
> > + depends on RISCV
> > + help
> > + Enables controlling the K210 various clocks and to enable
> > + general purpose use of the extra 2MB of SRAM normally
> > + reserved for the AI engine.
> > +
> > +endif
> > diff --git a/drivers/soc/kendryte/Makefile b/drivers/soc/kendryte/Makefile
> > new file mode 100644
> > index 000000000000..002d9ce95c0d
> > --- /dev/null
> > +++ b/drivers/soc/kendryte/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +obj-$(CONFIG_K210_SYSCTL) += k210-sysctl.o
> > diff --git a/drivers/soc/kendryte/k210-sysctl.c b/drivers/soc/kendryte/k210-sysctl.c
> > new file mode 100644
> > index 000000000000..7d4ecd954af0
> > --- /dev/null
> > +++ b/drivers/soc/kendryte/k210-sysctl.c
> > @@ -0,0 +1,245 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2019 Christoph Hellwig.
> > + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > + */
> > +#include <linux/types.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/clkdev.h>
> > +#include <asm/soc.h>
> > +
> > +#define K210_SYSCTL_CLK0_FREQ 26000000UL
> > +
> > +/* Registers base address */
> > +#define K210_SYSCTL_SYSCTL_BASE_ADDR 0x50440000ULL
> > +
> > +/* Registers */
> > +#define K210_SYSCTL_PLL0 0x08
> > +#define K210_SYSCTL_PLL1 0x0c
> > +/* clkr: 4bits, clkf1: 6bits, clkod: 4bits, bwadj: 4bits */
> > +#define PLL_RESET (1 << 20)
> I think the preferred style is to use BIT(20), etc.
Depends who you ask. Plenty of discussions on various lists about these
BIT() macros... I am personally not a big fan of these macros as they
hide the implementation. 1 << 20 is easy to understand and obvious to
any C programmer...
>
> > +#define PLL_PWR (1 << 21)
> > +#define PLL_INTFB (1 << 22)
> > +#define PLL_BYPASS (1 << 23)
> > +#define PLL_TEST (1 << 24)
> > +#define PLL_OUT_EN (1 << 25)
> > +#define PLL_TEST_EN (1 << 26)
> > +#define K210_SYSCTL_PLL_LOCK 0x18
> Can you use GENMASK here?
We could, but having the values explicitly stated here like this match
the comments in the Kendryte SDK struct _sysctl structure. This makes
things easier to understand.
>
> > +#define PLL0_LOCK1 (1 << 0)
> > +#define PLL0_LOCK2 (1 << 1)
> > +#define PLL0_SLIP_CLEAR (1 << 2)
> > +#define PLL0_TEST_CLK_OUT (1 << 3)
> > +#define PLL1_LOCK1 (1 << 8)
> > +#define PLL1_LOCK2 (1 << 9)
> > +#define PLL1_SLIP_CLEAR (1 << 10)
> > +#define PLL1_TEST_CLK_OUT (1 << 11)
> > +#define PLL2_LOCK1 (1 << 16)
> > +#define PLL2_LOCK2 (1 << 16)
> > +#define PLL2_SLIP_CLEAR (1 << 18)
> > +#define PLL2_TEST_CLK_OUT (1 << 19)
> > +#define K210_SYSCTL_CLKSEL0 0x20
> > +#define CLKSEL_ACLK (1 << 0)
> > +#define K210_SYSCTL_CLKEN_CENT 0x28
> > +#define CLKEN_CPU (1 << 0)
> > +#define CLKEN_SRAM0 (1 << 1)
> > +#define CLKEN_SRAM1 (1 << 2)
> > +#define CLKEN_APB0 (1 << 3)
> > +#define CLKEN_APB1 (1 << 4)
> > +#define CLKEN_APB2 (1 << 5)
> > +#define K210_SYSCTL_CLKEN_PERI 0x2c
> > +#define CLKEN_ROM (1 << 0)
> > +#define CLKEN_DMA (1 << 1)
> > +#define CLKEN_AI (1 << 2)
> > +#define CLKEN_DVP (1 << 3)
> > +#define CLKEN_FFT (1 << 4)
> > +#define CLKEN_GPIO (1 << 5)
> > +#define CLKEN_SPI0 (1 << 6)
> > +#define CLKEN_SPI1 (1 << 7)
> > +#define CLKEN_SPI2 (1 << 8)
> > +#define CLKEN_SPI3 (1 << 9)
> > +#define CLKEN_I2S0 (1 << 10)
> > +#define CLKEN_I2S1 (1 << 11)
> > +#define CLKEN_I2S2 (1 << 12)
> > +#define CLKEN_I2C0 (1 << 13)
> > +#define CLKEN_I2C1 (1 << 14)
> > +#define CLKEN_I2C2 (1 << 15)
> > +#define CLKEN_UART1 (1 << 16)
> > +#define CLKEN_UART2 (1 << 17)
> > +#define CLKEN_UART3 (1 << 18)
> > +#define CLKEN_AES (1 << 19)
> > +#define CLKEN_FPIO (1 << 20)
> > +#define CLKEN_TIMER0 (1 << 21)
> > +#define CLKEN_TIMER1 (1 << 22)
> > +#define CLKEN_TIMER2 (1 << 23)
> > +#define CLKEN_WDT0 (1 << 24)
> > +#define CLKEN_WDT1 (1 << 25)
> > +#define CLKEN_SHA (1 << 26)
> > +#define CLKEN_OTP (1 << 27)
> > +#define CLKEN_RTC (1 << 29)
> > +
> > +struct k210_sysctl {
> > + void __iomem *regs;
> > + struct clk_hw hw;
> > +};
> > +
> > +static void k210_set_bits(u32 val, void __iomem *reg)
> > +{
> > + writel(readl(reg) | val, reg);
> > +}
> > +
> > +static void k210_clear_bits(u32 val, void __iomem *reg)
> > +{
> > + writel(readl(reg) & ~val, reg);
> > +}
> > +
> > +static void k210_pll1_enable(void __iomem *regs)
> > +{
> > + u32 val;
> > +
> > + val = readl(regs + K210_SYSCTL_PLL1);
> > + val &= ~0xfffff;
> > + val |= (59 << 4) | (3 << 10) | (59 << 15);
> Again, can this be done with GENMASK and FIELD_PREP?
Looking at the description of the FIELD_PREP macro, I find it obscure
and do not find its use very obvious. I agree that the above code is
full of "magic numbers" that would need description. But not sure if
the FIELD_PREP/GENMASK macros will help much with that.
In any case, that could be an incremental cleanup since this would need
to all be reworked into an mfd. No ?
>
> > + writel(val, regs + K210_SYSCTL_PLL1);
> > +
> > + k210_clear_bits(PLL_BYPASS, regs + K210_SYSCTL_PLL1);
> > + k210_set_bits(PLL_PWR, regs + K210_SYSCTL_PLL1);
> > +
> > + /*
> > + * Reset the pll. The magic NOPs come from the Kendryte reference SDK.
> > + */
> > + k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> > + k210_set_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> > + nop();
> > + nop();
> > + k210_clear_bits(PLL_RESET, regs + K210_SYSCTL_PLL1);
> > +
> > + for (;;) {
> > + val = readl(regs + K210_SYSCTL_PLL_LOCK);
> > + if (val & PLL1_LOCK2)
> > + break;
> > + writel(val | PLL1_SLIP_CLEAR, regs + K210_SYSCTL_PLL_LOCK);
> > + }
> > +
> > + k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL1);
> > +}
> > +
> > +static unsigned long k210_sysctl_clk_recalc_rate(struct clk_hw *hw,
> > + unsigned long parent_rate)
> > +{
> > + struct k210_sysctl *s = container_of(hw, struct k210_sysctl, hw);
> > + u32 clksel0, pll0;
> > + u64 pll0_freq, clkr0, clkf0, clkod0;
> > +
> > + /*
> > + * If the clock selector is not set, use the base frequency.
> > + * Otherwise, use PLL0 frequency with a frequency divisor.
> > + */
> > + clksel0 = readl(s->regs + K210_SYSCTL_CLKSEL0);
> > + if (!(clksel0 & CLKSEL_ACLK))
> > + return K210_SYSCTL_CLK0_FREQ;
> > +
> > + /*
> > + * Get PLL0 frequency:
> > + * freq = base frequency * clkf0 / (clkr0 * clkod0)
> > + */
> > + pll0 = readl(s->regs + K210_SYSCTL_PLL0);
> > + clkr0 = 1 + (pll0 & 0x0000000f);
> > + clkf0 = 1 + ((pll0 & 0x000003f0) >> 4);
> > + clkod0 = 1 + ((pll0 & 0x00003c00) >> 10);
> Same thing here, use FIELD_GET instead please.
This one is actually a little easier to understand. So yes, why not.
>
> > + pll0_freq = clkf0 * K210_SYSCTL_CLK0_FREQ / (clkr0 * clkod0);
> > +
> > + /* Get the frequency divisor from the clock selector */
> > + return pll0_freq / (2ULL << ((clksel0 & 0x00000006) >> 1));
> > +}
> > +
> > +static const struct clk_ops k210_sysctl_clk_ops = {
> > + .recalc_rate = k210_sysctl_clk_recalc_rate,
> > +};
> > +
> > +static const struct clk_init_data k210_clk_init_data = {
> > + .name = "k210-sysctl-pll1",
> > + .ops = &k210_sysctl_clk_ops,
> > +};
> > +
> > +static int k210_sysctl_probe(struct platform_device *pdev)
> > +{
> > + struct k210_sysctl *s;
> > + int error;
> > +
> > + pr_info("Kendryte K210 SoC sysctl\n");
> > +
> > + s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
> > + if (!s)
> > + return -ENOMEM;
> > +
> > + s->regs = devm_ioremap_resource(&pdev->dev,
> > + platform_get_resource(pdev, IORESOURCE_MEM, 0));
> > + if (IS_ERR(s->regs))
> > + return PTR_ERR(s->regs);
> > +
> > + s->hw.init = &k210_clk_init_data;
> > + error = devm_clk_hw_register(&pdev->dev, &s->hw);
> > + if (error) {
> > + dev_err(&pdev->dev, "failed to register clk");
> > + return error;
> > + }
> > +
> > + error = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
> > + &s->hw);
> > + if (error) {
> > + dev_err(&pdev->dev, "adding clk provider failed\n");
> > + return error;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id k210_sysctl_of_match[] = {
> > + { .compatible = "kendryte,k210-sysctl", },
> > + {}
> > +};
> > +
> > +static struct platform_driver k210_sysctl_driver = {
> > + .driver = {
> > + .name = "k210-sysctl",
> > + .of_match_table = k210_sysctl_of_match,
> > + },
> > + .probe = k210_sysctl_probe,
> > +};
> > +
> > +static int __init k210_sysctl_init(void)
> > +{
> > + return platform_driver_register(&k210_sysctl_driver);
> > +}
> > +core_initcall(k210_sysctl_init);
> > +
> > +/*
> > + * This needs to be called very early during initialization, given that
> > + * PLL1 needs to be enabled to be able to use all SRAM.
> > + */
> > +static void __init k210_soc_early_init(const void *fdt)
> > +{
> > + void __iomem *regs;
> > +
> > + regs = ioremap(K210_SYSCTL_SYSCTL_BASE_ADDR, 0x1000);
> > + if (!regs)
> > + panic("K210 sysctl ioremap");
> > +
> > + /* Enable PLL1 to make the KPU SRAM useable */
> > + k210_pll1_enable(regs);
> > +
> > + k210_set_bits(PLL_OUT_EN, regs + K210_SYSCTL_PLL0);
> > +
> > + k210_set_bits(CLKEN_CPU | CLKEN_SRAM0 | CLKEN_SRAM1,
> > + regs + K210_SYSCTL_CLKEN_CENT);
> > + k210_set_bits(CLKEN_ROM | CLKEN_TIMER0 | CLKEN_RTC,
> > + regs + K210_SYSCTL_CLKEN_PERI);
> > +
> > + k210_set_bits(CLKSEL_ACLK, regs + K210_SYSCTL_CLKSEL0);
> > +
> > + iounmap(regs);
> > +}
> > +SOC_EARLY_INIT_DECLARE("kendryte,k210", k210_soc_early_init);
> >
> --Sean
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-13 5:25 ` Damien Le Moal
@ 2020-03-13 5:47 ` Atish Patra
0 siblings, 0 replies; 36+ messages in thread
From: Atish Patra @ 2020-03-13 5:47 UTC (permalink / raw)
To: Damien Le Moal; +Cc: linux-riscv, palmer, seanga2
On Thu, Mar 12, 2020 at 10:25 PM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>
> On Thu, 2020-03-12 at 11:10 -0700, Atish Patra wrote:
> > On Thu, Mar 12, 2020 at 8:20 AM Sean Anderson <seanga2@gmail.com> wrote:
> > > On 3/12/20 1:11 AM, Damien Le Moal wrote:
> > > > Commit c68a9032299e ("riscv: set pmp configuration if kernel is running
> > > > in M-mode") added PMP initialization to M-Mode. While this patch is
> > > > valid for any SoC following the ratified riscv specifications, the
> > > > Kendryte K210 SoC is based on earlier unstable specifications and does
> > > > not seem to support PMP initialization (the SoC crashes if CSR_PMPADDR0
> > > > or CSR_PMPCFG0 are accessed).
> > >
> > > The PMP bit has its polarity inverted in the v1.9 specification, and is
> > > called the SUM or Supervisor User Memory Access bit.
> > >
> > > --Sean
> > >
> > I don't think supporting old specs in Linux is a good idea. As per the
> > patch guideline
> > for RISC-V Linux, patches for only "frozen" or "ratified"
> > specifications are allowed.
>
> Yes, I agree on this point. However, this should be taken a little more
> lightly in my opinion. As long as we do not try to run the K210 with
> MMU turned on, this is the only known tiny deviation from the current
> ratified privileged specs v1.11. Since this is really a small one, I am
> inclined to consider this in the same way as a hardware bug, for which
> software exceptions are perfectly acceptable in the kernel. There are
> tons of "quirk" bits defined for ratified specifications such as NVMe
> or AHCI for example, due to hardware bugs. Even though the hardware
> intend to follow the specifications, quirks are sometimes necessary as
> work-around for hardware implementation bugs which are far more
> difficult to fix than software.
>
> Of course there are limits to this and sometimes, the decision has to
> be "go fix your hardware". In this case, I do not think we are at that
> level of seriousness, again assuming we never run with MMU on (because
> then we would need to implement support for the 1.9 specs, and that
> would seriously mess things up).
>
> Without this fix, the K210 cannot boot, at all. So if this small change
> is refused, we may as well just give up on the entire effort. That
> would really be too bad since the K210 boards are really cheap and
> would enable a lot of hobbyist and students to start playing with Linux
> on RISC-V...
>
I think there is some confusion. I was suggesting that supporting v1.9
spec is not a good idea.
That means allowing PMP access as per v1.9 spec instead of this patch
as Sean suggested.
This patch is fine as it just ignores touching the PMP CSR for
kendryte board. There is no issue with this patch
and it doesn't violate the patch policy.
> In the end, I think this is Palmer's decision. I gave my 2 cents above.
> If there is too much push-back on this, I will stop the effort because
> I do not see how to work around this one within 1.11 specs.
>
> Cheers.
>
> --
> Damien Le Moal
> Western Digital Research
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-12 18:21 ` Sean Anderson
@ 2020-03-13 5:52 ` Damien Le Moal
0 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-13 5:52 UTC (permalink / raw)
To: linux-riscv, palmer, seanga2; +Cc: Anup Patel
On Thu, 2020-03-12 at 14:21 -0400, Sean Anderson wrote:
> On 3/12/20 1:11 AM, Damien Le Moal wrote:
> > Add a mechanism for early SoC initialization for platforms that need
> > additional hardware initialization not possible through the regular
> > device tree and drivers mechanism. With this, a SoC specific
> > initialization function can be called very early, before DTB parsing
> > is done by parse_dtb() in Linux RISC-V kernel setup code.
>
> Why does it need to be called that early (e.g. before parsing dtb)?
Because dtb parsing will trigger the initialization of the memory
segments listed for use with memory allocation. That leads to the dtb
parsing itself allocating memory that ends up on the kpu sram before a
device driver specified in the dt can be initialized to turn the memory
on.
That is at least what I observed: I never go past the parse_dtb() point
without the memory turned on if there is an entry in the device tree
for it.
>
> > This can be very useful for early hardware initialization for No-MMU
> > kernels booted directly in M-mode because it is quite likely that no
> > other booting stage exist prior to the No-MMU kernel.
> >
> > Example use of a SoC early initialization is as follows:
> >
> > static void vendor_abc_early_init(const void *fdt)
> > {
> > /*
> > * some early init code here that can use simple matches
> > * against the flat device tree file.
> > */
> > }
> > SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
> >
> > This early initialization function is executed only if the flat device
> > tree for the board has a 'compatible = "vendor,abc"' entry;
> >
> > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> > Signed-off-by: Anup Patel <anup.patel@wdc.com>
> > Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
>
> --Sean
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 7/9] riscv: Kendryte K210 default config
2020-03-12 19:03 ` Atish Patra
@ 2020-03-13 5:52 ` Damien Le Moal
0 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-13 5:52 UTC (permalink / raw)
To: atishp; +Cc: linux-riscv, Anup Patel, palmer
On Thu, 2020-03-12 at 12:03 -0700, Atish Patra wrote:
> On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
> > This patch adds a defconfig file to build No-MMU kernels meant for
> > boards based on the Kendryte K210 SoC.
> >
> > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> > Reviewed-by: Anup Patel <anup@brainfault.org>
> > Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> > ---
> > arch/riscv/configs/nommu_k210_defconfig | 68 +++++++++++++++++++++++++
> > 1 file changed, 68 insertions(+)
> > create mode 100644 arch/riscv/configs/nommu_k210_defconfig
> >
> > diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig
> > new file mode 100644
> > index 000000000000..00ded8f0bc55
> > --- /dev/null
> > +++ b/arch/riscv/configs/nommu_k210_defconfig
> > @@ -0,0 +1,68 @@
> > +# CONFIG_CPU_ISOLATION is not set
> > +CONFIG_LOG_BUF_SHIFT=15
> > +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12
> > +CONFIG_BLK_DEV_INITRD=y
> > +CONFIG_INITRAMFS_SOURCE="k210.cpio"
>
> I don't think it is a common practice to provide a default rootfs file
> in defconfig if it is not
> part of the kernel. I may be wrong but I have not seen an example before.
> It is expected that developers will generate their own rootfs and
> modify it here.
>
> It may also raise compiler errors for auto builders in absence of k210.cpio.
Good point. Will remove it.
>
> > +CONFIG_INITRAMFS_FORCE=y
> > +# CONFIG_RD_BZIP2 is not set
> > +# CONFIG_RD_LZMA is not set
> > +# CONFIG_RD_XZ is not set
> > +# CONFIG_RD_LZO is not set
> > +# CONFIG_RD_LZ4 is not set
> > +# CONFIG_BOOT_CONFIG is not set
> > +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
> > +# CONFIG_SYSFS_SYSCALL is not set
> > +# CONFIG_FHANDLE is not set
> > +# CONFIG_BASE_FULL is not set
> > +# CONFIG_EPOLL is not set
> > +# CONFIG_SIGNALFD is not set
> > +# CONFIG_TIMERFD is not set
> > +# CONFIG_EVENTFD is not set
> > +# CONFIG_AIO is not set
> > +# CONFIG_IO_URING is not set
> > +# CONFIG_ADVISE_SYSCALLS is not set
> > +# CONFIG_MEMBARRIER is not set
> > +# CONFIG_KALLSYMS is not set
> > +CONFIG_EMBEDDED=y
> > +# CONFIG_VM_EVENT_COUNTERS is not set
> > +# CONFIG_COMPAT_BRK is not set
> > +CONFIG_SLOB=y
> > +# CONFIG_SLAB_MERGE_DEFAULT is not set
> > +# CONFIG_MMU is not set
> > +CONFIG_SOC_KENDRYTE=y
> > +CONFIG_MAXPHYSMEM_2GB=y
> > +CONFIG_SMP=y
> > +CONFIG_NR_CPUS=2
> > +CONFIG_CMDLINE="earlycon console=ttySIF0"
> > +CONFIG_CMDLINE_FORCE=y
> > +CONFIG_USE_BUILTIN_DTB=y
> > +CONFIG_BUILTIN_DTB_SOURCE="kendryte/k210"
> > +# CONFIG_BLOCK is not set
> > +CONFIG_BINFMT_FLAT=y
> > +# CONFIG_COREDUMP is not set
> > +CONFIG_DEVTMPFS=y
> > +CONFIG_DEVTMPFS_MOUNT=y
> > +# CONFIG_FW_LOADER is not set
> > +# CONFIG_ALLOW_DEV_COREDUMP is not set
> > +# CONFIG_INPUT_KEYBOARD is not set
> > +# CONFIG_INPUT_MOUSE is not set
> > +# CONFIG_SERIO is not set
> > +# CONFIG_LEGACY_PTYS is not set
> > +# CONFIG_LDISC_AUTOLOAD is not set
> > +# CONFIG_DEVMEM is not set
> > +# CONFIG_HW_RANDOM is not set
> > +# CONFIG_HWMON is not set
> > +# CONFIG_VGA_CONSOLE is not set
> > +# CONFIG_HID is not set
> > +# CONFIG_USB_SUPPORT is not set
> > +# CONFIG_VIRTIO_MENU is not set
> > +# CONFIG_DNOTIFY is not set
> > +# CONFIG_INOTIFY_USER is not set
> > +# CONFIG_MISC_FILESYSTEMS is not set
> > +CONFIG_LSM="[]"
> > +CONFIG_PRINTK_TIME=y
> > +# CONFIG_DEBUG_MISC is not set
> > +# CONFIG_SCHED_DEBUG is not set
> > +# CONFIG_RCU_TRACE is not set
> > +# CONFIG_FTRACE is not set
> > +# CONFIG_RUNTIME_TESTING_MENU is not set
> > --
> > 2.24.1
> >
> >
>
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 9/9] riscv: Do not initialize PMP on Kendryte SoC
2020-03-12 19:12 ` Atish Patra
2020-03-12 20:09 ` Sean Anderson
@ 2020-03-13 6:03 ` Damien Le Moal
1 sibling, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-13 6:03 UTC (permalink / raw)
To: atishp, seanga2; +Cc: linux-riscv, palmer
On Thu, 2020-03-12 at 12:12 -0700, Atish Patra wrote:
> On Thu, Mar 12, 2020 at 11:49 AM Sean Anderson <seanga2@gmail.com> wrote:
> > On 3/12/20 2:29 PM, Atish Patra wrote:
> > > On Thu, Mar 12, 2020 at 11:14 AM Sean Anderson <seanga2@gmail.com> wrote:
> > > >
> > > > > I don't think supporting old specs in Linux is a good idea. As per the
> > > > > patch guideline
> > > > > for RISC-V Linux, patches for only "frozen" or "ratified"
> > > > > specifications are allowed.
> > > > >
> > > >
> > > > Well this CPU follows the v1.9 spec. It's real hardware, if it is to be
> > > > be supported, then the 1.9 spec needs to be as well.
> > > >
> > >
> > > As RISC-V is an open ISA and it's continuously evolving, there will be
> > > some hardware
> > > that will implement old specifications or non-backward compatible features.
> > > I fear the number of hardware with such features/implementations will
> > > grow in the future.
> > > If Linux is going to support all of them, it may be a maintenance nightmare.
> >
> > I agree. There is also no standard way to communicate the implemented
> > privileged spec level e.g. in the device tree. The base integer
> > instruction set version can be specified in the riscv,isa property, such
> > as
> >
> > riscv,isa = "rv64i2p1..."
> >
> > However, there is no "extension" for the privileged specification.
> > A method to specify this would be helpful, especially since the
> > bootloader may need to enable the MMU before loading Linux since there
> > is no way to enable it from S-mode until v1.10.
> >
> > On the other hand, there is relatively little changed from v1.9 to the
> > current revision. The following list has the differences from the
> > current spec:
> >
> > * The PMP has flipped polarity
> > * The mcounteren CSRs are split
> > * sfence.vma is sfence.vm (though this should be handled by the sbi
> > anyway)
> > * satp has a different name, and mode no longer exists in the top four
> > bits. Since these bits used to be part of ASID, it's fine to write the
> > mode to those bits. If linux never switches from (e.g.) sv39 to
> > something else, there will be no observed difference either.
> >
> > Everything else is mostly forwards-compatible, as far as I can tell.
> > That is, assuming new behaviour on old hardware won't cause problems.
> >
> Even if the changes are minimal and we can easily hide under macro magic,
> it will create a bad precedent for the future. What if somebody sends
> a patch for
> a non-standard extension and cites kendryte support as an example.
Come on ! ISA extensions are much bigger beasts ! And refusing upstream
support for non-ratified extensions is fine. This case is nowhere near
as complex. And as I mentioned in an earlier email, it is so simple
that we could consider it as a hardware bug rather than spec deviation
(which hardware bugs are in fact, even though they are not
intentional).
> > A sufficiently smart kernel could even detect the version at runtime by
> > intentionally triggering behaviour which is illegal depending on the
> > privileged version, and then checking for an exception.
> >
> That's the maintenance nightmare I was talking about. For kendryte, it
> is only few incompatible changes
> in privilege specification but what if some hardware implements a
> variation of hypervisor spec or vector extension.
If you add "what if" like that, we will never be able to make progress
and innovate with RISC-V. I for one do not expect the specs 1.11 to be
"THE" RISC-V specs forever. There surely will be someday an evolution
of it. We most likely will have to support someday RISC-V 2.0. And we
will need to keep support for 1.11 as well when that day comes.
Support nightmare most often come from code getting out of hand in
terms of cleanliness/structure (in my opinion). As long as tiny changes
are not invasive, clearly very limited in scope and clean, I am
perfectly fine with exceptions. Again, we will have to deal with
various hardware bugs as we get more HW anyway. That will be the same
problem...
>
> > --Sean
> >
>
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-12 20:53 ` Atish Patra
@ 2020-03-13 6:42 ` Damien Le Moal
2020-03-13 21:10 ` Atish Patra
0 siblings, 1 reply; 36+ messages in thread
From: Damien Le Moal @ 2020-03-13 6:42 UTC (permalink / raw)
To: atishp; +Cc: linux-riscv, Anup Patel, palmer
On Thu, 2020-03-12 at 13:53 -0700, Atish Patra wrote:
> On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
> > Add a mechanism for early SoC initialization for platforms that need
> > additional hardware initialization not possible through the regular
> > device tree and drivers mechanism. With this, a SoC specific
> > initialization function can be called very early, before DTB parsing
> > is done by parse_dtb() in Linux RISC-V kernel setup code.
> >
> > This can be very useful for early hardware initialization for No-MMU
> > kernels booted directly in M-mode because it is quite likely that no
> > other booting stage exist prior to the No-MMU kernel.
> >
> > Example use of a SoC early initialization is as follows:
> >
> > static void vendor_abc_early_init(const void *fdt)
> > {
> > /*
> > * some early init code here that can use simple matches
> > * against the flat device tree file.
> > */
> > }
> > SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
> >
> > This early initialization function is executed only if the flat device
> > tree for the board has a 'compatible = "vendor,abc"' entry;
> >
> > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> > Signed-off-by: Anup Patel <anup.patel@wdc.com>
> > Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> > ---
> > arch/riscv/include/asm/soc.h | 23 +++++++++++++++++++++++
> > arch/riscv/kernel/Makefile | 1 +
> > arch/riscv/kernel/head.S | 1 +
> > arch/riscv/kernel/soc.c | 28 ++++++++++++++++++++++++++++
> > arch/riscv/kernel/vmlinux.lds.S | 6 ++++++
> > 5 files changed, 59 insertions(+)
> > create mode 100644 arch/riscv/include/asm/soc.h
> > create mode 100644 arch/riscv/kernel/soc.c
> >
> > diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h
> > new file mode 100644
> > index 000000000000..9b8c332cbe76
> > --- /dev/null
> > +++ b/arch/riscv/include/asm/soc.h
> > @@ -0,0 +1,23 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> > + */
> > +
> > +#ifndef _ASM_RISCV_SOC_H
> > +#define _ASM_RISCV_SOC_H
> > +
> > +#include <linux/of.h>
> > +#include <linux/linkage.h>
> > +#include <linux/types.h>
> > +
> > +#define SOC_EARLY_INIT_DECLARE(compat, fn) \
> > + static const struct of_device_id __soc_early_init \
> > + __used __section(__soc_early_init_table) \
> > + = { .compatible = compat, .data = fn }
> > +
>
> There may be some future kendryte board or some other RISC-V board
> which want to use SOC_EARLY_INIT_DECLARE.
> There should be a name parameter as well which allows multiple usage
> of SOC_EARLY_INIT_DECLARE.
I am not sure I understand your point here. Currently, the call to an
early init functions is driven by the value (name) specified in the DT
compatible entry. If what needs to be done in the early init function
for one SoC is common with another, the same function can be used for
different SOC_EARLY_INIT_DECLARE() with different compatible strings,
or the same compatible string used in the different boards DT. No ? Am
I missing something ?
>
> > +void soc_early_init(void);
> > +
> > +extern unsigned long __soc_early_init_table_start;
> > +extern unsigned long __soc_early_init_table_end;
> > +
> > +#endif
> > diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> > index 97d0c35f8b37..e4a22999dbc6 100644
> > --- a/arch/riscv/kernel/Makefile
> > +++ b/arch/riscv/kernel/Makefile
> > @@ -10,6 +10,7 @@ endif
> > extra-y += head.o
> > extra-y += vmlinux.lds
> >
> > +obj-y += soc.o
> > obj-y += cpu.o
> > obj-y += cpufeature.o
> > obj-y += entry.o
> > diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> > index 85f2073e7fe4..52ed11b4fda6 100644
> > --- a/arch/riscv/kernel/head.S
> > +++ b/arch/riscv/kernel/head.S
> > @@ -131,6 +131,7 @@ clear_bss_done:
> > call kasan_early_init
> > #endif
> > /* Start the kernel */
> > + call soc_early_init
> > call parse_dtb
> > tail start_kernel
> >
> > diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c
> > new file mode 100644
> > index 000000000000..0b3b3dc9ad0f
> > --- /dev/null
> > +++ b/arch/riscv/kernel/soc.c
> > @@ -0,0 +1,28 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> > + */
> > +#include <linux/init.h>
> > +#include <linux/libfdt.h>
> > +#include <asm/pgtable.h>
> > +#include <asm/soc.h>
> > +
> > +/*
> > + * This is called extremly early, before parse_dtb(), to allow initializing
> > + * SoC hardware before memory or any device driver initialization.
> > + */
> > +void __init soc_early_init(void)
> > +{
> > + void (*early_fn)(const void *fdt);
> > + const struct of_device_id *s;
> > + const void *fdt = dtb_early_va;
> > +
> > + for (s = (void *)&__soc_early_init_table_start;
> > + (void *)s < (void *)&__soc_early_init_table_end; s++) {
> > + if (!fdt_node_check_compatible(fdt, 0, s->compatible)) {
> > + early_fn = s->data;
> > + early_fn(fdt);
> > + return;
> > + }
> > + }
> > +}
> > diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> > index 1e0193ded420..32b160942f40 100644
> > --- a/arch/riscv/kernel/vmlinux.lds.S
> > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > @@ -24,6 +24,12 @@ SECTIONS
> > HEAD_TEXT_SECTION
> > INIT_TEXT_SECTION(PAGE_SIZE)
> > INIT_DATA_SECTION(16)
> > + . = ALIGN(8);
> > + __soc_early_init_table : {
> > + __soc_early_init_table_start = .;
> > + KEEP(*(__soc_early_init_table))
> > + __soc_early_init_table_end = .;
> > + }
> > /* we have to discard exit text and such at runtime, not link time */
> > .exit.text :
> > {
> > --
> > 2.24.1
> >
> >
>
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-13 6:42 ` Damien Le Moal
@ 2020-03-13 21:10 ` Atish Patra
2020-03-16 0:34 ` Damien Le Moal
0 siblings, 1 reply; 36+ messages in thread
From: Atish Patra @ 2020-03-13 21:10 UTC (permalink / raw)
To: Damien Le Moal; +Cc: linux-riscv, Anup Patel, palmer
On Thu, Mar 12, 2020 at 11:42 PM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>
> On Thu, 2020-03-12 at 13:53 -0700, Atish Patra wrote:
> > On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
> > > Add a mechanism for early SoC initialization for platforms that need
> > > additional hardware initialization not possible through the regular
> > > device tree and drivers mechanism. With this, a SoC specific
> > > initialization function can be called very early, before DTB parsing
> > > is done by parse_dtb() in Linux RISC-V kernel setup code.
> > >
> > > This can be very useful for early hardware initialization for No-MMU
> > > kernels booted directly in M-mode because it is quite likely that no
> > > other booting stage exist prior to the No-MMU kernel.
> > >
> > > Example use of a SoC early initialization is as follows:
> > >
> > > static void vendor_abc_early_init(const void *fdt)
> > > {
> > > /*
> > > * some early init code here that can use simple matches
> > > * against the flat device tree file.
> > > */
> > > }
> > > SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
> > >
> > > This early initialization function is executed only if the flat device
> > > tree for the board has a 'compatible = "vendor,abc"' entry;
> > >
> > > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> > > Signed-off-by: Anup Patel <anup.patel@wdc.com>
> > > Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> > > ---
> > > arch/riscv/include/asm/soc.h | 23 +++++++++++++++++++++++
> > > arch/riscv/kernel/Makefile | 1 +
> > > arch/riscv/kernel/head.S | 1 +
> > > arch/riscv/kernel/soc.c | 28 ++++++++++++++++++++++++++++
> > > arch/riscv/kernel/vmlinux.lds.S | 6 ++++++
> > > 5 files changed, 59 insertions(+)
> > > create mode 100644 arch/riscv/include/asm/soc.h
> > > create mode 100644 arch/riscv/kernel/soc.c
> > >
> > > diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h
> > > new file mode 100644
> > > index 000000000000..9b8c332cbe76
> > > --- /dev/null
> > > +++ b/arch/riscv/include/asm/soc.h
> > > @@ -0,0 +1,23 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > > +/*
> > > + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> > > + */
> > > +
> > > +#ifndef _ASM_RISCV_SOC_H
> > > +#define _ASM_RISCV_SOC_H
> > > +
> > > +#include <linux/of.h>
> > > +#include <linux/linkage.h>
> > > +#include <linux/types.h>
> > > +
> > > +#define SOC_EARLY_INIT_DECLARE(compat, fn) \
> > > + static const struct of_device_id __soc_early_init \
> > > + __used __section(__soc_early_init_table) \
> > > + = { .compatible = compat, .data = fn }
> > > +
> >
> > There may be some future kendryte board or some other RISC-V board
> > which want to use SOC_EARLY_INIT_DECLARE.
> > There should be a name parameter as well which allows multiple usage
> > of SOC_EARLY_INIT_DECLARE.
>
> I am not sure I understand your point here. Currently, the call to an
> early init functions is driven by the value (name) specified in the DT
> compatible entry. If what needs to be done in the early init function
> for one SoC is common with another, the same function can be used for
> different SOC_EARLY_INIT_DECLARE() with different compatible strings,
> or the same compatible string used in the different boards DT. No ? Am
> I missing something ?
>
To use different compatible strings, SOC_EARLY_INIT_DECLARE has to be
declared twice.
As SOC_EARLY_INIT_DECLARE is just a macro that declares
__soc_early_init, redefinition compile error
will happen. That's why __soc_early_init has to be suffixed with name
to avoid the redefinition error.
Here is the diff I am talking about
-#define SOC_EARLY_INIT_DECLARE(compat, fn) \
- static const struct of_device_id __soc_early_init \
+#define SOC_EARLY_INIT_DECLARE(name, compat, fn)
\
+ static const struct of_device_id __soc_early_init__##name
\
__used __section(__soc_early_init_table) \
= { .compatible = compat, .data = fn }
> >
> > > +void soc_early_init(void);
> > > +
> > > +extern unsigned long __soc_early_init_table_start;
> > > +extern unsigned long __soc_early_init_table_end;
> > > +
> > > +#endif
> > > diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> > > index 97d0c35f8b37..e4a22999dbc6 100644
> > > --- a/arch/riscv/kernel/Makefile
> > > +++ b/arch/riscv/kernel/Makefile
> > > @@ -10,6 +10,7 @@ endif
> > > extra-y += head.o
> > > extra-y += vmlinux.lds
> > >
> > > +obj-y += soc.o
> > > obj-y += cpu.o
> > > obj-y += cpufeature.o
> > > obj-y += entry.o
> > > diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> > > index 85f2073e7fe4..52ed11b4fda6 100644
> > > --- a/arch/riscv/kernel/head.S
> > > +++ b/arch/riscv/kernel/head.S
> > > @@ -131,6 +131,7 @@ clear_bss_done:
> > > call kasan_early_init
> > > #endif
> > > /* Start the kernel */
> > > + call soc_early_init
> > > call parse_dtb
> > > tail start_kernel
> > >
> > > diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c
> > > new file mode 100644
> > > index 000000000000..0b3b3dc9ad0f
> > > --- /dev/null
> > > +++ b/arch/riscv/kernel/soc.c
> > > @@ -0,0 +1,28 @@
> > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > +/*
> > > + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
> > > + */
> > > +#include <linux/init.h>
> > > +#include <linux/libfdt.h>
> > > +#include <asm/pgtable.h>
> > > +#include <asm/soc.h>
> > > +
> > > +/*
> > > + * This is called extremly early, before parse_dtb(), to allow initializing
> > > + * SoC hardware before memory or any device driver initialization.
> > > + */
> > > +void __init soc_early_init(void)
> > > +{
> > > + void (*early_fn)(const void *fdt);
> > > + const struct of_device_id *s;
> > > + const void *fdt = dtb_early_va;
> > > +
> > > + for (s = (void *)&__soc_early_init_table_start;
> > > + (void *)s < (void *)&__soc_early_init_table_end; s++) {
> > > + if (!fdt_node_check_compatible(fdt, 0, s->compatible)) {
> > > + early_fn = s->data;
> > > + early_fn(fdt);
> > > + return;
> > > + }
> > > + }
> > > +}
> > > diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> > > index 1e0193ded420..32b160942f40 100644
> > > --- a/arch/riscv/kernel/vmlinux.lds.S
> > > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > > @@ -24,6 +24,12 @@ SECTIONS
> > > HEAD_TEXT_SECTION
> > > INIT_TEXT_SECTION(PAGE_SIZE)
> > > INIT_DATA_SECTION(16)
> > > + . = ALIGN(8);
> > > + __soc_early_init_table : {
> > > + __soc_early_init_table_start = .;
> > > + KEEP(*(__soc_early_init_table))
> > > + __soc_early_init_table_end = .;
> > > + }
> > > /* we have to discard exit text and such at runtime, not link time */
> > > .exit.text :
> > > {
> > > --
> > > 2.24.1
> > >
> > >
> >
> >
>
> --
> Damien Le Moal
> Western Digital Research
--
Regards,
Atish
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2 3/9] riscv: Add SOC early init support
2020-03-13 21:10 ` Atish Patra
@ 2020-03-16 0:34 ` Damien Le Moal
0 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-16 0:34 UTC (permalink / raw)
To: Atish Patra; +Cc: linux-riscv, Anup Patel, palmer
On 2020/03/14 6:10, Atish Patra wrote:
> On Thu, Mar 12, 2020 at 11:42 PM Damien Le Moal <Damien.LeMoal@wdc.com> wrote:
>>
>> On Thu, 2020-03-12 at 13:53 -0700, Atish Patra wrote:
>>> On Wed, Mar 11, 2020 at 10:11 PM Damien Le Moal <damien.lemoal@wdc.com> wrote:
>>>> Add a mechanism for early SoC initialization for platforms that need
>>>> additional hardware initialization not possible through the regular
>>>> device tree and drivers mechanism. With this, a SoC specific
>>>> initialization function can be called very early, before DTB parsing
>>>> is done by parse_dtb() in Linux RISC-V kernel setup code.
>>>>
>>>> This can be very useful for early hardware initialization for No-MMU
>>>> kernels booted directly in M-mode because it is quite likely that no
>>>> other booting stage exist prior to the No-MMU kernel.
>>>>
>>>> Example use of a SoC early initialization is as follows:
>>>>
>>>> static void vendor_abc_early_init(const void *fdt)
>>>> {
>>>> /*
>>>> * some early init code here that can use simple matches
>>>> * against the flat device tree file.
>>>> */
>>>> }
>>>> SOC_EARLY_INIT_DECLARE("vendor,abc", abc_early_init);
>>>>
>>>> This early initialization function is executed only if the flat device
>>>> tree for the board has a 'compatible = "vendor,abc"' entry;
>>>>
>>>> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
>>>> Signed-off-by: Anup Patel <anup.patel@wdc.com>
>>>> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
>>>> ---
>>>> arch/riscv/include/asm/soc.h | 23 +++++++++++++++++++++++
>>>> arch/riscv/kernel/Makefile | 1 +
>>>> arch/riscv/kernel/head.S | 1 +
>>>> arch/riscv/kernel/soc.c | 28 ++++++++++++++++++++++++++++
>>>> arch/riscv/kernel/vmlinux.lds.S | 6 ++++++
>>>> 5 files changed, 59 insertions(+)
>>>> create mode 100644 arch/riscv/include/asm/soc.h
>>>> create mode 100644 arch/riscv/kernel/soc.c
>>>>
>>>> diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h
>>>> new file mode 100644
>>>> index 000000000000..9b8c332cbe76
>>>> --- /dev/null
>>>> +++ b/arch/riscv/include/asm/soc.h
>>>> @@ -0,0 +1,23 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>>> +/*
>>>> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
>>>> + */
>>>> +
>>>> +#ifndef _ASM_RISCV_SOC_H
>>>> +#define _ASM_RISCV_SOC_H
>>>> +
>>>> +#include <linux/of.h>
>>>> +#include <linux/linkage.h>
>>>> +#include <linux/types.h>
>>>> +
>>>> +#define SOC_EARLY_INIT_DECLARE(compat, fn) \
>>>> + static const struct of_device_id __soc_early_init \
>>>> + __used __section(__soc_early_init_table) \
>>>> + = { .compatible = compat, .data = fn }
>>>> +
>>>
>>> There may be some future kendryte board or some other RISC-V board
>>> which want to use SOC_EARLY_INIT_DECLARE.
>>> There should be a name parameter as well which allows multiple usage
>>> of SOC_EARLY_INIT_DECLARE.
>>
>> I am not sure I understand your point here. Currently, the call to an
>> early init functions is driven by the value (name) specified in the DT
>> compatible entry. If what needs to be done in the early init function
>> for one SoC is common with another, the same function can be used for
>> different SOC_EARLY_INIT_DECLARE() with different compatible strings,
>> or the same compatible string used in the different boards DT. No ? Am
>> I missing something ?
>>
>
> To use different compatible strings, SOC_EARLY_INIT_DECLARE has to be
> declared twice.
> As SOC_EARLY_INIT_DECLARE is just a macro that declares
> __soc_early_init, redefinition compile error
> will happen. That's why __soc_early_init has to be suffixed with name
> to avoid the redefinition error.
> Here is the diff I am talking about
>
> -#define SOC_EARLY_INIT_DECLARE(compat, fn) \
> - static const struct of_device_id __soc_early_init \
> +#define SOC_EARLY_INIT_DECLARE(name, compat, fn)
> \
> + static const struct of_device_id __soc_early_init__##name
> \
> __used __section(__soc_early_init_table) \
> = { .compatible = compat, .data = fn }
>
OK. Got it. I will make this simple change and send a v4 of the series.
>
>>>
>>>> +void soc_early_init(void);
>>>> +
>>>> +extern unsigned long __soc_early_init_table_start;
>>>> +extern unsigned long __soc_early_init_table_end;
>>>> +
>>>> +#endif
>>>> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
>>>> index 97d0c35f8b37..e4a22999dbc6 100644
>>>> --- a/arch/riscv/kernel/Makefile
>>>> +++ b/arch/riscv/kernel/Makefile
>>>> @@ -10,6 +10,7 @@ endif
>>>> extra-y += head.o
>>>> extra-y += vmlinux.lds
>>>>
>>>> +obj-y += soc.o
>>>> obj-y += cpu.o
>>>> obj-y += cpufeature.o
>>>> obj-y += entry.o
>>>> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
>>>> index 85f2073e7fe4..52ed11b4fda6 100644
>>>> --- a/arch/riscv/kernel/head.S
>>>> +++ b/arch/riscv/kernel/head.S
>>>> @@ -131,6 +131,7 @@ clear_bss_done:
>>>> call kasan_early_init
>>>> #endif
>>>> /* Start the kernel */
>>>> + call soc_early_init
>>>> call parse_dtb
>>>> tail start_kernel
>>>>
>>>> diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c
>>>> new file mode 100644
>>>> index 000000000000..0b3b3dc9ad0f
>>>> --- /dev/null
>>>> +++ b/arch/riscv/kernel/soc.c
>>>> @@ -0,0 +1,28 @@
>>>> +// SPDX-License-Identifier: GPL-2.0-or-later
>>>> +/*
>>>> + * Copyright (C) 2020 Western Digital Corporation or its affiliates.
>>>> + */
>>>> +#include <linux/init.h>
>>>> +#include <linux/libfdt.h>
>>>> +#include <asm/pgtable.h>
>>>> +#include <asm/soc.h>
>>>> +
>>>> +/*
>>>> + * This is called extremly early, before parse_dtb(), to allow initializing
>>>> + * SoC hardware before memory or any device driver initialization.
>>>> + */
>>>> +void __init soc_early_init(void)
>>>> +{
>>>> + void (*early_fn)(const void *fdt);
>>>> + const struct of_device_id *s;
>>>> + const void *fdt = dtb_early_va;
>>>> +
>>>> + for (s = (void *)&__soc_early_init_table_start;
>>>> + (void *)s < (void *)&__soc_early_init_table_end; s++) {
>>>> + if (!fdt_node_check_compatible(fdt, 0, s->compatible)) {
>>>> + early_fn = s->data;
>>>> + early_fn(fdt);
>>>> + return;
>>>> + }
>>>> + }
>>>> +}
>>>> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
>>>> index 1e0193ded420..32b160942f40 100644
>>>> --- a/arch/riscv/kernel/vmlinux.lds.S
>>>> +++ b/arch/riscv/kernel/vmlinux.lds.S
>>>> @@ -24,6 +24,12 @@ SECTIONS
>>>> HEAD_TEXT_SECTION
>>>> INIT_TEXT_SECTION(PAGE_SIZE)
>>>> INIT_DATA_SECTION(16)
>>>> + . = ALIGN(8);
>>>> + __soc_early_init_table : {
>>>> + __soc_early_init_table_start = .;
>>>> + KEEP(*(__soc_early_init_table))
>>>> + __soc_early_init_table_end = .;
>>>> + }
>>>> /* we have to discard exit text and such at runtime, not link time */
>>>> .exit.text :
>>>> {
>>>> --
>>>> 2.24.1
>>>>
>>>>
>>>
>>>
>>
>> --
>> Damien Le Moal
>> Western Digital Research
>
>
>
> --
> Regards,
> Atish
>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2 0/9] Kendryte k210 SoC boards support
@ 2020-03-12 5:25 Damien Le Moal
0 siblings, 0 replies; 36+ messages in thread
From: Damien Le Moal @ 2020-03-12 5:25 UTC (permalink / raw)
To: linux-riscv, Palmer Dabbelt; +Cc: Anup Patel
[Added changelog]
This series adds support to boot nommu Linux on Kendryte K210 SoC based
boards. This is all based on initial work done by Christoph Hellwig.
Patch 1 adds unaligned load/store trap handlers for M-mode.
Patch 2 enables a builtin DTB to allow passing a device tree to the
kernel when the board bootchain is not able to pass one. This option
can be used only for NOMMU kernels for now
Patch 3 introduces an early SoC initialization enabling very early
hardware initialization not possible with device tree entries pointing
to drivers. This is used in patch 6 which introduces a sysctl driver for
the K210 SoC. The early SoC initialization is used to enable the
additional 2MB of SRAM normally reserved to the SoC AI chip.
Patch 4 to 9 add necessary Kconfig changes, a defconfig, a generic
device tree suitable for many K210 boards and compilation of a bootable
image file (bin file) that can be used to flash on K210 board ROM.
Finally, patch 9 disables PMP initialization for K210 SoCs.
This series was tested on the Kendryte KD233 development board, the
Sipeed MAIX dan dock board and the Sipeed MAIXDUINO board. The userspace
used was built using a modified buildroot tree for the toolchain part
and an unmodified busybox tree for the initramfs image (embedded in the
kernel as a cpio file). The folowwing github project contains the
modified buildroot tree:
https://github.com/damien-lemoal/riscv64-nommu-buildroot
This is based on work from Christoph Hellwig, with additional changes
and updates to the latest upstream versions for buildroot and uClibc.
Precompiled versions of the toolchain (gcc 9.2) and initramfs file tree
and cpio file can be found in this project under the directory:
buildroot/riscv64-uclibc-nommu/
Flashing the file arch/riscv/boot/loader.bin to a board can be done
using the Sipeed kflash.py tool with the command:
kflash.py/kflash.py -p /dev/ttyUSB0 -b 1500000 -t loader.bin
The kflash.py tool can be found here:
https://github.com/sipeed/kflash.py
For reference, using the Sipeed MAIXDUINO board, here is the boot
output:
[INFO] Rebooting...
--- forcing DTR inactive
--- forcing RTS inactive
--- Miniterm on /dev/ttyUSB0 115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
[ 0.000000] Linux version 5.6.0-rc1-00011-ga2b5be1c4374 (damien@yyy) (gcc version 8.2.0 (Buildroot 2018.11-rc2-00003-ga0787e9)) #610 SMP Wed Feb 12 18:53:50 JST 2020
[ 0.000000] earlycon: sifive0 at MMIO 0x0000000038000000 (options '')
[ 0.000000] printk: bootconsole [sifive0] enabled
[ 0.000000] initrd not found or empty - disabling initrd
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000080000000-0x00000000807fffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080000000-0x00000000807fffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000807fffff]
[ 0.000000] elf_hwcap is 0x112d
[ 0.000000] percpu: max_distance=0x18000 too large for vmalloc space 0x0
[ 0.000000] percpu: Embedded 12 pages/cpu s18272 r0 d30880 u49152
[ 0.000000] Built 1 zonelists, mobility grouping off. Total pages: 2020
[ 0.000000] Kernel command line: earlycon console=ttySIF0
[ 0.000000] Dentry cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.000000] Sorting __ex_table...
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 6328K/8192K available (924K kernel code, 110K rwdata, 164K rodata, 321K init, 91K bss, 1864K reserved, 0K cma-reserved)
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
[ 0.000000] plic: mapped 65 interrupts with 2 handlers for 4 contexts.
[ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0]
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x3990be68b, max_idle_ns: 881590404272 ns
[ 0.000014] sched_clock: 64 bits at 7MHz, resolution 128ns, wraps every 4398046511054ns
[ 0.008232] Console: colour dummy device 80x25
[ 0.012474] Calibrating delay loop (skipped), value calculated using timer frequency.. 15.60 BogoMIPS (lpj=31200)
[ 0.022678] pid_max: default: 4096 minimum: 301
[ 0.027288] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.034414] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.044796] rcu: Hierarchical SRCU implementation.
[ 0.049602] smp: Bringing up secondary CPUs ...
[ 0.054746] smp: Brought up 1 node, 2 CPUs
[ 0.059093] devtmpfs: initialized
[ 0.065523] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.074544] futex hash table entries: 16 (order: -2, 1024 bytes, linear)
[ 0.082512] Kendryte K210 SoC sysctl
[ 0.096010] clocksource: Switched to clocksource riscv_clocksource
[ 0.178581] workingset: timestamp_bits=62 max_order=11 bucket_order=0
[ 0.185846] 38000000.serial: ttySIF0 at MMIO 0x38000000 (irq = 1, base_baud = 0) is a SiFive UART v0
[ 0.194344] printk: console [ttySIF0] enabled
[ 0.194344] printk: console [ttySIF0] enabled
[ 0.202929] printk: bootconsole [sifive0] disabled
[ 0.202929] printk: bootconsole [sifive0] disabled
[ 0.214853] random: get_random_bytes called from 0x0000000080055178 with crng_init=0
[ 0.223606] devtmpfs: mounted
[ 0.226861] Freeing unused kernel memory: 320K
[ 0.230574] This architecture does not have kernel memory protection.
[ 0.236987] Run /sbin/init as init process
[ 0.241181] Run /etc/init as init process
[ 0.245178] Run /bin/init as init process
-----------------------------
| Kendryte K210 NOMMU Linux |
-----------------------------
Mounting /proc
Starting shell
BusyBox v1.32.0.git (2020-02-12 17:51:45 JST) hush - the humble shell
Enter 'help' for a list of built-in commands.
/ # cat /proc/cpuinfo
processor : 0
hart : 0
isa : rv64imafdc
processor : 1
hart : 1
isa : rv64imafdc
/ #
/ # ls -l /
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 bin
drwxr-xr-x 2 0 0 0 Jan 1 00:00 dev
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 etc
dr-xr-xr-x 58 0 0 0 Jan 1 00:00 proc
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 root
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 sbin
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 sys
drwxrwxr-x 2 1000 1000 0 Feb 12 2020 tmp
drwxrwxr-x 4 1000 1000 0 Feb 12 2020 usr
/ #
/ # cat /proc/vmstat
nr_free_pages 1148
...
/ #
The K210 SoC has more devices (GPIO, SD-card, LCD, etc) that likely can
be enabled and used. For this, the sysctl driver will need further
improvements as each device uses a different clock. To share the fun,
supporting these is left as an exercise for the hobbyist and hackers
interested in this SoC/boards :)
Changes from v1:
* Rebased on rc5 kernel
* Fixed misaligned trap handling (removed static dependency on
__riscv_compressed)
* Cleanup device tree:
- Single memory node for all memory banks
- Added clock IDs
- More commonality with Sean latest v7 U-Boot device tree
* Added last patch to avoid board crash on boot due to out-of-spec PMP
on K210 SoC.
Christoph Hellwig (2):
riscv: Add Kendryte K210 SoC support
riscv: create a loader.bin boot image for Kendryte SoC
Damien Le Moal (7):
riscv: Unaligned load/store handling for M_MODE
riscv: Add BUILTIN_DTB support
riscv: Add SOC early init support
riscv: Select required drivers for Kendryte SOC
riscv: Add Kendryte K210 device tree
riscv: Kendryte K210 default config
riscv: Do not initialize PMP on Kendryte SoC
arch/riscv/Kbuild | 1 +
arch/riscv/Kconfig | 19 ++
arch/riscv/Kconfig.socs | 10 +
arch/riscv/Makefile | 6 +-
arch/riscv/boot/Makefile | 3 +
arch/riscv/boot/dts/Makefile | 5 +
arch/riscv/boot/dts/kendryte/Makefile | 2 +
arch/riscv/boot/dts/kendryte/k210.dts | 23 ++
arch/riscv/boot/dts/kendryte/k210.dtsi | 117 ++++++++
arch/riscv/configs/nommu_k210_defconfig | 68 +++++
arch/riscv/include/asm/soc.h | 23 ++
arch/riscv/kernel/Makefile | 3 +-
arch/riscv/kernel/head.S | 9 +-
arch/riscv/kernel/setup.c | 6 +
arch/riscv/kernel/soc.c | 28 ++
arch/riscv/kernel/traps.c | 27 +-
arch/riscv/kernel/traps_misaligned.c | 370 ++++++++++++++++++++++++
arch/riscv/kernel/vmlinux.lds.S | 6 +
arch/riscv/mm/init.c | 4 +
drivers/soc/Kconfig | 1 +
drivers/soc/Makefile | 1 +
drivers/soc/kendryte/Kconfig | 14 +
drivers/soc/kendryte/Makefile | 3 +
drivers/soc/kendryte/k210-sysctl.c | 245 ++++++++++++++++
include/dt-bindings/clock/k210-clk.h | 20 ++
25 files changed, 1006 insertions(+), 8 deletions(-)
create mode 100644 arch/riscv/boot/dts/kendryte/Makefile
create mode 100644 arch/riscv/boot/dts/kendryte/k210.dts
create mode 100644 arch/riscv/boot/dts/kendryte/k210.dtsi
create mode 100644 arch/riscv/configs/nommu_k210_defconfig
create mode 100644 arch/riscv/include/asm/soc.h
create mode 100644 arch/riscv/kernel/soc.c
create mode 100644 arch/riscv/kernel/traps_misaligned.c
create mode 100644 drivers/soc/kendryte/Kconfig
create mode 100644 drivers/soc/kendryte/Makefile
create mode 100644 drivers/soc/kendryte/k210-sysctl.c
create mode 100644 include/dt-bindings/clock/k210-clk.h
--
2.24.1
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2020-03-16 0:34 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-12 5:10 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
2020-03-12 5:10 ` [PATCH v2 1/9] riscv: Unaligned load/store handling for M_MODE Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 2/9] riscv: Add BUILTIN_DTB support Damien Le Moal
2020-03-12 20:03 ` Atish Patra
2020-03-12 5:11 ` [PATCH v2 3/9] riscv: Add SOC early init support Damien Le Moal
2020-03-12 18:21 ` Sean Anderson
2020-03-13 5:52 ` Damien Le Moal
2020-03-12 19:50 ` Atish Patra
2020-03-12 20:53 ` Atish Patra
2020-03-13 6:42 ` Damien Le Moal
2020-03-13 21:10 ` Atish Patra
2020-03-16 0:34 ` Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 4/9] riscv: Add Kendryte K210 SoC support Damien Le Moal
2020-03-12 18:19 ` Sean Anderson
2020-03-13 5:43 ` Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 5/9] riscv: Select required drivers for Kendryte SOC Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 6/9] riscv: Add Kendryte K210 device tree Damien Le Moal
2020-03-12 18:16 ` Sean Anderson
2020-03-13 5:29 ` Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 7/9] riscv: Kendryte K210 default config Damien Le Moal
2020-03-12 19:03 ` Atish Patra
2020-03-13 5:52 ` Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 8/9] riscv: create a loader.bin boot image for Kendryte SoC Damien Le Moal
2020-03-12 5:11 ` [PATCH v2 9/9] riscv: Do not initialize PMP on " Damien Le Moal
2020-03-12 15:20 ` Sean Anderson
2020-03-12 18:10 ` Atish Patra
2020-03-12 18:14 ` Sean Anderson
2020-03-12 18:29 ` Atish Patra
2020-03-12 18:49 ` Sean Anderson
2020-03-12 19:12 ` Atish Patra
2020-03-12 20:09 ` Sean Anderson
2020-03-13 6:03 ` Damien Le Moal
2020-03-13 5:40 ` Anup Patel
2020-03-13 5:25 ` Damien Le Moal
2020-03-13 5:47 ` Atish Patra
2020-03-12 5:25 [PATCH v2 0/9] Kendryte k210 SoC boards support Damien Le Moal
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.