All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 00/14] RISCV basic exception handling implementation
@ 2023-01-20 14:59 Oleksii Kurochko
  2023-01-20 14:59 ` [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS Oleksii Kurochko
                   ` (13 more replies)
  0 siblings, 14 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis,
	Doug Goldstein

The patch series is based on another one [Basic early_printk and smoke
test implementation] which hasn't been commited yet.

The patch series provides a basic implementation of exception handling.
It can do only basic things such as decode a cause of an exception,
save/restore registers and execute "wfi" instruction if an exception
can not be handled.

To verify that exception handling works well it was implemented macros
from <asm/bug.h> such as BUG/WARN/run_in_exception/assert_failed.
The implementation of macros is used "ebreak" instruction and set up bug
frame tables for each type of macros.
Also it was implemented register save/restore to return and continue work
after WARN/run_in_exception.
Not all functionality of the macros was implemented as some of them
require hard-panic the system which is not available now. Instead of
hard-panic 'wfi' instruction is used but it should be definitely changed
in the neareset future.
It wasn't implemented show_execution_state() and stack trace discovering
as it's not necessary now.

Oleksii Kurochko (14):
  xen/riscv: add _zicsr to CFLAGS
  xen/riscv: add <asm/asm.h> header
  xen/riscv: add <asm/riscv_encoding.h header
  xen/riscv: add <asm/csr.h> header
  xen/riscv: add early_printk_hnum() function
  xen/riscv: introduce exception context
  xen/riscv: introduce exception handlers implementation
  xen/riscv: introduce decode_cause() stuff
  xen/riscv: introduce do_unexpected_trap()
  xen/riscv: mask all interrupts
  xen/riscv: introduce setup_trap_handler()
  xen/riscv: introduce an implementation of macros from <asm/bug.h>
  xen/riscv: test basic handling stuff
  automation: add smoke test to verify macros from bug.h

 automation/scripts/qemu-smoke-riscv64.sh    |   2 +
 xen/arch/riscv/Makefile                     |   2 +
 xen/arch/riscv/arch.mk                      |   2 +-
 xen/arch/riscv/early_printk.c               |  39 +
 xen/arch/riscv/entry.S                      |  97 ++
 xen/arch/riscv/include/asm/asm.h            |  54 ++
 xen/arch/riscv/include/asm/bug.h            | 120 +++
 xen/arch/riscv/include/asm/csr.h            |  82 ++
 xen/arch/riscv/include/asm/early_printk.h   |   2 +
 xen/arch/riscv/include/asm/processor.h      | 114 +++
 xen/arch/riscv/include/asm/riscv_encoding.h | 945 ++++++++++++++++++++
 xen/arch/riscv/include/asm/traps.h          |  13 +
 xen/arch/riscv/riscv64/head.S               |   5 +
 xen/arch/riscv/setup.c                      |  27 +
 xen/arch/riscv/traps.c                      | 229 +++++
 xen/arch/riscv/xen.lds.S                    |  10 +
 16 files changed, 1742 insertions(+), 1 deletion(-)
 create mode 100644 xen/arch/riscv/entry.S
 create mode 100644 xen/arch/riscv/include/asm/asm.h
 create mode 100644 xen/arch/riscv/include/asm/bug.h
 create mode 100644 xen/arch/riscv/include/asm/csr.h
 create mode 100644 xen/arch/riscv/include/asm/processor.h
 create mode 100644 xen/arch/riscv/include/asm/riscv_encoding.h
 create mode 100644 xen/arch/riscv/include/asm/traps.h
 create mode 100644 xen/arch/riscv/traps.c

-- 
2.39.0



