summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2022-01-19 09:26:42 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2022-01-19 09:26:42 +0100
commit5c3c23f10ac4a478e2f2ab3ff689422c19268022 (patch)
tree63f5c3ebd90fceda6d3574a57497a1941d8d0a0e /arch
parentbe1539b920302cfcde300f8e8607d548e1f75b8a (diff)
parent0d1fc926e8ad71d4f4626d58b3b447c1856d3703 (diff)
downloadbarebox-5c3c23f10ac4a478e2f2ab3ff689422c19268022.tar.gz
barebox-5c3c23f10ac4a478e2f2ab3ff689422c19268022.tar.xz
Merge branch 'for-next/riscv'
Diffstat (limited to 'arch')
-rw-r--r--arch/riscv/Kconfig10
-rw-r--r--arch/riscv/boards/riscvemu/Makefile1
-rw-r--r--arch/riscv/boards/riscvemu/board.c25
-rw-r--r--arch/riscv/boards/riscvemu/overlay-of-sram.dts129
-rw-r--r--arch/riscv/configs/virt32_defconfig9
-rw-r--r--arch/riscv/configs/virt64_defconfig9
-rw-r--r--arch/riscv/cpu/interrupts.c3
-rw-r--r--arch/riscv/include/asm/barebox-riscv-head.h1
-rw-r--r--arch/riscv/include/asm/csr.h213
-rw-r--r--arch/riscv/include/asm/debug_ll.h11
-rw-r--r--arch/riscv/include/asm/debug_ll_litex.h12
-rw-r--r--arch/riscv/include/asm/debug_ll_ns16550.h8
-rw-r--r--arch/riscv/include/asm/htif.h40
-rw-r--r--arch/riscv/include/asm/ptrace.h10
-rw-r--r--arch/riscv/include/asm/riscv_nmon.h50
-rw-r--r--arch/riscv/include/asm/unwind.h8
-rw-r--r--arch/riscv/lib/Makefile1
-rw-r--r--arch/riscv/lib/stacktrace.c79
18 files changed, 512 insertions, 107 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 8c66697185..c5b373e3af 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -83,6 +83,16 @@ config RISCV_EXCEPTIONS
default y
select ARCH_HAS_DATA_ABORT_MASK
+config RISCV_UNWIND
+ bool "enable stack unwinding support"
+ select ARCH_HAS_STACK_DUMP
+ select ARCH_WANT_FRAME_POINTERS
+ help
+ This option enables stack unwinding support in barebox
+ using the information automatically generated by the
+ compiler. The resulting kernel image is slightly bigger but
+ the performance is not affected.
+
config HAS_NMON
bool
diff --git a/arch/riscv/boards/riscvemu/Makefile b/arch/riscv/boards/riscvemu/Makefile
index dcfc2937d3..81fad4670f 100644
--- a/arch/riscv/boards/riscvemu/Makefile
+++ b/arch/riscv/boards/riscvemu/Makefile
@@ -1 +1,2 @@
obj-y += board.o
+obj-y += overlay-of-sram.dtb.o
diff --git a/arch/riscv/boards/riscvemu/board.c b/arch/riscv/boards/riscvemu/board.c
index 7dbf9afe4c..31d0c70be6 100644
--- a/arch/riscv/boards/riscvemu/board.c
+++ b/arch/riscv/boards/riscvemu/board.c
@@ -7,6 +7,7 @@
#include <driver.h>
#include <poweroff.h>
#include <restart.h>
+#include <deep-probe.h>
#include <asm/system.h>
#include <asm/barebox-riscv.h>
@@ -16,22 +17,13 @@ struct riscvemu_priv {
};
-#define HTIF_BASE_ADDR IOMEM(0x40008000)
-#define HTIF_TOHOST_LOW (HTIF_BASE_ADDR + 0)
-#define HTIF_TOHOST_HIGH (HTIF_BASE_ADDR + 4)
-
-static void __noreturn riscvemu_poweroff(struct poweroff_handler *pwr)
-{
- writel(1, HTIF_TOHOST_LOW);
- writel(0, HTIF_TOHOST_HIGH);
-
- __builtin_unreachable();
-}
-
static void __noreturn riscvemu_restart(struct restart_handler *rst)
{
struct riscvemu_priv *priv = container_of(rst, struct riscvemu_priv, rst);
+ /* clear screen on graphic console */
+ puts("\e[J");
+
/*
* barebox PBL relocates itself to end of RAM early on, so unless
* something explicitly scrubbed the initial PBL, we can jump back to
@@ -40,14 +32,18 @@ static void __noreturn riscvemu_restart(struct restart_handler *rst)
priv->restart(riscv_hartid(), barebox_riscv_boot_dtb());
}
+extern char __dtb_overlay_of_sram_start[];
+
static int riscvemu_probe(struct device_d *dev)
{
struct device_node *of_chosen;
+ struct device_node *overlay;
struct riscvemu_priv *priv;
u64 start;
- if (of_find_compatible_node(NULL, NULL, "ucb,htif0"))
- poweroff_handler_register_fn(riscvemu_poweroff);
+ overlay = of_unflatten_dtb(__dtb_overlay_of_sram_start, INT_MAX);
+ of_overlay_apply_tree(dev->device_node, overlay);
+ /* of_probe() will happen later at of_populate_initcall */
of_chosen = of_find_node_by_path("/chosen");
@@ -67,6 +63,7 @@ static const struct of_device_id riscvemu_of_match[] = {
{ .compatible = "ucbbar,riscvemu-bar_dev" },
{ /* sentinel */ },
};
+BAREBOX_DEEP_PROBE_ENABLE(riscvemu_of_match);
static struct driver_d riscvemu_board_driver = {
.name = "board-riscvemu",
diff --git a/arch/riscv/boards/riscvemu/overlay-of-sram.dts b/arch/riscv/boards/riscvemu/overlay-of-sram.dts
new file mode 100644
index 0000000000..506d45bde9
--- /dev/null
+++ b/arch/riscv/boards/riscvemu/overlay-of-sram.dts
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ fragment@0 {
+ target-path = "/soc";
+ __overlay__ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ sram@0 {
+ compatible = "mtd-ram";
+ reg = <0 0x1000 0 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bootrom";
+ reg = <0x0 0x40>;
+ };
+
+ partition@40 {
+ label = "fdt";
+ reg = <0x40 0x1fc0>;
+ };
+
+ environment_sram: partition@3000 {
+ label = "barebox-environment";
+ reg = <0x3000 0xb000>;
+ };
+
+ backend_state_sram: partition@e000 {
+ label = "barebox-state";
+ reg = <0xe000 0x1000>;
+ };
+ };
+ };
+ };
+ };
+
+ fragment@2 {
+ target-path = "/chosen";
+ __overlay__ {
+ environment {
+ compatible = "barebox,environment";
+ device-path = "/soc/sram@0/partitions/partition@3000";
+ };
+ };
+ };
+
+ fragment@3 {
+ target-path = "/";
+ __overlay__ {
+ aliases {
+ state = "/state";
+ };
+
+ state {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "barebox,state";
+ magic = <0x290cf8c6>;
+ backend-type = "raw";
+ backend = <&backend_state_sram>;
+ backend-stridesize = <64>;
+
+ bootstate {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ system0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ remaining_attempts@0 {
+ reg = <0x0 0x4>;
+ type = "uint32";
+ default = <3>;
+ };
+
+ priority@4 {
+ reg = <0x4 0x4>;
+ type = "uint32";
+ default = <20>;
+ };
+ };
+
+ system1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ remaining_attempts@8 {
+ reg = <0x8 0x4>;
+ type = "uint32";
+ default = <3>;
+ };
+
+ priority@c {
+ reg = <0xc 0x4>;
+ type = "uint32";
+ default = <21>;
+ };
+ };
+
+ last_chosen@10 {
+ reg = <0x10 0x4>;
+ type = "uint32";
+ };
+ };
+ };
+ };
+ };
+
+ fragment@4 {
+ target-path = "/htif";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ __overlay__ {
+ reg = <0 0x40008000 0 0x8>;
+ };
+ };
+};
diff --git a/arch/riscv/configs/virt32_defconfig b/arch/riscv/configs/virt32_defconfig
index 1d7b70fc0f..b5044cf34a 100644
--- a/arch/riscv/configs/virt32_defconfig
+++ b/arch/riscv/configs/virt32_defconfig
@@ -10,10 +10,15 @@ CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
+CONFIG_BOOTM_VERBOSE=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_BLSPEC=y
+CONFIG_CONSOLE_ACTIVATE_ALL=y
CONFIG_CONSOLE_ALLOW_COLOR=y
CONFIG_PBL_CONSOLE=y
CONFIG_PARTITION_DISK_EFI=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_IKCONFIG=y
CONFIG_STATE=y
CONFIG_STATE_CRYPTO=y
CONFIG_BOOTCHOOSER=y
@@ -45,6 +50,7 @@ CONFIG_CMD_MSLEEP=y
CONFIG_CMD_SLEEP=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
+CONFIG_CMD_ECHO_E=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_SPLASH=y
CONFIG_CMD_FBTEST=y
@@ -87,6 +93,7 @@ CONFIG_MTD=y
# CONFIG_MTD_OOB_DEVICE is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_M25P80=y
+CONFIG_MTD_MTDRAM=y
CONFIG_DRIVER_CFI=y
CONFIG_DRIVER_CFI_BANK_WIDTH_8=y
CONFIG_DISK=y
@@ -99,6 +106,7 @@ CONFIG_DRIVER_VIDEO_SIMPLEFB_CLIENT=y
CONFIG_CLOCKSOURCE_DUMMY_RATE=60000
CONFIG_STATE_DRV=y
CONFIG_EEPROM_AT24=y
+CONFIG_VIRTIO_INPUT=y
CONFIG_HWRNG=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_GPIO_GENERIC_PLATFORM=y
@@ -108,6 +116,7 @@ CONFIG_BLK_DEV_NVME=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_RESET_HTIF_POWEROFF=y
CONFIG_VIRTIO_MMIO=y
CONFIG_FS_EXT4=y
CONFIG_FS_TFTP=y
diff --git a/arch/riscv/configs/virt64_defconfig b/arch/riscv/configs/virt64_defconfig
index 8c66e3e574..c2edd2dc28 100644
--- a/arch/riscv/configs/virt64_defconfig
+++ b/arch/riscv/configs/virt64_defconfig
@@ -11,10 +11,15 @@ CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
+CONFIG_BOOTM_VERBOSE=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_BLSPEC=y
+CONFIG_CONSOLE_ACTIVATE_ALL=y
CONFIG_CONSOLE_ALLOW_COLOR=y
CONFIG_PBL_CONSOLE=y
CONFIG_PARTITION_DISK_EFI=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_IKCONFIG=y
CONFIG_STATE=y
CONFIG_STATE_CRYPTO=y
CONFIG_BOOTCHOOSER=y
@@ -46,6 +51,7 @@ CONFIG_CMD_MSLEEP=y
CONFIG_CMD_SLEEP=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
+CONFIG_CMD_ECHO_E=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_SPLASH=y
CONFIG_CMD_FBTEST=y
@@ -88,6 +94,7 @@ CONFIG_MTD=y
# CONFIG_MTD_OOB_DEVICE is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_M25P80=y
+CONFIG_MTD_MTDRAM=y
CONFIG_DRIVER_CFI=y
CONFIG_DRIVER_CFI_BANK_WIDTH_8=y
CONFIG_DISK=y
@@ -100,6 +107,7 @@ CONFIG_DRIVER_VIDEO_SIMPLEFB_CLIENT=y
CONFIG_CLOCKSOURCE_DUMMY_RATE=60000
CONFIG_STATE_DRV=y
CONFIG_EEPROM_AT24=y
+CONFIG_VIRTIO_INPUT=y
CONFIG_HWRNG=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_GPIO_GENERIC_PLATFORM=y
@@ -109,6 +117,7 @@ CONFIG_BLK_DEV_NVME=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_RESET_HTIF_POWEROFF=y
CONFIG_VIRTIO_MMIO=y
CONFIG_FS_EXT4=y
CONFIG_FS_TFTP=y
diff --git a/arch/riscv/cpu/interrupts.c b/arch/riscv/cpu/interrupts.c
index 1f2d7b8857..0bb56d441d 100644
--- a/arch/riscv/cpu/interrupts.c
+++ b/arch/riscv/cpu/interrupts.c
@@ -14,6 +14,7 @@
#include <asm/ptrace.h>
#include <asm/irq.h>
#include <asm/csr.h>
+#include <asm/unwind.h>
#include <abort.h>
#include <pbl.h>
@@ -81,6 +82,8 @@ static void report_trap(const struct pt_regs *regs)
regs->epc, regs->ra, regs->badaddr);
show_regs(regs);
+
+ unwind_backtrace(regs);
}
diff --git a/arch/riscv/include/asm/barebox-riscv-head.h b/arch/riscv/include/asm/barebox-riscv-head.h
index a4c33472cd..4d62c20d1b 100644
--- a/arch/riscv/include/asm/barebox-riscv-head.h
+++ b/arch/riscv/include/asm/barebox-riscv-head.h
@@ -23,6 +23,7 @@
".ascii \"" magic2 "\"\n" /* magic 2 */ \
".word 0\n" /* reserved (PE-COFF offset) */ \
"1:\n" \
+ "li fp, 0\n" \
)
#define __barebox_riscv_header(instr, load_offset, version, magic1, magic2) \
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 1a15089cae..8bba809e45 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -13,13 +13,12 @@
/* Status register flags */
#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
+#define SR_MIE _AC(0x00000008, UL) /* Machine Interrupt Enable */
#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */
+#define SR_MPIE _AC(0x00000080, UL) /* Previous Machine IE */
#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */
-#ifdef CONFIG_RISCV_PRIV_1_9
-#define SR_PUM _AC(0x00040000, UL) /* Protect User Memory Access */
-#else
+#define SR_MPP _AC(0x00001800, UL) /* Previously Machine */
#define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */
-#endif
#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */
#define SR_FS_OFF _AC(0x00000000, UL)
@@ -33,22 +32,6 @@
#define SR_XS_CLEAN _AC(0x00010000, UL)
#define SR_XS_DIRTY _AC(0x00018000, UL)
-#ifdef CONFIG_RISCV_PRIV_1_9
-#define SR_VM _AC(0x1F000000, UL) /* Virtualization Management */
-#define SR_VM_MODE_BARE _AC(0x00000000, UL) /* No translation or protection */
-#define SR_VM_MODE_BB _AC(0x01000000, UL) /* Single base-and-bound */
-/* Separate instruction and data base-and-bound */
-#define SR_VM_MODE_BBID _AC(0x02000000, UL)
-#ifndef CONFIG_64BIT
-#define SR_VM_MODE_32 _AC(0x08000000, UL)
-#define SR_VM_MODE SR_VM_MODE_32
-#else
-#define SR_VM_MODE_39 _AC(0x09000000, UL)
-#define SR_VM_MODE_48 _AC(0x0A000000, UL)
-#define SR_VM_MODE SR_VM_MODE_39
-#endif
-#endif
-
#ifndef CONFIG_64BIT
#define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */
#else
@@ -56,51 +39,127 @@
#endif
/* SATP flags */
-#ifndef CONFIG_RISCV_PRIV_1_9
#ifndef CONFIG_64BIT
#define SATP_PPN _AC(0x003FFFFF, UL)
#define SATP_MODE_32 _AC(0x80000000, UL)
#define SATP_MODE SATP_MODE_32
+#define SATP_ASID_BITS 9
+#define SATP_ASID_SHIFT 22
+#define SATP_ASID_MASK _AC(0x1FF, UL)
#else
#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL)
#define SATP_MODE_39 _AC(0x8000000000000000, UL)
#define SATP_MODE SATP_MODE_39
-#endif
+#define SATP_ASID_BITS 16
+#define SATP_ASID_SHIFT 44
+#define SATP_ASID_MASK _AC(0xFFFF, UL)
#endif
-/* SCAUSE */
-#define SCAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1))
+/* Exception cause high bit - is an interrupt if set */
+#define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1))
#define IRQ_U_SOFT 0
+/* Interrupt causes (minus the high bit) */
#define IRQ_S_SOFT 1
+#define IRQ_VS_SOFT 2
#define IRQ_M_SOFT 3
#define IRQ_U_TIMER 4
#define IRQ_S_TIMER 5
+#define IRQ_VS_TIMER 6
#define IRQ_M_TIMER 7
#define IRQ_U_EXT 8
#define IRQ_S_EXT 9
+#define IRQ_VS_EXT 10
#define IRQ_M_EXT 11
+/* Exception causes */
#define EXC_INST_MISALIGNED 0
#define EXC_INST_ACCESS 1
+#define EXC_INST_ILLEGAL 2
#define EXC_BREAKPOINT 3
#define EXC_LOAD_ACCESS 5
#define EXC_STORE_ACCESS 7
#define EXC_SYSCALL 8
+#define EXC_HYPERVISOR_SYSCALL 9
+#define EXC_SUPERVISOR_SYSCALL 10
#define EXC_INST_PAGE_FAULT 12
#define EXC_LOAD_PAGE_FAULT 13
#define EXC_STORE_PAGE_FAULT 15
+#define EXC_INST_GUEST_PAGE_FAULT 20
+#define EXC_LOAD_GUEST_PAGE_FAULT 21
+#define EXC_VIRTUAL_INST_FAULT 22
+#define EXC_STORE_GUEST_PAGE_FAULT 23
+
+/* PMP configuration */
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_A_TOR 0x08
+#define PMP_A_NA4 0x10
+#define PMP_A_NAPOT 0x18
+#define PMP_L 0x80
+
+/* HSTATUS flags */
+#ifdef CONFIG_64BIT
+#define HSTATUS_VSXL _AC(0x300000000, UL)
+#define HSTATUS_VSXL_SHIFT 32
+#endif
+#define HSTATUS_VTSR _AC(0x00400000, UL)
+#define HSTATUS_VTW _AC(0x00200000, UL)
+#define HSTATUS_VTVM _AC(0x00100000, UL)
+#define HSTATUS_VGEIN _AC(0x0003f000, UL)
+#define HSTATUS_VGEIN_SHIFT 12
+#define HSTATUS_HU _AC(0x00000200, UL)
+#define HSTATUS_SPVP _AC(0x00000100, UL)
+#define HSTATUS_SPV _AC(0x00000080, UL)
+#define HSTATUS_GVA _AC(0x00000040, UL)
+#define HSTATUS_VSBE _AC(0x00000020, UL)
+
+/* HGATP flags */
+#define HGATP_MODE_OFF _AC(0, UL)
+#define HGATP_MODE_SV32X4 _AC(1, UL)
+#define HGATP_MODE_SV39X4 _AC(8, UL)
+#define HGATP_MODE_SV48X4 _AC(9, UL)
+
+#define HGATP32_MODE_SHIFT 31
+#define HGATP32_VMID_SHIFT 22
+#define HGATP32_VMID_MASK _AC(0x1FC00000, UL)
+#define HGATP32_PPN _AC(0x003FFFFF, UL)
+
+#define HGATP64_MODE_SHIFT 60
+#define HGATP64_VMID_SHIFT 44
+#define HGATP64_VMID_MASK _AC(0x03FFF00000000000, UL)
+#define HGATP64_PPN _AC(0x00000FFFFFFFFFFF, UL)
+
+#define HGATP_PAGE_SHIFT 12
-/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */
-#define MIE_MSIE (_AC(0x1, UL) << IRQ_M_SOFT)
-#define SIE_SSIE (_AC(0x1, UL) << IRQ_S_SOFT)
-#define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER)
-#define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT)
+#ifdef CONFIG_64BIT
+#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 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
+
+/* VSIP & HVIP relation */
+#define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT)
+#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \
+ (_AC(1, UL) << IRQ_S_TIMER) | \
+ (_AC(1, UL) << IRQ_S_EXT))
-#define CSR_FCSR 0x003
+/* symbolic CSR names: */
#define CSR_CYCLE 0xc00
#define CSR_TIME 0xc01
#define CSR_INSTRET 0xc02
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+
#define CSR_SSTATUS 0x100
#define CSR_SIE 0x104
#define CSR_STVEC 0x105
@@ -110,40 +169,90 @@
#define CSR_SCAUSE 0x142
#define CSR_STVAL 0x143
#define CSR_SIP 0x144
-#ifdef CONFIG_RISCV_PRIV_1_9
-#define CSR_SPTBR 0x180
-#else
#define CSR_SATP 0x180
-#endif
+
+#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
+
+#define CSR_HSTATUS 0x600
+#define CSR_HEDELEG 0x602
+#define CSR_HIDELEG 0x603
+#define CSR_HIE 0x604
+#define CSR_HTIMEDELTA 0x605
+#define CSR_HCOUNTEREN 0x606
+#define CSR_HGEIE 0x607
+#define CSR_HTIMEDELTAH 0x615
+#define CSR_HTVAL 0x643
+#define CSR_HIP 0x644
+#define CSR_HVIP 0x645
+#define CSR_HTINST 0x64a
+#define CSR_HGATP 0x680
+#define CSR_HGEIP 0xe12
+
#define CSR_MSTATUS 0x300
#define CSR_MISA 0x301
#define CSR_MIE 0x304
#define CSR_MTVEC 0x305
-#ifdef CONFIG_RISCV_PRIV_1_9
-#define CSR_MUCOUNTEREN 0x320
-#define CSR_MSCOUNTEREN 0x321
-#define CSR_MHCOUNTEREN 0x322
-#else
-#define CSR_MCOUNTEREN 0x306
-#endif
#define CSR_MSCRATCH 0x340
#define CSR_MEPC 0x341
#define CSR_MCAUSE 0x342
#define CSR_MTVAL 0x343
#define CSR_MIP 0x344
-#ifdef CONFIG_RISCV_PRIV_1_9
-#define CSR_MBASE 0x380
-#define CSR_MBOUND 0x381
-#define CSR_MIBASE 0x382
-#define CSR_MIBOUND 0x383
-#define CSR_MDBASE 0x384
-#define CSR_MDBOUND 0x385
-#endif
-#define CSR_CYCLEH 0xc80
-#define CSR_TIMEH 0xc81
-#define CSR_INSTRETH 0xc82
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPADDR0 0x3b0
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
#define CSR_MHARTID 0xf14
+#ifdef CONFIG_RISCV_M_MODE
+# define CSR_STATUS CSR_MSTATUS
+# define CSR_IE CSR_MIE
+# define CSR_TVEC CSR_MTVEC
+# define CSR_SCRATCH CSR_MSCRATCH
+# define CSR_EPC CSR_MEPC
+# define CSR_CAUSE CSR_MCAUSE
+# define CSR_TVAL CSR_MTVAL
+# define CSR_IP CSR_MIP
+
+# define SR_IE SR_MIE
+# define SR_PIE SR_MPIE
+# define SR_PP SR_MPP
+
+# define RV_IRQ_SOFT IRQ_M_SOFT
+# define RV_IRQ_TIMER IRQ_M_TIMER
+# define RV_IRQ_EXT IRQ_M_EXT
+#else /* CONFIG_RISCV_M_MODE */
+# define CSR_STATUS CSR_SSTATUS
+# define CSR_IE CSR_SIE
+# define CSR_TVEC CSR_STVEC
+# define CSR_SCRATCH CSR_SSCRATCH
+# define CSR_EPC CSR_SEPC
+# define CSR_CAUSE CSR_SCAUSE
+# define CSR_TVAL CSR_STVAL
+# define CSR_IP CSR_SIP
+
+# define SR_IE SR_SIE
+# define SR_PIE SR_SPIE
+# define SR_PP SR_SPP
+
+# define RV_IRQ_SOFT IRQ_S_SOFT
+# define RV_IRQ_TIMER IRQ_S_TIMER
+# define RV_IRQ_EXT IRQ_S_EXT
+#endif /* CONFIG_RISCV_M_MODE */
+
+/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */
+#define IE_SIE (_AC(0x1, UL) << RV_IRQ_SOFT)
+#define IE_TIE (_AC(0x1, UL) << RV_IRQ_TIMER)
+#define IE_EIE (_AC(0x1, UL) << RV_IRQ_EXT)
+
#ifndef __ASSEMBLY__
#define csr_swap(csr, val) \
diff --git a/arch/riscv/include/asm/debug_ll.h b/arch/riscv/include/asm/debug_ll.h
index 867c96d797..de9bc5f5fd 100644
--- a/arch/riscv/include/asm/debug_ll.h
+++ b/arch/riscv/include/asm/debug_ll.h
@@ -53,6 +53,17 @@ static inline void PUTC_LL(char ch)
#include <asm/debug_ll_litex.h>
+#elif defined CONFIG_DEBUG_RISCVEMU_HTIF
+
+#include <asm/htif.h>
+
+#ifndef __ASSEMBLY__
+static inline void PUTC_LL(char ch)
+{
+ htif_putc(IOMEM(HTIF_DEFAULT_BASE_ADDR), ch);
+}
+#endif
+
#endif
#ifndef debug_ll_init
diff --git a/arch/riscv/include/asm/debug_ll_litex.h b/arch/riscv/include/asm/debug_ll_litex.h
index 2fcdd9b0ec..295477fc10 100644
--- a/arch/riscv/include/asm/debug_ll_litex.h
+++ b/arch/riscv/include/asm/debug_ll_litex.h
@@ -90,11 +90,11 @@ static inline void PUTC_LL(char ch)
li t0, DEBUG_LL_UART_ADDR
/* get line status and check for data present */
- lbu s0, UART_RXEMPTY(t0)
- bnez s0, 243f
- li s0, 1
+ lbu s1, UART_RXEMPTY(t0)
+ bnez s1, 243f
+ li s1, 1
j 244f
-243: li s0, 0
+243: li s1, 0
244: nop
#endif /* CONFIG_DEBUG_LL */
.endm
@@ -109,10 +109,10 @@ static inline void PUTC_LL(char ch)
debug_ll_tstc
/* try again */
- beqz s0, 204b
+ beqz s1, 204b
/* read a character */
- lb s0, UART_RXTX(t0)
+ lb s1, UART_RXTX(t0)
li t1, UART_EV_RX
sb t1, UART_EV_PENDING(t0)
diff --git a/arch/riscv/include/asm/debug_ll_ns16550.h b/arch/riscv/include/asm/debug_ll_ns16550.h
index e208ef4fb1..47f0be328c 100644
--- a/arch/riscv/include/asm/debug_ll_ns16550.h
+++ b/arch/riscv/include/asm/debug_ll_ns16550.h
@@ -143,8 +143,8 @@ static inline void debug_ll_ns16550_init(void)
li t0, DEBUG_LL_UART_ADDR
/* get line status and check for data present */
- UART_REG_L s0, UART_LSR(DEBUG_LL_UART_SHIFT)(t0)
- andi s0, s0, UART_LSR_DR
+ UART_REG_L s1, UART_LSR(DEBUG_LL_UART_SHIFT)(t0)
+ andi s1, s1, UART_LSR_DR
#endif /* CONFIG_DEBUG_LL */
.endm
@@ -159,10 +159,10 @@ static inline void debug_ll_ns16550_init(void)
debug_ll_tstc
/* try again */
- beqz s0, 204b
+ beqz s1, 204b
/* read a character */
- UART_REG_L s0, UART_RBR(DEBUG_LL_UART_SHIFT)(t0)
+ UART_REG_L s1, UART_RBR(DEBUG_LL_UART_SHIFT)(t0)
#endif /* CONFIG_DEBUG_LL */
.endm
diff --git a/arch/riscv/include/asm/htif.h b/arch/riscv/include/asm/htif.h
new file mode 100644
index 0000000000..b35afdd98e
--- /dev/null
+++ b/arch/riscv/include/asm/htif.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef __ASM_HTIF_LL__
+#define __ASM_HTIF_LL__
+
+#define HTIF_DEFAULT_BASE_ADDR 0x40008000
+
+#define HTIF_DEV_SYSCALL 0
+#define HTIF_CMD_SYSCALL 0
+
+#define HTIF_DEV_CONSOLE 1 /* blocking character device */
+#define HTIF_CMD_GETCHAR 0
+#define HTIF_CMD_PUTCHAR 1
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <io-64-nonatomic-lo-hi.h>
+
+static inline void __htif_tohost(void __iomem *htif, u8 device, u8 command, u64 arg)
+{
+ writeq(((u64)device << 56) | ((u64)command << 48) | arg, htif);
+}
+
+static inline void htif_tohost(u8 device, u8 command, u64 arg)
+{
+ __htif_tohost(IOMEM(HTIF_DEFAULT_BASE_ADDR), device, command, arg);
+}
+
+static inline void htif_putc(void __iomem *base, int c)
+{
+ __htif_tohost(base, HTIF_DEV_CONSOLE, HTIF_CMD_PUTCHAR, c);
+}
+
+#endif
+
+#endif
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index b5e792f666..319c50f946 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -61,7 +61,7 @@ struct pt_regs {
#define MAX_REG_OFFSET offsetof(struct pt_regs, cause)
/* Helpers for working with the instruction pointer */
-static inline unsigned long instruction_pointer(struct pt_regs *regs)
+static inline unsigned long instruction_pointer(const struct pt_regs *regs)
{
return regs->epc;
}
@@ -74,7 +74,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs,
#define profile_pc(regs) instruction_pointer(regs)
/* Helpers for working with the user stack pointer */
-static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+static inline unsigned long user_stack_pointer(const struct pt_regs *regs)
{
return regs->sp;
}
@@ -85,13 +85,13 @@ static inline void user_stack_pointer_set(struct pt_regs *regs,
}
/* Valid only for Kernel mode traps. */
-static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+static inline unsigned long kernel_stack_pointer(const struct pt_regs *regs)
{
return regs->sp;
}
/* Helpers for working with the frame pointer */
-static inline unsigned long frame_pointer(struct pt_regs *regs)
+static inline unsigned long frame_pointer(const struct pt_regs *regs)
{
return regs->s0;
}
@@ -101,7 +101,7 @@ static inline void frame_pointer_set(struct pt_regs *regs,
regs->s0 = val;
}
-static inline unsigned long regs_return_value(struct pt_regs *regs)
+static inline unsigned long regs_return_value(const struct pt_regs *regs)
{
return regs->a0;
}
diff --git a/arch/riscv/include/asm/riscv_nmon.h b/arch/riscv/include/asm/riscv_nmon.h
index 8a44e216d7..3e349025fe 100644
--- a/arch/riscv/include/asm/riscv_nmon.h
+++ b/arch/riscv/include/asm/riscv_nmon.h
@@ -84,7 +84,7 @@ nmon_main:
debug_ll_getc
li a0, 'q'
- bne s0, a0, 3f
+ bne s1, a0, 3f
jal a2, _nmon_outc_a0
@@ -92,13 +92,13 @@ nmon_main:
3:
li a0, 'd'
- beq s0, a0, nmon_cmd_d
+ beq s1, a0, nmon_cmd_d
li a0, 'w'
- beq s0, a0, nmon_cmd_w
+ beq s1, a0, nmon_cmd_w
li a0, 'g'
- beq s0, a0, nmon_cmd_g
+ beq s1, a0, nmon_cmd_g
j nmon_main_help
@@ -112,7 +112,7 @@ nmon_cmd_d:
nmon_outs msg_nl
- lw a0, (s0)
+ lw a0, (s1)
debug_ll_outhexw
j nmon_main
@@ -124,13 +124,13 @@ nmon_cmd_w:
jal a2, _nmon_outc_a0
jal a2, _nmon_gethexw
- move s2, s0
+ move s3, s1
li a0, ' '
jal a2, _nmon_outc_a0
jal a2, _nmon_gethexw
- sw s0, 0(s2)
+ sw s1, 0(s3)
j nmon_main
nmon_cmd_g:
@@ -140,11 +140,11 @@ nmon_cmd_g:
jal a2, _nmon_outc_a0
jal a2, _nmon_gethexw
- move s2, s0
+ move s3, s1
nmon_outs msg_nl
- jalr s2
+ jalr s3
j nmon_main
_nmon_outc_a0:
@@ -169,37 +169,37 @@ _nmon_gethexw:
_get_hex_digit:
debug_ll_getc
- li s1, CODE_ESC
- beq s0, s1, nmon_main
+ li s2, CODE_ESC
+ beq s1, s2, nmon_main
- li s1, '0'
- bge s0, s1, 0f
+ li s2, '0'
+ bge s1, s2, 0f
j _get_hex_digit
0:
- li s1, '9'
- ble s0, s1, 9f
+ li s2, '9'
+ ble s1, s2, 9f
- li s1, 'f'
- ble s0, s1, 1f
+ li s2, 'f'
+ ble s1, s2, 1f
j _get_hex_digit
1:
- li s1, 'a'
- bge s0, s1, 8f
+ li s2, 'a'
+ bge s1, s2, 8f
j _get_hex_digit
-8: /* s0 \in {'a', 'b' ... 'f'} */
- sub a3, s0, s1
+8: /* s1 \in {'a', 'b' ... 'f'} */
+ sub a3, s1, s2
addi a3, a3, 0xa
j 0f
-9: /* s0 \in {'0', '1' ... '9'} */
+9: /* s1 \in {'0', '1' ... '9'} */
li a3, '0'
- sub a3, s0, a3
+ sub a3, s1, a3
-0: move a0, s0
+0: move a0, s1
debug_ll_outc_a0
sll t2, t2, 4
@@ -212,7 +212,7 @@ _get_hex_digit:
j _get_hex_digit
0:
- move s0, t2
+ move s1, t2
_nmon_jr_ra_exit:
jr a2
diff --git a/arch/riscv/include/asm/unwind.h b/arch/riscv/include/asm/unwind.h
index 9e5c8b5420..00f7845147 100644
--- a/arch/riscv/include/asm/unwind.h
+++ b/arch/riscv/include/asm/unwind.h
@@ -4,6 +4,12 @@
struct pt_regs;
-void unwind_backtrace(struct pt_regs *regs);
+#if defined CONFIG_RISCV_UNWIND && !defined __PBL__
+void unwind_backtrace(const struct pt_regs *regs);
+#else
+static inline void unwind_backtrace(const struct pt_regs *regs)
+{
+}
+#endif
#endif
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index a399de7399..f3db5320f7 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_RISCV_OPTIMZED_STRING_FUNCTIONS) += memcpy.o memset.o memmove.o
obj-$(CONFIG_RISCV_SBI) += sbi.o
obj-$(CONFIG_CMD_RISCV_CPUINFO) += cpuinfo.o
obj-$(CONFIG_BOOTM) += bootm.o
+obj-$(CONFIG_RISCV_UNWIND) += stacktrace.o
diff --git a/arch/riscv/lib/stacktrace.c b/arch/riscv/lib/stacktrace.c
new file mode 100644
index 0000000000..663938019e
--- /dev/null
+++ b/arch/riscv/lib/stacktrace.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2008 ARM Limited
+ * Copyright (C) 2014 Regents of the University of California
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ *
+ * Framepointer assisted stack unwinder
+ */
+
+#include <linux/kernel.h>
+#include <printk.h>
+#include <asm/unwind.h>
+#include <asm/ptrace.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/sections.h>
+
+struct stackframe {
+ unsigned long fp;
+ unsigned long ra;
+};
+
+static void dump_backtrace_entry(unsigned long where, unsigned long from)
+{
+#ifdef CONFIG_KALLSYMS
+ printf("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
+#else
+ printf("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
+#endif
+}
+
+static int unwind_frame(struct stackframe *frame, unsigned long *sp)
+{
+ unsigned long low, high;
+ unsigned long fp = frame->fp;
+
+ low = *sp;
+ high = ALIGN(low, STACK_SIZE);
+
+ if (fp < low || fp > high - sizeof(struct stackframe) || fp & 0x7)
+ return -1;
+
+ *frame = *((struct stackframe *)fp - 1);
+ *sp = fp;
+
+ return 0;
+}
+
+void unwind_backtrace(const struct pt_regs *regs)
+{
+ struct stackframe frame = {};
+ register unsigned long current_sp asm ("sp");
+ unsigned long sp = 0;
+
+ if (regs) {
+ frame.fp = frame_pointer(regs);
+ frame.ra = regs->ra;
+ } else {
+ sp = current_sp;
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.ra = (unsigned long)unwind_backtrace;
+ }
+
+ printf("Call trace:\n");
+ for (;;) {
+ unsigned long where = frame.ra;
+ int ret;
+
+ ret = unwind_frame(&frame, &sp);
+ if (ret < 0)
+ break;
+
+ dump_backtrace_entry(where, frame.ra);
+ }
+}
+
+void dump_stack(void)
+{
+ unwind_backtrace(NULL);
+}