All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.