^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-20 15:29   ` Andrew Cooper
  2023-01-20 14:59 ` [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header Oleksii Kurochko
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Work with some registers requires csr command which is part of
Zicsr.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/arch.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/riscv/arch.mk b/xen/arch/riscv/arch.mk
index 012dc677c3..95b41d9f3e 100644
--- a/xen/arch/riscv/arch.mk
+++ b/xen/arch/riscv/arch.mk
@@ -10,7 +10,7 @@ riscv-march-$(CONFIG_RISCV_ISA_C)       := $(riscv-march-y)c
 # into the upper half _or_ the lower half of the address space.
 # -mcmodel=medlow would force Xen into the lower half.
 
-CFLAGS += -march=$(riscv-march-y) -mstrict-align -mcmodel=medany
+CFLAGS += -march=$(riscv-march-y)_zicsr -mstrict-align -mcmodel=medany
 
 # TODO: Drop override when more of the build is working
 override ALL_OBJS-y = arch/$(TARGET_ARCH)/built_in.o
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
  2023-01-20 14:59 ` [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-20 15:31   ` Andrew Cooper
  2023-01-22 22:58   ` Alistair Francis
  2023-01-20 14:59 ` [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header Oleksii Kurochko
                   ` (11 subsequent siblings)
  13 siblings, 2 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/include/asm/asm.h | 54 ++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/asm.h

diff --git a/xen/arch/riscv/include/asm/asm.h b/xen/arch/riscv/include/asm/asm.h
new file mode 100644
index 0000000000..6d426ecea7
--- /dev/null
+++ b/xen/arch/riscv/include/asm/asm.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: (GPL-2.0-only) */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_ASM_H
+#define _ASM_RISCV_ASM_H
+
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x)	x
+#else
+#define __ASM_STR(x)	#x
+#endif
+
+#if __riscv_xlen == 64
+#define __REG_SEL(a, b)	__ASM_STR(a)
+#elif __riscv_xlen == 32
+#define __REG_SEL(a, b)	__ASM_STR(b)
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+#define REG_L		__REG_SEL(ld, lw)
+#define REG_S		__REG_SEL(sd, sw)
+
+#if __SIZEOF_POINTER__ == 8
+#ifdef __ASSEMBLY__
+#define RISCV_PTR		.dword
+#else
+#define RISCV_PTR		".dword"
+#endif
+#elif __SIZEOF_POINTER__ == 4
+#ifdef __ASSEMBLY__
+#define RISCV_PTR		.word
+#else
+#define RISCV_PTR		".word"
+#endif
+#else
+#error "Unexpected __SIZEOF_POINTER__"
+#endif
+
+#if (__SIZEOF_INT__ == 4)
+#define RISCV_INT		__ASM_STR(.word)
+#else
+#error "Unexpected __SIZEOF_INT__"
+#endif
+
+#if (__SIZEOF_SHORT__ == 2)
+#define RISCV_SHORT		__ASM_STR(.half)
+#else
+#error "Unexpected __SIZEOF_SHORT__"
+#endif
+
+#endif /* _ASM_RISCV_ASM_H */
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
  2023-01-20 14:59 ` [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS Oleksii Kurochko
  2023-01-20 14:59 ` [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-22 23:24   ` Alistair Francis
  2023-01-23 13:52   ` Jan Beulich
  2023-01-20 14:59 ` [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header Oleksii Kurochko
                   ` (10 subsequent siblings)
  13 siblings, 2 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/include/asm/riscv_encoding.h | 945 ++++++++++++++++++++
 1 file changed, 945 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/riscv_encoding.h

diff --git a/xen/arch/riscv/include/asm/riscv_encoding.h b/xen/arch/riscv/include/asm/riscv_encoding.h
new file mode 100644
index 0000000000..8a43d49f7a
--- /dev/null
+++ b/xen/arch/riscv/include/asm/riscv_encoding.h
@@ -0,0 +1,945 @@
+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ *   Anup Patel <anup.patel@wdc.com>
+ * 
+ * The source has been largely adapted from OpenSBI:
+ * include/sbi/riscv_encodnig.h
+ * 
+ */
+
+#ifndef __RISCV_ENCODING_H__
+#define __RISCV_ENCODING_H__
+
+#define _UL(X) _AC(X, UL)
+#define _ULL(X) _AC(X, ULL)
+
+/* clang-format off */
+#define MSTATUS_SIE			_UL(0x00000002)
+#define MSTATUS_MIE			_UL(0x00000008)
+#define MSTATUS_SPIE_SHIFT		5
+#define MSTATUS_SPIE			(_UL(1) << MSTATUS_SPIE_SHIFT)
+#define MSTATUS_UBE			_UL(0x00000040)
+#define MSTATUS_MPIE			_UL(0x00000080)
+#define MSTATUS_SPP_SHIFT		8
+#define MSTATUS_SPP			(_UL(1) << MSTATUS_SPP_SHIFT)
+#define MSTATUS_MPP_SHIFT		11
+#define MSTATUS_MPP			(_UL(3) << MSTATUS_MPP_SHIFT)
+#define MSTATUS_FS			_UL(0x00006000)
+#define MSTATUS_FS_OFF			_UL(0x00000000)
+#define MSTATUS_FS_INITIAL		_UL(0x00002000)
+#define MSTATUS_FS_CLEAN		_UL(0x00004000)
+#define MSTATUS_FS_DIRTY		_UL(0x00006000)
+#define MSTATUS_XS			_UL(0x00018000)
+#define MSTATUS_XS_OFF			_UL(0x00000000)
+#define MSTATUS_XS_INITIAL		_UL(0x00008000)
+#define MSTATUS_XS_CLEAN		_UL(0x00010000)
+#define MSTATUS_XS_DIRTY		_UL(0x00018000)
+#define MSTATUS_VS			_UL(0x01800000)
+#define MSTATUS_VS_OFF			_UL(0x00000000)
+#define MSTATUS_VS_INITIAL		_UL(0x00800000)
+#define MSTATUS_VS_CLEAN		_UL(0x01000000)
+#define MSTATUS_VS_DIRTY		_UL(0x01800000)
+#define MSTATUS_MPRV			_UL(0x00020000)
+#define MSTATUS_SUM			_UL(0x00040000)
+#define MSTATUS_MXR			_UL(0x00080000)
+#define MSTATUS_TVM			_UL(0x00100000)
+#define MSTATUS_TW			_UL(0x00200000)
+#define MSTATUS_TSR			_UL(0x00400000)
+#define MSTATUS32_SD			_UL(0x80000000)
+#if __riscv_xlen == 64
+#define MSTATUS_UXL			_ULL(0x0000000300000000)
+#define MSTATUS_SXL			_ULL(0x0000000C00000000)
+#define MSTATUS_SBE			_ULL(0x0000001000000000)
+#define MSTATUS_MBE			_ULL(0x0000002000000000)
+#define MSTATUS_MPV			_ULL(0x0000008000000000)
+#else
+#define MSTATUSH_SBE			_UL(0x00000010)
+#define MSTATUSH_MBE			_UL(0x00000020)
+#define MSTATUSH_MPV			_UL(0x00000080)
+#endif
+#define MSTATUS32_SD			_UL(0x80000000)
+#define MSTATUS64_SD			_ULL(0x8000000000000000)
+
+#define SSTATUS_SIE			MSTATUS_SIE
+#define SSTATUS_SPIE_SHIFT		MSTATUS_SPIE_SHIFT
+#define SSTATUS_SPIE			MSTATUS_SPIE
+#define SSTATUS_SPP_SHIFT		MSTATUS_SPP_SHIFT
+#define SSTATUS_SPP			MSTATUS_SPP
+#define SSTATUS_FS			MSTATUS_FS
+#define SSTATUS_FS_OFF			MSTATUS_FS_OFF
+#define SSTATUS_FS_INITIAL		MSTATUS_FS_INITIAL
+#define SSTATUS_FS_CLEAN		MSTATUS_FS_CLEAN
+#define SSTATUS_FS_DIRTY		MSTATUS_FS_DIRTY
+#define SSTATUS_XS			MSTATUS_XS
+#define SSTATUS_XS_OFF			MSTATUS_XS_OFF
+#define SSTATUS_XS_INITIAL		MSTATUS_XS_INITIAL
+#define SSTATUS_XS_CLEAN		MSTATUS_XS_CLEAN
+#define SSTATUS_XS_DIRTY		MSTATUS_XS_DIRTY
+#define SSTATUS_VS			MSTATUS_VS
+#define SSTATUS_VS_OFF			MSTATUS_VS_OFF
+#define SSTATUS_VS_INITIAL		MSTATUS_VS_INITIAL
+#define SSTATUS_VS_CLEAN		MSTATUS_VS_CLEAN
+#define SSTATUS_VS_DIRTY		MSTATUS_VS_DIRTY
+#define SSTATUS_SUM			MSTATUS_SUM
+#define SSTATUS_MXR			MSTATUS_MXR
+#define SSTATUS32_SD			MSTATUS32_SD
+#define SSTATUS64_UXL			MSTATUS_UXL
+#define SSTATUS64_SD			MSTATUS64_SD
+
+#if __riscv_xlen == 64
+#define HSTATUS_VSXL			_UL(0x300000000)
+#define HSTATUS_VSXL_SHIFT		32
+#endif
+#define HSTATUS_VTSR			_UL(0x00400000)
+#define HSTATUS_VTW			_UL(0x00200000)
+#define HSTATUS_VTVM			_UL(0x00100000)
+#define HSTATUS_VGEIN			_UL(0x0003f000)
+#define HSTATUS_VGEIN_SHIFT		12
+#define HSTATUS_HU			_UL(0x00000200)
+#define HSTATUS_SPVP			_UL(0x00000100)
+#define HSTATUS_SPV			_UL(0x00000080)
+#define HSTATUS_GVA			_UL(0x00000040)
+#define HSTATUS_VSBE			_UL(0x00000020)
+
+#define IRQ_S_SOFT			1
+#define IRQ_VS_SOFT			2
+#define IRQ_M_SOFT			3
+#define IRQ_S_TIMER			5
+#define IRQ_VS_TIMER			6
+#define IRQ_M_TIMER			7
+#define IRQ_S_EXT			9
+#define IRQ_VS_EXT			10
+#define IRQ_M_EXT			11
+#define IRQ_S_GEXT			12
+#define IRQ_PMU_OVF			13
+
+#define MIP_SSIP			(_UL(1) << IRQ_S_SOFT)
+#define MIP_VSSIP			(_UL(1) << IRQ_VS_SOFT)
+#define MIP_MSIP			(_UL(1) << IRQ_M_SOFT)
+#define MIP_STIP			(_UL(1) << IRQ_S_TIMER)
+#define MIP_VSTIP			(_UL(1) << IRQ_VS_TIMER)
+#define MIP_MTIP			(_UL(1) << IRQ_M_TIMER)
+#define MIP_SEIP			(_UL(1) << IRQ_S_EXT)
+#define MIP_VSEIP			(_UL(1) << IRQ_VS_EXT)
+#define MIP_MEIP			(_UL(1) << IRQ_M_EXT)
+#define MIP_SGEIP			(_UL(1) << IRQ_S_GEXT)
+#define MIP_LCOFIP			(_UL(1) << IRQ_PMU_OVF)
+
+#define SIP_SSIP			MIP_SSIP
+#define SIP_STIP			MIP_STIP
+
+#define PRV_U				_UL(0)
+#define PRV_S				_UL(1)
+#define PRV_M				_UL(3)
+
+#define SATP32_MODE			_UL(0x80000000)
+#define SATP32_MODE_SHIFT		31
+#define SATP32_ASID			_UL(0x7FC00000)
+#define SATP32_ASID_SHIFT		22
+#define SATP32_PPN			_UL(0x003FFFFF)
+#define SATP64_MODE			_ULL(0xF000000000000000)
+#define SATP64_MODE_SHIFT		60
+#define SATP64_ASID			_ULL(0x0FFFF00000000000)
+#define SATP64_ASID_SHIFT		44
+#define SATP64_PPN			_ULL(0x00000FFFFFFFFFFF)
+
+#define SATP_MODE_OFF			_UL(0)
+#define SATP_MODE_SV32			_UL(1)
+#define SATP_MODE_SV39			_UL(8)
+#define SATP_MODE_SV48			_UL(9)
+#define SATP_MODE_SV57			_UL(10)
+#define SATP_MODE_SV64			_UL(11)
+
+#define HGATP_MODE_OFF			_UL(0)
+#define HGATP_MODE_SV32X4		_UL(1)
+#define HGATP_MODE_SV39X4		_UL(8)
+#define HGATP_MODE_SV48X4		_UL(9)
+
+#define HGATP32_MODE_SHIFT		31
+#define HGATP32_VMID_SHIFT		22
+#define HGATP32_VMID_MASK		_UL(0x1FC00000)
+#define HGATP32_PPN			_UL(0x003FFFFF)
+
+#define HGATP64_MODE_SHIFT		60
+#define HGATP64_VMID_SHIFT		44
+#define HGATP64_VMID_MASK		_ULL(0x03FFF00000000000)
+#define HGATP64_PPN			_ULL(0x00000FFFFFFFFFFF)
+
+#define PMP_R				_UL(0x01)
+#define PMP_W				_UL(0x02)
+#define PMP_X				_UL(0x04)
+#define PMP_A				_UL(0x18)
+#define PMP_A_TOR			_UL(0x08)
+#define PMP_A_NA4			_UL(0x10)
+#define PMP_A_NAPOT			_UL(0x18)
+#define PMP_L				_UL(0x80)
+
+#define PMP_SHIFT			2
+#define PMP_COUNT			64
+#if __riscv_xlen == 64
+#define PMP_ADDR_MASK			((_ULL(0x1) << 54) - 1)
+#else
+#define PMP_ADDR_MASK			_UL(0xFFFFFFFF)
+#endif
+
+#if __riscv_xlen == 64
+#define MSTATUS_SD			MSTATUS64_SD
+#define SSTATUS_SD			SSTATUS64_SD
+#define SATP_MODE			SATP64_MODE
+#define SATP_MODE_SHIFT			SATP64_MODE_SHIFT
+
+#define HGATP_PPN			HGATP64_PPN
+#define HGATP_VMID_SHIFT		HGATP64_VMID_SHIFT
+#define HGATP_VMID_MASK			HGATP64_VMID_MASK
+#define HGATP_MODE_SHIFT		HGATP64_MODE_SHIFT
+#else
+#define MSTATUS_SD			MSTATUS32_SD
+#define SSTATUS_SD			SSTATUS32_SD
+#define SATP_MODE			SATP32_MODE
+#define SATP_MODE_SHIFT			SATP32_MODE_SHIFT
+
+#define HGATP_PPN			HGATP32_PPN
+#define HGATP_VMID_SHIFT		HGATP32_VMID_SHIFT
+#define HGATP_VMID_MASK			HGATP32_VMID_MASK
+#define HGATP_MODE_SHIFT		HGATP32_MODE_SHIFT
+#endif
+
+#define TOPI_IID_SHIFT			16
+#define TOPI_IID_MASK			0xfff
+#define TOPI_IPRIO_MASK		0xff
+
+#if __riscv_xlen == 64
+#define MHPMEVENT_OF			(_UL(1) << 63)
+#define MHPMEVENT_MINH			(_UL(1) << 62)
+#define MHPMEVENT_SINH			(_UL(1) << 61)
+#define MHPMEVENT_UINH			(_UL(1) << 60)
+#define MHPMEVENT_VSINH			(_UL(1) << 59)
+#define MHPMEVENT_VUINH			(_UL(1) << 58)
+#else
+#define MHPMEVENTH_OF			(_ULL(1) << 31)
+#define MHPMEVENTH_MINH			(_ULL(1) << 30)
+#define MHPMEVENTH_SINH			(_ULL(1) << 29)
+#define MHPMEVENTH_UINH			(_ULL(1) << 28)
+#define MHPMEVENTH_VSINH		(_ULL(1) << 27)
+#define MHPMEVENTH_VUINH		(_ULL(1) << 26)
+
+#define MHPMEVENT_OF			(MHPMEVENTH_OF << 32)
+#define MHPMEVENT_MINH			(MHPMEVENTH_MINH << 32)
+#define MHPMEVENT_SINH			(MHPMEVENTH_SINH << 32)
+#define MHPMEVENT_UINH			(MHPMEVENTH_UINH << 32)
+#define MHPMEVENT_VSINH			(MHPMEVENTH_VSINH << 32)
+#define MHPMEVENT_VUINH			(MHPMEVENTH_VUINH << 32)
+
+#endif
+
+#define MHPMEVENT_SSCOF_MASK		_ULL(0xFFFF000000000000)
+
+#if __riscv_xlen > 32
+#define ENVCFG_STCE			(_ULL(1) << 63)
+#define ENVCFG_PBMTE			(_ULL(1) << 62)
+#else
+#define ENVCFGH_STCE			(_UL(1) << 31)
+#define ENVCFGH_PBMTE			(_UL(1) << 30)
+#endif
+#define ENVCFG_CBZE			(_UL(1) << 7)
+#define ENVCFG_CBCFE			(_UL(1) << 6)
+#define ENVCFG_CBIE_SHIFT		4
+#define ENVCFG_CBIE			(_UL(0x3) << ENVCFG_CBIE_SHIFT)
+#define ENVCFG_CBIE_ILL			_UL(0x0)
+#define ENVCFG_CBIE_FLUSH		_UL(0x1)
+#define ENVCFG_CBIE_INV			_UL(0x3)
+#define ENVCFG_FIOM			_UL(0x1)
+
+/* ===== User-level CSRs ===== */
+
+/* User Trap Setup (N-extension) */
+#define CSR_USTATUS			0x000
+#define CSR_UIE				0x004
+#define CSR_UTVEC			0x005
+
+/* User Trap Handling (N-extension) */
+#define CSR_USCRATCH			0x040
+#define CSR_UEPC			0x041
+#define CSR_UCAUSE			0x042
+#define CSR_UTVAL			0x043
+#define CSR_UIP				0x044
+
+/* User Floating-point CSRs */
+#define CSR_FFLAGS			0x001
+#define CSR_FRM				0x002
+#define CSR_FCSR			0x003
+
+/* User Counters/Timers */
+#define CSR_CYCLE			0xc00
+#define CSR_TIME			0xc01
+#define CSR_INSTRET			0xc02
+#define CSR_HPMCOUNTER3			0xc03
+#define CSR_HPMCOUNTER4			0xc04
+#define CSR_HPMCOUNTER5			0xc05
+#define CSR_HPMCOUNTER6			0xc06
+#define CSR_HPMCOUNTER7			0xc07
+#define CSR_HPMCOUNTER8			0xc08
+#define CSR_HPMCOUNTER9			0xc09
+#define CSR_HPMCOUNTER10		0xc0a
+#define CSR_HPMCOUNTER11		0xc0b
+#define CSR_HPMCOUNTER12		0xc0c
+#define CSR_HPMCOUNTER13		0xc0d
+#define CSR_HPMCOUNTER14		0xc0e
+#define CSR_HPMCOUNTER15		0xc0f
+#define CSR_HPMCOUNTER16		0xc10
+#define CSR_HPMCOUNTER17		0xc11
+#define CSR_HPMCOUNTER18		0xc12
+#define CSR_HPMCOUNTER19		0xc13
+#define CSR_HPMCOUNTER20		0xc14
+#define CSR_HPMCOUNTER21		0xc15
+#define CSR_HPMCOUNTER22		0xc16
+#define CSR_HPMCOUNTER23		0xc17
+#define CSR_HPMCOUNTER24		0xc18
+#define CSR_HPMCOUNTER25		0xc19
+#define CSR_HPMCOUNTER26		0xc1a
+#define CSR_HPMCOUNTER27		0xc1b
+#define CSR_HPMCOUNTER28		0xc1c
+#define CSR_HPMCOUNTER29		0xc1d
+#define CSR_HPMCOUNTER30		0xc1e
+#define CSR_HPMCOUNTER31		0xc1f
+#define CSR_CYCLEH			0xc80
+#define CSR_TIMEH			0xc81
+#define CSR_INSTRETH			0xc82
+#define CSR_HPMCOUNTER3H		0xc83
+#define CSR_HPMCOUNTER4H		0xc84
+#define CSR_HPMCOUNTER5H		0xc85
+#define CSR_HPMCOUNTER6H		0xc86
+#define CSR_HPMCOUNTER7H		0xc87
+#define CSR_HPMCOUNTER8H		0xc88
+#define CSR_HPMCOUNTER9H		0xc89
+#define CSR_HPMCOUNTER10H		0xc8a
+#define CSR_HPMCOUNTER11H		0xc8b
+#define CSR_HPMCOUNTER12H		0xc8c
+#define CSR_HPMCOUNTER13H		0xc8d
+#define CSR_HPMCOUNTER14H		0xc8e
+#define CSR_HPMCOUNTER15H		0xc8f
+#define CSR_HPMCOUNTER16H		0xc90
+#define CSR_HPMCOUNTER17H		0xc91
+#define CSR_HPMCOUNTER18H		0xc92
+#define CSR_HPMCOUNTER19H		0xc93
+#define CSR_HPMCOUNTER20H		0xc94
+#define CSR_HPMCOUNTER21H		0xc95
+#define CSR_HPMCOUNTER22H		0xc96
+#define CSR_HPMCOUNTER23H		0xc97
+#define CSR_HPMCOUNTER24H		0xc98
+#define CSR_HPMCOUNTER25H		0xc99
+#define CSR_HPMCOUNTER26H		0xc9a
+#define CSR_HPMCOUNTER27H		0xc9b
+#define CSR_HPMCOUNTER28H		0xc9c
+#define CSR_HPMCOUNTER29H		0xc9d
+#define CSR_HPMCOUNTER30H		0xc9e
+#define CSR_HPMCOUNTER31H		0xc9f
+
+/* ===== Supervisor-level CSRs ===== */
+
+/* Supervisor Trap Setup */
+#define CSR_SSTATUS			0x100
+#define CSR_SEDELEG			0x102
+#define CSR_SIDELEG			0x103
+#define CSR_SIE				0x104
+#define CSR_STVEC			0x105
+#define CSR_SCOUNTEREN			0x106
+
+/* Supervisor Configuration */
+#define CSR_SENVCFG			0x10a
+
+/* Supervisor Trap Handling */
+#define CSR_SSCRATCH			0x140
+#define CSR_SEPC			0x141
+#define CSR_SCAUSE			0x142
+#define CSR_STVAL			0x143
+#define CSR_SIP				0x144
+
+/* Supervisor Protection and Translation */
+#define CSR_SATP			0x180
+
+/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
+#define CSR_SISELECT			0x150
+#define CSR_SIREG			0x151
+
+/* Supervisor-Level Interrupts (AIA) */
+#define CSR_STOPI			0xdb0
+
+/* Supervisor-Level IMSIC Interface (AIA) */
+#define CSR_SSETEIPNUM			0x158
+#define CSR_SCLREIPNUM			0x159
+#define CSR_SSETEIENUM			0x15a
+#define CSR_SCLREIENUM			0x15b
+#define CSR_STOPEI			0x15c
+
+/* Supervisor-Level High-Half CSRs (AIA) */
+#define CSR_SIEH			0x114
+#define CSR_SIPH			0x154
+
+/* Supervisor stateen CSRs */
+#define CSR_SSTATEEN0			0x10C
+#define CSR_SSTATEEN1			0x10D
+#define CSR_SSTATEEN2			0x10E
+#define CSR_SSTATEEN3			0x10F
+
+/* ===== Hypervisor-level CSRs ===== */
+
+/* Hypervisor Trap Setup (H-extension) */
+#define CSR_HSTATUS			0x600
+#define CSR_HEDELEG			0x602
+#define CSR_HIDELEG			0x603
+#define CSR_HIE				0x604
+#define CSR_HCOUNTEREN			0x606
+#define CSR_HGEIE			0x607
+
+/* Hypervisor Configuration */
+#define CSR_HENVCFG			0x60a
+#define CSR_HENVCFGH			0x61a
+
+/* Hypervisor Trap Handling (H-extension) */
+#define CSR_HTVAL			0x643
+#define CSR_HIP				0x644
+#define CSR_HVIP			0x645
+#define CSR_HTINST			0x64a
+#define CSR_HGEIP			0xe12
+
+/* Hypervisor Protection and Translation (H-extension) */
+#define CSR_HGATP			0x680
+
+/* Hypervisor Counter/Timer Virtualization Registers (H-extension) */
+#define CSR_HTIMEDELTA			0x605
+#define CSR_HTIMEDELTAH			0x615
+
+/* Virtual Supervisor Registers (H-extension) */
+#define CSR_VSSTATUS			0x200
+#define CSR_VSIE			0x204
+#define CSR_VSTVEC			0x205
+#define CSR_VSSCRATCH			0x240
+#define CSR_VSEPC			0x241
+#define CSR_VSCAUSE			0x242
+#define CSR_VSTVAL			0x243
+#define CSR_VSIP			0x244
+#define CSR_VSATP			0x280
+
+/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
+#define CSR_HVIEN			0x608
+#define CSR_HVICTL			0x609
+#define CSR_HVIPRIO1			0x646
+#define CSR_HVIPRIO2			0x647
+
+/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
+#define CSR_VSISELECT			0x250
+#define CSR_VSIREG			0x251
+
+/* VS-Level Interrupts (H-extension with AIA) */
+#define CSR_VSTOPI			0xeb0
+
+/* VS-Level IMSIC Interface (H-extension with AIA) */
+#define CSR_VSSETEIPNUM		0x258
+#define CSR_VSCLREIPNUM		0x259
+#define CSR_VSSETEIENUM		0x25a
+#define CSR_VSCLREIENUM		0x25b
+#define CSR_VSTOPEI			0x25c
+
+/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
+#define CSR_HIDELEGH			0x613
+#define CSR_HVIENH			0x618
+#define CSR_HVIPH			0x655
+#define CSR_HVIPRIO1H			0x656
+#define CSR_HVIPRIO2H			0x657
+#define CSR_VSIEH			0x214
+#define CSR_VSIPH			0x254
+
+/* Hypervisor stateen CSRs */
+#define CSR_HSTATEEN0			0x60C
+#define CSR_HSTATEEN0H			0x61C
+#define CSR_HSTATEEN1			0x60D
+#define CSR_HSTATEEN1H			0x61D
+#define CSR_HSTATEEN2			0x60E
+#define CSR_HSTATEEN2H			0x61E
+#define CSR_HSTATEEN3			0x60F
+#define CSR_HSTATEEN3H			0x61F
+
+/* ===== Machine-level CSRs ===== */
+
+/* Machine Information Registers */
+#define CSR_MVENDORID			0xf11
+#define CSR_MARCHID			0xf12
+#define CSR_MIMPID			0xf13
+#define CSR_MHARTID			0xf14
+
+/* Machine Trap Setup */
+#define CSR_MSTATUS			0x300
+#define CSR_MISA			0x301
+#define CSR_MEDELEG			0x302
+#define CSR_MIDELEG			0x303
+#define CSR_MIE				0x304
+#define CSR_MTVEC			0x305
+#define CSR_MCOUNTEREN			0x306
+#define CSR_MSTATUSH			0x310
+
+/* Machine Configuration */
+#define CSR_MENVCFG			0x30a
+#define CSR_MENVCFGH			0x31a
+
+/* Machine Trap Handling */
+#define CSR_MSCRATCH			0x340
+#define CSR_MEPC			0x341
+#define CSR_MCAUSE			0x342
+#define CSR_MTVAL			0x343
+#define CSR_MIP				0x344
+#define CSR_MTINST			0x34a
+#define CSR_MTVAL2			0x34b
+
+/* Machine Memory Protection */
+#define CSR_PMPCFG0			0x3a0
+#define CSR_PMPCFG1			0x3a1
+#define CSR_PMPCFG2			0x3a2
+#define CSR_PMPCFG3			0x3a3
+#define CSR_PMPCFG4			0x3a4
+#define CSR_PMPCFG5			0x3a5
+#define CSR_PMPCFG6			0x3a6
+#define CSR_PMPCFG7			0x3a7
+#define CSR_PMPCFG8			0x3a8
+#define CSR_PMPCFG9			0x3a9
+#define CSR_PMPCFG10			0x3aa
+#define CSR_PMPCFG11			0x3ab
+#define CSR_PMPCFG12			0x3ac
+#define CSR_PMPCFG13			0x3ad
+#define CSR_PMPCFG14			0x3ae
+#define CSR_PMPCFG15			0x3af
+#define CSR_PMPADDR0			0x3b0
+#define CSR_PMPADDR1			0x3b1
+#define CSR_PMPADDR2			0x3b2
+#define CSR_PMPADDR3			0x3b3
+#define CSR_PMPADDR4			0x3b4
+#define CSR_PMPADDR5			0x3b5
+#define CSR_PMPADDR6			0x3b6
+#define CSR_PMPADDR7			0x3b7
+#define CSR_PMPADDR8			0x3b8
+#define CSR_PMPADDR9			0x3b9
+#define CSR_PMPADDR10			0x3ba
+#define CSR_PMPADDR11			0x3bb
+#define CSR_PMPADDR12			0x3bc
+#define CSR_PMPADDR13			0x3bd
+#define CSR_PMPADDR14			0x3be
+#define CSR_PMPADDR15			0x3bf
+#define CSR_PMPADDR16			0x3c0
+#define CSR_PMPADDR17			0x3c1
+#define CSR_PMPADDR18			0x3c2
+#define CSR_PMPADDR19			0x3c3
+#define CSR_PMPADDR20			0x3c4
+#define CSR_PMPADDR21			0x3c5
+#define CSR_PMPADDR22			0x3c6
+#define CSR_PMPADDR23			0x3c7
+#define CSR_PMPADDR24			0x3c8
+#define CSR_PMPADDR25			0x3c9
+#define CSR_PMPADDR26			0x3ca
+#define CSR_PMPADDR27			0x3cb
+#define CSR_PMPADDR28			0x3cc
+#define CSR_PMPADDR29			0x3cd
+#define CSR_PMPADDR30			0x3ce
+#define CSR_PMPADDR31			0x3cf
+#define CSR_PMPADDR32			0x3d0
+#define CSR_PMPADDR33			0x3d1
+#define CSR_PMPADDR34			0x3d2
+#define CSR_PMPADDR35			0x3d3
+#define CSR_PMPADDR36			0x3d4
+#define CSR_PMPADDR37			0x3d5
+#define CSR_PMPADDR38			0x3d6
+#define CSR_PMPADDR39			0x3d7
+#define CSR_PMPADDR40			0x3d8
+#define CSR_PMPADDR41			0x3d9
+#define CSR_PMPADDR42			0x3da
+#define CSR_PMPADDR43			0x3db
+#define CSR_PMPADDR44			0x3dc
+#define CSR_PMPADDR45			0x3dd
+#define CSR_PMPADDR46			0x3de
+#define CSR_PMPADDR47			0x3df
+#define CSR_PMPADDR48			0x3e0
+#define CSR_PMPADDR49			0x3e1
+#define CSR_PMPADDR50			0x3e2
+#define CSR_PMPADDR51			0x3e3
+#define CSR_PMPADDR52			0x3e4
+#define CSR_PMPADDR53			0x3e5
+#define CSR_PMPADDR54			0x3e6
+#define CSR_PMPADDR55			0x3e7
+#define CSR_PMPADDR56			0x3e8
+#define CSR_PMPADDR57			0x3e9
+#define CSR_PMPADDR58			0x3ea
+#define CSR_PMPADDR59			0x3eb
+#define CSR_PMPADDR60			0x3ec
+#define CSR_PMPADDR61			0x3ed
+#define CSR_PMPADDR62			0x3ee
+#define CSR_PMPADDR63			0x3ef
+
+/* Machine Counters/Timers */
+#define CSR_MCYCLE			0xb00
+#define CSR_MINSTRET			0xb02
+#define CSR_MHPMCOUNTER3		0xb03
+#define CSR_MHPMCOUNTER4		0xb04
+#define CSR_MHPMCOUNTER5		0xb05
+#define CSR_MHPMCOUNTER6		0xb06
+#define CSR_MHPMCOUNTER7		0xb07
+#define CSR_MHPMCOUNTER8		0xb08
+#define CSR_MHPMCOUNTER9		0xb09
+#define CSR_MHPMCOUNTER10		0xb0a
+#define CSR_MHPMCOUNTER11		0xb0b
+#define CSR_MHPMCOUNTER12		0xb0c
+#define CSR_MHPMCOUNTER13		0xb0d
+#define CSR_MHPMCOUNTER14		0xb0e
+#define CSR_MHPMCOUNTER15		0xb0f
+#define CSR_MHPMCOUNTER16		0xb10
+#define CSR_MHPMCOUNTER17		0xb11
+#define CSR_MHPMCOUNTER18		0xb12
+#define CSR_MHPMCOUNTER19		0xb13
+#define CSR_MHPMCOUNTER20		0xb14
+#define CSR_MHPMCOUNTER21		0xb15
+#define CSR_MHPMCOUNTER22		0xb16
+#define CSR_MHPMCOUNTER23		0xb17
+#define CSR_MHPMCOUNTER24		0xb18
+#define CSR_MHPMCOUNTER25		0xb19
+#define CSR_MHPMCOUNTER26		0xb1a
+#define CSR_MHPMCOUNTER27		0xb1b
+#define CSR_MHPMCOUNTER28		0xb1c
+#define CSR_MHPMCOUNTER29		0xb1d
+#define CSR_MHPMCOUNTER30		0xb1e
+#define CSR_MHPMCOUNTER31		0xb1f
+#define CSR_MCYCLEH			0xb80
+#define CSR_MINSTRETH			0xb82
+#define CSR_MHPMCOUNTER3H		0xb83
+#define CSR_MHPMCOUNTER4H		0xb84
+#define CSR_MHPMCOUNTER5H		0xb85
+#define CSR_MHPMCOUNTER6H		0xb86
+#define CSR_MHPMCOUNTER7H		0xb87
+#define CSR_MHPMCOUNTER8H		0xb88
+#define CSR_MHPMCOUNTER9H		0xb89
+#define CSR_MHPMCOUNTER10H		0xb8a
+#define CSR_MHPMCOUNTER11H		0xb8b
+#define CSR_MHPMCOUNTER12H		0xb8c
+#define CSR_MHPMCOUNTER13H		0xb8d
+#define CSR_MHPMCOUNTER14H		0xb8e
+#define CSR_MHPMCOUNTER15H		0xb8f
+#define CSR_MHPMCOUNTER16H		0xb90
+#define CSR_MHPMCOUNTER17H		0xb91
+#define CSR_MHPMCOUNTER18H		0xb92
+#define CSR_MHPMCOUNTER19H		0xb93
+#define CSR_MHPMCOUNTER20H		0xb94
+#define CSR_MHPMCOUNTER21H		0xb95
+#define CSR_MHPMCOUNTER22H		0xb96
+#define CSR_MHPMCOUNTER23H		0xb97
+#define CSR_MHPMCOUNTER24H		0xb98
+#define CSR_MHPMCOUNTER25H		0xb99
+#define CSR_MHPMCOUNTER26H		0xb9a
+#define CSR_MHPMCOUNTER27H		0xb9b
+#define CSR_MHPMCOUNTER28H		0xb9c
+#define CSR_MHPMCOUNTER29H		0xb9d
+#define CSR_MHPMCOUNTER30H		0xb9e
+#define CSR_MHPMCOUNTER31H		0xb9f
+
+/* Machine Counter Setup */
+#define CSR_MCOUNTINHIBIT		0x320
+#define CSR_MHPMEVENT3			0x323
+#define CSR_MHPMEVENT4			0x324
+#define CSR_MHPMEVENT5			0x325
+#define CSR_MHPMEVENT6			0x326
+#define CSR_MHPMEVENT7			0x327
+#define CSR_MHPMEVENT8			0x328
+#define CSR_MHPMEVENT9			0x329
+#define CSR_MHPMEVENT10			0x32a
+#define CSR_MHPMEVENT11			0x32b
+#define CSR_MHPMEVENT12			0x32c
+#define CSR_MHPMEVENT13			0x32d
+#define CSR_MHPMEVENT14			0x32e
+#define CSR_MHPMEVENT15			0x32f
+#define CSR_MHPMEVENT16			0x330
+#define CSR_MHPMEVENT17			0x331
+#define CSR_MHPMEVENT18			0x332
+#define CSR_MHPMEVENT19			0x333
+#define CSR_MHPMEVENT20			0x334
+#define CSR_MHPMEVENT21			0x335
+#define CSR_MHPMEVENT22			0x336
+#define CSR_MHPMEVENT23			0x337
+#define CSR_MHPMEVENT24			0x338
+#define CSR_MHPMEVENT25			0x339
+#define CSR_MHPMEVENT26			0x33a
+#define CSR_MHPMEVENT27			0x33b
+#define CSR_MHPMEVENT28			0x33c
+#define CSR_MHPMEVENT29			0x33d
+#define CSR_MHPMEVENT30			0x33e
+#define CSR_MHPMEVENT31			0x33f
+
+/* For RV32 */
+#define CSR_MHPMEVENT3H			0x723
+#define CSR_MHPMEVENT4H			0x724
+#define CSR_MHPMEVENT5H			0x725
+#define CSR_MHPMEVENT6H			0x726
+#define CSR_MHPMEVENT7H			0x727
+#define CSR_MHPMEVENT8H			0x728
+#define CSR_MHPMEVENT9H			0x729
+#define CSR_MHPMEVENT10H		0x72a
+#define CSR_MHPMEVENT11H		0x72b
+#define CSR_MHPMEVENT12H		0x72c
+#define CSR_MHPMEVENT13H		0x72d
+#define CSR_MHPMEVENT14H		0x72e
+#define CSR_MHPMEVENT15H		0x72f
+#define CSR_MHPMEVENT16H		0x730
+#define CSR_MHPMEVENT17H		0x731
+#define CSR_MHPMEVENT18H		0x732
+#define CSR_MHPMEVENT19H		0x733
+#define CSR_MHPMEVENT20H		0x734
+#define CSR_MHPMEVENT21H		0x735
+#define CSR_MHPMEVENT22H		0x736
+#define CSR_MHPMEVENT23H		0x737
+#define CSR_MHPMEVENT24H		0x738
+#define CSR_MHPMEVENT25H		0x739
+#define CSR_MHPMEVENT26H		0x73a
+#define CSR_MHPMEVENT27H		0x73b
+#define CSR_MHPMEVENT28H		0x73c
+#define CSR_MHPMEVENT29H		0x73d
+#define CSR_MHPMEVENT30H		0x73e
+#define CSR_MHPMEVENT31H		0x73f
+
+/* Counter Overflow CSR */
+#define CSR_SCOUNTOVF			0xda0
+
+/* Debug/Trace Registers */
+#define CSR_TSELECT			0x7a0
+#define CSR_TDATA1			0x7a1
+#define CSR_TDATA2			0x7a2
+#define CSR_TDATA3			0x7a3
+
+/* Debug Mode Registers */
+#define CSR_DCSR			0x7b0
+#define CSR_DPC				0x7b1
+#define CSR_DSCRATCH0			0x7b2
+#define CSR_DSCRATCH1			0x7b3
+
+/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
+#define CSR_MISELECT			0x350
+#define CSR_MIREG			0x351
+
+/* Machine-Level Interrupts (AIA) */
+#define CSR_MTOPI			0xfb0
+
+/* Machine-Level IMSIC Interface (AIA) */
+#define CSR_MSETEIPNUM			0x358
+#define CSR_MCLREIPNUM			0x359
+#define CSR_MSETEIENUM			0x35a
+#define CSR_MCLREIENUM			0x35b
+#define CSR_MTOPEI			0x35c
+
+/* Virtual Interrupts for Supervisor Level (AIA) */
+#define CSR_MVIEN			0x308
+#define CSR_MVIP			0x309
+
+/* Smstateen extension registers */
+/* Machine stateen CSRs */
+#define CSR_MSTATEEN0			0x30C
+#define CSR_MSTATEEN0H			0x31C
+#define CSR_MSTATEEN1			0x30D
+#define CSR_MSTATEEN1H			0x31D
+#define CSR_MSTATEEN2			0x30E
+#define CSR_MSTATEEN2H			0x31E
+#define CSR_MSTATEEN3			0x30F
+#define CSR_MSTATEEN3H			0x31F
+
+/* Machine-Level High-Half CSRs (AIA) */
+#define CSR_MIDELEGH			0x313
+#define CSR_MIEH			0x314
+#define CSR_MVIENH			0x318
+#define CSR_MVIPH			0x319
+#define CSR_MIPH			0x354
+
+/* ===== Trap/Exception Causes ===== */
+
+/* Exception cause high bit - is an interrupt if set */
+#define CAUSE_IRQ_FLAG			(_UL(1) << (__riscv_xlen - 1))
+
+#define CAUSE_MISALIGNED_FETCH		0x0
+#define CAUSE_FETCH_ACCESS		0x1
+#define CAUSE_ILLEGAL_INSTRUCTION	0x2
+#define CAUSE_BREAKPOINT		0x3
+#define CAUSE_MISALIGNED_LOAD		0x4
+#define CAUSE_LOAD_ACCESS		0x5
+#define CAUSE_MISALIGNED_STORE		0x6
+#define CAUSE_STORE_ACCESS		0x7
+#define CAUSE_USER_ECALL		0x8
+#define CAUSE_SUPERVISOR_ECALL		0x9
+#define CAUSE_VIRTUAL_SUPERVISOR_ECALL	0xa
+#define CAUSE_MACHINE_ECALL		0xb
+#define CAUSE_FETCH_PAGE_FAULT		0xc
+#define CAUSE_LOAD_PAGE_FAULT		0xd
+#define CAUSE_STORE_PAGE_FAULT		0xf
+#define CAUSE_FETCH_GUEST_PAGE_FAULT	0x14
+#define CAUSE_LOAD_GUEST_PAGE_FAULT	0x15
+#define CAUSE_VIRTUAL_INST_FAULT	0x16
+#define CAUSE_STORE_GUEST_PAGE_FAULT	0x17
+
+/* Common defines for all smstateen */
+#define SMSTATEEN_MAX_COUNT		4
+#define SMSTATEEN0_CS_SHIFT		0
+#define SMSTATEEN0_CS			(_ULL(1) << SMSTATEEN0_CS_SHIFT)
+#define SMSTATEEN0_FCSR_SHIFT		1
+#define SMSTATEEN0_FCSR			(_ULL(1) << SMSTATEEN0_FCSR_SHIFT)
+#define SMSTATEEN0_IMSIC_SHIFT		58
+#define SMSTATEEN0_IMSIC		(_ULL(1) << SMSTATEEN0_IMSIC_SHIFT)
+#define SMSTATEEN0_AIA_SHIFT		59
+#define SMSTATEEN0_AIA			(_ULL(1) << SMSTATEEN0_AIA_SHIFT)
+#define SMSTATEEN0_SVSLCT_SHIFT		60
+#define SMSTATEEN0_SVSLCT		(_ULL(1) << SMSTATEEN0_SVSLCT_SHIFT)
+#define SMSTATEEN0_HSENVCFG_SHIFT	62
+#define SMSTATEEN0_HSENVCFG		(_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
+#define SMSTATEEN_STATEN_SHIFT		63
+#define SMSTATEEN_STATEN		(_ULL(1) << SMSTATEEN_STATEN_SHIFT)
+
+/* ===== Instruction Encodings ===== */
+
+#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_MASK_WFI			0xffffff00
+#define INSN_MATCH_WFI			0x10500000
+
+#define INSN_16BIT_MASK			0x3
+#define INSN_32BIT_MASK			0x1c
+
+#define INSN_IS_16BIT(insn)		\
+	(((insn) & INSN_16BIT_MASK) != INSN_16BIT_MASK)
+#define INSN_IS_32BIT(insn)		\
+	(((insn) & INSN_16BIT_MASK) == INSN_16BIT_MASK && \
+	 ((insn) & INSN_32BIT_MASK) != INSN_32BIT_MASK)
+
+#define INSN_LEN(insn)			(INSN_IS_16BIT(insn) ? 2 : 4)
+
+#if __riscv_xlen == 64
+#define LOG_REGBYTES			3
+#else
+#define LOG_REGBYTES			2
+#endif
+#define REGBYTES			(1 << LOG_REGBYTES)
+
+#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)	\
+	(unsigned long *)((unsigned long)(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
+
+/* clang-format on */
+
+#endif
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (2 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-22 23:25   ` Alistair Francis
  2023-01-23 13:57   ` Jan Beulich
  2023-01-20 14:59 ` [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function Oleksii Kurochko
                   ` (9 subsequent siblings)
  13 siblings, 2 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/include/asm/csr.h | 82 ++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/csr.h

diff --git a/xen/arch/riscv/include/asm/csr.h b/xen/arch/riscv/include/asm/csr.h
new file mode 100644
index 0000000000..1a879c6c4d
--- /dev/null
+++ b/xen/arch/riscv/include/asm/csr.h
@@ -0,0 +1,82 @@
+/*
+ * Take from Linux.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2015 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_CSR_H
+#define _ASM_RISCV_CSR_H
+
+#include <asm/asm.h>
+#include <xen/const.h>
+#include <asm/riscv_encoding.h>
+
+#ifndef __ASSEMBLY__
+
+#define csr_read(csr)						\
+({								\
+	register unsigned long __v;				\
+	__asm__ __volatile__ ("csrr %0, " __ASM_STR(csr)	\
+			      : "=r" (__v) :			\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_write(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0"	\
+			      : : "rK" (__v)			\
+			      : "memory");			\
+})
+
+/*
+#define csr_swap(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
+			      : "=r" (__v) : "rK" (__v)		\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_read_set(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
+			      : "=r" (__v) : "rK" (__v)		\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_set(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0"	\
+			      : : "rK" (__v)			\
+			      : "memory");			\
+})
+
+#define csr_read_clear(csr, val)				\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
+			      : "=r" (__v) : "rK" (__v)		\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_clear(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0"	\
+			      : : "rK" (__v)			\
+			      : "memory");			\
+})
+*/
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_CSR_H */
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (3 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-20 15:39   ` Andrew Cooper
  2023-01-23 11:10   ` Jan Beulich
  2023-01-20 14:59 ` [PATCH v1 06/14] xen/riscv: introduce exception context Oleksii Kurochko
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Add ability to print hex number.
It might be useful to print register value as debug information
in BUG(), WARN(), etc...

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/early_printk.c             | 39 +++++++++++++++++++++++
 xen/arch/riscv/include/asm/early_printk.h |  2 ++
 2 files changed, 41 insertions(+)

diff --git a/xen/arch/riscv/early_printk.c b/xen/arch/riscv/early_printk.c
index 6f590e712b..876d022dd6 100644
--- a/xen/arch/riscv/early_printk.c
+++ b/xen/arch/riscv/early_printk.c
@@ -43,3 +43,42 @@ void early_printk(const char *str)
         str++;
     }
 }
+
+static void reverse(char *s, int length)
+{
+    int c;
+    char *begin, *end, temp;
+
+    begin  = s;
+    end    = s + length - 1;
+
+    for ( c = 0; c < length/2; c++ )
+    {
+        temp   = *end;
+        *end   = *begin;
+        *begin = temp;
+
+        begin++;
+        end--;
+    }
+}
+
+void early_printk_hnum(const register_t reg_val)
+{
+    char hex[] = "0123456789ABCDEF";
+    char buf[17] = {0};
+
+    register_t num = reg_val;
+    unsigned int count = 0;
+
+    for ( count = 0; num != 0; count++, num >>= 4 )
+        buf[count] = hex[num & 0x0000000f];
+
+    buf[count] = '\0';
+
+    reverse(buf, count);
+
+    early_printk("0x");
+    early_printk(buf);
+    early_printk("\n");
+}
diff --git a/xen/arch/riscv/include/asm/early_printk.h b/xen/arch/riscv/include/asm/early_printk.h
index 05106e160d..f6d7580eb0 100644
--- a/xen/arch/riscv/include/asm/early_printk.h
+++ b/xen/arch/riscv/include/asm/early_printk.h
@@ -5,8 +5,10 @@
 
 #ifdef CONFIG_EARLY_PRINTK
 void early_printk(const char *str);
+void early_printk_hnum(const register_t reg_val);
 #else
 static inline void early_printk(const char *s) {};
+static inline void early_printk_hnum(const register_t reg_val) {};
 #endif
 
 #endif /* __EARLY_PRINTK_H__ */
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 06/14] xen/riscv: introduce exception context
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (4 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-20 15:54   ` Andrew Cooper
  2023-01-23 11:13   ` Jan Beulich
  2023-01-20 14:59 ` [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation Oleksii Kurochko
                   ` (7 subsequent siblings)
  13 siblings, 2 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis,
	Bobby Eshleman

The patch introduces a set of registers which should be saved to and
restored from a stack after an exception occurs and a set of defines
which will be used during exception context saving/restoring.

Originally <asm/processor.h> header was introduced in the patch series
from Bobby so mostly it was re-used and removed unneeded things from
it now.

Signed-off-by: Bobby Eshleman <bobby.eshleman@gmail.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/include/asm/processor.h | 114 +++++++++++++++++++++++++
 1 file changed, 114 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/processor.h

diff --git a/xen/arch/riscv/include/asm/processor.h b/xen/arch/riscv/include/asm/processor.h
new file mode 100644
index 0000000000..5898a09ce6
--- /dev/null
+++ b/xen/arch/riscv/include/asm/processor.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: MIT */
+/******************************************************************************
+ *
+ * Copyright 2019 (C) Alistair Francis <alistair.francis@wdc.com>
+ * Copyright 2021 (C) Bobby Eshleman <bobby.eshleman@gmail.com>
+ * Copyright 2023 (C) Vates
+ *
+ */
+
+#ifndef _ASM_RISCV_PROCESSOR_H
+#define _ASM_RISCV_PROCESSOR_H
+
+#include <asm/types.h>
+
+#define RISCV_CPU_USER_REGS_zero        0
+#define RISCV_CPU_USER_REGS_ra          1
+#define RISCV_CPU_USER_REGS_sp          2
+#define RISCV_CPU_USER_REGS_gp          3
+#define RISCV_CPU_USER_REGS_tp          4
+#define RISCV_CPU_USER_REGS_t0          5
+#define RISCV_CPU_USER_REGS_t1          6
+#define RISCV_CPU_USER_REGS_t2          7
+#define RISCV_CPU_USER_REGS_s0          8
+#define RISCV_CPU_USER_REGS_s1          9
+#define RISCV_CPU_USER_REGS_a0          10
+#define RISCV_CPU_USER_REGS_a1          11
+#define RISCV_CPU_USER_REGS_a2          12
+#define RISCV_CPU_USER_REGS_a3          13
+#define RISCV_CPU_USER_REGS_a4          14
+#define RISCV_CPU_USER_REGS_a5          15
+#define RISCV_CPU_USER_REGS_a6          16
+#define RISCV_CPU_USER_REGS_a7          17
+#define RISCV_CPU_USER_REGS_s2          18
+#define RISCV_CPU_USER_REGS_s3          19
+#define RISCV_CPU_USER_REGS_s4          20
+#define RISCV_CPU_USER_REGS_s5          21
+#define RISCV_CPU_USER_REGS_s6          22
+#define RISCV_CPU_USER_REGS_s7          23
+#define RISCV_CPU_USER_REGS_s8          24
+#define RISCV_CPU_USER_REGS_s9          25
+#define RISCV_CPU_USER_REGS_s10         26
+#define RISCV_CPU_USER_REGS_s11         27
+#define RISCV_CPU_USER_REGS_t3          28
+#define RISCV_CPU_USER_REGS_t4          29
+#define RISCV_CPU_USER_REGS_t5          30
+#define RISCV_CPU_USER_REGS_t6          31
+#define RISCV_CPU_USER_REGS_sepc        32
+#define RISCV_CPU_USER_REGS_sstatus     33
+#define RISCV_CPU_USER_REGS_pregs       34
+#define RISCV_CPU_USER_REGS_last        35
+
+#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x) * __SIZEOF_POINTER__)
+#define RISCV_CPU_USER_REGS_SIZE        RISCV_CPU_USER_REGS_OFFSET(last)
+
+#ifndef __ASSEMBLY__
+
+/* On stack VCPU state */
+struct cpu_user_regs
+{
+    register_t zero;
+    register_t ra;
+    register_t sp;
+    register_t gp;
+    register_t tp;
+    register_t t0;
+    register_t t1;
+    register_t t2;
+    register_t s0;
+    register_t s1;
+    register_t a0;
+    register_t a1;
+    register_t a2;
+    register_t a3;
+    register_t a4;
+    register_t a5;
+    register_t a6;
+    register_t a7;
+    register_t s2;
+    register_t s3;
+    register_t s4;
+    register_t s5;
+    register_t s6;
+    register_t s7;
+    register_t s8;
+    register_t s9;
+    register_t s10;
+    register_t s11;
+    register_t t3;
+    register_t t4;
+    register_t t5;
+    register_t t6;
+    register_t sepc;
+    register_t sstatus;
+    /* pointer to previous stack_cpu_regs */
+    register_t pregs;
+};
+
+static inline void wait_for_interrupt(void)
+{
+    __asm__ __volatile__ ("wfi");
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_PROCESSOR_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (5 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 06/14] xen/riscv: introduce exception context Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-22 23:29   ` Alistair Francis
                     ` (2 more replies)
  2023-01-20 14:59 ` [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff Oleksii Kurochko
                   ` (6 subsequent siblings)
  13 siblings, 3 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

The patch introduces an implementation of basic exception handlers:
- to save/restore context
- to handle an exception itself. The handler calls wait_for_interrupt
  now, nothing more.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/Makefile            |  2 +
 xen/arch/riscv/entry.S             | 97 ++++++++++++++++++++++++++++++
 xen/arch/riscv/include/asm/traps.h | 13 ++++
 xen/arch/riscv/traps.c             | 13 ++++
 4 files changed, 125 insertions(+)
 create mode 100644 xen/arch/riscv/entry.S
 create mode 100644 xen/arch/riscv/include/asm/traps.h
 create mode 100644 xen/arch/riscv/traps.c

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index 1a4f1a6015..443f6bf15f 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -1,7 +1,9 @@
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-y += entry.o
 obj-$(CONFIG_RISCV_64) += riscv64/
 obj-y += sbi.o
 obj-y += setup.o
+obj-y += traps.o
 
 $(TARGET): $(TARGET)-syms
 	$(OBJCOPY) -O binary -S $< $@
diff --git a/xen/arch/riscv/entry.S b/xen/arch/riscv/entry.S
new file mode 100644
index 0000000000..f7d46f42bb
--- /dev/null
+++ b/xen/arch/riscv/entry.S
@@ -0,0 +1,97 @@
+#include <asm/asm.h>
+#include <asm/processor.h>
+#include <asm/riscv_encoding.h>
+#include <asm/traps.h>
+
+        .global handle_exception
+        .align 4
+
+handle_exception:
+
+    /* Exceptions from xen */
+save_to_stack:
+        /* Save context to stack */
+        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) - RISCV_CPU_USER_REGS_SIZE) (sp)
+        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
+        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
+        j       save_context
+
+save_context:
+        /* Save registers */
+        REG_S   ra, RISCV_CPU_USER_REGS_OFFSET(ra)(sp)
+        REG_S   gp, RISCV_CPU_USER_REGS_OFFSET(gp)(sp)
+        REG_S   t1, RISCV_CPU_USER_REGS_OFFSET(t1)(sp)
+        REG_S   t2, RISCV_CPU_USER_REGS_OFFSET(t2)(sp)
+        REG_S   s0, RISCV_CPU_USER_REGS_OFFSET(s0)(sp)
+        REG_S   s1, RISCV_CPU_USER_REGS_OFFSET(s1)(sp)
+        REG_S   a0, RISCV_CPU_USER_REGS_OFFSET(a0)(sp)
+        REG_S   a1, RISCV_CPU_USER_REGS_OFFSET(a1)(sp)
+        REG_S   a2, RISCV_CPU_USER_REGS_OFFSET(a2)(sp)
+        REG_S   a3, RISCV_CPU_USER_REGS_OFFSET(a3)(sp)
+        REG_S   a4, RISCV_CPU_USER_REGS_OFFSET(a4)(sp)
+        REG_S   a5, RISCV_CPU_USER_REGS_OFFSET(a5)(sp)
+        REG_S   a6, RISCV_CPU_USER_REGS_OFFSET(a6)(sp)
+        REG_S   a7, RISCV_CPU_USER_REGS_OFFSET(a7)(sp)
+        REG_S   s2, RISCV_CPU_USER_REGS_OFFSET(s2)(sp)
+        REG_S   s3, RISCV_CPU_USER_REGS_OFFSET(s3)(sp)
+        REG_S   s4, RISCV_CPU_USER_REGS_OFFSET(s4)(sp)
+        REG_S   s5, RISCV_CPU_USER_REGS_OFFSET(s5)(sp)
+        REG_S   s6, RISCV_CPU_USER_REGS_OFFSET(s6)(sp)
+        REG_S   s7, RISCV_CPU_USER_REGS_OFFSET(s7)(sp)
+        REG_S   s8, RISCV_CPU_USER_REGS_OFFSET(s8)(sp)
+        REG_S   s9, RISCV_CPU_USER_REGS_OFFSET(s9)(sp)
+        REG_S   s10, RISCV_CPU_USER_REGS_OFFSET(s10)(sp)
+        REG_S   s11, RISCV_CPU_USER_REGS_OFFSET(s11)(sp)
+        REG_S   t3, RISCV_CPU_USER_REGS_OFFSET(t3)(sp)
+        REG_S   t4, RISCV_CPU_USER_REGS_OFFSET(t4)(sp)
+        REG_S   t5, RISCV_CPU_USER_REGS_OFFSET(t5)(sp)
+        REG_S   t6, RISCV_CPU_USER_REGS_OFFSET(t6)(sp)
+        csrr    t0, CSR_SEPC
+        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sepc)(sp)
+        csrr    t0, CSR_SSTATUS
+        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sstatus)(sp)
+
+        mv      a0, sp
+        jal     __handle_exception
+
+restore_registers:
+        /* Restore stack_cpu_regs */
+        REG_L   t0, RISCV_CPU_USER_REGS_OFFSET(sepc)(sp)
+        csrw    CSR_SEPC, t0
+        REG_L   t0, RISCV_CPU_USER_REGS_OFFSET(sstatus)(sp)
+        csrw    CSR_SSTATUS, t0
+
+        REG_L   ra, RISCV_CPU_USER_REGS_OFFSET(ra)(sp)
+        REG_L   gp, RISCV_CPU_USER_REGS_OFFSET(gp)(sp)
+        REG_L   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
+        REG_L   t1, RISCV_CPU_USER_REGS_OFFSET(t1)(sp)
+        REG_L   t2, RISCV_CPU_USER_REGS_OFFSET(t2)(sp)
+        REG_L   s0, RISCV_CPU_USER_REGS_OFFSET(s0)(sp)
+        REG_L   s1, RISCV_CPU_USER_REGS_OFFSET(s1)(sp)
+        REG_L   a0, RISCV_CPU_USER_REGS_OFFSET(a0)(sp)
+        REG_L   a1, RISCV_CPU_USER_REGS_OFFSET(a1)(sp)
+        REG_L   a2, RISCV_CPU_USER_REGS_OFFSET(a2)(sp)
+        REG_L   a3, RISCV_CPU_USER_REGS_OFFSET(a3)(sp)
+        REG_L   a4, RISCV_CPU_USER_REGS_OFFSET(a4)(sp)
+        REG_L   a5, RISCV_CPU_USER_REGS_OFFSET(a5)(sp)
+        REG_L   a6, RISCV_CPU_USER_REGS_OFFSET(a6)(sp)
+        REG_L   a7, RISCV_CPU_USER_REGS_OFFSET(a7)(sp)
+        REG_L   s2, RISCV_CPU_USER_REGS_OFFSET(s2)(sp)
+        REG_L   s3, RISCV_CPU_USER_REGS_OFFSET(s3)(sp)
+        REG_L   s4, RISCV_CPU_USER_REGS_OFFSET(s4)(sp)
+        REG_L   s5, RISCV_CPU_USER_REGS_OFFSET(s5)(sp)
+        REG_L   s6, RISCV_CPU_USER_REGS_OFFSET(s6)(sp)
+        REG_L   s7, RISCV_CPU_USER_REGS_OFFSET(s7)(sp)
+        REG_L   s8, RISCV_CPU_USER_REGS_OFFSET(s8)(sp)
+        REG_L   s9, RISCV_CPU_USER_REGS_OFFSET(s9)(sp)
+        REG_L   s10, RISCV_CPU_USER_REGS_OFFSET(s10)(sp)
+        REG_L   s11, RISCV_CPU_USER_REGS_OFFSET(s11)(sp)
+        REG_L   t3, RISCV_CPU_USER_REGS_OFFSET(t3)(sp)
+        REG_L   t4, RISCV_CPU_USER_REGS_OFFSET(t4)(sp)
+        REG_L   t5, RISCV_CPU_USER_REGS_OFFSET(t5)(sp)
+        REG_L   t6, RISCV_CPU_USER_REGS_OFFSET(t6)(sp)
+
+        /* Restore sp */
+        REG_L   sp, RISCV_CPU_USER_REGS_OFFSET(sp)(sp)
+
+        sret
diff --git a/xen/arch/riscv/include/asm/traps.h b/xen/arch/riscv/include/asm/traps.h
new file mode 100644
index 0000000000..816ab1178a
--- /dev/null
+++ b/xen/arch/riscv/include/asm/traps.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_TRAPS_H__
+#define __ASM_TRAPS_H__
+
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+
+void __handle_exception(struct cpu_user_regs *cpu_regs);
+void handle_exception(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_TRAPS_H__ */
diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
new file mode 100644
index 0000000000..3201b851ef
--- /dev/null
+++ b/xen/arch/riscv/traps.c
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Vates
+ *
+ * RISC-V Trap handlers
+ */
+#include <asm/processor.h>
+#include <asm/traps.h>
+
+void __handle_exception(struct cpu_user_regs *cpu_regs)
+{
+    wait_for_interrupt();
+}
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (6 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-22 23:38   ` Alistair Francis
  2023-01-23 12:09   ` Andrew Cooper
  2023-01-20 14:59 ` [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap() Oleksii Kurochko
                   ` (5 subsequent siblings)
  13 siblings, 2 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

The patch introduces stuff needed to decode a reason of an
exception.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/traps.c | 88 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
index 3201b851ef..dd64f053a5 100644
--- a/xen/arch/riscv/traps.c
+++ b/xen/arch/riscv/traps.c
@@ -4,8 +4,96 @@
  *
  * RISC-V Trap handlers
  */
+#include <asm/csr.h>
+#include <asm/early_printk.h>
 #include <asm/processor.h>
 #include <asm/traps.h>
+#include <xen/errno.h>
+
+const char *decode_trap_cause(unsigned long cause)
+{
+    switch ( cause )
+    {
+    case CAUSE_MISALIGNED_FETCH:
+        return "Instruction Address Misaligned";
+    case CAUSE_FETCH_ACCESS:
+        return "Instruction Access Fault";
+    case CAUSE_ILLEGAL_INSTRUCTION:
+        return "Illegal Instruction";
+    case CAUSE_BREAKPOINT:
+        return "Breakpoint";
+    case CAUSE_MISALIGNED_LOAD:
+        return "Load Address Misaligned";
+    case CAUSE_LOAD_ACCESS:
+        return "Load Access Fault";
+    case CAUSE_MISALIGNED_STORE:
+        return "Store/AMO Address Misaligned";
+    case CAUSE_STORE_ACCESS:
+        return "Store/AMO Access Fault";
+    case CAUSE_USER_ECALL:
+        return "Environment Call from U-Mode";
+    case CAUSE_SUPERVISOR_ECALL:
+        return "Environment Call from S-Mode";
+    case CAUSE_MACHINE_ECALL:
+        return "Environment Call from M-Mode";
+    case CAUSE_FETCH_PAGE_FAULT:
+        return "Instruction Page Fault";
+    case CAUSE_LOAD_PAGE_FAULT:
+        return "Load Page Fault";
+    case CAUSE_STORE_PAGE_FAULT:
+        return "Store/AMO Page Fault";
+    case CAUSE_FETCH_GUEST_PAGE_FAULT:
+        return "Instruction Guest Page Fault";
+    case CAUSE_LOAD_GUEST_PAGE_FAULT:
+        return "Load Guest Page Fault";
+    case CAUSE_VIRTUAL_INST_FAULT:
+        return "Virtualized Instruction Fault";
+    case CAUSE_STORE_GUEST_PAGE_FAULT:
+        return "Guest Store/AMO Page Fault";
+    default:
+        return "UNKNOWN";
+    }
+}
+
+const char *decode_reserved_interrupt_cause(unsigned long irq_cause)
+{
+    switch ( irq_cause )
+    {
+    case IRQ_M_SOFT:
+        return "M-mode Software Interrupt";
+    case IRQ_M_TIMER:
+        return "M-mode TIMER Interrupt";
+    case IRQ_M_EXT:
+        return "M-mode TIMER Interrupt";
+    default:
+        return "UNKNOWN IRQ type";
+    }
+}
+
+const char *decode_interrupt_cause(unsigned long cause)
+{
+    unsigned long irq_cause = cause & ~CAUSE_IRQ_FLAG;
+
+    switch ( irq_cause )
+    {
+    case IRQ_S_SOFT:
+        return "Supervisor Software Interrupt";
+    case IRQ_S_TIMER:
+        return "Supervisor Timer Interrupt";
+    case IRQ_S_EXT:
+        return "Supervisor External Interrupt";
+    default:
+        return decode_reserved_interrupt_cause(irq_cause);
+    }
+}
+
+const char *decode_cause(unsigned long cause)
+{
+    if ( cause & CAUSE_IRQ_FLAG )
+        return decode_interrupt_cause(cause);
+
+    return decode_trap_cause(cause);
+}
 
 void __handle_exception(struct cpu_user_regs *cpu_regs)
 {
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap()
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (7 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-22 23:39   ` Alistair Francis
  2023-01-20 14:59 ` [PATCH v1 10/14] xen/riscv: mask all interrupts Oleksii Kurochko
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

The patch introduces the function the purpose of which is to print
a cause of an exception and call "wfi" instruction.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/traps.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
index dd64f053a5..fc25138a4b 100644
--- a/xen/arch/riscv/traps.c
+++ b/xen/arch/riscv/traps.c
@@ -95,7 +95,19 @@ const char *decode_cause(unsigned long cause)
     return decode_trap_cause(cause);
 }
 
-void __handle_exception(struct cpu_user_regs *cpu_regs)
+static void do_unexpected_trap(const struct cpu_user_regs *regs)
 {
+    unsigned long cause = csr_read(CSR_SCAUSE);
+
+    early_printk("Unhandled exception: ");
+    early_printk(decode_cause(cause));
+    early_printk("\n");
+
+    // kind of die...
     wait_for_interrupt();
 }
+
+void __handle_exception(struct cpu_user_regs *cpu_regs)
+{
+    do_unexpected_trap(cpu_regs);
+}
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 10/14] xen/riscv: mask all interrupts
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (8 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap() Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-22 23:40   ` Alistair Francis
  2023-01-20 14:59 ` [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler() Oleksii Kurochko
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/riscv64/head.S | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/xen/arch/riscv/riscv64/head.S b/xen/arch/riscv/riscv64/head.S
index d444dd8aad..ffd95f9f89 100644
--- a/xen/arch/riscv/riscv64/head.S
+++ b/xen/arch/riscv/riscv64/head.S
@@ -1,6 +1,11 @@
+#include <asm/riscv_encoding.h>
+
         .section .text.header, "ax", %progbits
 
 ENTRY(start)
+        /* Mask all interrupts */
+        csrw    CSR_SIE, zero
+
         la      sp, cpu0_boot_stack
         li      t0, STACK_SIZE
         add     sp, sp, t0
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler()
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (9 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 10/14] xen/riscv: mask all interrupts Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-22 23:41   ` Alistair Francis
  2023-01-23 23:21   ` Andrew Cooper
  2023-01-20 14:59 ` [PATCH v1 12/14] xen/riscv: introduce an implementation of macros from <asm/bug.h> Oleksii Kurochko
                   ` (2 subsequent siblings)
  13 siblings, 2 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/setup.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
index d09ffe1454..174e134c93 100644
--- a/xen/arch/riscv/setup.c
+++ b/xen/arch/riscv/setup.c
@@ -1,16 +1,27 @@
 #include <xen/compile.h>
 #include <xen/init.h>
 
+#include <asm/csr.h>
 #include <asm/early_printk.h>
+#include <asm/traps.h>
 
 /* Xen stack for bringing up the first CPU. */
 unsigned char __initdata cpu0_boot_stack[STACK_SIZE]
     __aligned(STACK_SIZE);
 
+static void setup_trap_handler(void)
+{
+    unsigned long addr = (unsigned long)&handle_exception;
+    csr_write(CSR_STVEC, addr);
+}
+
 void __init noreturn start_xen(void)
 {
     early_printk("Hello from C env\n");
 
+    setup_trap_handler();
+    early_printk("exception handler has been setup\n");
+
     for ( ;; )
         asm volatile ("wfi");
 
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 12/14] xen/riscv: introduce an implementation of macros from <asm/bug.h>
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (10 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler() Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-23 11:37   ` Jan Beulich
  2023-01-20 14:59 ` [PATCH v1 13/14] xen/riscv: test basic handling stuff Oleksii Kurochko
  2023-01-20 14:59 ` [PATCH v1 14/14] automation: add smoke test to verify macros from bug.h Oleksii Kurochko
  13 siblings, 1 reply; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

The patch introduces macros: BUG(), WARN(), run_in_exception(),
assert_failed.

The implementation uses "ebreak" instruction in combination with
diffrent bug frame tables (for each type) which contains useful
information.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/include/asm/bug.h | 120 +++++++++++++++++++++++++++++++
 xen/arch/riscv/traps.c           | 116 ++++++++++++++++++++++++++++++
 xen/arch/riscv/xen.lds.S         |  10 +++
 3 files changed, 246 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/bug.h

diff --git a/xen/arch/riscv/include/asm/bug.h b/xen/arch/riscv/include/asm/bug.h
new file mode 100644
index 0000000000..d17ffdcc4d
--- /dev/null
+++ b/xen/arch/riscv/include/asm/bug.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2012 Regents of the University of California
+ * Copyright (C) 2021-2023 Vates
+ *
+ */
+
+#ifndef _ASM_RISCV_BUG_H
+#define _ASM_RISCV_BUG_H
+
+#include <xen/stringify.h>
+#include <xen/types.h>
+
+#ifndef __ASSEMBLY__
+
+struct bug_frame {
+    signed int loc_disp;    /* Relative address to the bug address */
+    signed int file_disp;   /* Relative address to the filename */
+    signed int msg_disp;    /* Relative address to the predicate (for ASSERT) */
+    uint16_t line;          /* Line number */
+    uint32_t pad0:16;       /* Padding for 8-bytes align */
+};
+
+#define bug_loc(b) ((const void *)(b) + (b)->loc_disp)
+#define bug_file(b) ((const void *)(b) + (b)->file_disp);
+#define bug_line(b) ((b)->line)
+#define bug_msg(b) ((const char *)(b) + (b)->msg_disp)
+
+#define BUGFRAME_run_fn 0
+#define BUGFRAME_warn   1
+#define BUGFRAME_bug    2
+#define BUGFRAME_assert 3
+
+#define BUGFRAME_NR     4
+
+#define __INSN_LENGTH_MASK  _UL(0x3)
+#define __INSN_LENGTH_32    _UL(0x3)
+#define __COMPRESSED_INSN_MASK	_UL(0xffff)
+
+#define __BUG_INSN_32	_UL(0x00100073) /* ebreak */
+#define __BUG_INSN_16	_UL(0x9002) /* c.ebreak */
+
+#define GET_INSN_LENGTH(insn)						\
+({									\
+	unsigned long __len;						\
+	__len = ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ?	\
+		4UL : 2UL;						\
+	__len;								\
+})
+
+typedef u32 bug_insn_t;
+
+/* These are defined by the architecture */
+int is_valid_bugaddr(bug_insn_t addr);
+
+#define BUG_FN_REG t0
+
+/* Many versions of GCC doesn't support the asm %c parameter which would
+ * be preferable to this unpleasantness. We use mergeable string
+ * sections to avoid multiple copies of the string appearing in the
+ * Xen image. BUGFRAME_run_fn needs to be handled separately.
+ */
+#define BUG_FRAME(type, line, file, has_msg, msg) do {                      \
+    asm ("1:ebreak\n"														\
+         ".pushsection .rodata.str, \"aMS\", %progbits, 1\n"                \
+         "2:\t.asciz " __stringify(file) "\n"                               \
+         "3:\n"                                                             \
+         ".if " #has_msg "\n"                                               \
+         "\t.asciz " #msg "\n"                                              \
+         ".endif\n"                                                         \
+         ".popsection\n"                                                    \
+         ".pushsection .bug_frames." __stringify(type) ", \"a\", %progbits\n"\
+         "4:\n"                                                             \
+         ".p2align 2\n"                                                     \
+         ".long (1b - 4b)\n"                                                \
+         ".long (2b - 4b)\n"                                                \
+         ".long (3b - 4b)\n"                                                \
+         ".hword " __stringify(line) ", 0\n"                                \
+         ".popsection");                                                    \
+} while (0)
+
+/*
+ * GCC will not allow to use "i"  when PIE is enabled (Xen doesn't set the
+ * flag but instead rely on the default value from the compiler). So the
+ * easiest way to implement run_in_exception_handler() is to pass the to
+ * be called function in a fixed register.
+ */
+#define  run_in_exception_handler(fn) do {                                  \
+    asm ("mv " __stringify(BUG_FN_REG) ", %0\n"                            	\
+         "1:ebreak\n"                                                  		\
+         ".pushsection .bug_frames." __stringify(BUGFRAME_run_fn) ","       \
+         "             \"a\", %%progbits\n"                                 \
+         "2:\n"                                                             \
+         ".p2align 2\n"                                                     \
+         ".long (1b - 2b)\n"                                                \
+         ".long 0, 0, 0\n"                                                  \
+         ".popsection" :: "r" (fn) : __stringify(BUG_FN_REG) );             \
+} while (0)
+
+#define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 0, "")
+
+#define BUG() do {                                              \
+    BUG_FRAME(BUGFRAME_bug,  __LINE__, __FILE__, 0, "");        \
+    unreachable();                                              \
+} while (0)
+
+#define assert_failed(msg) do {                                 \
+    BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, msg);     \
+    unreachable();                                              \
+} while (0)
+
+extern const struct bug_frame __start_bug_frames[],
+                              __stop_bug_frames_0[],
+                              __stop_bug_frames_1[],
+                              __stop_bug_frames_2[],
+                              __stop_bug_frames_3[];
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_BUG_H */
diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
index fc25138a4b..8b719a5ef5 100644
--- a/xen/arch/riscv/traps.c
+++ b/xen/arch/riscv/traps.c
@@ -4,6 +4,7 @@
  *
  * RISC-V Trap handlers
  */
+#include <asm/bug.h>
 #include <asm/csr.h>
 #include <asm/early_printk.h>
 #include <asm/processor.h>
@@ -107,7 +108,122 @@ static void do_unexpected_trap(const struct cpu_user_regs *regs)
     wait_for_interrupt();
 }
 
+void show_execution_state(const struct cpu_user_regs *regs)
+{
+    early_printk("implement show_execution_state(regs)\n");
+}
+
+int do_bug_frame(struct cpu_user_regs *regs, vaddr_t pc)
+{
+    struct bug_frame *start, *end;
+    struct bug_frame *bug = NULL;
+    unsigned int id = 0;
+    const char *filename, *predicate;
+    int lineno;
+
+    unsigned long bug_frames[] = {
+        (unsigned long)&__start_bug_frames[0],
+        (unsigned long)&__stop_bug_frames_0[0],
+        (unsigned long)&__stop_bug_frames_1[0],
+        (unsigned long)&__stop_bug_frames_2[0],
+        (unsigned long)&__stop_bug_frames_3[0],
+    };
+
+    for ( id = 0; id < BUGFRAME_NR; id++ )
+    {
+        start = (struct  bug_frame *)bug_frames[id];
+        end = (struct  bug_frame *)bug_frames[id + 1];
+
+        while ( start != end )
+        {
+            if ( (vaddr_t)bug_loc(start) == pc )
+            {
+                bug = start;
+                goto found;
+            }
+
+            start++;
+        }
+    }
+
+found:
+    if ( bug == NULL )
+        return -ENOENT;
+
+    if ( id == BUGFRAME_run_fn )
+    {
+        void (*fn)(const struct cpu_user_regs *) = (void *)regs->BUG_FN_REG;
+
+        fn(regs);
+
+        goto end;
+    }
+
+    /* WARN, BUG or ASSERT: decode the filename pointer and line number. */
+    filename = bug_file(bug);
+    lineno = bug_line(bug);
+
+    switch ( id )
+    {
+    case BUGFRAME_warn:
+        early_printk("Xen WARN at ");
+        early_printk(filename);
+        early_printk(":");
+        early_printk_hnum(lineno);
+
+        show_execution_state(regs);
+
+        goto end;
+
+    case BUGFRAME_bug:
+        early_printk("Xen BUG at ");
+        early_printk(filename);
+        early_printk(":");
+        early_printk_hnum(lineno);
+
+        show_execution_state(regs);
+        early_printk("change wait_for_interrupt to panic() when common is available\n");
+        wait_for_interrupt();
+
+    case BUGFRAME_assert:
+        /* ASSERT: decode the predicate string pointer. */
+        predicate = bug_msg(bug);
+
+        early_printk("Assertion \'");
+        early_printk(predicate);
+        early_printk("\' failed at ");
+        early_printk(filename);
+        early_printk(":");
+        early_printk_hnum(lineno);
+
+        show_execution_state(regs);
+        early_printk("change wait_for_interrupt to panic() when common is available\n");
+        wait_for_interrupt();
+    }
+
+    return -EINVAL;
+end:
+    regs->sepc += GET_INSN_LENGTH(*(bug_insn_t *)pc);
+
+    return 0;
+}
+
+int is_valid_bugaddr(bug_insn_t insn)
+{
+    if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32)
+        return (insn == __BUG_INSN_32);
+    else
+        return ((insn & __COMPRESSED_INSN_MASK) == __BUG_INSN_16);
+}
+
 void __handle_exception(struct cpu_user_regs *cpu_regs)
 {
+    register_t pc = cpu_regs->sepc;
+    uint32_t instr = *(bug_insn_t *)pc;
+
+    if (is_valid_bugaddr(instr))
+        if (!do_bug_frame(cpu_regs, pc)) return;
+
+// die:
     do_unexpected_trap(cpu_regs);
 }
diff --git a/xen/arch/riscv/xen.lds.S b/xen/arch/riscv/xen.lds.S
index ca57cce75c..139e2d04cb 100644
--- a/xen/arch/riscv/xen.lds.S
+++ b/xen/arch/riscv/xen.lds.S
@@ -39,6 +39,16 @@ SECTIONS
     . = ALIGN(PAGE_SIZE);
     .rodata : {
         _srodata = .;          /* Read-only data */
+        /* Bug frames table */
+       __start_bug_frames = .;
+       *(.bug_frames.0)
+       __stop_bug_frames_0 = .;
+       *(.bug_frames.1)
+       __stop_bug_frames_1 = .;
+       *(.bug_frames.2)
+       __stop_bug_frames_2 = .;
+       *(.bug_frames.3)
+       __stop_bug_frames_3 = .;
         *(.rodata)
         *(.rodata.*)
         *(.data.rel.ro)
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 13/14] xen/riscv: test basic handling stuff
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (11 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 12/14] xen/riscv: introduce an implementation of macros from <asm/bug.h> Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-20 14:59 ` [PATCH v1 14/14] automation: add smoke test to verify macros from bug.h Oleksii Kurochko
  13 siblings, 0 replies; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Bob Eshleman, Alistair Francis, Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/setup.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
index 174e134c93..35ab9d25c6 100644
--- a/xen/arch/riscv/setup.c
+++ b/xen/arch/riscv/setup.c
@@ -1,6 +1,7 @@
 #include <xen/compile.h>
 #include <xen/init.h>
 
+#include <asm/bug.h>
 #include <asm/csr.h>
 #include <asm/early_printk.h>
 #include <asm/traps.h>
@@ -15,12 +16,27 @@ static void setup_trap_handler(void)
     csr_write(CSR_STVEC, addr);
 }
 
+static void test_run_in_exception(struct cpu_user_regs *regs)
+{
+    early_printk("If you see this message, ");
+    early_printk("run_in_exception_handler is most likely working\n");
+}
+
+static void test_macros_from_bug_h(void)
+{
+    run_in_exception_handler(test_run_in_exception);
+    WARN();
+    early_printk("If you see this message, ");
+    early_printk("WARN is most likely working\n");
+}
+
 void __init noreturn start_xen(void)
 {
     early_printk("Hello from C env\n");
 
     setup_trap_handler();
-    early_printk("exception handler has been setup\n");
+
+    test_macros_from_bug_h();
 
     for ( ;; )
         asm volatile ("wfi");
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH v1 14/14] automation: add smoke test to verify macros from bug.h
  2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
                   ` (12 preceding siblings ...)
  2023-01-20 14:59 ` [PATCH v1 13/14] xen/riscv: test basic handling stuff Oleksii Kurochko
@ 2023-01-20 14:59 ` Oleksii Kurochko
  2023-01-24 23:53   ` Stefano Stabellini
  13 siblings, 1 reply; 58+ messages in thread
From: Oleksii Kurochko @ 2023-01-20 14:59 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Oleksii Kurochko, Doug Goldstein

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 automation/scripts/qemu-smoke-riscv64.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/automation/scripts/qemu-smoke-riscv64.sh b/automation/scripts/qemu-smoke-riscv64.sh
index e0f06360bc..e7cc7f1442 100755
--- a/automation/scripts/qemu-smoke-riscv64.sh
+++ b/automation/scripts/qemu-smoke-riscv64.sh
@@ -17,4 +17,6 @@ qemu-system-riscv64 \
 
 set -e
 (grep -q "Hello from C env" smoke.serial) || exit 1
+(grep -q "run_in_exception_handler is most likely working" smoke.serial) || exit 1
+(grep -q "WARN is most likely working" smoke.serial) || exit 1
 exit 0
-- 
2.39.0



^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS
  2023-01-20 14:59 ` [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS Oleksii Kurochko
@ 2023-01-20 15:29   ` Andrew Cooper
  2023-01-23 10:43     ` Oleksii
  0 siblings, 1 reply; 58+ messages in thread
From: Andrew Cooper @ 2023-01-20 15:29 UTC (permalink / raw)
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> Work with some registers requires csr command which is part of
> Zicsr.
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
>  xen/arch/riscv/arch.mk | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/xen/arch/riscv/arch.mk b/xen/arch/riscv/arch.mk
> index 012dc677c3..95b41d9f3e 100644
> --- a/xen/arch/riscv/arch.mk
> +++ b/xen/arch/riscv/arch.mk
> @@ -10,7 +10,7 @@ riscv-march-$(CONFIG_RISCV_ISA_C)       := $(riscv-march-y)c
>  # into the upper half _or_ the lower half of the address space.
>  # -mcmodel=medlow would force Xen into the lower half.
>  
> -CFLAGS += -march=$(riscv-march-y) -mstrict-align -mcmodel=medany
> +CFLAGS += -march=$(riscv-march-y)_zicsr -mstrict-align -mcmodel=medany

Should we just go straight for G, rather than bumping it along every
time we make a tweak?

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header
  2023-01-20 14:59 ` [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header Oleksii Kurochko
@ 2023-01-20 15:31   ` Andrew Cooper
  2023-01-23 11:00     ` Jan Beulich
  2023-01-22 22:58   ` Alistair Francis
  1 sibling, 1 reply; 58+ messages in thread
From: Andrew Cooper @ 2023-01-20 15:31 UTC (permalink / raw)
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

There's some stuff in here which is not RISCV-specific.  We really want
to dedup with the other architectures and move into common.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function
  2023-01-20 14:59 ` [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function Oleksii Kurochko
@ 2023-01-20 15:39   ` Andrew Cooper
  2023-01-23 12:05     ` Oleksii
  2023-01-23 11:10   ` Jan Beulich
  1 sibling, 1 reply; 58+ messages in thread
From: Andrew Cooper @ 2023-01-20 15:39 UTC (permalink / raw)
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> Add ability to print hex number.
> It might be useful to print register value as debug information
> in BUG(), WARN(), etc...
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

I think it would be better to get s(n)printf() working than to take
these.  We're going to need to get it working soon anyway, and will be
much easier than doing the full printk() infrastructure.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 06/14] xen/riscv: introduce exception context
  2023-01-20 14:59 ` [PATCH v1 06/14] xen/riscv: introduce exception context Oleksii Kurochko
@ 2023-01-20 15:54   ` Andrew Cooper
  2023-01-23 12:03     ` Oleksii
  2023-01-23 11:13   ` Jan Beulich
  1 sibling, 1 reply; 58+ messages in thread
From: Andrew Cooper @ 2023-01-20 15:54 UTC (permalink / raw)
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, Bobby Eshleman

On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> diff --git a/xen/arch/riscv/include/asm/processor.h b/xen/arch/riscv/include/asm/processor.h
> new file mode 100644
> index 0000000000..5898a09ce6
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/processor.h
> @@ -0,0 +1,114 @@
> +/* SPDX-License-Identifier: MIT */
> +/******************************************************************************
> + *
> + * Copyright 2019 (C) Alistair Francis <alistair.francis@wdc.com>
> + * Copyright 2021 (C) Bobby Eshleman <bobby.eshleman@gmail.com>
> + * Copyright 2023 (C) Vates
> + *
> + */
> +
> +#ifndef _ASM_RISCV_PROCESSOR_H
> +#define _ASM_RISCV_PROCESSOR_H
> +
> +#include <asm/types.h>
> +
> +#define RISCV_CPU_USER_REGS_zero        0
> +#define RISCV_CPU_USER_REGS_ra          1
> +#define RISCV_CPU_USER_REGS_sp          2
> +#define RISCV_CPU_USER_REGS_gp          3
> +#define RISCV_CPU_USER_REGS_tp          4
> +#define RISCV_CPU_USER_REGS_t0          5
> +#define RISCV_CPU_USER_REGS_t1          6
> +#define RISCV_CPU_USER_REGS_t2          7
> +#define RISCV_CPU_USER_REGS_s0          8
> +#define RISCV_CPU_USER_REGS_s1          9
> +#define RISCV_CPU_USER_REGS_a0          10
> +#define RISCV_CPU_USER_REGS_a1          11
> +#define RISCV_CPU_USER_REGS_a2          12
> +#define RISCV_CPU_USER_REGS_a3          13
> +#define RISCV_CPU_USER_REGS_a4          14
> +#define RISCV_CPU_USER_REGS_a5          15
> +#define RISCV_CPU_USER_REGS_a6          16
> +#define RISCV_CPU_USER_REGS_a7          17
> +#define RISCV_CPU_USER_REGS_s2          18
> +#define RISCV_CPU_USER_REGS_s3          19
> +#define RISCV_CPU_USER_REGS_s4          20
> +#define RISCV_CPU_USER_REGS_s5          21
> +#define RISCV_CPU_USER_REGS_s6          22
> +#define RISCV_CPU_USER_REGS_s7          23
> +#define RISCV_CPU_USER_REGS_s8          24
> +#define RISCV_CPU_USER_REGS_s9          25
> +#define RISCV_CPU_USER_REGS_s10         26
> +#define RISCV_CPU_USER_REGS_s11         27
> +#define RISCV_CPU_USER_REGS_t3          28
> +#define RISCV_CPU_USER_REGS_t4          29
> +#define RISCV_CPU_USER_REGS_t5          30
> +#define RISCV_CPU_USER_REGS_t6          31
> +#define RISCV_CPU_USER_REGS_sepc        32
> +#define RISCV_CPU_USER_REGS_sstatus     33
> +#define RISCV_CPU_USER_REGS_pregs       34
> +#define RISCV_CPU_USER_REGS_last        35

This block wants moving into the asm-offsets infrastructure, but I
suspect they won't want to survive in this form.

edit: yeah, definitely not this form.  RISCV_CPU_USER_REGS_OFFSET is a
recipe for bugs.

> +
> +#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x) * __SIZEOF_POINTER__)
> +#define RISCV_CPU_USER_REGS_SIZE        RISCV_CPU_USER_REGS_OFFSET(last)
> +
> +#ifndef __ASSEMBLY__
> +
> +/* On stack VCPU state */
> +struct cpu_user_regs
> +{
> +    register_t zero;

unsigned long.

> +    register_t ra;
> +    register_t sp;
> +    register_t gp;
> +    register_t tp;
> +    register_t t0;
> +    register_t t1;
> +    register_t t2;
> +    register_t s0;
> +    register_t s1;
> +    register_t a0;
> +    register_t a1;
> +    register_t a2;
> +    register_t a3;
> +    register_t a4;
> +    register_t a5;
> +    register_t a6;
> +    register_t a7;
> +    register_t s2;
> +    register_t s3;
> +    register_t s4;
> +    register_t s5;
> +    register_t s6;
> +    register_t s7;
> +    register_t s8;
> +    register_t s9;
> +    register_t s10;
> +    register_t s11;
> +    register_t t3;
> +    register_t t4;
> +    register_t t5;
> +    register_t t6;
> +    register_t sepc;
> +    register_t sstatus;
> +    /* pointer to previous stack_cpu_regs */
> +    register_t pregs;

Stale comment?  Also, surely this wants to be cpu_user_regs *pregs; ?

> +};
> +
> +static inline void wait_for_interrupt(void)

There's no point writing out the name in longhand for a wrapper around a
single instruction.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header
  2023-01-20 14:59 ` [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header Oleksii Kurochko
  2023-01-20 15:31   ` Andrew Cooper
@ 2023-01-22 22:58   ` Alistair Francis
  1 sibling, 0 replies; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 22:58 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  xen/arch/riscv/include/asm/asm.h | 54 ++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
>  create mode 100644 xen/arch/riscv/include/asm/asm.h
>
> diff --git a/xen/arch/riscv/include/asm/asm.h b/xen/arch/riscv/include/asm/asm.h
> new file mode 100644
> index 0000000000..6d426ecea7
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/asm.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only) */
> +/*
> + * Copyright (C) 2015 Regents of the University of California
> + */
> +
> +#ifndef _ASM_RISCV_ASM_H
> +#define _ASM_RISCV_ASM_H
> +
> +#ifdef __ASSEMBLY__
> +#define __ASM_STR(x)   x
> +#else
> +#define __ASM_STR(x)   #x
> +#endif
> +
> +#if __riscv_xlen == 64
> +#define __REG_SEL(a, b)        __ASM_STR(a)
> +#elif __riscv_xlen == 32
> +#define __REG_SEL(a, b)        __ASM_STR(b)
> +#else
> +#error "Unexpected __riscv_xlen"
> +#endif
> +
> +#define REG_L          __REG_SEL(ld, lw)
> +#define REG_S          __REG_SEL(sd, sw)
> +
> +#if __SIZEOF_POINTER__ == 8
> +#ifdef __ASSEMBLY__
> +#define RISCV_PTR              .dword
> +#else
> +#define RISCV_PTR              ".dword"
> +#endif
> +#elif __SIZEOF_POINTER__ == 4
> +#ifdef __ASSEMBLY__
> +#define RISCV_PTR              .word
> +#else
> +#define RISCV_PTR              ".word"
> +#endif
> +#else
> +#error "Unexpected __SIZEOF_POINTER__"
> +#endif
> +
> +#if (__SIZEOF_INT__ == 4)
> +#define RISCV_INT              __ASM_STR(.word)
> +#else
> +#error "Unexpected __SIZEOF_INT__"
> +#endif
> +
> +#if (__SIZEOF_SHORT__ == 2)
> +#define RISCV_SHORT            __ASM_STR(.half)
> +#else
> +#error "Unexpected __SIZEOF_SHORT__"
> +#endif
> +
> +#endif /* _ASM_RISCV_ASM_H */
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header
  2023-01-20 14:59 ` [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header Oleksii Kurochko
@ 2023-01-22 23:24   ` Alistair Francis
  2023-01-23 13:52   ` Jan Beulich
  1 sibling, 0 replies; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 23:24 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:01 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  xen/arch/riscv/include/asm/riscv_encoding.h | 945 ++++++++++++++++++++
>  1 file changed, 945 insertions(+)
>  create mode 100644 xen/arch/riscv/include/asm/riscv_encoding.h
>
> diff --git a/xen/arch/riscv/include/asm/riscv_encoding.h b/xen/arch/riscv/include/asm/riscv_encoding.h
> new file mode 100644
> index 0000000000..8a43d49f7a
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/riscv_encoding.h
> @@ -0,0 +1,945 @@
> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *   Anup Patel <anup.patel@wdc.com>
> + *
> + * The source has been largely adapted from OpenSBI:
> + * include/sbi/riscv_encodnig.h
> + *
> + */
> +
> +#ifndef __RISCV_ENCODING_H__
> +#define __RISCV_ENCODING_H__
> +
> +#define _UL(X) _AC(X, UL)
> +#define _ULL(X) _AC(X, ULL)
> +
> +/* clang-format off */
> +#define MSTATUS_SIE                    _UL(0x00000002)
> +#define MSTATUS_MIE                    _UL(0x00000008)
> +#define MSTATUS_SPIE_SHIFT             5
> +#define MSTATUS_SPIE                   (_UL(1) << MSTATUS_SPIE_SHIFT)
> +#define MSTATUS_UBE                    _UL(0x00000040)
> +#define MSTATUS_MPIE                   _UL(0x00000080)
> +#define MSTATUS_SPP_SHIFT              8
> +#define MSTATUS_SPP                    (_UL(1) << MSTATUS_SPP_SHIFT)
> +#define MSTATUS_MPP_SHIFT              11
> +#define MSTATUS_MPP                    (_UL(3) << MSTATUS_MPP_SHIFT)
> +#define MSTATUS_FS                     _UL(0x00006000)
> +#define MSTATUS_FS_OFF                 _UL(0x00000000)
> +#define MSTATUS_FS_INITIAL             _UL(0x00002000)
> +#define MSTATUS_FS_CLEAN               _UL(0x00004000)
> +#define MSTATUS_FS_DIRTY               _UL(0x00006000)
> +#define MSTATUS_XS                     _UL(0x00018000)
> +#define MSTATUS_XS_OFF                 _UL(0x00000000)
> +#define MSTATUS_XS_INITIAL             _UL(0x00008000)
> +#define MSTATUS_XS_CLEAN               _UL(0x00010000)
> +#define MSTATUS_XS_DIRTY               _UL(0x00018000)
> +#define MSTATUS_VS                     _UL(0x01800000)
> +#define MSTATUS_VS_OFF                 _UL(0x00000000)
> +#define MSTATUS_VS_INITIAL             _UL(0x00800000)
> +#define MSTATUS_VS_CLEAN               _UL(0x01000000)
> +#define MSTATUS_VS_DIRTY               _UL(0x01800000)
> +#define MSTATUS_MPRV                   _UL(0x00020000)
> +#define MSTATUS_SUM                    _UL(0x00040000)
> +#define MSTATUS_MXR                    _UL(0x00080000)
> +#define MSTATUS_TVM                    _UL(0x00100000)
> +#define MSTATUS_TW                     _UL(0x00200000)
> +#define MSTATUS_TSR                    _UL(0x00400000)
> +#define MSTATUS32_SD                   _UL(0x80000000)
> +#if __riscv_xlen == 64
> +#define MSTATUS_UXL                    _ULL(0x0000000300000000)
> +#define MSTATUS_SXL                    _ULL(0x0000000C00000000)
> +#define MSTATUS_SBE                    _ULL(0x0000001000000000)
> +#define MSTATUS_MBE                    _ULL(0x0000002000000000)
> +#define MSTATUS_MPV                    _ULL(0x0000008000000000)
> +#else
> +#define MSTATUSH_SBE                   _UL(0x00000010)
> +#define MSTATUSH_MBE                   _UL(0x00000020)
> +#define MSTATUSH_MPV                   _UL(0x00000080)
> +#endif
> +#define MSTATUS32_SD                   _UL(0x80000000)
> +#define MSTATUS64_SD                   _ULL(0x8000000000000000)
> +
> +#define SSTATUS_SIE                    MSTATUS_SIE
> +#define SSTATUS_SPIE_SHIFT             MSTATUS_SPIE_SHIFT
> +#define SSTATUS_SPIE                   MSTATUS_SPIE
> +#define SSTATUS_SPP_SHIFT              MSTATUS_SPP_SHIFT
> +#define SSTATUS_SPP                    MSTATUS_SPP
> +#define SSTATUS_FS                     MSTATUS_FS
> +#define SSTATUS_FS_OFF                 MSTATUS_FS_OFF
> +#define SSTATUS_FS_INITIAL             MSTATUS_FS_INITIAL
> +#define SSTATUS_FS_CLEAN               MSTATUS_FS_CLEAN
> +#define SSTATUS_FS_DIRTY               MSTATUS_FS_DIRTY
> +#define SSTATUS_XS                     MSTATUS_XS
> +#define SSTATUS_XS_OFF                 MSTATUS_XS_OFF
> +#define SSTATUS_XS_INITIAL             MSTATUS_XS_INITIAL
> +#define SSTATUS_XS_CLEAN               MSTATUS_XS_CLEAN
> +#define SSTATUS_XS_DIRTY               MSTATUS_XS_DIRTY
> +#define SSTATUS_VS                     MSTATUS_VS
> +#define SSTATUS_VS_OFF                 MSTATUS_VS_OFF
> +#define SSTATUS_VS_INITIAL             MSTATUS_VS_INITIAL
> +#define SSTATUS_VS_CLEAN               MSTATUS_VS_CLEAN
> +#define SSTATUS_VS_DIRTY               MSTATUS_VS_DIRTY
> +#define SSTATUS_SUM                    MSTATUS_SUM
> +#define SSTATUS_MXR                    MSTATUS_MXR
> +#define SSTATUS32_SD                   MSTATUS32_SD
> +#define SSTATUS64_UXL                  MSTATUS_UXL
> +#define SSTATUS64_SD                   MSTATUS64_SD
> +
> +#if __riscv_xlen == 64
> +#define HSTATUS_VSXL                   _UL(0x300000000)
> +#define HSTATUS_VSXL_SHIFT             32
> +#endif
> +#define HSTATUS_VTSR                   _UL(0x00400000)
> +#define HSTATUS_VTW                    _UL(0x00200000)
> +#define HSTATUS_VTVM                   _UL(0x00100000)
> +#define HSTATUS_VGEIN                  _UL(0x0003f000)
> +#define HSTATUS_VGEIN_SHIFT            12
> +#define HSTATUS_HU                     _UL(0x00000200)
> +#define HSTATUS_SPVP                   _UL(0x00000100)
> +#define HSTATUS_SPV                    _UL(0x00000080)
> +#define HSTATUS_GVA                    _UL(0x00000040)
> +#define HSTATUS_VSBE                   _UL(0x00000020)
> +
> +#define IRQ_S_SOFT                     1
> +#define IRQ_VS_SOFT                    2
> +#define IRQ_M_SOFT                     3
> +#define IRQ_S_TIMER                    5
> +#define IRQ_VS_TIMER                   6
> +#define IRQ_M_TIMER                    7
> +#define IRQ_S_EXT                      9
> +#define IRQ_VS_EXT                     10
> +#define IRQ_M_EXT                      11
> +#define IRQ_S_GEXT                     12
> +#define IRQ_PMU_OVF                    13
> +
> +#define MIP_SSIP                       (_UL(1) << IRQ_S_SOFT)
> +#define MIP_VSSIP                      (_UL(1) << IRQ_VS_SOFT)
> +#define MIP_MSIP                       (_UL(1) << IRQ_M_SOFT)
> +#define MIP_STIP                       (_UL(1) << IRQ_S_TIMER)
> +#define MIP_VSTIP                      (_UL(1) << IRQ_VS_TIMER)
> +#define MIP_MTIP                       (_UL(1) << IRQ_M_TIMER)
> +#define MIP_SEIP                       (_UL(1) << IRQ_S_EXT)
> +#define MIP_VSEIP                      (_UL(1) << IRQ_VS_EXT)
> +#define MIP_MEIP                       (_UL(1) << IRQ_M_EXT)
> +#define MIP_SGEIP                      (_UL(1) << IRQ_S_GEXT)
> +#define MIP_LCOFIP                     (_UL(1) << IRQ_PMU_OVF)
> +
> +#define SIP_SSIP                       MIP_SSIP
> +#define SIP_STIP                       MIP_STIP
> +
> +#define PRV_U                          _UL(0)
> +#define PRV_S                          _UL(1)
> +#define PRV_M                          _UL(3)
> +
> +#define SATP32_MODE                    _UL(0x80000000)
> +#define SATP32_MODE_SHIFT              31
> +#define SATP32_ASID                    _UL(0x7FC00000)
> +#define SATP32_ASID_SHIFT              22
> +#define SATP32_PPN                     _UL(0x003FFFFF)
> +#define SATP64_MODE                    _ULL(0xF000000000000000)
> +#define SATP64_MODE_SHIFT              60
> +#define SATP64_ASID                    _ULL(0x0FFFF00000000000)
> +#define SATP64_ASID_SHIFT              44
> +#define SATP64_PPN                     _ULL(0x00000FFFFFFFFFFF)
> +
> +#define SATP_MODE_OFF                  _UL(0)
> +#define SATP_MODE_SV32                 _UL(1)
> +#define SATP_MODE_SV39                 _UL(8)
> +#define SATP_MODE_SV48                 _UL(9)
> +#define SATP_MODE_SV57                 _UL(10)
> +#define SATP_MODE_SV64                 _UL(11)
> +
> +#define HGATP_MODE_OFF                 _UL(0)
> +#define HGATP_MODE_SV32X4              _UL(1)
> +#define HGATP_MODE_SV39X4              _UL(8)
> +#define HGATP_MODE_SV48X4              _UL(9)
> +
> +#define HGATP32_MODE_SHIFT             31
> +#define HGATP32_VMID_SHIFT             22
> +#define HGATP32_VMID_MASK              _UL(0x1FC00000)
> +#define HGATP32_PPN                    _UL(0x003FFFFF)
> +
> +#define HGATP64_MODE_SHIFT             60
> +#define HGATP64_VMID_SHIFT             44
> +#define HGATP64_VMID_MASK              _ULL(0x03FFF00000000000)
> +#define HGATP64_PPN                    _ULL(0x00000FFFFFFFFFFF)
> +
> +#define PMP_R                          _UL(0x01)
> +#define PMP_W                          _UL(0x02)
> +#define PMP_X                          _UL(0x04)
> +#define PMP_A                          _UL(0x18)
> +#define PMP_A_TOR                      _UL(0x08)
> +#define PMP_A_NA4                      _UL(0x10)
> +#define PMP_A_NAPOT                    _UL(0x18)
> +#define PMP_L                          _UL(0x80)
> +
> +#define PMP_SHIFT                      2
> +#define PMP_COUNT                      64
> +#if __riscv_xlen == 64
> +#define PMP_ADDR_MASK                  ((_ULL(0x1) << 54) - 1)
> +#else
> +#define PMP_ADDR_MASK                  _UL(0xFFFFFFFF)
> +#endif
> +
> +#if __riscv_xlen == 64
> +#define MSTATUS_SD                     MSTATUS64_SD
> +#define SSTATUS_SD                     SSTATUS64_SD
> +#define SATP_MODE                      SATP64_MODE
> +#define SATP_MODE_SHIFT                        SATP64_MODE_SHIFT
> +
> +#define HGATP_PPN                      HGATP64_PPN
> +#define HGATP_VMID_SHIFT               HGATP64_VMID_SHIFT
> +#define HGATP_VMID_MASK                        HGATP64_VMID_MASK
> +#define HGATP_MODE_SHIFT               HGATP64_MODE_SHIFT
> +#else
> +#define MSTATUS_SD                     MSTATUS32_SD
> +#define SSTATUS_SD                     SSTATUS32_SD
> +#define SATP_MODE                      SATP32_MODE
> +#define SATP_MODE_SHIFT                        SATP32_MODE_SHIFT
> +
> +#define HGATP_PPN                      HGATP32_PPN
> +#define HGATP_VMID_SHIFT               HGATP32_VMID_SHIFT
> +#define HGATP_VMID_MASK                        HGATP32_VMID_MASK
> +#define HGATP_MODE_SHIFT               HGATP32_MODE_SHIFT
> +#endif
> +
> +#define TOPI_IID_SHIFT                 16
> +#define TOPI_IID_MASK                  0xfff
> +#define TOPI_IPRIO_MASK                0xff
> +
> +#if __riscv_xlen == 64
> +#define MHPMEVENT_OF                   (_UL(1) << 63)
> +#define MHPMEVENT_MINH                 (_UL(1) << 62)
> +#define MHPMEVENT_SINH                 (_UL(1) << 61)
> +#define MHPMEVENT_UINH                 (_UL(1) << 60)
> +#define MHPMEVENT_VSINH                        (_UL(1) << 59)
> +#define MHPMEVENT_VUINH                        (_UL(1) << 58)
> +#else
> +#define MHPMEVENTH_OF                  (_ULL(1) << 31)
> +#define MHPMEVENTH_MINH                        (_ULL(1) << 30)
> +#define MHPMEVENTH_SINH                        (_ULL(1) << 29)
> +#define MHPMEVENTH_UINH                        (_ULL(1) << 28)
> +#define MHPMEVENTH_VSINH               (_ULL(1) << 27)
> +#define MHPMEVENTH_VUINH               (_ULL(1) << 26)
> +
> +#define MHPMEVENT_OF                   (MHPMEVENTH_OF << 32)
> +#define MHPMEVENT_MINH                 (MHPMEVENTH_MINH << 32)
> +#define MHPMEVENT_SINH                 (MHPMEVENTH_SINH << 32)
> +#define MHPMEVENT_UINH                 (MHPMEVENTH_UINH << 32)
> +#define MHPMEVENT_VSINH                        (MHPMEVENTH_VSINH << 32)
> +#define MHPMEVENT_VUINH                        (MHPMEVENTH_VUINH << 32)
> +
> +#endif
> +
> +#define MHPMEVENT_SSCOF_MASK           _ULL(0xFFFF000000000000)
> +
> +#if __riscv_xlen > 32
> +#define ENVCFG_STCE                    (_ULL(1) << 63)
> +#define ENVCFG_PBMTE                   (_ULL(1) << 62)
> +#else
> +#define ENVCFGH_STCE                   (_UL(1) << 31)
> +#define ENVCFGH_PBMTE                  (_UL(1) << 30)
> +#endif
> +#define ENVCFG_CBZE                    (_UL(1) << 7)
> +#define ENVCFG_CBCFE                   (_UL(1) << 6)
> +#define ENVCFG_CBIE_SHIFT              4
> +#define ENVCFG_CBIE                    (_UL(0x3) << ENVCFG_CBIE_SHIFT)
> +#define ENVCFG_CBIE_ILL                        _UL(0x0)
> +#define ENVCFG_CBIE_FLUSH              _UL(0x1)
> +#define ENVCFG_CBIE_INV                        _UL(0x3)
> +#define ENVCFG_FIOM                    _UL(0x1)
> +
> +/* ===== User-level CSRs ===== */
> +
> +/* User Trap Setup (N-extension) */
> +#define CSR_USTATUS                    0x000
> +#define CSR_UIE                                0x004
> +#define CSR_UTVEC                      0x005
> +
> +/* User Trap Handling (N-extension) */
> +#define CSR_USCRATCH                   0x040
> +#define CSR_UEPC                       0x041
> +#define CSR_UCAUSE                     0x042
> +#define CSR_UTVAL                      0x043
> +#define CSR_UIP                                0x044
> +
> +/* User Floating-point CSRs */
> +#define CSR_FFLAGS                     0x001
> +#define CSR_FRM                                0x002
> +#define CSR_FCSR                       0x003
> +
> +/* User Counters/Timers */
> +#define CSR_CYCLE                      0xc00
> +#define CSR_TIME                       0xc01
> +#define CSR_INSTRET                    0xc02
> +#define CSR_HPMCOUNTER3                        0xc03
> +#define CSR_HPMCOUNTER4                        0xc04
> +#define CSR_HPMCOUNTER5                        0xc05
> +#define CSR_HPMCOUNTER6                        0xc06
> +#define CSR_HPMCOUNTER7                        0xc07
> +#define CSR_HPMCOUNTER8                        0xc08
> +#define CSR_HPMCOUNTER9                        0xc09
> +#define CSR_HPMCOUNTER10               0xc0a
> +#define CSR_HPMCOUNTER11               0xc0b
> +#define CSR_HPMCOUNTER12               0xc0c
> +#define CSR_HPMCOUNTER13               0xc0d
> +#define CSR_HPMCOUNTER14               0xc0e
> +#define CSR_HPMCOUNTER15               0xc0f
> +#define CSR_HPMCOUNTER16               0xc10
> +#define CSR_HPMCOUNTER17               0xc11
> +#define CSR_HPMCOUNTER18               0xc12
> +#define CSR_HPMCOUNTER19               0xc13
> +#define CSR_HPMCOUNTER20               0xc14
> +#define CSR_HPMCOUNTER21               0xc15
> +#define CSR_HPMCOUNTER22               0xc16
> +#define CSR_HPMCOUNTER23               0xc17
> +#define CSR_HPMCOUNTER24               0xc18
> +#define CSR_HPMCOUNTER25               0xc19
> +#define CSR_HPMCOUNTER26               0xc1a
> +#define CSR_HPMCOUNTER27               0xc1b
> +#define CSR_HPMCOUNTER28               0xc1c
> +#define CSR_HPMCOUNTER29               0xc1d
> +#define CSR_HPMCOUNTER30               0xc1e
> +#define CSR_HPMCOUNTER31               0xc1f
> +#define CSR_CYCLEH                     0xc80
> +#define CSR_TIMEH                      0xc81
> +#define CSR_INSTRETH                   0xc82
> +#define CSR_HPMCOUNTER3H               0xc83
> +#define CSR_HPMCOUNTER4H               0xc84
> +#define CSR_HPMCOUNTER5H               0xc85
> +#define CSR_HPMCOUNTER6H               0xc86
> +#define CSR_HPMCOUNTER7H               0xc87
> +#define CSR_HPMCOUNTER8H               0xc88
> +#define CSR_HPMCOUNTER9H               0xc89
> +#define CSR_HPMCOUNTER10H              0xc8a
> +#define CSR_HPMCOUNTER11H              0xc8b
> +#define CSR_HPMCOUNTER12H              0xc8c
> +#define CSR_HPMCOUNTER13H              0xc8d
> +#define CSR_HPMCOUNTER14H              0xc8e
> +#define CSR_HPMCOUNTER15H              0xc8f
> +#define CSR_HPMCOUNTER16H              0xc90
> +#define CSR_HPMCOUNTER17H              0xc91
> +#define CSR_HPMCOUNTER18H              0xc92
> +#define CSR_HPMCOUNTER19H              0xc93
> +#define CSR_HPMCOUNTER20H              0xc94
> +#define CSR_HPMCOUNTER21H              0xc95
> +#define CSR_HPMCOUNTER22H              0xc96
> +#define CSR_HPMCOUNTER23H              0xc97
> +#define CSR_HPMCOUNTER24H              0xc98
> +#define CSR_HPMCOUNTER25H              0xc99
> +#define CSR_HPMCOUNTER26H              0xc9a
> +#define CSR_HPMCOUNTER27H              0xc9b
> +#define CSR_HPMCOUNTER28H              0xc9c
> +#define CSR_HPMCOUNTER29H              0xc9d
> +#define CSR_HPMCOUNTER30H              0xc9e
> +#define CSR_HPMCOUNTER31H              0xc9f
> +
> +/* ===== Supervisor-level CSRs ===== */
> +
> +/* Supervisor Trap Setup */
> +#define CSR_SSTATUS                    0x100
> +#define CSR_SEDELEG                    0x102
> +#define CSR_SIDELEG                    0x103
> +#define CSR_SIE                                0x104
> +#define CSR_STVEC                      0x105
> +#define CSR_SCOUNTEREN                 0x106
> +
> +/* Supervisor Configuration */
> +#define CSR_SENVCFG                    0x10a
> +
> +/* Supervisor Trap Handling */
> +#define CSR_SSCRATCH                   0x140
> +#define CSR_SEPC                       0x141
> +#define CSR_SCAUSE                     0x142
> +#define CSR_STVAL                      0x143
> +#define CSR_SIP                                0x144
> +
> +/* Supervisor Protection and Translation */
> +#define CSR_SATP                       0x180
> +
> +/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
> +#define CSR_SISELECT                   0x150
> +#define CSR_SIREG                      0x151
> +
> +/* Supervisor-Level Interrupts (AIA) */
> +#define CSR_STOPI                      0xdb0
> +
> +/* Supervisor-Level IMSIC Interface (AIA) */
> +#define CSR_SSETEIPNUM                 0x158
> +#define CSR_SCLREIPNUM                 0x159
> +#define CSR_SSETEIENUM                 0x15a
> +#define CSR_SCLREIENUM                 0x15b
> +#define CSR_STOPEI                     0x15c
> +
> +/* Supervisor-Level High-Half CSRs (AIA) */
> +#define CSR_SIEH                       0x114
> +#define CSR_SIPH                       0x154
> +
> +/* Supervisor stateen CSRs */
> +#define CSR_SSTATEEN0                  0x10C
> +#define CSR_SSTATEEN1                  0x10D
> +#define CSR_SSTATEEN2                  0x10E
> +#define CSR_SSTATEEN3                  0x10F
> +
> +/* ===== Hypervisor-level CSRs ===== */
> +
> +/* Hypervisor Trap Setup (H-extension) */
> +#define CSR_HSTATUS                    0x600
> +#define CSR_HEDELEG                    0x602
> +#define CSR_HIDELEG                    0x603
> +#define CSR_HIE                                0x604
> +#define CSR_HCOUNTEREN                 0x606
> +#define CSR_HGEIE                      0x607
> +
> +/* Hypervisor Configuration */
> +#define CSR_HENVCFG                    0x60a
> +#define CSR_HENVCFGH                   0x61a
> +
> +/* Hypervisor Trap Handling (H-extension) */
> +#define CSR_HTVAL                      0x643
> +#define CSR_HIP                                0x644
> +#define CSR_HVIP                       0x645
> +#define CSR_HTINST                     0x64a
> +#define CSR_HGEIP                      0xe12
> +
> +/* Hypervisor Protection and Translation (H-extension) */
> +#define CSR_HGATP                      0x680
> +
> +/* Hypervisor Counter/Timer Virtualization Registers (H-extension) */
> +#define CSR_HTIMEDELTA                 0x605
> +#define CSR_HTIMEDELTAH                        0x615
> +
> +/* Virtual Supervisor Registers (H-extension) */
> +#define CSR_VSSTATUS                   0x200
> +#define CSR_VSIE                       0x204
> +#define CSR_VSTVEC                     0x205
> +#define CSR_VSSCRATCH                  0x240
> +#define CSR_VSEPC                      0x241
> +#define CSR_VSCAUSE                    0x242
> +#define CSR_VSTVAL                     0x243
> +#define CSR_VSIP                       0x244
> +#define CSR_VSATP                      0x280
> +
> +/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
> +#define CSR_HVIEN                      0x608
> +#define CSR_HVICTL                     0x609
> +#define CSR_HVIPRIO1                   0x646
> +#define CSR_HVIPRIO2                   0x647
> +
> +/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
> +#define CSR_VSISELECT                  0x250
> +#define CSR_VSIREG                     0x251
> +
> +/* VS-Level Interrupts (H-extension with AIA) */
> +#define CSR_VSTOPI                     0xeb0
> +
> +/* VS-Level IMSIC Interface (H-extension with AIA) */
> +#define CSR_VSSETEIPNUM                0x258
> +#define CSR_VSCLREIPNUM                0x259
> +#define CSR_VSSETEIENUM                0x25a
> +#define CSR_VSCLREIENUM                0x25b
> +#define CSR_VSTOPEI                    0x25c
> +
> +/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
> +#define CSR_HIDELEGH                   0x613
> +#define CSR_HVIENH                     0x618
> +#define CSR_HVIPH                      0x655
> +#define CSR_HVIPRIO1H                  0x656
> +#define CSR_HVIPRIO2H                  0x657
> +#define CSR_VSIEH                      0x214
> +#define CSR_VSIPH                      0x254
> +
> +/* Hypervisor stateen CSRs */
> +#define CSR_HSTATEEN0                  0x60C
> +#define CSR_HSTATEEN0H                 0x61C
> +#define CSR_HSTATEEN1                  0x60D
> +#define CSR_HSTATEEN1H                 0x61D
> +#define CSR_HSTATEEN2                  0x60E
> +#define CSR_HSTATEEN2H                 0x61E
> +#define CSR_HSTATEEN3                  0x60F
> +#define CSR_HSTATEEN3H                 0x61F
> +
> +/* ===== Machine-level CSRs ===== */
> +
> +/* Machine Information Registers */
> +#define CSR_MVENDORID                  0xf11
> +#define CSR_MARCHID                    0xf12
> +#define CSR_MIMPID                     0xf13
> +#define CSR_MHARTID                    0xf14
> +
> +/* Machine Trap Setup */
> +#define CSR_MSTATUS                    0x300
> +#define CSR_MISA                       0x301
> +#define CSR_MEDELEG                    0x302
> +#define CSR_MIDELEG                    0x303
> +#define CSR_MIE                                0x304
> +#define CSR_MTVEC                      0x305
> +#define CSR_MCOUNTEREN                 0x306
> +#define CSR_MSTATUSH                   0x310
> +
> +/* Machine Configuration */
> +#define CSR_MENVCFG                    0x30a
> +#define CSR_MENVCFGH                   0x31a
> +
> +/* Machine Trap Handling */
> +#define CSR_MSCRATCH                   0x340
> +#define CSR_MEPC                       0x341
> +#define CSR_MCAUSE                     0x342
> +#define CSR_MTVAL                      0x343
> +#define CSR_MIP                                0x344
> +#define CSR_MTINST                     0x34a
> +#define CSR_MTVAL2                     0x34b
> +
> +/* Machine Memory Protection */
> +#define CSR_PMPCFG0                    0x3a0
> +#define CSR_PMPCFG1                    0x3a1
> +#define CSR_PMPCFG2                    0x3a2
> +#define CSR_PMPCFG3                    0x3a3
> +#define CSR_PMPCFG4                    0x3a4
> +#define CSR_PMPCFG5                    0x3a5
> +#define CSR_PMPCFG6                    0x3a6
> +#define CSR_PMPCFG7                    0x3a7
> +#define CSR_PMPCFG8                    0x3a8
> +#define CSR_PMPCFG9                    0x3a9
> +#define CSR_PMPCFG10                   0x3aa
> +#define CSR_PMPCFG11                   0x3ab
> +#define CSR_PMPCFG12                   0x3ac
> +#define CSR_PMPCFG13                   0x3ad
> +#define CSR_PMPCFG14                   0x3ae
> +#define CSR_PMPCFG15                   0x3af
> +#define CSR_PMPADDR0                   0x3b0
> +#define CSR_PMPADDR1                   0x3b1
> +#define CSR_PMPADDR2                   0x3b2
> +#define CSR_PMPADDR3                   0x3b3
> +#define CSR_PMPADDR4                   0x3b4
> +#define CSR_PMPADDR5                   0x3b5
> +#define CSR_PMPADDR6                   0x3b6
> +#define CSR_PMPADDR7                   0x3b7
> +#define CSR_PMPADDR8                   0x3b8
> +#define CSR_PMPADDR9                   0x3b9
> +#define CSR_PMPADDR10                  0x3ba
> +#define CSR_PMPADDR11                  0x3bb
> +#define CSR_PMPADDR12                  0x3bc
> +#define CSR_PMPADDR13                  0x3bd
> +#define CSR_PMPADDR14                  0x3be
> +#define CSR_PMPADDR15                  0x3bf
> +#define CSR_PMPADDR16                  0x3c0
> +#define CSR_PMPADDR17                  0x3c1
> +#define CSR_PMPADDR18                  0x3c2
> +#define CSR_PMPADDR19                  0x3c3
> +#define CSR_PMPADDR20                  0x3c4
> +#define CSR_PMPADDR21                  0x3c5
> +#define CSR_PMPADDR22                  0x3c6
> +#define CSR_PMPADDR23                  0x3c7
> +#define CSR_PMPADDR24                  0x3c8
> +#define CSR_PMPADDR25                  0x3c9
> +#define CSR_PMPADDR26                  0x3ca
> +#define CSR_PMPADDR27                  0x3cb
> +#define CSR_PMPADDR28                  0x3cc
> +#define CSR_PMPADDR29                  0x3cd
> +#define CSR_PMPADDR30                  0x3ce
> +#define CSR_PMPADDR31                  0x3cf
> +#define CSR_PMPADDR32                  0x3d0
> +#define CSR_PMPADDR33                  0x3d1
> +#define CSR_PMPADDR34                  0x3d2
> +#define CSR_PMPADDR35                  0x3d3
> +#define CSR_PMPADDR36                  0x3d4
> +#define CSR_PMPADDR37                  0x3d5
> +#define CSR_PMPADDR38                  0x3d6
> +#define CSR_PMPADDR39                  0x3d7
> +#define CSR_PMPADDR40                  0x3d8
> +#define CSR_PMPADDR41                  0x3d9
> +#define CSR_PMPADDR42                  0x3da
> +#define CSR_PMPADDR43                  0x3db
> +#define CSR_PMPADDR44                  0x3dc
> +#define CSR_PMPADDR45                  0x3dd
> +#define CSR_PMPADDR46                  0x3de
> +#define CSR_PMPADDR47                  0x3df
> +#define CSR_PMPADDR48                  0x3e0
> +#define CSR_PMPADDR49                  0x3e1
> +#define CSR_PMPADDR50                  0x3e2
> +#define CSR_PMPADDR51                  0x3e3
> +#define CSR_PMPADDR52                  0x3e4
> +#define CSR_PMPADDR53                  0x3e5
> +#define CSR_PMPADDR54                  0x3e6
> +#define CSR_PMPADDR55                  0x3e7
> +#define CSR_PMPADDR56                  0x3e8
> +#define CSR_PMPADDR57                  0x3e9
> +#define CSR_PMPADDR58                  0x3ea
> +#define CSR_PMPADDR59                  0x3eb
> +#define CSR_PMPADDR60                  0x3ec
> +#define CSR_PMPADDR61                  0x3ed
> +#define CSR_PMPADDR62                  0x3ee
> +#define CSR_PMPADDR63                  0x3ef
> +
> +/* Machine Counters/Timers */
> +#define CSR_MCYCLE                     0xb00
> +#define CSR_MINSTRET                   0xb02
> +#define CSR_MHPMCOUNTER3               0xb03
> +#define CSR_MHPMCOUNTER4               0xb04
> +#define CSR_MHPMCOUNTER5               0xb05
> +#define CSR_MHPMCOUNTER6               0xb06
> +#define CSR_MHPMCOUNTER7               0xb07
> +#define CSR_MHPMCOUNTER8               0xb08
> +#define CSR_MHPMCOUNTER9               0xb09
> +#define CSR_MHPMCOUNTER10              0xb0a
> +#define CSR_MHPMCOUNTER11              0xb0b
> +#define CSR_MHPMCOUNTER12              0xb0c
> +#define CSR_MHPMCOUNTER13              0xb0d
> +#define CSR_MHPMCOUNTER14              0xb0e
> +#define CSR_MHPMCOUNTER15              0xb0f
> +#define CSR_MHPMCOUNTER16              0xb10
> +#define CSR_MHPMCOUNTER17              0xb11
> +#define CSR_MHPMCOUNTER18              0xb12
> +#define CSR_MHPMCOUNTER19              0xb13
> +#define CSR_MHPMCOUNTER20              0xb14
> +#define CSR_MHPMCOUNTER21              0xb15
> +#define CSR_MHPMCOUNTER22              0xb16
> +#define CSR_MHPMCOUNTER23              0xb17
> +#define CSR_MHPMCOUNTER24              0xb18
> +#define CSR_MHPMCOUNTER25              0xb19
> +#define CSR_MHPMCOUNTER26              0xb1a
> +#define CSR_MHPMCOUNTER27              0xb1b
> +#define CSR_MHPMCOUNTER28              0xb1c
> +#define CSR_MHPMCOUNTER29              0xb1d
> +#define CSR_MHPMCOUNTER30              0xb1e
> +#define CSR_MHPMCOUNTER31              0xb1f
> +#define CSR_MCYCLEH                    0xb80
> +#define CSR_MINSTRETH                  0xb82
> +#define CSR_MHPMCOUNTER3H              0xb83
> +#define CSR_MHPMCOUNTER4H              0xb84
> +#define CSR_MHPMCOUNTER5H              0xb85
> +#define CSR_MHPMCOUNTER6H              0xb86
> +#define CSR_MHPMCOUNTER7H              0xb87
> +#define CSR_MHPMCOUNTER8H              0xb88
> +#define CSR_MHPMCOUNTER9H              0xb89
> +#define CSR_MHPMCOUNTER10H             0xb8a
> +#define CSR_MHPMCOUNTER11H             0xb8b
> +#define CSR_MHPMCOUNTER12H             0xb8c
> +#define CSR_MHPMCOUNTER13H             0xb8d
> +#define CSR_MHPMCOUNTER14H             0xb8e
> +#define CSR_MHPMCOUNTER15H             0xb8f
> +#define CSR_MHPMCOUNTER16H             0xb90
> +#define CSR_MHPMCOUNTER17H             0xb91
> +#define CSR_MHPMCOUNTER18H             0xb92
> +#define CSR_MHPMCOUNTER19H             0xb93
> +#define CSR_MHPMCOUNTER20H             0xb94
> +#define CSR_MHPMCOUNTER21H             0xb95
> +#define CSR_MHPMCOUNTER22H             0xb96
> +#define CSR_MHPMCOUNTER23H             0xb97
> +#define CSR_MHPMCOUNTER24H             0xb98
> +#define CSR_MHPMCOUNTER25H             0xb99
> +#define CSR_MHPMCOUNTER26H             0xb9a
> +#define CSR_MHPMCOUNTER27H             0xb9b
> +#define CSR_MHPMCOUNTER28H             0xb9c
> +#define CSR_MHPMCOUNTER29H             0xb9d
> +#define CSR_MHPMCOUNTER30H             0xb9e
> +#define CSR_MHPMCOUNTER31H             0xb9f
> +
> +/* Machine Counter Setup */
> +#define CSR_MCOUNTINHIBIT              0x320
> +#define CSR_MHPMEVENT3                 0x323
> +#define CSR_MHPMEVENT4                 0x324
> +#define CSR_MHPMEVENT5                 0x325
> +#define CSR_MHPMEVENT6                 0x326
> +#define CSR_MHPMEVENT7                 0x327
> +#define CSR_MHPMEVENT8                 0x328
> +#define CSR_MHPMEVENT9                 0x329
> +#define CSR_MHPMEVENT10                        0x32a
> +#define CSR_MHPMEVENT11                        0x32b
> +#define CSR_MHPMEVENT12                        0x32c
> +#define CSR_MHPMEVENT13                        0x32d
> +#define CSR_MHPMEVENT14                        0x32e
> +#define CSR_MHPMEVENT15                        0x32f
> +#define CSR_MHPMEVENT16                        0x330
> +#define CSR_MHPMEVENT17                        0x331
> +#define CSR_MHPMEVENT18                        0x332
> +#define CSR_MHPMEVENT19                        0x333
> +#define CSR_MHPMEVENT20                        0x334
> +#define CSR_MHPMEVENT21                        0x335
> +#define CSR_MHPMEVENT22                        0x336
> +#define CSR_MHPMEVENT23                        0x337
> +#define CSR_MHPMEVENT24                        0x338
> +#define CSR_MHPMEVENT25                        0x339
> +#define CSR_MHPMEVENT26                        0x33a
> +#define CSR_MHPMEVENT27                        0x33b
> +#define CSR_MHPMEVENT28                        0x33c
> +#define CSR_MHPMEVENT29                        0x33d
> +#define CSR_MHPMEVENT30                        0x33e
> +#define CSR_MHPMEVENT31                        0x33f
> +
> +/* For RV32 */
> +#define CSR_MHPMEVENT3H                        0x723
> +#define CSR_MHPMEVENT4H                        0x724
> +#define CSR_MHPMEVENT5H                        0x725
> +#define CSR_MHPMEVENT6H                        0x726
> +#define CSR_MHPMEVENT7H                        0x727
> +#define CSR_MHPMEVENT8H                        0x728
> +#define CSR_MHPMEVENT9H                        0x729
> +#define CSR_MHPMEVENT10H               0x72a
> +#define CSR_MHPMEVENT11H               0x72b
> +#define CSR_MHPMEVENT12H               0x72c
> +#define CSR_MHPMEVENT13H               0x72d
> +#define CSR_MHPMEVENT14H               0x72e
> +#define CSR_MHPMEVENT15H               0x72f
> +#define CSR_MHPMEVENT16H               0x730
> +#define CSR_MHPMEVENT17H               0x731
> +#define CSR_MHPMEVENT18H               0x732
> +#define CSR_MHPMEVENT19H               0x733
> +#define CSR_MHPMEVENT20H               0x734
> +#define CSR_MHPMEVENT21H               0x735
> +#define CSR_MHPMEVENT22H               0x736
> +#define CSR_MHPMEVENT23H               0x737
> +#define CSR_MHPMEVENT24H               0x738
> +#define CSR_MHPMEVENT25H               0x739
> +#define CSR_MHPMEVENT26H               0x73a
> +#define CSR_MHPMEVENT27H               0x73b
> +#define CSR_MHPMEVENT28H               0x73c
> +#define CSR_MHPMEVENT29H               0x73d
> +#define CSR_MHPMEVENT30H               0x73e
> +#define CSR_MHPMEVENT31H               0x73f
> +
> +/* Counter Overflow CSR */
> +#define CSR_SCOUNTOVF                  0xda0
> +
> +/* Debug/Trace Registers */
> +#define CSR_TSELECT                    0x7a0
> +#define CSR_TDATA1                     0x7a1
> +#define CSR_TDATA2                     0x7a2
> +#define CSR_TDATA3                     0x7a3
> +
> +/* Debug Mode Registers */
> +#define CSR_DCSR                       0x7b0
> +#define CSR_DPC                                0x7b1
> +#define CSR_DSCRATCH0                  0x7b2
> +#define CSR_DSCRATCH1                  0x7b3
> +
> +/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
> +#define CSR_MISELECT                   0x350
> +#define CSR_MIREG                      0x351
> +
> +/* Machine-Level Interrupts (AIA) */
> +#define CSR_MTOPI                      0xfb0
> +
> +/* Machine-Level IMSIC Interface (AIA) */
> +#define CSR_MSETEIPNUM                 0x358
> +#define CSR_MCLREIPNUM                 0x359
> +#define CSR_MSETEIENUM                 0x35a
> +#define CSR_MCLREIENUM                 0x35b
> +#define CSR_MTOPEI                     0x35c
> +
> +/* Virtual Interrupts for Supervisor Level (AIA) */
> +#define CSR_MVIEN                      0x308
> +#define CSR_MVIP                       0x309
> +
> +/* Smstateen extension registers */
> +/* Machine stateen CSRs */
> +#define CSR_MSTATEEN0                  0x30C
> +#define CSR_MSTATEEN0H                 0x31C
> +#define CSR_MSTATEEN1                  0x30D
> +#define CSR_MSTATEEN1H                 0x31D
> +#define CSR_MSTATEEN2                  0x30E
> +#define CSR_MSTATEEN2H                 0x31E
> +#define CSR_MSTATEEN3                  0x30F
> +#define CSR_MSTATEEN3H                 0x31F
> +
> +/* Machine-Level High-Half CSRs (AIA) */
> +#define CSR_MIDELEGH                   0x313
> +#define CSR_MIEH                       0x314
> +#define CSR_MVIENH                     0x318
> +#define CSR_MVIPH                      0x319
> +#define CSR_MIPH                       0x354
> +
> +/* ===== Trap/Exception Causes ===== */
> +
> +/* Exception cause high bit - is an interrupt if set */
> +#define CAUSE_IRQ_FLAG                 (_UL(1) << (__riscv_xlen - 1))
> +
> +#define CAUSE_MISALIGNED_FETCH         0x0
> +#define CAUSE_FETCH_ACCESS             0x1
> +#define CAUSE_ILLEGAL_INSTRUCTION      0x2
> +#define CAUSE_BREAKPOINT               0x3
> +#define CAUSE_MISALIGNED_LOAD          0x4
> +#define CAUSE_LOAD_ACCESS              0x5
> +#define CAUSE_MISALIGNED_STORE         0x6
> +#define CAUSE_STORE_ACCESS             0x7
> +#define CAUSE_USER_ECALL               0x8
> +#define CAUSE_SUPERVISOR_ECALL         0x9
> +#define CAUSE_VIRTUAL_SUPERVISOR_ECALL 0xa
> +#define CAUSE_MACHINE_ECALL            0xb
> +#define CAUSE_FETCH_PAGE_FAULT         0xc
> +#define CAUSE_LOAD_PAGE_FAULT          0xd
> +#define CAUSE_STORE_PAGE_FAULT         0xf
> +#define CAUSE_FETCH_GUEST_PAGE_FAULT   0x14
> +#define CAUSE_LOAD_GUEST_PAGE_FAULT    0x15
> +#define CAUSE_VIRTUAL_INST_FAULT       0x16
> +#define CAUSE_STORE_GUEST_PAGE_FAULT   0x17
> +
> +/* Common defines for all smstateen */
> +#define SMSTATEEN_MAX_COUNT            4
> +#define SMSTATEEN0_CS_SHIFT            0
> +#define SMSTATEEN0_CS                  (_ULL(1) << SMSTATEEN0_CS_SHIFT)
> +#define SMSTATEEN0_FCSR_SHIFT          1
> +#define SMSTATEEN0_FCSR                        (_ULL(1) << SMSTATEEN0_FCSR_SHIFT)
> +#define SMSTATEEN0_IMSIC_SHIFT         58
> +#define SMSTATEEN0_IMSIC               (_ULL(1) << SMSTATEEN0_IMSIC_SHIFT)
> +#define SMSTATEEN0_AIA_SHIFT           59
> +#define SMSTATEEN0_AIA                 (_ULL(1) << SMSTATEEN0_AIA_SHIFT)
> +#define SMSTATEEN0_SVSLCT_SHIFT                60
> +#define SMSTATEEN0_SVSLCT              (_ULL(1) << SMSTATEEN0_SVSLCT_SHIFT)
> +#define SMSTATEEN0_HSENVCFG_SHIFT      62
> +#define SMSTATEEN0_HSENVCFG            (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
> +#define SMSTATEEN_STATEN_SHIFT         63
> +#define SMSTATEEN_STATEN               (_ULL(1) << SMSTATEEN_STATEN_SHIFT)
> +
> +/* ===== Instruction Encodings ===== */
> +
> +#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_MASK_WFI                  0xffffff00
> +#define INSN_MATCH_WFI                 0x10500000
> +
> +#define INSN_16BIT_MASK                        0x3
> +#define INSN_32BIT_MASK                        0x1c
> +
> +#define INSN_IS_16BIT(insn)            \
> +       (((insn) & INSN_16BIT_MASK) != INSN_16BIT_MASK)
> +#define INSN_IS_32BIT(insn)            \
> +       (((insn) & INSN_16BIT_MASK) == INSN_16BIT_MASK && \
> +        ((insn) & INSN_32BIT_MASK) != INSN_32BIT_MASK)
> +
> +#define INSN_LEN(insn)                 (INSN_IS_16BIT(insn) ? 2 : 4)
> +
> +#if __riscv_xlen == 64
> +#define LOG_REGBYTES                   3
> +#else
> +#define LOG_REGBYTES                   2
> +#endif
> +#define REGBYTES                       (1 << LOG_REGBYTES)
> +
> +#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)       \
> +       (unsigned long *)((unsigned long)(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
> +
> +/* clang-format on */
> +
> +#endif
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header
  2023-01-20 14:59 ` [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header Oleksii Kurochko
@ 2023-01-22 23:25   ` Alistair Francis
  2023-01-23 13:57   ` Jan Beulich
  1 sibling, 0 replies; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 23:25 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  xen/arch/riscv/include/asm/csr.h | 82 ++++++++++++++++++++++++++++++++
>  1 file changed, 82 insertions(+)
>  create mode 100644 xen/arch/riscv/include/asm/csr.h
>
> diff --git a/xen/arch/riscv/include/asm/csr.h b/xen/arch/riscv/include/asm/csr.h
> new file mode 100644
> index 0000000000..1a879c6c4d
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/csr.h
> @@ -0,0 +1,82 @@
> +/*
> + * Take from Linux.
> + *
> + * SPDX-License-Identifier: GPL-2.0-only
> + *
> + * Copyright (C) 2015 Regents of the University of California
> + */
> +
> +#ifndef _ASM_RISCV_CSR_H
> +#define _ASM_RISCV_CSR_H
> +
> +#include <asm/asm.h>
> +#include <xen/const.h>
> +#include <asm/riscv_encoding.h>
> +
> +#ifndef __ASSEMBLY__
> +
> +#define csr_read(csr)                                          \
> +({                                                             \
> +       register unsigned long __v;                             \
> +       __asm__ __volatile__ ("csrr %0, " __ASM_STR(csr)        \
> +                             : "=r" (__v) :                    \
> +                             : "memory");                      \
> +       __v;                                                    \
> +})
> +
> +#define csr_write(csr, val)                                    \
> +({                                                             \
> +       unsigned long __v = (unsigned long)(val);               \
> +       __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0"     \
> +                             : : "rK" (__v)                    \
> +                             : "memory");                      \
> +})
> +
> +/*
> +#define csr_swap(csr, val)                                     \
> +({                                                             \
> +       unsigned long __v = (unsigned long)(val);               \
> +       __asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
> +                             : "=r" (__v) : "rK" (__v)         \
> +                             : "memory");                      \
> +       __v;                                                    \
> +})
> +
> +#define csr_read_set(csr, val)                                 \
> +({                                                             \
> +       unsigned long __v = (unsigned long)(val);               \
> +       __asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
> +                             : "=r" (__v) : "rK" (__v)         \
> +                             : "memory");                      \
> +       __v;                                                    \
> +})
> +
> +#define csr_set(csr, val)                                      \
> +({                                                             \
> +       unsigned long __v = (unsigned long)(val);               \
> +       __asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0"     \
> +                             : : "rK" (__v)                    \
> +                             : "memory");                      \
> +})
> +
> +#define csr_read_clear(csr, val)                               \
> +({                                                             \
> +       unsigned long __v = (unsigned long)(val);               \
> +       __asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
> +                             : "=r" (__v) : "rK" (__v)         \
> +                             : "memory");                      \
> +       __v;                                                    \
> +})
> +
> +#define csr_clear(csr, val)                                    \
> +({                                                             \
> +       unsigned long __v = (unsigned long)(val);               \
> +       __asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0"     \
> +                             : : "rK" (__v)                    \
> +                             : "memory");                      \
> +})
> +*/
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _ASM_RISCV_CSR_H */
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-20 14:59 ` [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation Oleksii Kurochko
@ 2023-01-22 23:29   ` Alistair Francis
  2023-01-23 11:17   ` Jan Beulich
  2023-01-23 11:50   ` Andrew Cooper
  2 siblings, 0 replies; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 23:29 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> The patch introduces an implementation of basic exception handlers:
> - to save/restore context
> - to handle an exception itself. The handler calls wait_for_interrupt
>   now, nothing more.
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  xen/arch/riscv/Makefile            |  2 +
>  xen/arch/riscv/entry.S             | 97 ++++++++++++++++++++++++++++++
>  xen/arch/riscv/include/asm/traps.h | 13 ++++
>  xen/arch/riscv/traps.c             | 13 ++++
>  4 files changed, 125 insertions(+)
>  create mode 100644 xen/arch/riscv/entry.S
>  create mode 100644 xen/arch/riscv/include/asm/traps.h
>  create mode 100644 xen/arch/riscv/traps.c
>
> diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
> index 1a4f1a6015..443f6bf15f 100644
> --- a/xen/arch/riscv/Makefile
> +++ b/xen/arch/riscv/Makefile
> @@ -1,7 +1,9 @@
>  obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
> +obj-y += entry.o
>  obj-$(CONFIG_RISCV_64) += riscv64/
>  obj-y += sbi.o
>  obj-y += setup.o
> +obj-y += traps.o
>
>  $(TARGET): $(TARGET)-syms
>         $(OBJCOPY) -O binary -S $< $@
> diff --git a/xen/arch/riscv/entry.S b/xen/arch/riscv/entry.S
> new file mode 100644
> index 0000000000..f7d46f42bb
> --- /dev/null
> +++ b/xen/arch/riscv/entry.S
> @@ -0,0 +1,97 @@
> +#include <asm/asm.h>
> +#include <asm/processor.h>
> +#include <asm/riscv_encoding.h>
> +#include <asm/traps.h>
> +
> +        .global handle_exception
> +        .align 4
> +
> +handle_exception:
> +
> +    /* Exceptions from xen */
> +save_to_stack:
> +        /* Save context to stack */
> +        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) - RISCV_CPU_USER_REGS_SIZE) (sp)
> +        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
> +        j       save_context
> +
> +save_context:
> +        /* Save registers */
> +        REG_S   ra, RISCV_CPU_USER_REGS_OFFSET(ra)(sp)
> +        REG_S   gp, RISCV_CPU_USER_REGS_OFFSET(gp)(sp)
> +        REG_S   t1, RISCV_CPU_USER_REGS_OFFSET(t1)(sp)
> +        REG_S   t2, RISCV_CPU_USER_REGS_OFFSET(t2)(sp)
> +        REG_S   s0, RISCV_CPU_USER_REGS_OFFSET(s0)(sp)
> +        REG_S   s1, RISCV_CPU_USER_REGS_OFFSET(s1)(sp)
> +        REG_S   a0, RISCV_CPU_USER_REGS_OFFSET(a0)(sp)
> +        REG_S   a1, RISCV_CPU_USER_REGS_OFFSET(a1)(sp)
> +        REG_S   a2, RISCV_CPU_USER_REGS_OFFSET(a2)(sp)
> +        REG_S   a3, RISCV_CPU_USER_REGS_OFFSET(a3)(sp)
> +        REG_S   a4, RISCV_CPU_USER_REGS_OFFSET(a4)(sp)
> +        REG_S   a5, RISCV_CPU_USER_REGS_OFFSET(a5)(sp)
> +        REG_S   a6, RISCV_CPU_USER_REGS_OFFSET(a6)(sp)
> +        REG_S   a7, RISCV_CPU_USER_REGS_OFFSET(a7)(sp)
> +        REG_S   s2, RISCV_CPU_USER_REGS_OFFSET(s2)(sp)
> +        REG_S   s3, RISCV_CPU_USER_REGS_OFFSET(s3)(sp)
> +        REG_S   s4, RISCV_CPU_USER_REGS_OFFSET(s4)(sp)
> +        REG_S   s5, RISCV_CPU_USER_REGS_OFFSET(s5)(sp)
> +        REG_S   s6, RISCV_CPU_USER_REGS_OFFSET(s6)(sp)
> +        REG_S   s7, RISCV_CPU_USER_REGS_OFFSET(s7)(sp)
> +        REG_S   s8, RISCV_CPU_USER_REGS_OFFSET(s8)(sp)
> +        REG_S   s9, RISCV_CPU_USER_REGS_OFFSET(s9)(sp)
> +        REG_S   s10, RISCV_CPU_USER_REGS_OFFSET(s10)(sp)
> +        REG_S   s11, RISCV_CPU_USER_REGS_OFFSET(s11)(sp)
> +        REG_S   t3, RISCV_CPU_USER_REGS_OFFSET(t3)(sp)
> +        REG_S   t4, RISCV_CPU_USER_REGS_OFFSET(t4)(sp)
> +        REG_S   t5, RISCV_CPU_USER_REGS_OFFSET(t5)(sp)
> +        REG_S   t6, RISCV_CPU_USER_REGS_OFFSET(t6)(sp)
> +        csrr    t0, CSR_SEPC
> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sepc)(sp)
> +        csrr    t0, CSR_SSTATUS
> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sstatus)(sp)
> +
> +        mv      a0, sp
> +        jal     __handle_exception
> +
> +restore_registers:
> +        /* Restore stack_cpu_regs */
> +        REG_L   t0, RISCV_CPU_USER_REGS_OFFSET(sepc)(sp)
> +        csrw    CSR_SEPC, t0
> +        REG_L   t0, RISCV_CPU_USER_REGS_OFFSET(sstatus)(sp)
> +        csrw    CSR_SSTATUS, t0
> +
> +        REG_L   ra, RISCV_CPU_USER_REGS_OFFSET(ra)(sp)
> +        REG_L   gp, RISCV_CPU_USER_REGS_OFFSET(gp)(sp)
> +        REG_L   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
> +        REG_L   t1, RISCV_CPU_USER_REGS_OFFSET(t1)(sp)
> +        REG_L   t2, RISCV_CPU_USER_REGS_OFFSET(t2)(sp)
> +        REG_L   s0, RISCV_CPU_USER_REGS_OFFSET(s0)(sp)
> +        REG_L   s1, RISCV_CPU_USER_REGS_OFFSET(s1)(sp)
> +        REG_L   a0, RISCV_CPU_USER_REGS_OFFSET(a0)(sp)
> +        REG_L   a1, RISCV_CPU_USER_REGS_OFFSET(a1)(sp)
> +        REG_L   a2, RISCV_CPU_USER_REGS_OFFSET(a2)(sp)
> +        REG_L   a3, RISCV_CPU_USER_REGS_OFFSET(a3)(sp)
> +        REG_L   a4, RISCV_CPU_USER_REGS_OFFSET(a4)(sp)
> +        REG_L   a5, RISCV_CPU_USER_REGS_OFFSET(a5)(sp)
> +        REG_L   a6, RISCV_CPU_USER_REGS_OFFSET(a6)(sp)
> +        REG_L   a7, RISCV_CPU_USER_REGS_OFFSET(a7)(sp)
> +        REG_L   s2, RISCV_CPU_USER_REGS_OFFSET(s2)(sp)
> +        REG_L   s3, RISCV_CPU_USER_REGS_OFFSET(s3)(sp)
> +        REG_L   s4, RISCV_CPU_USER_REGS_OFFSET(s4)(sp)
> +        REG_L   s5, RISCV_CPU_USER_REGS_OFFSET(s5)(sp)
> +        REG_L   s6, RISCV_CPU_USER_REGS_OFFSET(s6)(sp)
> +        REG_L   s7, RISCV_CPU_USER_REGS_OFFSET(s7)(sp)
> +        REG_L   s8, RISCV_CPU_USER_REGS_OFFSET(s8)(sp)
> +        REG_L   s9, RISCV_CPU_USER_REGS_OFFSET(s9)(sp)
> +        REG_L   s10, RISCV_CPU_USER_REGS_OFFSET(s10)(sp)
> +        REG_L   s11, RISCV_CPU_USER_REGS_OFFSET(s11)(sp)
> +        REG_L   t3, RISCV_CPU_USER_REGS_OFFSET(t3)(sp)
> +        REG_L   t4, RISCV_CPU_USER_REGS_OFFSET(t4)(sp)
> +        REG_L   t5, RISCV_CPU_USER_REGS_OFFSET(t5)(sp)
> +        REG_L   t6, RISCV_CPU_USER_REGS_OFFSET(t6)(sp)
> +
> +        /* Restore sp */
> +        REG_L   sp, RISCV_CPU_USER_REGS_OFFSET(sp)(sp)
> +
> +        sret
> diff --git a/xen/arch/riscv/include/asm/traps.h b/xen/arch/riscv/include/asm/traps.h
> new file mode 100644
> index 0000000000..816ab1178a
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/traps.h
> @@ -0,0 +1,13 @@
> +#ifndef __ASM_TRAPS_H__
> +#define __ASM_TRAPS_H__
> +
> +#include <asm/processor.h>
> +
> +#ifndef __ASSEMBLY__
> +
> +void __handle_exception(struct cpu_user_regs *cpu_regs);
> +void handle_exception(void);
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* __ASM_TRAPS_H__ */
> diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
> new file mode 100644
> index 0000000000..3201b851ef
> --- /dev/null
> +++ b/xen/arch/riscv/traps.c
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2023 Vates
> + *
> + * RISC-V Trap handlers
> + */
> +#include <asm/processor.h>
> +#include <asm/traps.h>
> +
> +void __handle_exception(struct cpu_user_regs *cpu_regs)
> +{
> +    wait_for_interrupt();
> +}
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff
  2023-01-20 14:59 ` [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff Oleksii Kurochko
@ 2023-01-22 23:38   ` Alistair Francis
  2023-01-23 12:09   ` Andrew Cooper
  1 sibling, 0 replies; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 23:38 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> The patch introduces stuff needed to decode a reason of an
> exception.
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  xen/arch/riscv/traps.c | 88 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 88 insertions(+)
>
> diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
> index 3201b851ef..dd64f053a5 100644
> --- a/xen/arch/riscv/traps.c
> +++ b/xen/arch/riscv/traps.c
> @@ -4,8 +4,96 @@
>   *
>   * RISC-V Trap handlers
>   */
> +#include <asm/csr.h>
> +#include <asm/early_printk.h>
>  #include <asm/processor.h>
>  #include <asm/traps.h>
> +#include <xen/errno.h>
> +
> +const char *decode_trap_cause(unsigned long cause)
> +{
> +    switch ( cause )
> +    {
> +    case CAUSE_MISALIGNED_FETCH:
> +        return "Instruction Address Misaligned";
> +    case CAUSE_FETCH_ACCESS:
> +        return "Instruction Access Fault";
> +    case CAUSE_ILLEGAL_INSTRUCTION:
> +        return "Illegal Instruction";
> +    case CAUSE_BREAKPOINT:
> +        return "Breakpoint";
> +    case CAUSE_MISALIGNED_LOAD:
> +        return "Load Address Misaligned";
> +    case CAUSE_LOAD_ACCESS:
> +        return "Load Access Fault";
> +    case CAUSE_MISALIGNED_STORE:
> +        return "Store/AMO Address Misaligned";
> +    case CAUSE_STORE_ACCESS:
> +        return "Store/AMO Access Fault";
> +    case CAUSE_USER_ECALL:
> +        return "Environment Call from U-Mode";
> +    case CAUSE_SUPERVISOR_ECALL:
> +        return "Environment Call from S-Mode";
> +    case CAUSE_MACHINE_ECALL:
> +        return "Environment Call from M-Mode";
> +    case CAUSE_FETCH_PAGE_FAULT:
> +        return "Instruction Page Fault";
> +    case CAUSE_LOAD_PAGE_FAULT:
> +        return "Load Page Fault";
> +    case CAUSE_STORE_PAGE_FAULT:
> +        return "Store/AMO Page Fault";
> +    case CAUSE_FETCH_GUEST_PAGE_FAULT:
> +        return "Instruction Guest Page Fault";
> +    case CAUSE_LOAD_GUEST_PAGE_FAULT:
> +        return "Load Guest Page Fault";
> +    case CAUSE_VIRTUAL_INST_FAULT:
> +        return "Virtualized Instruction Fault";
> +    case CAUSE_STORE_GUEST_PAGE_FAULT:
> +        return "Guest Store/AMO Page Fault";
> +    default:
> +        return "UNKNOWN";
> +    }
> +}
> +
> +const char *decode_reserved_interrupt_cause(unsigned long irq_cause)
> +{
> +    switch ( irq_cause )
> +    {
> +    case IRQ_M_SOFT:
> +        return "M-mode Software Interrupt";
> +    case IRQ_M_TIMER:
> +        return "M-mode TIMER Interrupt";
> +    case IRQ_M_EXT:
> +        return "M-mode TIMER Interrupt";
> +    default:
> +        return "UNKNOWN IRQ type";
> +    }
> +}
> +
> +const char *decode_interrupt_cause(unsigned long cause)
> +{
> +    unsigned long irq_cause = cause & ~CAUSE_IRQ_FLAG;
> +
> +    switch ( irq_cause )
> +    {
> +    case IRQ_S_SOFT:
> +        return "Supervisor Software Interrupt";
> +    case IRQ_S_TIMER:
> +        return "Supervisor Timer Interrupt";
> +    case IRQ_S_EXT:
> +        return "Supervisor External Interrupt";
> +    default:
> +        return decode_reserved_interrupt_cause(irq_cause);
> +    }
> +}
> +
> +const char *decode_cause(unsigned long cause)
> +{
> +    if ( cause & CAUSE_IRQ_FLAG )
> +        return decode_interrupt_cause(cause);
> +
> +    return decode_trap_cause(cause);
> +}
>
>  void __handle_exception(struct cpu_user_regs *cpu_regs)
>  {
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap()
  2023-01-20 14:59 ` [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap() Oleksii Kurochko
@ 2023-01-22 23:39   ` Alistair Francis
  2023-01-25 17:01     ` Oleksii
  0 siblings, 1 reply; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 23:39 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> The patch introduces the function the purpose of which is to print
> a cause of an exception and call "wfi" instruction.
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
>  xen/arch/riscv/traps.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
> index dd64f053a5..fc25138a4b 100644
> --- a/xen/arch/riscv/traps.c
> +++ b/xen/arch/riscv/traps.c
> @@ -95,7 +95,19 @@ const char *decode_cause(unsigned long cause)
>      return decode_trap_cause(cause);
>  }
>
> -void __handle_exception(struct cpu_user_regs *cpu_regs)
> +static void do_unexpected_trap(const struct cpu_user_regs *regs)
>  {
> +    unsigned long cause = csr_read(CSR_SCAUSE);
> +
> +    early_printk("Unhandled exception: ");
> +    early_printk(decode_cause(cause));
> +    early_printk("\n");
> +
> +    // kind of die...
>      wait_for_interrupt();

We could put this in a loop, to ensure we never progress

Alistair

>  }
> +
> +void __handle_exception(struct cpu_user_regs *cpu_regs)
> +{
> +    do_unexpected_trap(cpu_regs);
> +}
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 10/14] xen/riscv: mask all interrupts
  2023-01-20 14:59 ` [PATCH v1 10/14] xen/riscv: mask all interrupts Oleksii Kurochko
@ 2023-01-22 23:40   ` Alistair Francis
  0 siblings, 0 replies; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 23:40 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  xen/arch/riscv/riscv64/head.S | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/xen/arch/riscv/riscv64/head.S b/xen/arch/riscv/riscv64/head.S
> index d444dd8aad..ffd95f9f89 100644
> --- a/xen/arch/riscv/riscv64/head.S
> +++ b/xen/arch/riscv/riscv64/head.S
> @@ -1,6 +1,11 @@
> +#include <asm/riscv_encoding.h>
> +
>          .section .text.header, "ax", %progbits
>
>  ENTRY(start)
> +        /* Mask all interrupts */
> +        csrw    CSR_SIE, zero
> +
>          la      sp, cpu0_boot_stack
>          li      t0, STACK_SIZE
>          add     sp, sp, t0
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler()
  2023-01-20 14:59 ` [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler() Oleksii Kurochko
@ 2023-01-22 23:41   ` Alistair Francis
  2023-01-23 23:21   ` Andrew Cooper
  1 sibling, 0 replies; 58+ messages in thread
From: Alistair Francis @ 2023-01-22 23:41 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
<oleksii.kurochko@gmail.com> wrote:
>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  xen/arch/riscv/setup.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
> index d09ffe1454..174e134c93 100644
> --- a/xen/arch/riscv/setup.c
> +++ b/xen/arch/riscv/setup.c
> @@ -1,16 +1,27 @@
>  #include <xen/compile.h>
>  #include <xen/init.h>
>
> +#include <asm/csr.h>
>  #include <asm/early_printk.h>
> +#include <asm/traps.h>
>
>  /* Xen stack for bringing up the first CPU. */
>  unsigned char __initdata cpu0_boot_stack[STACK_SIZE]
>      __aligned(STACK_SIZE);
>
> +static void setup_trap_handler(void)
> +{
> +    unsigned long addr = (unsigned long)&handle_exception;
> +    csr_write(CSR_STVEC, addr);
> +}
> +
>  void __init noreturn start_xen(void)
>  {
>      early_printk("Hello from C env\n");
>
> +    setup_trap_handler();
> +    early_printk("exception handler has been setup\n");
> +
>      for ( ;; )
>          asm volatile ("wfi");
>
> --
> 2.39.0
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS
  2023-01-20 15:29   ` Andrew Cooper
@ 2023-01-23 10:43     ` Oleksii
  2023-01-31 11:49       ` Alistair Francis
  0 siblings, 1 reply; 58+ messages in thread
From: Oleksii @ 2023-01-23 10:43 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On Fri, 2023-01-20 at 15:29 +0000, Andrew Cooper wrote:
> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> > Work with some registers requires csr command which is part of
> > Zicsr.
> > 
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> >  xen/arch/riscv/arch.mk | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/xen/arch/riscv/arch.mk b/xen/arch/riscv/arch.mk
> > index 012dc677c3..95b41d9f3e 100644
> > --- a/xen/arch/riscv/arch.mk
> > +++ b/xen/arch/riscv/arch.mk
> > @@ -10,7 +10,7 @@ riscv-march-$(CONFIG_RISCV_ISA_C)       :=
> > $(riscv-march-y)c
> >  # into the upper half _or_ the lower half of the address space.
> >  # -mcmodel=medlow would force Xen into the lower half.
> >  
> > -CFLAGS += -march=$(riscv-march-y) -mstrict-align -mcmodel=medany
> > +CFLAGS += -march=$(riscv-march-y)_zicsr -mstrict-align -
> > mcmodel=medany
> 
> Should we just go straight for G, rather than bumping it along every
> time we make a tweak?
> 
I didn't go straight for G as it represents the “IMAFDZicsr Zifencei”
base and extensions thereby it will be needed to add support for FPU
(at least it requires {save,restore}_fp_state) but I am not sure that
we need it in general.

Another one reason is that Linux kernel introduces _zicsr extenstion
separately (but I am not sure that it can be considered as a serious
argument):
https://elixir.bootlin.com/linux/latest/source/arch/riscv/Makefile#L58
https://lore.kernel.org/all/20221024113000.891820486@linuxfoundation.org/
 
> ~Andrew
~Oleksii



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header
  2023-01-20 15:31   ` Andrew Cooper
@ 2023-01-23 11:00     ` Jan Beulich
  2023-01-23 11:10       ` Andrew Cooper
  0 siblings, 1 reply; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 11:00 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, Oleksii Kurochko, xen-devel

On 20.01.2023 16:31, Andrew Cooper wrote:
> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> 
> There's some stuff in here which is not RISCV-specific.  We really want
> to dedup with the other architectures and move into common.

I have to admit that I'm not fully convinced in this case: What an arch
may or may not need in support of its assembly code may heavily vary. It
would need to be very generic thing which could be moved out. Then again
xen/asm.h feels like slightly odd a name with, as kind of already implied
above, assembly code being at times very specific to an architecture
(including e.g. formatting constraints or whether labels are to be
followed by colons).

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function
  2023-01-20 14:59 ` [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function Oleksii Kurochko
  2023-01-20 15:39   ` Andrew Cooper
@ 2023-01-23 11:10   ` Jan Beulich
  1 sibling, 0 replies; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 11:10 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On 20.01.2023 15:59, Oleksii Kurochko wrote:
> Add ability to print hex number.
> It might be useful to print register value as debug information
> in BUG(), WARN(), etc...
> 
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Orthogonal to Andrew's reply (following which I think would be best)
a couple of comments which may be applicable elsewhere as well:

> --- a/xen/arch/riscv/early_printk.c
> +++ b/xen/arch/riscv/early_printk.c
> @@ -43,3 +43,42 @@ void early_printk(const char *str)
>          str++;
>      }
>  }
> +
> +static void reverse(char *s, int length)

Please can you get things const-correct (const char *s) and signedness-
correct (unsigned int length) from the beginning. We're converting other
code as we touch it, but this is extremely slow going and hence would
better be avoided in the first place in new code.

> +{
> +    int c;
> +    char *begin, *end, temp;
> +
> +    begin  = s;
> +    end    = s + length - 1;
> +
> +    for ( c = 0; c < length/2; c++ )

Style: Blanks around binary operators.

> +    {
> +        temp   = *end;
> +        *end   = *begin;
> +        *begin = temp;
> +
> +        begin++;
> +        end--;
> +    }
> +}
> +
> +void early_printk_hnum(const register_t reg_val)

Likely this function wants to be __init? (All functions that can be
should also be made so.) With that, reverse() then would also want
to become __init.

As to the const here vs the remark further up: In cases like this one
we typically don't use const. You're free to keep it of course, but
I think it should at least be purged from the declaration (and maybe
also the stub).

> +{
> +    char hex[] = "0123456789ABCDEF";

static const char __initconst?

> +    char buf[17] = {0};
> +
> +    register_t num = reg_val;
> +    unsigned int count = 0;
> +
> +    for ( count = 0; num != 0; count++, num >>= 4 )
> +        buf[count] = hex[num & 0x0000000f];

Just 0xf?

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header
  2023-01-23 11:00     ` Jan Beulich
@ 2023-01-23 11:10       ` Andrew Cooper
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Cooper @ 2023-01-23 11:10 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, Oleksii Kurochko, xen-devel

On 23/01/2023 11:00 am, Jan Beulich wrote:
> On 20.01.2023 16:31, Andrew Cooper wrote:
>> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>> There's some stuff in here which is not RISCV-specific.  We really want
>> to dedup with the other architectures and move into common.
> I have to admit that I'm not fully convinced in this case: What an arch
> may or may not need in support of its assembly code may heavily vary. It
> would need to be very generic thing which could be moved out. Then again
> xen/asm.h feels like slightly odd a name with, as kind of already implied
> above, assembly code being at times very specific to an architecture
> (including e.g. formatting constraints or whether labels are to be
> followed by colons).

Half of this header file is re-inventing generic concepts that we
already spell differently in the Xen codebase.

It is the difference between bolting something on the side, and
integrating the code properly.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 06/14] xen/riscv: introduce exception context
  2023-01-20 14:59 ` [PATCH v1 06/14] xen/riscv: introduce exception context Oleksii Kurochko
  2023-01-20 15:54   ` Andrew Cooper
@ 2023-01-23 11:13   ` Jan Beulich
  1 sibling, 0 replies; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 11:13 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, Bobby Eshleman, xen-devel

On 20.01.2023 15:59, Oleksii Kurochko wrote:
> +/* On stack VCPU state */
> +struct cpu_user_regs
> +{
> +    register_t zero;
> +    register_t ra;
> +    register_t sp;
> +    register_t gp;
> +    register_t tp;
> +    register_t t0;
> +    register_t t1;
> +    register_t t2;
> +    register_t s0;
> +    register_t s1;
> +    register_t a0;
> +    register_t a1;
> +    register_t a2;
> +    register_t a3;
> +    register_t a4;
> +    register_t a5;
> +    register_t a6;
> +    register_t a7;
> +    register_t s2;
> +    register_t s3;
> +    register_t s4;
> +    register_t s5;
> +    register_t s6;
> +    register_t s7;
> +    register_t s8;
> +    register_t s9;
> +    register_t s10;
> +    register_t s11;
> +    register_t t3;
> +    register_t t4;
> +    register_t t5;
> +    register_t t6;
> +    register_t sepc;
> +    register_t sstatus;
> +    /* pointer to previous stack_cpu_regs */
> +    register_t pregs;
> +};

What is the planned correlation of this to what x86 a Arm have in their
public headers (under the same name)? I think the public header want
spelling out first, and if a different internal structure is intended to
be used, the interaction between the two would then want outlining in
the description here.

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-20 14:59 ` [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation Oleksii Kurochko
  2023-01-22 23:29   ` Alistair Francis
@ 2023-01-23 11:17   ` Jan Beulich
  2023-01-23 15:04     ` Oleksii
  2023-01-23 11:50   ` Andrew Cooper
  2 siblings, 1 reply; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 11:17 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On 20.01.2023 15:59, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/entry.S
> @@ -0,0 +1,97 @@
> +#include <asm/asm.h>
> +#include <asm/processor.h>
> +#include <asm/riscv_encoding.h>
> +#include <asm/traps.h>
> +
> +        .global handle_exception
> +        .align 4
> +
> +handle_exception:
> +
> +    /* Exceptions from xen */
> +save_to_stack:
> +        /* Save context to stack */
> +        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) - RISCV_CPU_USER_REGS_SIZE) (sp)
> +        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
> +        j       save_context
> +
> +save_context:

Just curious: Why not simply fall through here, i.e. why the J which really
is a NOP in this case?

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 12/14] xen/riscv: introduce an implementation of macros from <asm/bug.h>
  2023-01-20 14:59 ` [PATCH v1 12/14] xen/riscv: introduce an implementation of macros from <asm/bug.h> Oleksii Kurochko
@ 2023-01-23 11:37   ` Jan Beulich
  0 siblings, 0 replies; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 11:37 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On 20.01.2023 15:59, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/bug.h
> @@ -0,0 +1,120 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2021-2023 Vates
> + *
> + */
> +
> +#ifndef _ASM_RISCV_BUG_H
> +#define _ASM_RISCV_BUG_H
> +
> +#include <xen/stringify.h>
> +#include <xen/types.h>
> +
> +#ifndef __ASSEMBLY__
> +
> +struct bug_frame {
> +    signed int loc_disp;    /* Relative address to the bug address */
> +    signed int file_disp;   /* Relative address to the filename */
> +    signed int msg_disp;    /* Relative address to the predicate (for ASSERT) */
> +    uint16_t line;          /* Line number */
> +    uint32_t pad0:16;       /* Padding for 8-bytes align */
> +};
> +
> +#define bug_loc(b) ((const void *)(b) + (b)->loc_disp)
> +#define bug_file(b) ((const void *)(b) + (b)->file_disp);
> +#define bug_line(b) ((b)->line)
> +#define bug_msg(b) ((const char *)(b) + (b)->msg_disp)
> +
> +#define BUGFRAME_run_fn 0
> +#define BUGFRAME_warn   1
> +#define BUGFRAME_bug    2
> +#define BUGFRAME_assert 3
> +
> +#define BUGFRAME_NR     4
> +
> +#define __INSN_LENGTH_MASK  _UL(0x3)
> +#define __INSN_LENGTH_32    _UL(0x3)
> +#define __COMPRESSED_INSN_MASK	_UL(0xffff)
> +
> +#define __BUG_INSN_32	_UL(0x00100073) /* ebreak */
> +#define __BUG_INSN_16	_UL(0x9002) /* c.ebreak */

May I suggest that you avoid double-underscore (or other reserved) names
where possible?

> +#define GET_INSN_LENGTH(insn)						\
> +({									\
> +	unsigned long __len;						\
> +	__len = ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ?	\
> +		4UL : 2UL;						\
> +	__len;								\
> +})
> +
> +typedef u32 bug_insn_t;

This is problematic beyond the u32 instead of uint32_t. You use it once, ...

> +/* These are defined by the architecture */
> +int is_valid_bugaddr(bug_insn_t addr);

... in a call to this function, but you can't assume that you can access
32 bits when the insn you look at might be a compressed one. Just to be
on the safe side I'd like to suggest to either avoid such a type, or to
introduce two (32- and 16-bit) which then of course need using properly
in respective contexts.


> +#define BUG_FN_REG t0
> +
> +/* Many versions of GCC doesn't support the asm %c parameter which would
> + * be preferable to this unpleasantness. We use mergeable string
> + * sections to avoid multiple copies of the string appearing in the
> + * Xen image. BUGFRAME_run_fn needs to be handled separately.
> + */
> +#define BUG_FRAME(type, line, file, has_msg, msg) do {                      \
> +    asm ("1:ebreak\n"														\

Something's odd with the padding here; looks like there might be hard tabs.

> +         ".pushsection .rodata.str, \"aMS\", %progbits, 1\n"                \
> +         "2:\t.asciz " __stringify(file) "\n"                               \
> +         "3:\n"                                                             \
> +         ".if " #has_msg "\n"                                               \
> +         "\t.asciz " #msg "\n"                                              \
> +         ".endif\n"                                                         \
> +         ".popsection\n"                                                    \
> +         ".pushsection .bug_frames." __stringify(type) ", \"a\", %progbits\n"\
> +         "4:\n"                                                             \
> +         ".p2align 2\n"                                                     \
> +         ".long (1b - 4b)\n"                                                \
> +         ".long (2b - 4b)\n"                                                \
> +         ".long (3b - 4b)\n"                                                \
> +         ".hword " __stringify(line) ", 0\n"                                \
> +         ".popsection");                                                    \
> +} while (0)
> +
> +/*
> + * GCC will not allow to use "i"  when PIE is enabled (Xen doesn't set the
> + * flag but instead rely on the default value from the compiler). So the
> + * easiest way to implement run_in_exception_handler() is to pass the to
> + * be called function in a fixed register.
> + */
> +#define  run_in_exception_handler(fn) do {                                  \

