diff --git a/sys/conf/files.riscv b/sys/conf/files.riscv index 1b03a8840109..37f4f203ab21 100644 --- a/sys/conf/files.riscv +++ b/sys/conf/files.riscv @@ -1,78 +1,79 @@ # $FreeBSD$ cddl/dev/dtrace/riscv/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/riscv/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/riscv/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" crypto/des/des_enc.c optional netsmb dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofwpci.c optional pci fdt dev/pci/pci_dw.c optional pci fdt dev/pci/pci_dw_if.m optional pci fdt dev/pci/pci_host_generic.c optional pci dev/pci/pci_host_generic_fdt.c optional pci fdt dev/uart/uart_cpu_fdt.c optional uart fdt dev/uart/uart_dev_lowrisc.c optional uart_lowrisc dev/xilinx/axi_quad_spi.c optional xilinx_spi dev/xilinx/axidma.c optional axidma xdma dev/xilinx/if_xae.c optional xae dev/xilinx/xlnx_pcib.c optional pci fdt xlnx_pcib kern/msi_if.m standard kern/pic_if.m standard kern/subr_devmap.c standard kern/subr_dummy_vdso_tc.c standard kern/subr_intr.c standard kern/subr_physmem.c standard libkern/bcmp.c standard libkern/bcopy.c standard libkern/ffs.c standard libkern/ffsl.c standard libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/memcmp.c standard libkern/memset.c standard libkern/strlen.c standard riscv/riscv/autoconf.c standard riscv/riscv/bus_machdep.c standard riscv/riscv/bus_space_asm.S standard riscv/riscv/busdma_bounce.c standard riscv/riscv/busdma_machdep.c standard riscv/riscv/clock.c standard riscv/riscv/copyinout.S standard riscv/riscv/cpufunc_asm.S standard riscv/riscv/db_disasm.c optional ddb riscv/riscv/db_interface.c optional ddb riscv/riscv/db_trace.c optional ddb riscv/riscv/dump_machdep.c standard riscv/riscv/elf_machdep.c standard riscv/riscv/exception.S standard riscv/riscv/exec_machdep.c standard +riscv/riscv/gdb_machdep.c optional gdb riscv/riscv/intr_machdep.c standard riscv/riscv/identcpu.c standard riscv/riscv/locore.S standard no-obj riscv/riscv/machdep.c standard riscv/riscv/minidump_machdep.c standard riscv/riscv/mp_machdep.c optional smp riscv/riscv/mem.c standard riscv/riscv/nexus.c standard riscv/riscv/ofw_machdep.c optional fdt riscv/riscv/plic.c standard riscv/riscv/pmap.c standard riscv/riscv/ptrace_machdep.c standard riscv/riscv/riscv_console.c optional rcons riscv/riscv/riscv_syscon.c optional ext_resources syscon riscv_syscon fdt riscv/riscv/sbi.c standard riscv/riscv/soc.c standard riscv/riscv/stack_machdep.c optional ddb | stack riscv/riscv/support.S standard riscv/riscv/swtch.S standard riscv/riscv/sys_machdep.c standard riscv/riscv/trap.c standard riscv/riscv/timer.c standard riscv/riscv/uio_machdep.c standard riscv/riscv/uma_machdep.c standard riscv/riscv/unwind.c optional ddb | kdtrace_hooks | stack riscv/riscv/vm_machdep.c standard # Zstd contrib/zstd/lib/freebsd/zstd_kfreebsd.c optional zstdio compile-with ${ZSTD_C} diff --git a/sys/riscv/conf/NOTES b/sys/riscv/conf/NOTES index 7dda89bfe1a8..1e4b8af1840e 100644 --- a/sys/riscv/conf/NOTES +++ b/sys/riscv/conf/NOTES @@ -1,104 +1,101 @@ # # NOTES -- Lines that can be cut/pasted into kernel and hints configs. # # This file contains machine dependent kernel configuration notes. For # machine independent notes, look in /sys/conf/NOTES. # # $FreeBSD$ # cpu RISCV makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options KDTRACE_FRAME # Ensure frames are compiled in options KDTRACE_HOOKS # Kernel DTrace hooks options DDB_CTF # Kernel ELF linker loads CTF data options FPE # Floating-point extension support options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default options INTRNG # Include INTRNG framework # RISC-V SBI console device rcons # EXT_RESOURCES pseudo devices options EXT_RESOURCES device clk device hwreset device phy device regulator device syscon device syscon_power device riscv_syscon # Backlight subsystem device backlight # VirtIO support device virtio # Generic VirtIO bus (required) device virtio_pci # VirtIO PCI device device vtnet # VirtIO Ethernet device device virtio_blk # VirtIO Block device device virtio_mmio # VirtIO MMIO bus device virtio_random # VirtIO Entropy device # NVM Express (NVMe) support device nvme # base NVMe driver options NVME_USE_NVD=0 # prefer the cam(4) based nda(4) driver device nvd # expose NVMe namespaces as disks, depends on nvme # NOTE: dtrace introduces CDDL-licensed components into the kernel device dtrace # dtrace core device dtraceall # include all dtrace modules # Serial (COM) ports device uart_lowrisc # lowRISC UART driver device uart_ns8250 # ns8250-type UART driver # RTC device goldfish_rtc # QEMU RTC # Ethernet drivers device xae # Xilinx AXI Ethernet MAC # DMA support device xdma # DMA interface device axidma # Xilinx AXI DMA Controller # SPI device xilinx_spi # Xilinx AXI Quad-SPI Controller # SiFive device drivers device fe310aon device fu740_pci_dw device sifive_gpio device sifive_spi files "../sifive/files.sifive" # Flattened Device Tree options FDT makeoptions MODULES_EXTRA+="dtb/sifive" # FreeBSD/riscv didn't exist for these releases nooptions COMPAT_FREEBSD4 nooptions COMPAT_FREEBSD5 nooptions COMPAT_FREEBSD6 nooptions COMPAT_FREEBSD7 nooptions COMPAT_FREEBSD9 nooptions COMPAT_FREEBSD10 nooptions COMPAT_FREEBSD11 -# No support for remote GDB -nooptions GDB - # riscv doesn't support inb/outb, so disable chipset probing which needs it nooptions PPC_PROBE_CHIPSET # Makes assumptions about bus tags that aren't true on riscv nodevice snd_cmi # Don't yet have hwpmc(4) nodevice hwpmc nooptions HWPMC_HOOKS diff --git a/sys/riscv/include/gdb_machdep.h b/sys/riscv/include/gdb_machdep.h new file mode 100644 index 000000000000..422f57a5742b --- /dev/null +++ b/sys/riscv/include/gdb_machdep.h @@ -0,0 +1,88 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Mitchell Horne + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _MACHINE_GDB_MACHDEP_H_ +#define _MACHINE_GDB_MACHDEP_H_ + +#define GDB_BUFSZ 4096 +#define GDB_NREGS 33 +#define GDB_REG_ZERO 0 +#define GDB_REG_RA 1 +#define GDB_REG_SP 2 +#define GDB_REG_GP 3 +#define GDB_REG_TP 4 +#define GDB_REG_T0 5 +#define GDB_REG_FP 8 +#define GDB_REG_S1 9 +#define GDB_REG_A0 10 +#define GDB_REG_S2 18 +#define GDB_REG_T3 28 +#define GDB_REG_PC 32 +#define GDB_REG_CSR_BASE 65 +#define GDB_REG_SSTATUS (GDB_REG_CSR_BASE + 0x100) +#define GDB_REG_SCAUSE (GDB_REG_CSR_BASE + 0x142) +#define GDB_REG_STVAL (GDB_REG_CSR_BASE + 0x143) +_Static_assert(GDB_BUFSZ >= (GDB_NREGS * 8), "buffer fits 'g' regs"); + +static __inline size_t +gdb_cpu_regsz(int regnum __unused) +{ + + return (8); +} + +static __inline int +gdb_cpu_query(void) +{ + return (0); +} + +static __inline void * +gdb_begin_write(void) +{ + + return (NULL); +} + +static __inline void +gdb_end_write(void *arg __unused) +{ + +} + +static __inline void +gdb_cpu_stop_reason(int type __unused, int code __unused) +{ + +} + +void *gdb_cpu_getreg(int, size_t *); +void gdb_cpu_setreg(int, void *); +int gdb_cpu_signal(int, int); + +#endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/riscv/riscv/gdb_machdep.c b/sys/riscv/riscv/gdb_machdep.c new file mode 100644 index 000000000000..06d4b8ba6e22 --- /dev/null +++ b/sys/riscv/riscv/gdb_machdep.c @@ -0,0 +1,135 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 Mitchell Horne + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +void * +gdb_cpu_getreg(int regnum, size_t *regsz) +{ + *regsz = gdb_cpu_regsz(regnum); + + if (kdb_thread == curthread) { + switch (regnum) { + case GDB_REG_RA: return (&kdb_frame->tf_ra); + case GDB_REG_PC: return (&kdb_frame->tf_sepc); + case GDB_REG_SSTATUS: return (&kdb_frame->tf_sstatus); + case GDB_REG_STVAL: return (&kdb_frame->tf_stval); + case GDB_REG_SCAUSE: return (&kdb_frame->tf_scause); + default: + if (regnum >= GDB_REG_A0 && regnum < GDB_REG_S2) + return (&kdb_frame->tf_a[regnum - GDB_REG_A0]); + if (regnum >= GDB_REG_T0 && regnum < GDB_REG_FP) + return (&kdb_frame->tf_t[regnum - GDB_REG_T0]); + if (regnum >= GDB_REG_T3 && regnum < GDB_REG_PC) + return (&kdb_frame->tf_t[regnum - GDB_REG_T3]); + break; + } + } + switch (regnum) { + case GDB_REG_PC: /* FALLTHROUGH */ + case GDB_REG_RA: return (&kdb_thrctx->pcb_ra); + case GDB_REG_SP: return (&kdb_thrctx->pcb_sp); + case GDB_REG_GP: return (&kdb_thrctx->pcb_gp); + case GDB_REG_TP: return (&kdb_thrctx->pcb_tp); + case GDB_REG_FP: return (&kdb_thrctx->pcb_s[0]); + case GDB_REG_S1: return (&kdb_thrctx->pcb_s[1]); + default: + if (regnum >= GDB_REG_S2 && regnum < GDB_REG_T3) + return (&kdb_thrctx->pcb_s[regnum - GDB_REG_S2]); + break; + } + + return (NULL); +} + +void +gdb_cpu_setreg(int regnum, void *val) +{ + register_t regval = *(register_t *)val; + + /* For curthread, keep the pcb and trapframe in sync. */ + if (kdb_thread == curthread) { + switch (regnum) { + case GDB_REG_PC: kdb_frame->tf_sepc = regval; break; + case GDB_REG_RA: kdb_frame->tf_ra = regval; break; + case GDB_REG_SP: kdb_frame->tf_sp = regval; break; + case GDB_REG_GP: kdb_frame->tf_gp = regval; break; + case GDB_REG_TP: kdb_frame->tf_tp = regval; break; + case GDB_REG_FP: kdb_frame->tf_s[0] = regval; break; + case GDB_REG_S1: kdb_frame->tf_s[1] = regval; break; + case GDB_REG_SSTATUS: kdb_frame->tf_sstatus = regval; break; + case GDB_REG_STVAL: kdb_frame->tf_stval = regval; break; + case GDB_REG_SCAUSE: kdb_frame->tf_scause = regval; break; + default: + if (regnum >= GDB_REG_A0 && regnum < GDB_REG_S2) + kdb_frame->tf_a[regnum - GDB_REG_A0] = regval; + if (regnum >= GDB_REG_S2 && regnum < GDB_REG_T3) + kdb_frame->tf_s[regnum - GDB_REG_S2] = regval; + if (regnum >= GDB_REG_T0 && regnum < GDB_REG_FP) + kdb_frame->tf_t[regnum - GDB_REG_T0] = regval; + if (regnum >= GDB_REG_T3 && regnum < GDB_REG_PC) + kdb_frame->tf_t[regnum - GDB_REG_T3] = regval; + break; + } + } + switch (regnum) { + case GDB_REG_PC: /* FALLTHROUGH */ + case GDB_REG_RA: kdb_thrctx->pcb_ra = regval; break; + case GDB_REG_SP: kdb_thrctx->pcb_sp = regval; break; + case GDB_REG_GP: kdb_thrctx->pcb_gp = regval; break; + case GDB_REG_TP: kdb_thrctx->pcb_tp = regval; break; + case GDB_REG_FP: kdb_thrctx->pcb_s[0] = regval; break; + case GDB_REG_S1: kdb_thrctx->pcb_s[1] = regval; break; + default: + if (regnum >= GDB_REG_S2 && regnum < GDB_REG_T3) + kdb_thrctx->pcb_s[regnum - GDB_REG_S2] = regval; + break; + } +} + +int +gdb_cpu_signal(int type, int code) +{ + + if (type == SCAUSE_BREAKPOINT) + return (SIGTRAP); + + return (SIGEMT); +}