diff options
Diffstat (limited to 'arch/riscv')
-rw-r--r-- | arch/riscv/Kconfig | 10 | ||||
-rw-r--r-- | arch/riscv/boards/riscvemu/Makefile | 1 | ||||
-rw-r--r-- | arch/riscv/boards/riscvemu/board.c | 25 | ||||
-rw-r--r-- | arch/riscv/boards/riscvemu/overlay-of-sram.dts | 129 | ||||
-rw-r--r-- | arch/riscv/configs/virt32_defconfig | 9 | ||||
-rw-r--r-- | arch/riscv/configs/virt64_defconfig | 9 | ||||
-rw-r--r-- | arch/riscv/cpu/interrupts.c | 3 | ||||
-rw-r--r-- | arch/riscv/include/asm/barebox-riscv-head.h | 1 | ||||
-rw-r--r-- | arch/riscv/include/asm/csr.h | 213 | ||||
-rw-r--r-- | arch/riscv/include/asm/debug_ll.h | 11 | ||||
-rw-r--r-- | arch/riscv/include/asm/debug_ll_litex.h | 12 | ||||
-rw-r--r-- | arch/riscv/include/asm/debug_ll_ns16550.h | 8 | ||||
-rw-r--r-- | arch/riscv/include/asm/htif.h | 40 | ||||
-rw-r--r-- | arch/riscv/include/asm/ptrace.h | 10 | ||||
-rw-r--r-- | arch/riscv/include/asm/riscv_nmon.h | 50 | ||||
-rw-r--r-- | arch/riscv/include/asm/unwind.h | 8 | ||||
-rw-r--r-- | arch/riscv/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/riscv/lib/stacktrace.c | 79 |
18 files changed, 512 insertions, 107 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index e093ed4226..1190cd4272 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -85,6 +85,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 ad283446ea..75f52ada8f 100644 --- a/arch/riscv/boards/riscvemu/Makefile +++ b/arch/riscv/boards/riscvemu/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only 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); +} |