With

    register void *fn_ asm(__stringify(BUG_FN_REG)) = (fn);

you should be able to avoid ...

> +    asm ("mv " __stringify(BUG_FN_REG) ", %0\n"                            	\

... this and simply use ...

> +         "1:ebreak\n"                                                  		\
> +         ".pushsection .bug_frames." __stringify(BUGFRAME_run_fn) ","       \
> +         "             \"a\", %%progbits\n"                                 \
> +         "2:\n"                                                             \
> +         ".p2align 2\n"                                                     \
> +         ".long (1b - 2b)\n"                                                \
> +         ".long 0, 0, 0\n"                                                  \
> +         ".popsection" :: "r" (fn) : __stringify(BUG_FN_REG) );             \

   :: "r" (fn_) );

here. See x86's alternative_callN() for similar examples.

> @@ -107,7 +108,122 @@ static void do_unexpected_trap(const struct cpu_user_regs *regs)
>      wait_for_interrupt();
>  }
>  
> +void show_execution_state(const struct cpu_user_regs *regs)
> +{
> +    early_printk("implement show_execution_state(regs)\n");
> +}
> +
> +int do_bug_frame(struct cpu_user_regs *regs, vaddr_t pc)
> +{
> +    struct bug_frame *start, *end;
> +    struct bug_frame *bug = NULL;
> +    unsigned int id = 0;
> +    const char *filename, *predicate;
> +    int lineno;
> +
> +    unsigned long bug_frames[] = {
> +        (unsigned long)&__start_bug_frames[0],
> +        (unsigned long)&__stop_bug_frames_0[0],
> +        (unsigned long)&__stop_bug_frames_1[0],
> +        (unsigned long)&__stop_bug_frames_2[0],
> +        (unsigned long)&__stop_bug_frames_3[0],
> +    };
> +
> +    for ( id = 0; id < BUGFRAME_NR; id++ )
> +    {
> +        start = (struct  bug_frame *)bug_frames[id];
> +        end = (struct  bug_frame *)bug_frames[id + 1];
> +
> +        while ( start != end )
> +        {
> +            if ( (vaddr_t)bug_loc(start) == pc )
> +            {
> +                bug = start;
> +                goto found;
> +            }
> +
> +            start++;
> +        }
> +    }
> +
> +found:

Please indent labels by at least one blank; see ./CODING_STYLE.

> +    if ( bug == NULL )
> +        return -ENOENT;
> +
> +    if ( id == BUGFRAME_run_fn )
> +    {
> +        void (*fn)(const struct cpu_user_regs *) = (void *)regs->BUG_FN_REG;
> +
> +        fn(regs);
> +
> +        goto end;
> +    }
> +
> +    /* WARN, BUG or ASSERT: decode the filename pointer and line number. */
> +    filename = bug_file(bug);
> +    lineno = bug_line(bug);
> +
> +    switch ( id )
> +    {
> +    case BUGFRAME_warn:
> +        early_printk("Xen WARN at ");
> +        early_printk(filename);
> +        early_printk(":");
> +        early_printk_hnum(lineno);
> +
> +        show_execution_state(regs);
> +
> +        goto end;
> +
> +    case BUGFRAME_bug:
> +        early_printk("Xen BUG at ");
> +        early_printk(filename);
> +        early_printk(":");
> +        early_printk_hnum(lineno);
> +
> +        show_execution_state(regs);
> +        early_printk("change wait_for_interrupt to panic() when common is available\n");
> +        wait_for_interrupt();
> +
> +    case BUGFRAME_assert:
> +        /* ASSERT: decode the predicate string pointer. */
> +        predicate = bug_msg(bug);
> +
> +        early_printk("Assertion \'");
> +        early_printk(predicate);
> +        early_printk("\' failed at ");
> +        early_printk(filename);
> +        early_printk(":");
> +        early_printk_hnum(lineno);
> +
> +        show_execution_state(regs);
> +        early_printk("change wait_for_interrupt to panic() when common is available\n");
> +        wait_for_interrupt();
> +    }
> +
> +    return -EINVAL;
> +end:
> +    regs->sepc += GET_INSN_LENGTH(*(bug_insn_t *)pc);
> +
> +    return 0;
> +}
> +
> +int is_valid_bugaddr(bug_insn_t insn)
> +{
> +    if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32)
> +        return (insn == __BUG_INSN_32);
> +    else
> +        return ((insn & __COMPRESSED_INSN_MASK) == __BUG_INSN_16);
> +}
> +
>  void __handle_exception(struct cpu_user_regs *cpu_regs)
>  {
> +    register_t pc = cpu_regs->sepc;
> +    uint32_t instr = *(bug_insn_t *)pc;
> +
> +    if (is_valid_bugaddr(instr))
> +        if (!do_bug_frame(cpu_regs, pc)) return;
> +
> +// die:

Perhaps better to omit the label until it's actually needed? In any
event you shouldn't be using C++-style comments (see ./CODING_STYLE
again).

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-20 14:59 ` [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation Oleksii Kurochko
  2023-01-22 23:29   ` Alistair Francis
  2023-01-23 11:17   ` Jan Beulich
@ 2023-01-23 11:50   ` Andrew Cooper
  2023-01-23 12:41     ` Jan Beulich
                       ` (2 more replies)
  2 siblings, 3 replies; 58+ messages in thread
