[PATCH v9 15/21] riscv: Add option to support RISC-V privileged spec 1.9

2020-05-02 Thread Sean Anderson
Some older processors (notably the Kendryte K210) use an older version of
the RISC-V privileged specification. The primary changes between the old
and new are in virtual memory, and in the merging of three separate counter
enable CSRs.  Using the new CSR on an old processor causes an illegal
instruction exception.  This patch adds an option to use the old CSRs
instead of the new one.

Signed-off-by: Sean Anderson 
Reviewed-by: Bin Meng 
---

Changes in v6:
- Reformat so chechpatch errors less

Changes in v5:
- Rename to 1.9 to reflect the spec as implemented by the k210

Changes in v4:
- Fixed CSRs not being defined properly (thanks bmeng)
- Added ifdefs for all changed CSRs (e.g. for VM)
- Also properly disable VM on boot

Changes in v3:
- Renamed from "riscv: Add option to disable writes to mcounteren"
- Added original functionality back for older priv specs.

Changes in v2:
- Moved forward in the patch series

 arch/riscv/Kconfig   | 10 +
 arch/riscv/cpu/cpu.c |  9 
 arch/riscv/include/asm/csr.h | 40 
 3 files changed, 59 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 3061bf8863..cb1ca31b1b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -238,6 +238,16 @@ config XIP
 config SHOW_REGS
bool "Show registers on unhandled exception"
 
+config RISCV_PRIV_1_9
+   bool "Use version 1.9 of the RISC-V priviledged specification"
+   help
+ Older versions of the RISC-V priviledged specification had
+ separate counter enable CSRs for each privilege mode. Writing
+ to the unified mcounteren CSR on a processor implementing the
+ old specification will result in an illegal instruction
+ exception. In addition to counter CSR changes, the way virtual
+ memory is configured was also changed.
+
 config STACK_SIZE_SHIFT
int
default 14
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index f851374255..3c1836694a 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -89,11 +89,20 @@ int arch_cpu_init_dm(void)
 * Enable perf counters for cycle, time,
 * and instret counters only
 */
+#ifdef CONFIG_RISCV_PRIV_1_9
+   csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0));
+   csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0));
+#else
csr_write(CSR_MCOUNTEREN, GENMASK(2, 0));
+#endif
 
/* Disable paging */
if (supports_extension('s'))
+#ifdef CONFIG_RISCV_PRIV_1_9
+   csr_read_clear(CSR_MSTATUS, SR_VM);
+#else
csr_write(CSR_SATP, 0);
+#endif
}
 
 #ifdef CONFIG_SMP
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index d1520743a2..1a15089cae 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -15,7 +15,11 @@
 #define SR_SIE _AC(0x0002, UL) /* Supervisor Interrupt Enable */
 #define SR_SPIE_AC(0x0020, UL) /* Previous Supervisor IE */
 #define SR_SPP _AC(0x0100, UL) /* Previously Supervisor */
+#ifdef CONFIG_RISCV_PRIV_1_9
+#define SR_PUM _AC(0x0004, UL) /* Protect User Memory Access */
+#else
 #define SR_SUM _AC(0x0004, UL) /* Supervisor User Memory Access */
+#endif
 
 #define SR_FS  _AC(0x6000, UL) /* Floating-point Status */
 #define SR_FS_OFF  _AC(0x, UL)
@@ -29,6 +33,22 @@
 #define SR_XS_CLEAN_AC(0x0001, UL)
 #define SR_XS_DIRTY_AC(0x00018000, UL)
 
+#ifdef CONFIG_RISCV_PRIV_1_9
+#define SR_VM  _AC(0x1F00, UL) /* Virtualization Management */
+#define SR_VM_MODE_BARE_AC(0x, UL) /* No translation or 
protection */
+#define SR_VM_MODE_BB  _AC(0x0100, UL) /* Single base-and-bound */
+/* Separate instruction and data base-and-bound */
+#define SR_VM_MODE_BBID_AC(0x0200, UL)
+#ifndef CONFIG_64BIT
+#define SR_VM_MODE_32  _AC(0x0800, UL)
+#define SR_VM_MODE SR_VM_MODE_32
+#else
+#define SR_VM_MODE_39  _AC(0x0900, UL)
+#define SR_VM_MODE_48  _AC(0x0A00, UL)
+#define SR_VM_MODE SR_VM_MODE_39
+#endif
+#endif
+
 #ifndef CONFIG_64BIT
 #define SR_SD  _AC(0x8000, UL) /* FS/XS dirty */
 #else
@@ -36,6 +56,7 @@
 #endif
 
 /* SATP flags */
+#ifndef CONFIG_RISCV_PRIV_1_9
 #ifndef CONFIG_64BIT
 #define SATP_PPN   _AC(0x003F, UL)
 #define SATP_MODE_32   _AC(0x8000, UL)
@@ -45,6 +66,7 @@
 #define SATP_MODE_39   _AC(0x8000, UL)
 #define SATP_MODE  SATP_MODE_39
 #endif
+#endif
 
 /* SCAUSE */
 #define SCAUSE_IRQ_FLAG(_AC(1, UL) << (__riscv_xlen - 1))
@@ -88,17 +110,35 @@
 #define CSR_SCAUSE 0x142
 #define CSR_STVAL  0x143
 #define CSR_SIP0x144
+#ifdef CONFIG_RISCV_PRIV_1_9
+#define CSR_SPTBR  0x180
+#else
 #define CSR_SATP   0x180
+#endif
 #define CSR_MSTATUS 