From: Andrew Cooper @ 2023-01-23 11:50 UTC (permalink / raw)
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> diff --git a/xen/arch/riscv/entry.S b/xen/arch/riscv/entry.S
> new file mode 100644
> index 0000000000..f7d46f42bb
> --- /dev/null
> +++ b/xen/arch/riscv/entry.S
> @@ -0,0 +1,97 @@
> +#include <asm/asm.h>
> +#include <asm/processor.h>
> +#include <asm/riscv_encoding.h>
> +#include <asm/traps.h>
> +
> +        .global handle_exception
> +        .align 4
> +
> +handle_exception:

ENTRY() which takes care of the global and the align.

Also, you want a size and type at the end, just like in head.S  (Sorry,
we *still* don't have any sane infrastructure for doing that nicely. 
Opencode it for now.)

> +
> +    /* Exceptions from xen */
> +save_to_stack:

This label isn't used at all, is it?

> +        /* Save context to stack */
> +        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) - RISCV_CPU_USER_REGS_SIZE) (sp)
> +        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)

Exceptions on RISC-V don't adjust the stack pointer.  This logic depends
on interrupting Xen code, and Xen not having suffered a stack overflow
(and actually, that the space on the stack for all registers also
doesn't overflow).

Which might be fine for now, but I think it warrants a comment somewhere
(probably at handle_exception itself) stating the expectations while
it's still a work in progress.  So in this case something like:

/* Work-in-progress:  Depends on interrupting Xen, and the stack being
good. */


But, do we want to allocate stemp right away (even with an empty
struct), and get tp set up properly?

That said, aren't we going to have to rewrite this when enabling H mode
anyway?

> +        j       save_context
> +
> +save_context:

I'd drop this.  It's a nop right now.

> <snip>
> +        csrr    t0, CSR_SEPC
> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sepc)(sp)
> +        csrr    t0, CSR_SSTATUS
> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sstatus)(sp)

So something I've noticed about CSRs through this series.

The C CSR macros are set up to use real CSR names, but the CSR_*
constants used in C and ASM are raw numbers.

If we're using raw numbers, then the C CSR accessors should be static
inlines instead, but the advantage of using names is the toolchain can
issue an error when we reference a CSR not supported by the current
extensions.

We ought to use a single form, consistently through Xen.  How feasible
will it be to use names throughout?

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 06/14] xen/riscv: introduce exception context
  2023-01-20 15:54   ` Andrew Cooper
@ 2023-01-23 12:03     ` Oleksii
  2023-01-23 12:25       ` Andrew Cooper
  0 siblings, 1 reply; 58+ messages in thread
From: Oleksii @ 2023-01-23 12:03 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, Bobby Eshleman

On Fri, 2023-01-20 at 15:54 +0000, Andrew Cooper wrote:
> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> > diff --git a/xen/arch/riscv/include/asm/processor.h
> > b/xen/arch/riscv/include/asm/processor.h
> > new file mode 100644
> > index 0000000000..5898a09ce6
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/processor.h
> > @@ -0,0 +1,114 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*****************************************************************
> > *************
> > + *
> > + * Copyright 2019 (C) Alistair Francis <alistair.francis@wdc.com>
> > + * Copyright 2021 (C) Bobby Eshleman <bobby.eshleman@gmail.com>
> > + * Copyright 2023 (C) Vates
> > + *
> > + */
> > +
> > +#ifndef _ASM_RISCV_PROCESSOR_H
> > +#define _ASM_RISCV_PROCESSOR_H
> > +
> > +#include <asm/types.h>
> > +
> > +#define RISCV_CPU_USER_REGS_zero        0
> > +#define RISCV_CPU_USER_REGS_ra          1
> > +#define RISCV_CPU_USER_REGS_sp          2
> > +#define RISCV_CPU_USER_REGS_gp          3
> > +#define RISCV_CPU_USER_REGS_tp          4
> > +#define RISCV_CPU_USER_REGS_t0          5
> > +#define RISCV_CPU_USER_REGS_t1          6
> > +#define RISCV_CPU_USER_REGS_t2          7
> > +#define RISCV_CPU_USER_REGS_s0          8
> > +#define RISCV_CPU_USER_REGS_s1          9
> > +#define RISCV_CPU_USER_REGS_a0          10
> > +#define RISCV_CPU_USER_REGS_a1          11
> > +#define RISCV_CPU_USER_REGS_a2          12
> > +#define RISCV_CPU_USER_REGS_a3          13
> > +#define RISCV_CPU_USER_REGS_a4          14
> > +#define RISCV_CPU_USER_REGS_a5          15
> > +#define RISCV_CPU_USER_REGS_a6          16
> > +#define RISCV_CPU_USER_REGS_a7          17
> > +#define RISCV_CPU_USER_REGS_s2          18
> > +#define RISCV_CPU_USER_REGS_s3          19
> > +#define RISCV_CPU_USER_REGS_s4          20
> > +#define RISCV_CPU_USER_REGS_s5          21
> > +#define RISCV_CPU_USER_REGS_s6          22
> > +#define RISCV_CPU_USER_REGS_s7          23
> > +#define RISCV_CPU_USER_REGS_s8          24
> > +#define RISCV_CPU_USER_REGS_s9          25
> > +#define RISCV_CPU_USER_REGS_s10         26
> > +#define RISCV_CPU_USER_REGS_s11         27
> > +#define RISCV_CPU_USER_REGS_t3          28
> > +#define RISCV_CPU_USER_REGS_t4          29
> > +#define RISCV_CPU_USER_REGS_t5          30
> > +#define RISCV_CPU_USER_REGS_t6          31
> > +#define RISCV_CPU_USER_REGS_sepc        32
> > +#define RISCV_CPU_USER_REGS_sstatus     33
> > +#define RISCV_CPU_USER_REGS_pregs       34
> > +#define RISCV_CPU_USER_REGS_last        35
> 
> This block wants moving into the asm-offsets infrastructure, but I
> suspect they won't want to survive in this form.
> 
> edit: yeah, definitely not this form.  RISCV_CPU_USER_REGS_OFFSET is
> a
> recipe for bugs.
> 
Thanks for the recommendation I'll take it into account during a work
on new version of the patch series.

> > +
> > +#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x)
> > * __SIZEOF_POINTER__)
> > +#define RISCV_CPU_USER_REGS_SIZE       
> > RISCV_CPU_USER_REGS_OFFSET(last)
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +/* On stack VCPU state */
> > +struct cpu_user_regs
> > +{
> > +    register_t zero;
> 
> unsigned long.
Why is it better to define them as \unsigned long' instead of
register_t?
> 
> > +    register_t ra;
> > +    register_t sp;
> > +    register_t gp;
> > +    register_t tp;
> > +    register_t t0;
> > +    register_t t1;
> > +    register_t t2;
> > +    register_t s0;
> > +    register_t s1;
> > +    register_t a0;
> > +    register_t a1;
> > +    register_t a2;
> > +    register_t a3;
> > +    register_t a4;
> > +    register_t a5;
> > +    register_t a6;
> > +    register_t a7;
> > +    register_t s2;
> > +    register_t s3;
> > +    register_t s4;
> > +    register_t s5;
> > +    register_t s6;
> > +    register_t s7;
> > +    register_t s8;
> > +    register_t s9;
> > +    register_t s10;
> > +    register_t s11;
> > +    register_t t3;
> > +    register_t t4;
> > +    register_t t5;
> > +    register_t t6;
> > +    register_t sepc;
> > +    register_t sstatus;
> > +    /* pointer to previous stack_cpu_regs */
> > +    register_t pregs;
> 
> Stale comment?  Also, surely this wants to be cpu_user_regs *pregs; ?
> 
Not really.
Later it would be introduced another one structure:
	struct pcpu_info {
	...
		struct cpu_user_regs *stack_cpu_regs;
	...
	};
And stack_cpu_regs will be updated during context saving before jump to
__handle_exception:

    	/* new_stack_cpu_regs.pregs = old_stack_cpu_res */
    	REG_L   t0, RISCV_PCPUINFO_OFFSET(stack_cpu_regs)(tp)
    	REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(pregs)(sp)
    	/* Update stack_cpu_regs */
    	REG_S   sp, RISCV_PCPUINFO_OFFSET(stack_cpu_regs)(tp)
And I skipped this part as pcpu_info isn't used anywhere now but
reserve some place for pregs in advance.

> > +};
> > +
> > +static inline void wait_for_interrupt(void)
> 
> There's no point writing out the name in longhand for a wrapper
> around a
> single instruction.
> 
Will change it to "... wfi(void)"
> ~Andrew



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function
  2023-01-20 15:39   ` Andrew Cooper