[PATCH v9 15/21] riscv: Add option to support RISC-V privileged spec 1.9

2020-04-22 Thread Sean Anderson
Some older processors (notably the Kendryte K210) use an older version of
the RISC-V privileged specification. The primary changes between the old
and new are in virtual memory, and in the merging of three separate counter
enable CSRs.  Using the new CSR on an old processor causes an illegal
instruction exception.  This patch adds an option to use the old CSRs
instead of the new one.

Signed-off-by: Sean Anderson 
Reviewed-by: Bin Meng 
---

Changes in v6:
- Reformat so chechpatch errors less

Changes in v5:
- Rename to 1.9 to reflect the spec as implemented by the k210

Changes in v4:
- Fixed CSRs not being defined properly (thanks bmeng)
- Added ifdefs for all changed CSRs (e.g. for VM)
- Also properly disable VM on boot

Changes in v3:
- Renamed from "riscv: Add option to disable writes to mcounteren"
- Added original functionality back for older priv specs.

Changes in v2:
- Moved forward in the patch series

 arch/riscv/Kconfig   | 10 +
 arch/riscv/cpu/cpu.c |  9 
 arch/riscv/include/asm/csr.h | 40 
 3 files changed, 59 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 3061bf8863..cb1ca31b1b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -238,6 +238,16 @@ config XIP
 config SHOW_REGS
bool "Show registers on unhandled exception"
 
+config RISCV_PRIV_1_9
+   bool "Use version 1.9 of the RISC-V priviledged specification"
+   help
+ Older versions of the RISC-V priviledged specification had
+ separate counter enable CSRs for each privilege mode. Writing
+ to the unified mcounteren CSR on a processor implementing the
+ old specification will result in an illegal instruction
+ exception. In addition to counter CSR changes, the way virtual
+ memory is configured was also changed.
+
 config STACK_SIZE_SHIFT
int
default 14
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index f851374255..3c1836694a 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -89,11 +89,20 @@ int arch_cpu_init_dm(void)
 * Enable perf counters for cycle, time,
 * and instret counters only
 */
+#ifdef CONFIG_RISCV_PRIV_1_9
+   csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0));
+   csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0));
+#else
csr_write(CSR_MCOUNTEREN, GENMASK(2, 0));
+#endif
 
/* Disable paging */
if (supports_extension('s'))
+#ifdef CONFIG_RISCV_PRIV_1_9
+   csr_read_clear(CSR_MSTATUS, SR_VM);
+#else
csr_write(CSR_SATP, 0);
+#endif
}
 
 #ifdef CONFIG_SMP
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index d1520743a2..1a15089cae 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -15,7 +15,11 @@
 #define SR_SIE _AC(0x0002, UL) /* Supervisor Interrupt Enable */
 #define SR_SPIE_AC(0x0020, UL) /* Previous Supervisor IE */
 #define SR_SPP _AC(0x0100, UL) /* Previously Supervisor */
+#ifdef CONFIG_RISCV_PRIV_1_9
+#define SR_PUM _AC(0x0004, UL) /* Protect User Memory Access */
+#else
 #define SR_SUM _AC(0x0004, UL) /* Supervisor User Memory Access */
+#endif
 
 #define SR_FS  _AC(0x6000, UL) /* Floating-point Status */
 #define SR_FS_OFF  _AC(0x, UL)
@@ -29,6 +33,22 @@
 #define SR_XS_CLEAN_AC(0x0001, UL)
 #define SR_XS_DIRTY_AC(0x00018000, UL)
 
+#ifdef CONFIG_RISCV_PRIV_1_9
+#define SR_VM  _AC(0x1F00, UL) /* Virtualization Management */
+#define SR_VM_MODE_BARE_AC(0x, UL) /* No translation or 
protection */
+#define SR_VM_MODE_BB  _AC(0x0100, UL) /* Single base-and-bound */
+/* Separate instruction and data base-and-bound */
+#define SR_VM_MODE_BBID_AC(0x0200, UL)
+#ifndef CONFIG_64BIT
+#define SR_VM_MODE_32  _AC(0x0800, UL)
+#define SR_VM_MODE SR_VM_MODE_32
+#else
+#define SR_VM_MODE_39  _AC(0x0900, UL)
+#define SR_VM_MODE_48  _AC(0x0A00, UL)
+#define SR_VM_MODE SR_VM_MODE_39
+#endif
+#endif
+
 #ifndef CONFIG_64BIT
 #define SR_SD  _AC(0x8000, UL) /* FS/XS dirty */
 #else
@@ -36,6 +56,7 @@
 #endif
 
 /* SATP flags */
+#ifndef CONFIG_RISCV_PRIV_1_9
 #ifndef CONFIG_64BIT
 #define SATP_PPN   _AC(0x003F, UL)
 #define SATP_MODE_32   _AC(0x8000, UL)
@@ -45,6 +66,7 @@
 #define SATP_MODE_39   _AC(0x8000, UL)
 #define SATP_MODE  SATP_MODE_39
 #endif
+#endif
 
 /* SCAUSE */
 #define SCAUSE_IRQ_FLAG(_AC(1, UL) << (__riscv_xlen - 1))
@@ -88,17 +110,35 @@
 #define CSR_SCAUSE 0x142
 #define CSR_STVAL  0x143
 #define CSR_SIP0x144
+#ifdef CONFIG_RISCV_PRIV_1_9
+#define CSR_SPTBR  0x180
+#else
 #define CSR_SATP   0x180
+#endif
 #define CSR_MSTATUS