@ 2023-01-23 12:05     ` Oleksii
  0 siblings, 0 replies; 58+ messages in thread
From: Oleksii @ 2023-01-23 12:05 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On Fri, 2023-01-20 at 15:39 +0000, Andrew Cooper wrote:
> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> > Add ability to print hex number.
> > It might be useful to print register value as debug information
> > in BUG(), WARN(), etc...
> > 
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> 
> I think it would be better to get s(n)printf() working than to take
> these.  We're going to need to get it working soon anyway, and will
> be
> much easier than doing the full printk() infrastructure.
> 
Agree here.

I re-watched the patch and I do not use this function now at all.
(it looks like it was needed only for my personal debug stuff)

This patch can be dropped now.
> ~Andrew



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff
  2023-01-20 14:59 ` [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff Oleksii Kurochko
  2023-01-22 23:38   ` Alistair Francis
@ 2023-01-23 12:09   ` Andrew Cooper
  1 sibling, 0 replies; 58+ messages in thread
From: Andrew Cooper @ 2023-01-23 12:09 UTC (permalink / raw)
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
> index 3201b851ef..dd64f053a5 100644
> --- a/xen/arch/riscv/traps.c
> +++ b/xen/arch/riscv/traps.c
> @@ -4,8 +4,96 @@
>   *
>   * RISC-V Trap handlers
>   */
> +#include <asm/csr.h>
> +#include <asm/early_printk.h>
>  #include <asm/processor.h>
>  #include <asm/traps.h>
> +#include <xen/errno.h>
> +
> +const char *decode_trap_cause(unsigned long cause)

These should be static as you've not put a declaration in a header
file.  But as it stands, you'll then get a compiler warning on
decode_cause() as it's not used.

I would merge this patch with the following patch, as the following
patch is very related to this, and then you can get everything nicely
static without unused warnings.

> +{
> +    switch ( cause )
> +    {
> +    case CAUSE_MISALIGNED_FETCH:
> +        return "Instruction Address Misaligned";
> +    case CAUSE_FETCH_ACCESS:
> +        return "Instruction Access Fault";
> +    case CAUSE_ILLEGAL_INSTRUCTION:
> +        return "Illegal Instruction";
> +    case CAUSE_BREAKPOINT:
> +        return "Breakpoint";
> +    case CAUSE_MISALIGNED_LOAD:
> +        return "Load Address Misaligned";
> +    case CAUSE_LOAD_ACCESS:
> +        return "Load Access Fault";
> +    case CAUSE_MISALIGNED_STORE:
> +        return "Store/AMO Address Misaligned";
> +    case CAUSE_STORE_ACCESS:
> +        return "Store/AMO Access Fault";
> +    case CAUSE_USER_ECALL:
> +        return "Environment Call from U-Mode";
> +    case CAUSE_SUPERVISOR_ECALL:
> +        return "Environment Call from S-Mode";
> +    case CAUSE_MACHINE_ECALL:
> +        return "Environment Call from M-Mode";
> +    case CAUSE_FETCH_PAGE_FAULT:
> +        return "Instruction Page Fault";
> +    case CAUSE_LOAD_PAGE_FAULT:
> +        return "Load Page Fault";
> +    case CAUSE_STORE_PAGE_FAULT:
> +        return "Store/AMO Page Fault";
> +    case CAUSE_FETCH_GUEST_PAGE_FAULT:
> +        return "Instruction Guest Page Fault";
> +    case CAUSE_LOAD_GUEST_PAGE_FAULT:
> +        return "Load Guest Page Fault";
> +    case CAUSE_VIRTUAL_INST_FAULT:
> +        return "Virtualized Instruction Fault";
> +    case CAUSE_STORE_GUEST_PAGE_FAULT:
> +        return "Guest Store/AMO Page Fault";
> +    default:
> +        return "UNKNOWN";

This style tends to lead to poor code generation.  You probably want:

const char *decode_trap_cause(unsigned long cause)
{
    static const char *const trap_causes[] = {
        [CAUSE_MISALIGNED_FETCH] = "Instruction Address Misaligned",
        ...
        [CAUSE_STORE_GUEST_PAGE_FAULT] = "Guest Store/AMO Page Fault",
    };

    if ( cause < ARRAY_SIZE(trap_causes) && trap_causes[cause] )
        return trap_causes[cause];
    return "UNKNOWN";
}

(note the trailing comma on the final entry, which is there to simply
future diffs)

However, given the hope to get snprintf() wired up, you actually want to
to adjust this to:

    if ( cause < ARRAY_SIZE(trap_causes) )
        return trap_causes[cause];
    return NULL;

And render the raw cause number for the unknown case, because that is
far more useful for whomever is debugging.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 06/14] xen/riscv: introduce exception context
  2023-01-23 12:03     ` Oleksii
@ 2023-01-23 12:25       ` Andrew Cooper
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Cooper @ 2023-01-23 12:25 UTC (permalink / raw)
  To: Oleksii, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, Bobby Eshleman

On 23/01/2023 12:03 pm, Oleksii wrote:
> On Fri, 2023-01-20 at 15:54 +0000, Andrew Cooper wrote:
>> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
>>> +
>>> +#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x)
>>> * __SIZEOF_POINTER__)
>>> +#define RISCV_CPU_USER_REGS_SIZE       
>>> RISCV_CPU_USER_REGS_OFFSET(last)
>>> +
>>> +#ifndef __ASSEMBLY__
>>> +
>>> +/* On stack VCPU state */
>>> +struct cpu_user_regs
>>> +{
>>> +    register_t zero;
>> unsigned long.
> Why is it better to define them as \unsigned long' instead of
> register_t?

Because there is a material cost to deliberately hiding the type, in
terms of code clarity and legibility.

Things like register_t and vaddr_t are nonsense in a POSIX-y build
environment where these things are spelled "unsigned long", not to
mention that the associated infrastructure is longer than the
non-obfuscated form.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-23 11:50   ` Andrew Cooper
@ 2023-01-23 12:41     ` Jan Beulich
  2023-01-23 15:17     ` Oleksii
  2023-01-25 14:44     ` Oleksii
  2 siblings, 0 replies; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 12:41 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, Oleksii Kurochko, xen-devel

On 23.01.2023 12:50, Andrew Cooper wrote:
> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
>> +        csrr    t0, CSR_SEPC
>> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sepc)(sp)
>> +        csrr    t0, CSR_SSTATUS
>> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sstatus)(sp)
> 
> So something I've noticed about CSRs through this series.
> 
> The C CSR macros are set up to use real CSR names, but the CSR_*
> constants used in C and ASM are raw numbers.
> 
> If we're using raw numbers, then the C CSR accessors should be static
> inlines instead, but the advantage of using names is the toolchain can
> issue an error when we reference a CSR not supported by the current
> extensions.

That's a default-off diagnostic iirc, so we'd gain something here only
when explicitly turning that on as well.

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header
  2023-01-20 14:59 ` [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header Oleksii Kurochko
  2023-01-22 23:24   ` Alistair Francis
@ 2023-01-23 13:52   ` Jan Beulich
  2023-01-23 14:04     ` Oleksii
  1 sibling, 1 reply; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 13:52 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On 20.01.2023 15:59, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

I was about to commit this, but ...

> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/riscv_encoding.h
> @@ -0,0 +1,945 @@
> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *   Anup Patel <anup.patel@wdc.com>

... this raises a patch authorship question: Are you missing her/his
S-o-b: and/or From:? 

> + * The source has been largely adapted from OpenSBI:
> + * include/sbi/riscv_encodnig.h

Nit: Typo.

> + * 

Nit: trailing blank.

There also look to be hard tabs in the file. This is fine if the file
is being imported (almost) verbatim from elsewhere, but then the origin
wants stating in an Origin: tag (see docs/process/sending-patches.pandoc).

>[...]
> +#define IMM_I(insn)			((s32)(insn) >> 20)
> +#define IMM_S(insn)			(((s32)(insn) >> 25 << 5) | \
> +					 (s32)(((insn) >> 7) & 0x1f))

Please can you avoid introducing new instances of s<N> or u<N>? See
./CODING_STYLE.

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header
  2023-01-20 14:59 ` [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header Oleksii Kurochko
  2023-01-22 23:25   ` Alistair Francis
@ 2023-01-23 13:57   ` Jan Beulich
  2023-01-23 14:23     ` Oleksii
  1 sibling, 1 reply; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 13:57 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On 20.01.2023 15:59, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/csr.h
> @@ -0,0 +1,82 @@
> +/*
> + * Take from Linux.

This again means you want an Origin: tag. Whether the comment itself is
useful depends on how much customization you expect there to be down
the road. But wait - the header here is quite dissimilar from Linux'es,
so the description wants to go into further detail. That would then want
to include why 5 of the 7 functions are actually commented out at this
point.

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header
  2023-01-23 13:52   ` Jan Beulich
@ 2023-01-23 14:04     ` Oleksii
  2023-01-23 14:06       ` Jan Beulich
  0 siblings, 1 reply; 58+ messages in thread
From: Oleksii @ 2023-01-23 14:04 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On Mon, 2023-01-23 at 14:52 +0100, Jan Beulich wrote:
> On 20.01.2023 15:59, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> 
> I was about to commit this, but ...
> 
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/riscv_encoding.h
> > @@ -0,0 +1,945 @@
> > +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
> > +/*
> > + * Copyright (c) 2019 Western Digital Corporation or its
> > affiliates.
> > + *
> > + * Authors:
> > + *   Anup Patel <anup.patel@wdc.com>
> 
> ... this raises a patch authorship question: Are you missing her/his
> S-o-b: and/or From:? 
> 
It is not clear who should be in S-o-b and/or From. So let me explain
situation:

Anup Patel <anup.patel@wdc.com> is a person who introduced
riscv_encoding.h in OpenSBI.

A person who introduced the header to Xen isn't clear as I see 3 people
who did it:
- Bobby Eshleman <bobbyeshleman@gmail.com>
- Alistair Francis <alistair.francis@wdc.com>
- One more person whoose last name, unfortunately, I can't find
And in all cases I saw that an author is different.

> > + * The source has been largely adapted from OpenSBI:
> > + * include/sbi/riscv_encodnig.h
> 
> Nit: Typo.
> 
> > + * 
> 
> Nit: trailing blank.
> 
> There also look to be hard tabs in the file. This is fine if the file
> is being imported (almost) verbatim from elsewhere, but then the
> origin
> wants stating in an Origin: tag (see docs/process/sending-
> patches.pandoc).
> 
> > [...]
> > +#define IMM_I(insn)                    ((s32)(insn) >> 20)
> > +#define IMM_S(insn)                    (((s32)(insn) >> 25 << 5) |
> > \
> > +                                        (s32)(((insn) >> 7) &
> > 0x1f))
> 
> Please can you avoid introducing new instances of s<N> or u<N>? See
> ./CODING_STYLE.
> 
Thanks. I will update the header.
> Jan



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header
  2023-01-23 14:04     ` Oleksii
@ 2023-01-23 14:06       ` Jan Beulich
  0 siblings, 0 replies; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 14:06 UTC (permalink / raw)
  To: Oleksii
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On 23.01.2023 15:04, Oleksii wrote:
> On Mon, 2023-01-23 at 14:52 +0100, Jan Beulich wrote:
>> On 20.01.2023 15:59, Oleksii Kurochko wrote:
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>
>> I was about to commit this, but ...
>>
>>> --- /dev/null
>>> +++ b/xen/arch/riscv/include/asm/riscv_encoding.h
>>> @@ -0,0 +1,945 @@
>>> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
>>> +/*
>>> + * Copyright (c) 2019 Western Digital Corporation or its
>>> affiliates.
>>> + *
>>> + * Authors:
>>> + *   Anup Patel <anup.patel@wdc.com>
>>
>> ... this raises a patch authorship question: Are you missing her/his
>> S-o-b: and/or From:? 
>>
> It is not clear who should be in S-o-b and/or From. So let me explain
> situation:
> 
> Anup Patel <anup.patel@wdc.com> is a person who introduced
> riscv_encoding.h in OpenSBI.
> 
> A person who introduced the header to Xen isn't clear as I see 3 people
> who did it:
> - Bobby Eshleman <bobbyeshleman@gmail.com>
> - Alistair Francis <alistair.francis@wdc.com>
> - One more person whoose last name, unfortunately, I can't find
> And in all cases I saw that an author is different.

Then maybe simply move the "Author:" part into ...

>>> + * The source has been largely adapted from OpenSBI:
>>> + * include/sbi/riscv_encodnig.h

... this sentence, e.g. by appending "originally authored by ..."?

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header
  2023-01-23 13:57   ` Jan Beulich
@ 2023-01-23 14:23     ` Oleksii
  2023-01-23 14:31       ` Jan Beulich
  0 siblings, 1 reply; 58+ messages in thread
From: Oleksii @ 2023-01-23 14:23 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On Mon, 2023-01-23 at 14:57 +0100, Jan Beulich wrote:
> On 20.01.2023 15:59, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/csr.h
> > @@ -0,0 +1,82 @@
> > +/*
> > + * Take from Linux.
> 
> This again means you want an Origin: tag. Whether the comment itself
> is
> useful depends on how much customization you expect there to be down
> the road. But wait - the header here is quite dissimilar from
> Linux'es,
> so the description wants to go into further detail. That would then
> want
> to include why 5 of the 7 functions are actually commented out at
> this
> point.
> 
I forgot two remove them. They were commented as they aren't used now.
But probably there is a sense to add them from the start.

I am curious if "Take from Linux" is needed at all?
Should it be described what was removed from the original header [1] ?

[1]
https://elixir.bootlin.com/linux/latest/source/arch/riscv/include/asm/csr.h
> Jan



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header
  2023-01-23 14:23     ` Oleksii
@ 2023-01-23 14:31       ` Jan Beulich
  0 siblings, 0 replies; 58+ messages in thread
From: Jan Beulich @ 2023-01-23 14:31 UTC (permalink / raw)
  To: Oleksii
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On 23.01.2023 15:23, Oleksii wrote:
> On Mon, 2023-01-23 at 14:57 +0100, Jan Beulich wrote:
>> On 20.01.2023 15:59, Oleksii Kurochko wrote:
>>> --- /dev/null
>>> +++ b/xen/arch/riscv/include/asm/csr.h
>>> @@ -0,0 +1,82 @@
>>> +/*
>>> + * Take from Linux.
>>
>> This again means you want an Origin: tag. Whether the comment itself
>> is
>> useful depends on how much customization you expect there to be down
>> the road. But wait - the header here is quite dissimilar from
>> Linux'es,
>> so the description wants to go into further detail. That would then
>> want
>> to include why 5 of the 7 functions are actually commented out at
>> this
>> point.
>>
> I forgot two remove them. They were commented as they aren't used now.
> But probably there is a sense to add them from the start.
> 
> I am curious if "Take from Linux" is needed at all?

I said, I was wondering too. The fewer you take from Linux (and the more
you add on top), the less useful such a comment is going to be.

> Should it be described what was removed from the original header [1] ?

In the description, yes (or, if it's very little, simply say that much
more is present there). Doing so in the leading comment in the header
is risking to go stale very quickly.

Jan


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-23 11:17   ` Jan Beulich
@ 2023-01-23 15:04     ` Oleksii
  0 siblings, 0 replies; 58+ messages in thread
From: Oleksii @ 2023-01-23 15:04 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Andrew Cooper, Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis, xen-devel

On Mon, 2023-01-23 at 12:17 +0100, Jan Beulich wrote:
> On 20.01.2023 15:59, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/entry.S
> > @@ -0,0 +1,97 @@
> > +#include <asm/asm.h>
> > +#include <asm/processor.h>
> > +#include <asm/riscv_encoding.h>
> > +#include <asm/traps.h>
> > +
> > +        .global handle_exception
> > +        .align 4
> > +
> > +handle_exception:
> > +
> > +    /* Exceptions from xen */
> > +save_to_stack:
> > +        /* Save context to stack */
> > +        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) -
> > RISCV_CPU_USER_REGS_SIZE) (sp)
> > +        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
> > +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
> > +        j       save_context
> > +
> > +save_context:
> 
> Just curious: Why not simply fall through here, i.e. why the J which
> really
> is a NOP in this case?
> 
There is no any specific reason.
I left it for future.
Will remove it in the next patch version.
> Jan



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-23 11:50   ` Andrew Cooper
  2023-01-23 12:41     ` Jan Beulich
@ 2023-01-23 15:17     ` Oleksii
  2023-01-23 20:09       ` Andrew Cooper
  2023-01-25 14:44     ` Oleksii
  2 siblings, 1 reply; 58+ messages in thread
From: Oleksii @ 2023-01-23 15:17 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On Mon, 2023-01-23 at 11:50 +0000, Andrew Cooper wrote:
> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> > diff --git a/xen/arch/riscv/entry.S b/xen/arch/riscv/entry.S
> > new file mode 100644
> > index 0000000000..f7d46f42bb
> > --- /dev/null
> > +++ b/xen/arch/riscv/entry.S
> > @@ -0,0 +1,97 @@
> > +#include <asm/asm.h>
> > +#include <asm/processor.h>
> > +#include <asm/riscv_encoding.h>
> > +#include <asm/traps.h>
> > +
> > +        .global handle_exception
> > +        .align 4
> > +
> > +handle_exception:
> 
> ENTRY() which takes care of the global and the align.
> 
> Also, you want a size and type at the end, just like in head.S 
> (Sorry,
> we *still* don't have any sane infrastructure for doing that nicely. 
> Opencode it for now.)
> 
> > +
> > +    /* Exceptions from xen */
> > +save_to_stack:
> 
> This label isn't used at all, is it?
> 
> > +        /* Save context to stack */
> > +        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) -
> > RISCV_CPU_USER_REGS_SIZE) (sp)
> > +        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
> > +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
> 
> Exceptions on RISC-V don't adjust the stack pointer.  This logic
> depends
> on interrupting Xen code, and Xen not having suffered a stack
> overflow
> (and actually, that the space on the stack for all registers also
> doesn't overflow).
> 
> Which might be fine for now, but I think it warrants a comment
> somewhere
> (probably at handle_exception itself) stating the expectations while
> it's still a work in progress.  So in this case something like:
> 
> /* Work-in-progress:  Depends on interrupting Xen, and the stack
> being
> good. */
> 
> 
> But, do we want to allocate stemp right away (even with an empty
> struct), and get tp set up properly?
> 
I am not sure that I get you here about stemp. Could you please clarify
a little bit.

> That said, aren't we going to have to rewrite this when enabling H
> mode
> anyway?
I based these code on a code from Bobby's repo ( on top of which with
some additional patches I've successfully ran Dom0 ) so I am not sure
that it will be re-written.
Probably I don't understand about which one part you are talking about.

Regarding H mode if to be honest I didn't see where it is switched to
it.
Maybe Bobby or Alistair can explain me?
> 
> > +        j       save_context
> > +
> > +save_context:
> 
> I'd drop this.  It's a nop right now.
> 
> > <snip>
> > +        csrr    t0, CSR_SEPC
> > +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sepc)(sp)
> > +        csrr    t0, CSR_SSTATUS
> > +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(sstatus)(sp)
> 
> So something I've noticed about CSRs through this series.
> 
> The C CSR macros are set up to use real CSR names, but the CSR_*
> constants used in C and ASM are raw numbers.
> 
> If we're using raw numbers, then the C CSR accessors should be static
> inlines instead, but the advantage of using names is the toolchain
> can
> issue an error when we reference a CSR not supported by the current
> extensions.
> 
> We ought to use a single form, consistently through Xen.  How
> feasible
> will it be to use names throughout?
> 
> ~Andrew



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-23 15:17     ` Oleksii
@ 2023-01-23 20:09       ` Andrew Cooper
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Cooper @ 2023-01-23 20:09 UTC (permalink / raw)
  To: Oleksii, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On 23/01/2023 3:17 pm, Oleksii wrote:
> On Mon, 2023-01-23 at 11:50 +0000, Andrew Cooper wrote:
>> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
>>> +        /* Save context to stack */
>>> +        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) -
>>> RISCV_CPU_USER_REGS_SIZE) (sp)
>>> +        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
>>> +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
>> Exceptions on RISC-V don't adjust the stack pointer.  This logic
>> depends
>> on interrupting Xen code, and Xen not having suffered a stack
>> overflow
>> (and actually, that the space on the stack for all registers also
>> doesn't overflow).
>>
>> Which might be fine for now, but I think it warrants a comment
>> somewhere
>> (probably at handle_exception itself) stating the expectations while
>> it's still a work in progress.  So in this case something like:
>>
>> /* Work-in-progress:  Depends on interrupting Xen, and the stack
>> being
>> good. */
>>
>>
>> But, do we want to allocate stemp right away (even with an empty
>> struct), and get tp set up properly?
>>
> I am not sure that I get you here about stemp. Could you please clarify
> a little bit.

Sorry - sscratch, not stemp - I got the name wrong.

All registers are the interrupted context, not Xen's context.  This
includes the stack pointer, global pointer, and thread pointer.

Trap setup is supposed to stash Xen's tp in sscratch so on an
interrupt/exception, it can exchange sscratch with tp and recover the
stack pointer.

Linux plays games with having sscratch be 0 while in kernel and uses
this to determine whether the exception occurred in kernel or user
mode.  This is massive can of re-entrancy bugs that appears to be baked
into the architecture.

I genuinely can't figure out a safe way to cope with a stack overflow,
or a bad tp, because it is not safe to a pagefault until the exception
prologue has completed.  If you do, you'll switch back to the
interrupted task's tp and use that as if it were Xen's.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler()
  2023-01-20 14:59 ` [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler() Oleksii Kurochko
  2023-01-22 23:41   ` Alistair Francis
@ 2023-01-23 23:21   ` Andrew Cooper
  1 sibling, 0 replies; 58+ messages in thread
From: Andrew Cooper @ 2023-01-23 23:21 UTC (permalink / raw)
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
>  xen/arch/riscv/setup.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
> index d09ffe1454..174e134c93 100644
> --- a/xen/arch/riscv/setup.c
> +++ b/xen/arch/riscv/setup.c
> @@ -1,16 +1,27 @@
>  #include <xen/compile.h>
>  #include <xen/init.h>
>  
> +#include <asm/csr.h>
>  #include <asm/early_printk.h>
> +#include <asm/traps.h>
>  
>  /* Xen stack for bringing up the first CPU. */
>  unsigned char __initdata cpu0_boot_stack[STACK_SIZE]
>      __aligned(STACK_SIZE);
>  
> +static void setup_trap_handler(void)

We'd normally call this trap_init(), but it wants to live in traps.c
rather than setup.c, with a prototype in traps.h.

> +{
> +    unsigned long addr = (unsigned long)&handle_exception;

Coding style.  Newline between variable declarations and code.

Having looked at the spec, the entrypoint should be named handle_trap
rather than handle_exception.  Per the spec, a trap is either an
interrupt or an exception based on the IRQ flag in CAUSE.

That adjustment to naming wants to percolate down through the calltree
and also in earlier patches.

To avoid the __handle_exception() function in C, you could call the C
version do_trap() which is a reasonably common idiom in other architectures.

> +    csr_write(CSR_STVEC, addr);
> +}
> +
>  void __init noreturn start_xen(void)
>  {
>      early_printk("Hello from C env\n");
>  
> +    setup_trap_handler();
> +    early_printk("exception handler has been setup\n");

Personally I don't think this printk() adds any value.  It's not one
looked at by the smoke test, and it's only a single CSRW away from the
"Hello from C" message.

~Andrew

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 14/14] automation: add smoke test to verify macros from bug.h
  2023-01-20 14:59 ` [PATCH v1 14/14] automation: add smoke test to verify macros from bug.h Oleksii Kurochko
@ 2023-01-24 23:53   ` Stefano Stabellini
  0 siblings, 0 replies; 58+ messages in thread
From: Stefano Stabellini @ 2023-01-24 23:53 UTC (permalink / raw)
  To: Oleksii Kurochko
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Doug Goldstein

On Fri, 20 Jan 2023, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

I think you should remove the old greps. This script is part of the Xen
repository and in-sync with the codebase, so it is OK to only keep the
most recent version of the grep string.

> ---
>  automation/scripts/qemu-smoke-riscv64.sh | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/automation/scripts/qemu-smoke-riscv64.sh b/automation/scripts/qemu-smoke-riscv64.sh
> index e0f06360bc..e7cc7f1442 100755
> --- a/automation/scripts/qemu-smoke-riscv64.sh
> +++ b/automation/scripts/qemu-smoke-riscv64.sh
> @@ -17,4 +17,6 @@ qemu-system-riscv64 \
>  
>  set -e
>  (grep -q "Hello from C env" smoke.serial) || exit 1
> +(grep -q "run_in_exception_handler is most likely working" smoke.serial) || exit 1
> +(grep -q "WARN is most likely working" smoke.serial) || exit 1
>  exit 0
> -- 
> 2.39.0
> 


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation
  2023-01-23 11:50   ` Andrew Cooper
  2023-01-23 12:41     ` Jan Beulich
  2023-01-23 15:17     ` Oleksii
@ 2023-01-25 14:44     ` Oleksii
  2 siblings, 0 replies; 58+ messages in thread
From: Oleksii @ 2023-01-25 14:44 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: Stefano Stabellini, Gianluca Guida, Bob Eshleman,
	Alistair Francis, Connor Davis

On Mon, 2023-01-23 at 11:50 +0000, Andrew Cooper wrote:
> 
> 
> > +        /* Save context to stack */
> > +        REG_S   sp, (RISCV_CPU_USER_REGS_OFFSET(sp) -
> > RISCV_CPU_USER_REGS_SIZE) (sp)
> > +        addi    sp, sp, -RISCV_CPU_USER_REGS_SIZE
> > +        REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(t0)(sp)
> 
> Exceptions on RISC-V don't adjust the stack pointer.  This logic
> depends
> on interrupting Xen code, and Xen not having suffered a stack
> overflow
> (and actually, that the space on the stack for all registers also
> doesn't overflow).
> 
Probably I missed something but an idea of the code above was to
reserve memory on a stack to save the registers which can be changed
in __handler_expception() as the line of code where exception occurs
will expect that registers value weren't changed.
Otherwise if we won't reserve memory on stack it will be corrupted by
REG_S which basically is SD instruction.




^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap()
  2023-01-22 23:39   ` Alistair Francis
@ 2023-01-25 17:01     ` Oleksii
  2023-01-25 17:11       ` Julien Grall
  2023-01-25 17:15       ` Andrew Cooper
  0 siblings, 2 replies; 58+ messages in thread
From: Oleksii @ 2023-01-25 17:01 UTC (permalink / raw)
  To: Alistair Francis
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Mon, 2023-01-23 at 09:39 +1000, Alistair Francis wrote:
> On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
> <oleksii.kurochko@gmail.com> wrote:
> > 
> > The patch introduces the function the purpose of which is to print
> > a cause of an exception and call "wfi" instruction.
> > 
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> >  xen/arch/riscv/traps.c | 14 +++++++++++++-
> >  1 file changed, 13 insertions(+), 1 deletion(-)
> > 
> > diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
> > index dd64f053a5..fc25138a4b 100644
> > --- a/xen/arch/riscv/traps.c
> > +++ b/xen/arch/riscv/traps.c
> > @@ -95,7 +95,19 @@ const char *decode_cause(unsigned long cause)
> >      return decode_trap_cause(cause);
> >  }
> > 
> > -void __handle_exception(struct cpu_user_regs *cpu_regs)
> > +static void do_unexpected_trap(const struct cpu_user_regs *regs)
> >  {
> > +    unsigned long cause = csr_read(CSR_SCAUSE);
> > +
> > +    early_printk("Unhandled exception: ");
> > +    early_printk(decode_cause(cause));
> > +    early_printk("\n");
> > +
> > +    // kind of die...
> >      wait_for_interrupt();
> 
> We could put this in a loop, to ensure we never progress
> 
I think that right now there is no big difference how to stop
because we have only 1 CPU, interrupts are disabled and we are in
exception so it looks like anything can interrupt us.
And in future it will be changed to panic() so we won't need here wfi()
any more.
> 

Oleksii


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap()
  2023-01-25 17:01     ` Oleksii
@ 2023-01-25 17:11       ` Julien Grall
  2023-01-25 17:15       ` Andrew Cooper
  1 sibling, 0 replies; 58+ messages in thread
From: Julien Grall @ 2023-01-25 17:11 UTC (permalink / raw)
  To: Oleksii, Alistair Francis
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

Hi,

On 25/01/2023 17:01, Oleksii wrote:
> On Mon, 2023-01-23 at 09:39 +1000, Alistair Francis wrote:
>> On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
>> <oleksii.kurochko@gmail.com> wrote:
>>>
>>> The patch introduces the function the purpose of which is to print
>>> a cause of an exception and call "wfi" instruction.
>>>
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>> ---
>>>   xen/arch/riscv/traps.c | 14 +++++++++++++-
>>>   1 file changed, 13 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
>>> index dd64f053a5..fc25138a4b 100644
>>> --- a/xen/arch/riscv/traps.c
>>> +++ b/xen/arch/riscv/traps.c
>>> @@ -95,7 +95,19 @@ const char *decode_cause(unsigned long cause)
>>>       return decode_trap_cause(cause);
>>>   }
>>>
>>> -void __handle_exception(struct cpu_user_regs *cpu_regs)
>>> +static void do_unexpected_trap(const struct cpu_user_regs *regs)
>>>   {
>>> +    unsigned long cause = csr_read(CSR_SCAUSE);
>>> +
>>> +    early_printk("Unhandled exception: ");
>>> +    early_printk(decode_cause(cause));
>>> +    early_printk("\n");
>>> +
>>> +    // kind of die...
>>>       wait_for_interrupt();
>>
>> We could put this in a loop, to ensure we never progress
>>
> I think that right now there is no big difference how to stop
> because we have only 1 CPU, interrupts are disabled and we are in
> exception so it looks like anything can interrupt us.

 From my understanding of the specification, WFI is an hint. So it could 
be implemented as a NOP.

Therefore it would sound better to wrap in a loop. That said...

> And in future it will be changed to panic() so we won't need here wfi()
> any more.

... ideally using panic() right now would be the best.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap()
  2023-01-25 17:01     ` Oleksii
  2023-01-25 17:11       ` Julien Grall
@ 2023-01-25 17:15       ` Andrew Cooper
  2023-01-26  8:40         ` Oleksii
  1 sibling, 1 reply; 58+ messages in thread
From: Andrew Cooper @ 2023-01-25 17:15 UTC (permalink / raw)
  To: Oleksii, Alistair Francis
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On 25/01/2023 5:01 pm, Oleksii wrote:
> On Mon, 2023-01-23 at 09:39 +1000, Alistair Francis wrote:
>> On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
>> <oleksii.kurochko@gmail.com> wrote:
>>> The patch introduces the function the purpose of which is to print
>>> a cause of an exception and call "wfi" instruction.
>>>
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>> ---
>>>  xen/arch/riscv/traps.c | 14 +++++++++++++-
>>>  1 file changed, 13 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
>>> index dd64f053a5..fc25138a4b 100644
>>> --- a/xen/arch/riscv/traps.c
>>> +++ b/xen/arch/riscv/traps.c
>>> @@ -95,7 +95,19 @@ const char *decode_cause(unsigned long cause)
>>>      return decode_trap_cause(cause);
>>>  }
>>>
>>> -void __handle_exception(struct cpu_user_regs *cpu_regs)
>>> +static void do_unexpected_trap(const struct cpu_user_regs *regs)
>>>  {
>>> +    unsigned long cause = csr_read(CSR_SCAUSE);
>>> +
>>> +    early_printk("Unhandled exception: ");
>>> +    early_printk(decode_cause(cause));
>>> +    early_printk("\n");
>>> +
>>> +    // kind of die...
>>>      wait_for_interrupt();
>> We could put this in a loop, to ensure we never progress
>>
> I think that right now there is no big difference how to stop
> because we have only 1 CPU, interrupts are disabled and we are in
> exception so it looks like anything can interrupt us.
> And in future it will be changed to panic() so we won't need here wfi()
> any more.

WFI is permitted to be implemented as a NOP by hardware.  Furthermore,
WFI with interrupts already disabled is a supported usecase, and will
resume execution without taking the interrupt that became pending.

You need an infinite loop of WFI's for execution to halt here.

~Andrew


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap()
  2023-01-25 17:15       ` Andrew Cooper
@ 2023-01-26  8:40         ` Oleksii
  0 siblings, 0 replies; 58+ messages in thread
From: Oleksii @ 2023-01-26  8:40 UTC (permalink / raw)
  To: Andrew Cooper, Alistair Francis
  Cc: xen-devel, Andrew Cooper, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Wed, 2023-01-25 at 17:15 +0000, Andrew Cooper wrote:
> On 25/01/2023 5:01 pm, Oleksii wrote:
> > On Mon, 2023-01-23 at 09:39 +1000, Alistair Francis wrote:
> > > On Sat, Jan 21, 2023 at 1:00 AM Oleksii Kurochko
> > > <oleksii.kurochko@gmail.com> wrote:
> > > > The patch introduces the function the purpose of which is to
> > > > print
> > > > a cause of an exception and call "wfi" instruction.
> > > > 
> > > > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > > > ---
> > > >  xen/arch/riscv/traps.c | 14 +++++++++++++-
> > > >  1 file changed, 13 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
> > > > index dd64f053a5..fc25138a4b 100644
> > > > --- a/xen/arch/riscv/traps.c
> > > > +++ b/xen/arch/riscv/traps.c
> > > > @@ -95,7 +95,19 @@ const char *decode_cause(unsigned long
> > > > cause)
> > > >      return decode_trap_cause(cause);
> > > >  }
> > > > 
> > > > -void __handle_exception(struct cpu_user_regs *cpu_regs)
> > > > +static void do_unexpected_trap(const struct cpu_user_regs
> > > > *regs)
> > > >  {
> > > > +    unsigned long cause = csr_read(CSR_SCAUSE);
> > > > +
> > > > +    early_printk("Unhandled exception: ");
> > > > +    early_printk(decode_cause(cause));
> > > > +    early_printk("\n");
> > > > +
> > > > +    // kind of die...
> > > >      wait_for_interrupt();
> > > We could put this in a loop, to ensure we never progress
> > > 
> > I think that right now there is no big difference how to stop
> > because we have only 1 CPU, interrupts are disabled and we are in
> > exception so it looks like anything can interrupt us.
> > And in future it will be changed to panic() so we won't need here
> > wfi()
> > any more.
> 
> WFI is permitted to be implemented as a NOP by hardware. 
> Furthermore,
> WFI with interrupts already disabled is a supported usecase, and will
> resume execution without taking the interrupt that became pending.
> 
> You need an infinite loop of WFI's for execution to halt here.
> 
Thanks a lot for clarification!
Then definitely it should changed to loop.
> ~Andrew



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS
  2023-01-23 10:43     ` Oleksii
@ 2023-01-31 11:49       ` Alistair Francis
  2023-01-31 12:30         ` Oleksii
  0 siblings, 1 reply; 58+ messages in thread
From: Alistair Francis @ 2023-01-31 11:49 UTC (permalink / raw)
  To: Oleksii
  Cc: Andrew Cooper, xen-devel, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Mon, Jan 23, 2023 at 8:43 PM Oleksii <oleksii.kurochko@gmail.com> wrote:
>
> On Fri, 2023-01-20 at 15:29 +0000, Andrew Cooper wrote:
> > On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> > > Work with some registers requires csr command which is part of
> > > Zicsr.
> > >
> > > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > > ---
> > >  xen/arch/riscv/arch.mk | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/xen/arch/riscv/arch.mk b/xen/arch/riscv/arch.mk
> > > index 012dc677c3..95b41d9f3e 100644
> > > --- a/xen/arch/riscv/arch.mk
> > > +++ b/xen/arch/riscv/arch.mk
> > > @@ -10,7 +10,7 @@ riscv-march-$(CONFIG_RISCV_ISA_C)       :=
> > > $(riscv-march-y)c
> > >  # into the upper half _or_ the lower half of the address space.
> > >  # -mcmodel=medlow would force Xen into the lower half.
> > >
> > > -CFLAGS += -march=$(riscv-march-y) -mstrict-align -mcmodel=medany
> > > +CFLAGS += -march=$(riscv-march-y)_zicsr -mstrict-align -
> > > mcmodel=medany
> >
> > Should we just go straight for G, rather than bumping it along every
> > time we make a tweak?
> >
> I didn't go straight for G as it represents the “IMAFDZicsr Zifencei”
> base and extensions thereby it will be needed to add support for FPU
> (at least it requires {save,restore}_fp_state) but I am not sure that
> we need it in general.

That seems fair enough. I don't see a reason to restrict ourselves if
we aren't using something. Although we probably will hit a requirement
on G at some point anyway.

Alistair

>
> Another one reason is that Linux kernel introduces _zicsr extenstion
> separately (but I am not sure that it can be considered as a serious
> argument):
> https://elixir.bootlin.com/linux/latest/source/arch/riscv/Makefile#L58
> https://lore.kernel.org/all/20221024113000.891820486@linuxfoundation.org/
>
> > ~Andrew
> ~Oleksii
>
>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS
  2023-01-31 11:49       ` Alistair Francis
@ 2023-01-31 12:30         ` Oleksii
  0 siblings, 0 replies; 58+ messages in thread
From: Oleksii @ 2023-01-31 12:30 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Andrew Cooper, xen-devel, Stefano Stabellini, Gianluca Guida,
	Bob Eshleman, Alistair Francis, Connor Davis

On Tue, 2023-01-31 at 21:49 +1000, Alistair Francis wrote:
> On Mon, Jan 23, 2023 at 8:43 PM Oleksii <oleksii.kurochko@gmail.com>
> wrote:
> > 
> > On Fri, 2023-01-20 at 15:29 +0000, Andrew Cooper wrote:
> > > On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> > > > Work with some registers requires csr command which is part of
> > > > Zicsr.
> > > > 
> > > > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > > > ---
> > > >  xen/arch/riscv/arch.mk | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > diff --git a/xen/arch/riscv/arch.mk b/xen/arch/riscv/arch.mk
> > > > index 012dc677c3..95b41d9f3e 100644
> > > > --- a/xen/arch/riscv/arch.mk
> > > > +++ b/xen/arch/riscv/arch.mk
> > > > @@ -10,7 +10,7 @@ riscv-march-$(CONFIG_RISCV_ISA_C)       :=
> > > > $(riscv-march-y)c
> > > >  # into the upper half _or_ the lower half of the address
> > > > space.
> > > >  # -mcmodel=medlow would force Xen into the lower half.
> > > > 
> > > > -CFLAGS += -march=$(riscv-march-y) -mstrict-align -
> > > > mcmodel=medany
> > > > +CFLAGS += -march=$(riscv-march-y)_zicsr -mstrict-align -
> > > > mcmodel=medany
> > > 
> > > Should we just go straight for G, rather than bumping it along
> > > every
> > > time we make a tweak?
> > > 
> > I didn't go straight for G as it represents the “IMAFDZicsr
> > Zifencei”
> > base and extensions thereby it will be needed to add support for
> > FPU
> > (at least it requires {save,restore}_fp_state) but I am not sure
> > that
> > we need it in general.
> 
> That seems fair enough. I don't see a reason to restrict ourselves if
> we aren't using something. Although we probably will hit a
> requirement
> on G at some point anyway.
> 
Thanks for your notes so I will change it to G.

> Alistair
> 
> > 
> > Another one reason is that Linux kernel introduces _zicsr
> > extenstion
> > separately (but I am not sure that it can be considered as a
> > serious
> > argument):
> > https://elixir.bootlin.com/linux/latest/source/arch/riscv/Makefile#L58
> > https://lore.kernel.org/all/20221024113000.891820486@linuxfoundation.org/
> > 
> > > ~Andrew
> > ~Oleksii
> > 
> > 



^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2023-01-31 12:30 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-20 14:59 [PATCH v1 00/14] RISCV basic exception handling implementation Oleksii Kurochko
2023-01-20 14:59 ` [PATCH v1 01/14] xen/riscv: add _zicsr to CFLAGS Oleksii Kurochko
2023-01-20 15:29   ` Andrew Cooper
2023-01-23 10:43     ` Oleksii
2023-01-31 11:49       ` Alistair Francis
2023-01-31 12:30         ` Oleksii
2023-01-20 14:59 ` [PATCH v1 02/14] xen/riscv: add <asm/asm.h> header Oleksii Kurochko
2023-01-20 15:31   ` Andrew Cooper
2023-01-23 11:00     ` Jan Beulich
2023-01-23 11:10       ` Andrew Cooper
2023-01-22 22:58   ` Alistair Francis
2023-01-20 14:59 ` [PATCH v1 03/14] xen/riscv: add <asm/riscv_encoding.h header Oleksii Kurochko
2023-01-22 23:24   ` Alistair Francis
2023-01-23 13:52   ` Jan Beulich
2023-01-23 14:04     ` Oleksii
2023-01-23 14:06       ` Jan Beulich
2023-01-20 14:59 ` [PATCH v1 04/14] xen/riscv: add <asm/csr.h> header Oleksii Kurochko
2023-01-22 23:25   ` Alistair Francis
2023-01-23 13:57   ` Jan Beulich
2023-01-23 14:23     ` Oleksii
2023-01-23 14:31       ` Jan Beulich
2023-01-20 14:59 ` [PATCH v1 05/14] xen/riscv: add early_printk_hnum() function Oleksii Kurochko
2023-01-20 15:39   ` Andrew Cooper
2023-01-23 12:05     ` Oleksii
2023-01-23 11:10   ` Jan Beulich
2023-01-20 14:59 ` [PATCH v1 06/14] xen/riscv: introduce exception context Oleksii Kurochko
2023-01-20 15:54   ` Andrew Cooper
2023-01-23 12:03     ` Oleksii
2023-01-23 12:25       ` Andrew Cooper
2023-01-23 11:13   ` Jan Beulich
2023-01-20 14:59 ` [PATCH v1 07/14] xen/riscv: introduce exception handlers implementation Oleksii Kurochko
2023-01-22 23:29   ` Alistair Francis
2023-01-23 11:17   ` Jan Beulich
2023-01-23 15:04     ` Oleksii
2023-01-23 11:50   ` Andrew Cooper
2023-01-23 12:41     ` Jan Beulich
2023-01-23 15:17     ` Oleksii
2023-01-23 20:09       ` Andrew Cooper
2023-01-25 14:44     ` Oleksii
2023-01-20 14:59 ` [PATCH v1 08/14] xen/riscv: introduce decode_cause() stuff Oleksii Kurochko
2023-01-22 23:38   ` Alistair Francis
2023-01-23 12:09   ` Andrew Cooper
2023-01-20 14:59 ` [PATCH v1 09/14] xen/riscv: introduce do_unexpected_trap() Oleksii Kurochko
2023-01-22 23:39   ` Alistair Francis
2023-01-25 17:01     ` Oleksii
2023-01-25 17:11       ` Julien Grall
2023-01-25 17:15       ` Andrew Cooper
2023-01-26  8:40         ` Oleksii
2023-01-20 14:59 ` [PATCH v1 10/14] xen/riscv: mask all interrupts Oleksii Kurochko
2023-01-22 23:40   ` Alistair Francis
2023-01-20 14:59 ` [PATCH v1 11/14] xen/riscv: introduce setup_trap_handler() Oleksii Kurochko
2023-01-22 23:41   ` Alistair Francis
2023-01-23 23:21   ` Andrew Cooper
2023-01-20 14:59 ` [PATCH v1 12/14] xen/riscv: introduce an implementation of macros from <asm/bug.h> Oleksii Kurochko
2023-01-23 11:37   ` Jan Beulich
2023-01-20 14:59 ` [PATCH v1 13/14] xen/riscv: test basic handling stuff Oleksii Kurochko
2023-01-20 14:59 ` [PATCH v1 14/14] automation: add smoke test to verify macros from bug.h Oleksii Kurochko
2023-01-24 23:53   ` Stefano Stabellini

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.