diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-07-18 07:13:55 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-07-18 07:13:55 +0200 |
commit | 33f8f53317659cd2c61dd118bfa7150f33aa30fb (patch) | |
tree | cec893f4b273f4a78e1d84326d15e97b75a456df /arch/riscv | |
parent | ca922d6044e49b1ed9782aa8eb28d1ed70931978 (diff) | |
parent | b60bdac8a5870dc136c9b028771371dd123a2431 (diff) | |
download | barebox-33f8f53317659cd2c61dd118bfa7150f33aa30fb.tar.gz barebox-33f8f53317659cd2c61dd118bfa7150f33aa30fb.tar.xz |
Merge branch 'for-next/riscv'
Diffstat (limited to 'arch/riscv')
48 files changed, 2428 insertions, 108 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index a4aa799acf..a814a1a45b 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -77,6 +77,11 @@ config RISCV_OPTIMZED_STRING_FUNCTIONS These functions work faster than the normal versions but increase your binary size. +config RISCV_EXCEPTIONS + bool "enable exception handling support" + default y + select ARCH_HAS_DATA_ABORT_MASK + config HAS_NMON bool @@ -97,14 +102,18 @@ config NMON_HELP Say yes here to get the nmon commands message on every nmon start. -# set if we run in machine mode, cleared if we run in supervisor mode +# selected by boards where barebox runs in machine mode config RISCV_M_MODE bool -# set if we are running in S-mode and can use SBI calls -config RISCV_SBI +# selected by boards where barebox runs in supervisor mode +config RISCV_S_MODE bool - depends on !RISCV_M_MODE - default y + +config RISCV_MULTI_MODE + def_bool RISCV_S_MODE && RISCV_M_MODE + +config RISCV_SBI + def_bool RISCV_S_MODE endmenu diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs index c6875738d0..221ea133d4 100644 --- a/arch/riscv/Kconfig.socs +++ b/arch/riscv/Kconfig.socs @@ -15,14 +15,21 @@ config BOARD_ERIZO_GENERIC config SOC_VIRT bool "QEMU Virt Machine" + select RISCV_S_MODE select BOARD_RISCV_GENERIC_DT - select CLINT_TIMER + select HAS_CACHE help Generates an image tht can be be booted by QEMU. The image is called barebox-dt-2nd.img +config CPU_SIFIVE + bool + select HAS_CACHE + config SOC_SIFIVE bool "SiFive SoCs" + select CPU_SIFIVE + select RISCV_S_MODE select CLK_SIFIVE select CLK_SIFIVE_PRCI select RISCV_TIMER @@ -40,4 +47,52 @@ config BOARD_HIFIVE endif +config SOC_STARFIVE + bool "StarFive SoCs" + select ARCH_HAS_RESET_CONTROLLER + select RISCV_S_MODE + select HAS_ASM_DEBUG_LL + select HAS_NMON + help + This enables support for SiFive SoC platform hardware. + +if SOC_STARFIVE + +config SOC_STARFIVE_JH71XX + bool + select CPU_SIFIVE + +config SOC_STARFIVE_JH7100 + bool + select SOC_STARFIVE_JH71XX + select SIFIVE_L2 + help + Unlike JH7110 and later, CPU on the JH7100 are not cache-coherent + with respect to DMA masters like GMAC and DW MMC controller. + Select this if barebox needs to do DMA on this SoC. + +config BOARD_BEAGLEV + bool "BeagleV" + depends on ARCH_RV64I + select SOC_STARFIVE_JH71XX + select USE_COMPRESSED_DTB + +config BOARD_BEAGLEV_BETA + bool "BeagleV Beta (with JH7100)" + depends on BOARD_BEAGLEV + select SOC_STARFIVE_JH7100 + help + Select this for hardware using the earlier JH7100 SoC. The JH7110 + used with later production runs is cache-coherent and thus can do + without the special DMA handling enabled by this option. It's safe + to enable this option for other SoCs. + +endif + +comment "CPU features" + +config SIFIVE_L2 + bool "SiFive L2 cache controller" + depends on CPU_SIFIVE + endmenu diff --git a/arch/riscv/boards/Makefile b/arch/riscv/boards/Makefile index 99f22f32b4..cb28a25d8b 100644 --- a/arch/riscv/boards/Makefile +++ b/arch/riscv/boards/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_BOARD_ERIZO_GENERIC) += erizo/ obj-$(CONFIG_BOARD_HIFIVE) += hifive/ +obj-$(CONFIG_BOARD_BEAGLEV) += beaglev/ diff --git a/arch/riscv/boards/beaglev/Makefile b/arch/riscv/boards/beaglev/Makefile new file mode 100644 index 0000000000..23efc273ee --- /dev/null +++ b/arch/riscv/boards/beaglev/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +pbl-y += lowlevel.o +obj-y += board.o +bbenv-y += defaultenv-beaglev diff --git a/arch/riscv/boards/beaglev/board.c b/arch/riscv/boards/beaglev/board.c new file mode 100644 index 0000000000..110754ea95 --- /dev/null +++ b/arch/riscv/boards/beaglev/board.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Ahmad Fatoum, Pengutronix + */ + +#include <common.h> +#include <driver.h> +#include <bbu.h> +#include <envfs.h> + +static int beaglev_probe(struct device_d *dev) +{ + barebox_set_hostname("beaglev-starlight"); + + defaultenv_append_directory(defaultenv_beaglev); + + return 0; +} + +static const struct of_device_id beaglev_of_match[] = { + { .compatible = "beagle,beaglev-starlight-jh7100" }, + { /* sentinel */ }, +}; + +static struct driver_d beaglev_board_driver = { + .name = "board-beaglev", + .probe = beaglev_probe, + .of_compatible = beaglev_of_match, +}; +device_platform_driver(beaglev_board_driver); diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot new file mode 100755 index 0000000000..157223bbee --- /dev/null +++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot @@ -0,0 +1,13 @@ +#!/bin/sh + +BOOT=/mnt/mmc0.0/boot + +detect mmc0 + +global.linux.bootargs.base="rhgb stmmaceth=chain_mode:1" + +global.bootm.oftree=$BOOT/jh7100-starlight.dtb +global.bootm.image=$BOOT/Image +global linux.bootargs.root=rootwait +global linux.bootargs.earlycon=earlycon +global.bootm.appendroot=1 diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora new file mode 100755 index 0000000000..4f9ab16f82 --- /dev/null +++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora @@ -0,0 +1,16 @@ +#!/bin/sh + +BOOT=/mnt/mmc0.0 +VERSION=5.10.6-210.0.riscv64.fc33.riscv64 + +detect mmc0 + +global.linux.bootargs.base="root=UUID=ae1e722a-d01b-4cdc-ab56-7b68abcdd0fe rhgb stmmaceth=chain_mode:1 selinux=0 LANG=en_US.UTF-8" + +global.bootm.oftree=${BOOT}/starfive_vic7100_beagle_v.dtb +global.bootm.initrd=${BOOT}/initramfs-${VERSION}.img +global.bootm.image=${BOOT}/vmlinuz-${VERSION} +global linux.bootargs.root=rootwait +global linux.bootargs.earlycon=earlycon +#global.bootm.root_dev=mmc0.1 +#global.bootm.appendroot=1 diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default b/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default new file mode 100644 index 0000000000..880a6b1d8c --- /dev/null +++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default @@ -0,0 +1 @@ +buildroot net diff --git a/arch/riscv/boards/beaglev/lowlevel.c b/arch/riscv/boards/beaglev/lowlevel.c new file mode 100644 index 0000000000..db884dc762 --- /dev/null +++ b/arch/riscv/boards/beaglev/lowlevel.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <common.h> +#include <debug_ll.h> +#include <asm/barebox-riscv.h> +#include <asm/riscv_nmon.h> + +ENTRY_FUNCTION(start_beaglev_starlight, a0, a1, a2) +{ + extern char __dtb_z_jh7100_beaglev_starlight_start[]; + void *fdt; + + debug_ll_init(); + barebox_nmon_entry(); + putc_ll('>'); + + fdt = __dtb_z_jh7100_beaglev_starlight_start + get_runtime_offset(); + + barebox_riscv_supervisor_entry(0x84000000, SZ_512M, a0, fdt); +} diff --git a/arch/riscv/boards/erizo/lowlevel.c b/arch/riscv/boards/erizo/lowlevel.c index 6acf15931c..ab06634bdb 100644 --- a/arch/riscv/boards/erizo/lowlevel.c +++ b/arch/riscv/boards/erizo/lowlevel.c @@ -3,16 +3,20 @@ #include <common.h> #include <asm/barebox-riscv.h> #include <debug_ll.h> +#include <asm/riscv_nmon.h> ENTRY_FUNCTION(start_erizo_generic, a0, a1, a2) { extern char __dtb_z_erizo_generic_start[]; + void *fdt; debug_ll_init(); + barebox_nmon_entry(); putc_ll('>'); /* On POR, we are running from read-only memory here. */ - barebox_riscv_entry(0x80000000, SZ_8M, - __dtb_z_erizo_generic_start + get_runtime_offset()); + fdt = __dtb_z_erizo_generic_start + get_runtime_offset(); + + barebox_riscv_machine_entry(0x80000000, SZ_8M, fdt); } diff --git a/arch/riscv/boards/hifive/lowlevel.c b/arch/riscv/boards/hifive/lowlevel.c index 1de13cac16..5e8969bef1 100644 --- a/arch/riscv/boards/hifive/lowlevel.c +++ b/arch/riscv/boards/hifive/lowlevel.c @@ -4,22 +4,23 @@ #include <asm/barebox-riscv.h> #include <debug_ll.h> +static __always_inline void start_hifive(unsigned long hartid, void *fdt) +{ + putc_ll('>'); + + barebox_riscv_supervisor_entry(0x80000000, SZ_128M, hartid, fdt); +} + ENTRY_FUNCTION(start_hifive_unmatched, a0, a1, a2) { extern char __dtb_z_hifive_unmatched_a00_start[]; - putc_ll('>'); - - barebox_riscv_entry(0x80000000, SZ_128M, - __dtb_z_hifive_unmatched_a00_start + get_runtime_offset()); + start_hifive(a0, __dtb_z_hifive_unmatched_a00_start + get_runtime_offset()); } ENTRY_FUNCTION(start_hifive_unleashed, a0, a1, a2) { extern char __dtb_z_hifive_unleashed_a00_start[]; - putc_ll('>'); - - barebox_riscv_entry(0x80000000, SZ_128M, - __dtb_z_hifive_unleashed_a00_start + get_runtime_offset()); + start_hifive(a0, __dtb_z_hifive_unleashed_a00_start + get_runtime_offset()); } diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile index 968a826d16..80f63a4a0a 100644 --- a/arch/riscv/boot/Makefile +++ b/arch/riscv/boot/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += start.o pbl-y += entry.o uncompress.o +pbl-y += nmon_entry.o pbl-$(CONFIG_BOARD_GENERIC_DT) += board-dt-2nd.o diff --git a/arch/riscv/boot/board-dt-2nd.c b/arch/riscv/boot/board-dt-2nd.c index e9810f8add..f31c48a906 100644 --- a/arch/riscv/boot/board-dt-2nd.c +++ b/arch/riscv/boot/board-dt-2nd.c @@ -40,7 +40,7 @@ static const struct fdt_device_id console_ids[] = { { /* sentinel */ } }; -ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2) +ENTRY_FUNCTION(start_dt_2nd, hartid, _fdt, a2) { unsigned long membase, memsize, endmem, endfdt, uncompressed_len; struct fdt_header *fdt = (void *)_fdt; @@ -73,5 +73,5 @@ ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2) _fdt < riscv_mem_stack_top(membase, endmem)) memsize = ALIGN_DOWN(_fdt - membase, SZ_1M); - barebox_riscv_entry(membase, memsize, fdt); + barebox_riscv_supervisor_entry(membase, memsize, hartid, fdt); } diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c index eb286423d8..e4a5c2208d 100644 --- a/arch/riscv/boot/entry.c +++ b/arch/riscv/boot/entry.c @@ -20,10 +20,11 @@ */ void __noreturn __naked barebox_riscv_entry(unsigned long membase, - unsigned long memsize, void *boarddata) + unsigned long memsize, void *boarddata, + unsigned flags) { unsigned long stack_top = riscv_mem_stack_top(membase, membase + memsize); asm volatile ("move sp, %0" : : "r"(stack_top)); - barebox_pbl_start(membase, memsize, boarddata); + barebox_pbl_start(membase, memsize, boarddata, flags); } diff --git a/arch/riscv/boot/entry.h b/arch/riscv/boot/entry.h index b3a24d2783..fb4af5eae5 100644 --- a/arch/riscv/boot/entry.h +++ b/arch/riscv/boot/entry.h @@ -6,10 +6,12 @@ void __noreturn barebox_non_pbl_start(unsigned long membase, unsigned long memsize, - void *boarddata); + void *boarddata, + unsigned flags); void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize, - void *boarddata); + void *boarddata, + unsigned flags); #endif diff --git a/arch/riscv/boot/nmon_entry.S b/arch/riscv/boot/nmon_entry.S new file mode 100644 index 0000000000..ae017d2a1c --- /dev/null +++ b/arch/riscv/boot/nmon_entry.S @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include <linux/linkage.h> +#include <asm/sections.h> + +#include "asm/debug_ll.h" +#include "asm/riscv_nmon.h" + +.section .text_bare_init + +ENTRY(__barebox_nmon_entry) + riscv_nmon + ret +ENDPROC(__barebox_nmon_entry) diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c index 05f6c6231f..72ab93cb76 100644 --- a/arch/riscv/boot/start.c +++ b/arch/riscv/boot/start.c @@ -16,6 +16,7 @@ #include <uncompress.h> #include <malloc.h> #include <compressed-dtb.h> +#include <asm/irq.h> #include <debug_ll.h> @@ -26,6 +27,7 @@ static unsigned long riscv_barebox_size; static unsigned long riscv_endmem; static void *barebox_boarddata; static unsigned long barebox_boarddata_size; +unsigned barebox_riscv_pbl_flags; void *barebox_riscv_boot_dtb(void) { @@ -107,7 +109,8 @@ device_initcall(barebox_memory_areas_init); * the pbl. The stack already has been set up by the pbl. */ __noreturn __no_sanitize_address __section(.text_entry) -void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) +void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, + void *boarddata, unsigned flags) { unsigned long endmem = membase + memsize; unsigned long malloc_start, malloc_end; @@ -120,6 +123,8 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *b barrier(); + irq_init_vector(__riscv_mode(flags)); + pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize); riscv_endmem = endmem; @@ -168,18 +173,20 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *b mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1); + barebox_riscv_pbl_flags = flags; + pr_debug("starting barebox...\n"); start_barebox(); } -void start(unsigned long membase, unsigned long memsize, void *boarddata); +void start(unsigned long membase, unsigned long memsize, void *boarddata, unsigned flags); /* * First function in the uncompressed image. We get here from * the pbl. The stack already has been set up by the pbl. */ void __no_sanitize_address __section(.text_entry) start(unsigned long membase, - unsigned long memsize, void *boarddata) + unsigned long memsize, void *boarddata, unsigned flags) { - barebox_non_pbl_start(membase, memsize, boarddata); + barebox_non_pbl_start(membase, memsize, boarddata, flags); } diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c index b4e010998a..4ed9b4d371 100644 --- a/arch/riscv/boot/uncompress.c +++ b/arch/riscv/boot/uncompress.c @@ -14,6 +14,7 @@ #include <asm-generic/memory_layout.h> #include <asm/sections.h> #include <asm/unaligned.h> +#include <asm/irq.h> #include <debug_ll.h> @@ -23,15 +24,17 @@ unsigned long free_mem_ptr; unsigned long free_mem_end_ptr; void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize, - void *fdt) + void *fdt, unsigned flags) { uint32_t pg_len, uncompressed_len; - void __noreturn (*barebox)(unsigned long, unsigned long, void *); + void __noreturn (*barebox)(unsigned long, unsigned long, void *, unsigned); unsigned long endmem = membase + memsize; unsigned long barebox_base; void *pg_start, *pg_end; unsigned long pc = get_pc(); + irq_init_vector(__riscv_mode(flags)); + /* piggy data is not relocated, so determine the bounds now */ pg_start = input_data + get_runtime_offset(); pg_end = input_data_end + get_runtime_offset(); @@ -63,9 +66,11 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize, pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); + sync_caches_for_execution(); + barebox = (void *)barebox_base; pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt); - barebox(membase, memsize, fdt); + barebox(membase, memsize, fdt, flags); } diff --git a/arch/riscv/configs/starfive_defconfig b/arch/riscv/configs/starfive_defconfig new file mode 100644 index 0000000000..c4df2256f5 --- /dev/null +++ b/arch/riscv/configs/starfive_defconfig @@ -0,0 +1,131 @@ +CONFIG_ARCH_RV64I=y +CONFIG_SOC_STARFIVE=y +CONFIG_BOARD_BEAGLEV=y +CONFIG_BOARD_BEAGLEV_BETA=y +CONFIG_BOARD_RISCV_GENERIC_DT=y +CONFIG_RISCV_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_STACK_SIZE=0x20000 +CONFIG_MALLOC_SIZE=0x0 +CONFIG_MALLOC_TLSF=y +CONFIG_KALLSYMS=y +CONFIG_RELOCATABLE=y +CONFIG_PANIC_HANG=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_BOOTM_INITRD=y +CONFIG_SYSTEM_PARTITIONS=y +CONFIG_IMD_TARGET=y +CONFIG_CONSOLE_ALLOW_COLOR=y +CONFIG_PBL_CONSOLE=y +CONFIG_PARTITION_DISK_EFI=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_BAREBOXENV_TARGET=y +CONFIG_BAREBOXCRC32_TARGET=y +CONFIG_STATE=y +CONFIG_STATE_CRYPTO=y +CONFIG_BOOTCHOOSER=y +CONFIG_RESET_SOURCE=y +CONFIG_MACHINE_ID=y +CONFIG_CMD_DMESG=y +CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_IMD=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_POLLER=y +CONFIG_CMD_SLICE=y +CONFIG_CMD_GO=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_RESET=y +CONFIG_CMD_BOOTCHOOSER=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_CMP=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_LN=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_SHA1SUM=y +CONFIG_CMD_SHA256SUM=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_MSLEEP=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_PING=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_MM=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DETECT=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_WD=y +CONFIG_CMD_2048=y +CONFIG_CMD_BAREBOX_UPDATE=y +CONFIG_CMD_OF_DIFF=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OF_DISPLAY_TIMINGS=y +CONFIG_CMD_OF_FIXUP_STATUS=y +CONFIG_CMD_OF_OVERLAY=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_DHRYSTONE=y +CONFIG_NET=y +CONFIG_NET_NFS=y +CONFIG_DRIVER_SERIAL_NS16550=y +CONFIG_DRIVER_NET_DESIGNWARE=y +CONFIG_DRIVER_NET_DESIGNWARE_GENERIC=y +CONFIG_DRIVER_NET_DESIGNWARE_STARFIVE=y +CONFIG_MICREL_PHY=y +CONFIG_SPI_MEM=y +CONFIG_DRIVER_SPI_GPIO=y +CONFIG_MCI=y +CONFIG_MCI_DW=y +CONFIG_CLOCKSOURCE_DUMMY_RATE=60000 +CONFIG_SRAM=y +CONFIG_STARFIVE_PWRSEQ=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_GPIO_OF=y +CONFIG_LED_TRIGGERS=y +CONFIG_WATCHDOG=y +CONFIG_STARFIVE_WDT=y +CONFIG_HWRNG=y +CONFIG_HW_RANDOM_STARFIVE=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_STARFIVE=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_NVMEM=y +CONFIG_NVMEM_RMEM=y +CONFIG_STARFIVE_OTP=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_NVMEM_REBOOT_MODE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_VIRTIO_MENU is not set +CONFIG_FS_EXT4=y +CONFIG_FS_TFTP=y +CONFIG_FS_NFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y +CONFIG_FS_UIMAGEFS=y +CONFIG_FS_PSTORE=y +CONFIG_FS_SQUASHFS=y +CONFIG_ZLIB=y +CONFIG_BZLIB=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DECOMPRESS=y +CONFIG_BASE64=y +CONFIG_DIGEST_CRC32_GENERIC=y diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile index f1312be699..717baaaaa7 100644 --- a/arch/riscv/cpu/Makefile +++ b/arch/riscv/cpu/Makefile @@ -1,3 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += core.o time.o +obj-$(CONFIG_HAS_DMA) += dma.o +obj-pbl-$(CONFIG_RISCV_M_MODE) += mtrap.o +obj-pbl-$(CONFIG_RISCV_S_MODE) += strap.o +obj-pbl-y += interrupts.o diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c index 982d378edd..80730c05b5 100644 --- a/arch/riscv/cpu/core.c +++ b/arch/riscv/cpu/core.c @@ -18,7 +18,11 @@ #include <linux/clk.h> #include <linux/err.h> #include <memory.h> +#include <asm/barebox-riscv.h> #include <asm-generic/memory_layout.h> +#include <globalvar.h> +#include <magicvar.h> +#include <asm/system.h> #include <io.h> static int riscv_request_stack(void) @@ -30,6 +34,31 @@ coredevice_initcall(riscv_request_stack); static struct device_d timer_dev; +static s64 hartid; + +BAREBOX_MAGICVAR(global.hartid, "RISC-V hartid"); + +static int riscv_fixup_cpus(struct device_node *root, void *context) +{ + struct device_node *cpus_node, *np, *tmp; + + cpus_node = of_find_node_by_name(root, "cpus"); + if (!cpus_node) + return 0; + + for_each_child_of_node_safe(cpus_node, tmp, np) { + u32 cpu_index; + + if (of_property_read_u32(np, "reg", &cpu_index)) + continue; + + if (cpu_index != hartid) + of_delete_node(np); + } + + return 0; +} + static int riscv_probe(struct device_d *parent) { int ret; @@ -46,7 +75,11 @@ static int riscv_probe(struct device_d *parent) return ret; } - return 0; + hartid = riscv_hartid(); + if (hartid >= 0) + globalvar_add_simple_uint64("hartid", &hartid, "%llu"); + + return of_register_fixup(riscv_fixup_cpus, NULL); } static struct of_device_id riscv_dt_ids[] = { @@ -60,3 +93,9 @@ static struct driver_d riscv_driver = { .of_compatible = riscv_dt_ids, }; postcore_platform_driver(riscv_driver); + +static void arch_shutdown(void) +{ + sync_caches_for_execution(); +} +archshutdown_exitcall(arch_shutdown); diff --git a/arch/riscv/cpu/dma.c b/arch/riscv/cpu/dma.c new file mode 100644 index 0000000000..5a4d714e5e --- /dev/null +++ b/arch/riscv/cpu/dma.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <common.h> +#include <xfuncs.h> +#include <asm/dma.h> +#include <malloc.h> + +static void __dma_flush_range(dma_addr_t start, dma_addr_t end) +{ +} + +static void *__dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) +{ + void *ret; + + ret = xmemalign(PAGE_SIZE, size); + + memset(ret, 0, size); + + if (dma_handle) + *dma_handle = (dma_addr_t)ret; + + return ret; +} + +static void __dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size) +{ + free(vaddr); +} + +static const struct dma_ops coherent_dma_ops = { + .alloc_coherent = __dma_alloc_coherent, + .free_coherent = __dma_free_coherent, + .flush_range = __dma_flush_range, + .inv_range = __dma_flush_range, +}; + +static const struct dma_ops *dma_ops = &coherent_dma_ops; + +void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) +{ + return dma_ops->alloc_coherent(size, dma_handle); +} + +void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size) +{ + dma_ops->free_coherent(vaddr, dma_handle, size); +} + +void dma_set_ops(const struct dma_ops *ops) +{ + dma_ops = ops; +} + +void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir) +{ + /* + * FIXME: This function needs a device argument to support non 1:1 mappings + */ + if (dir != DMA_TO_DEVICE) + dma_ops->inv_range(address, address + size); +} + +void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir) +{ + /* + * FIXME: This function needs a device argument to support non 1:1 mappings + */ + + if (dir == DMA_FROM_DEVICE) + dma_ops->inv_range(address, address + size); + else + dma_ops->flush_range(address, address + size); +} diff --git a/arch/riscv/cpu/interrupts.c b/arch/riscv/cpu/interrupts.c new file mode 100644 index 0000000000..0e8951b619 --- /dev/null +++ b/arch/riscv/cpu/interrupts.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2016-17 Microsemi Corporation. + * Padmarao Begari, Microsemi Corporation <padmarao.begari@microsemi.com> + * + * Copyright (C) 2017 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation <rick@andestech.com> + * + * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com> + */ + +#include <common.h> +#include <asm/system.h> +#include <asm/ptrace.h> +#include <asm/irq.h> +#include <asm/csr.h> +#include <abort.h> +#include <pbl.h> + +#define MCAUSE32_INT 0x80000000 +#define MCAUSE64_INT 0x8000000000000000 + +#ifdef CONFIG_64BIT +# define MCAUSE_INT MCAUSE64_INT +#else +# define MCAUSE_INT MCAUSE32_INT +#endif + +static void show_regs(const struct pt_regs *regs) +{ + printf("\nsp: " REG_FMT " gp: " REG_FMT " tp: " REG_FMT "\n", + regs->sp, regs->gp, regs->tp); + printf("t0: " REG_FMT " t1: " REG_FMT " t2: " REG_FMT "\n", + regs->t0, regs->t1, regs->t2); + printf("s0: " REG_FMT " s1: " REG_FMT " a0: " REG_FMT "\n", + regs->s0, regs->s1, regs->a0); + printf("a1: " REG_FMT " a2: " REG_FMT " a3: " REG_FMT "\n", + regs->a1, regs->a2, regs->a3); + printf("a4: " REG_FMT " a5: " REG_FMT " a6: " REG_FMT "\n", + regs->a4, regs->a5, regs->a6); + printf("a7: " REG_FMT " s2: " REG_FMT " s3: " REG_FMT "\n", + regs->a7, regs->s2, regs->s3); + printf("s4: " REG_FMT " s5: " REG_FMT " s6: " REG_FMT "\n", + regs->s4, regs->s5, regs->s6); + printf("s7: " REG_FMT " s8: " REG_FMT " s9: " REG_FMT "\n", + regs->s7, regs->s8, regs->s9); + printf("s10: " REG_FMT " s11: " REG_FMT " t3: " REG_FMT "\n", + regs->s10, regs->s11, regs->t3); + printf("t4: " REG_FMT " t5: " REG_FMT " t6: " REG_FMT "\n", + regs->t4, regs->t5, regs->t6); +} + +static void report_trap(const struct pt_regs *regs) +{ + static const char * const exception_code[] = { + [0] = "Instruction address misaligned", + [1] = "Instruction access fault", + [2] = "Illegal instruction", + [3] = "Breakpoint", + [4] = "Load address misaligned", + [5] = "Load access fault", + [6] = "Store/AMO address misaligned", + [7] = "Store/AMO access fault", + [8] = "Environment call from U-mode", + [9] = "Environment call from S-mode", + [10] = "Reserved", + [11] = "Environment call from M-mode", + [12] = "Instruction page fault", + [13] = "Load page fault", + [14] = "Reserved", + [15] = "Store/AMO page fault", + + }; + + printf("Unhandled exception: %ld", regs->cause); + + if (regs->cause < ARRAY_SIZE(exception_code)) + printf(" \"%s\"\n", exception_code[regs->cause]); + + printf("E [<" REG_FMT ">] ra: [<" REG_FMT ">] tval: " REG_FMT "\n", + regs->epc, regs->ra, regs->badaddr); + + show_regs(regs); +} + + + +#ifdef __PBL__ + +static inline bool skip_data_abort(struct pt_regs *regs) +{ + return false; +} + +#else + +static volatile bool riscv_data_abort_occurred; +static volatile bool riscv_ignore_data_abort; + +void data_abort_mask(void) +{ + riscv_data_abort_occurred = false; + riscv_ignore_data_abort = true; +} + +int data_abort_unmask(void) +{ + riscv_ignore_data_abort = false; + return riscv_data_abort_occurred; +} + +static inline bool skip_data_abort(struct pt_regs *regs) +{ + return regs->cause == EXC_LOAD_ACCESS && riscv_ignore_data_abort; +} + +#endif + +unsigned long handle_trap(struct pt_regs *regs) +{ + if (skip_data_abort(regs)) + goto skip; + + if (regs->cause == 2) { /* illegal instruction */ + switch(*(unsigned long *)regs->epc) { + case 0x0000100f: /* fence.i */ + goto skip; + default: + break; + } + } + + report_trap(regs); + hang(); + +skip: + return regs->epc + 4; +} + diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S new file mode 100644 index 0000000000..e4aba7d694 --- /dev/null +++ b/arch/riscv/cpu/mtrap.S @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 FORTH-ICS/CARV + * Nick Kossifidis <mick@ics.forth.gr> + */ + +#include <asm/asm.h> +#include <asm/irq.h> +#include <linux/linkage.h> + +.section .text.mtrap_entry +ENTRY(mtrap_entry) + addi sp, sp, -PT_SIZE_ON_STACK + pt_regs_push sp + csrr t1, mstatus + csrr t2, mepc + csrr t3, mtval + csrr t4, mcause + + REG_S t1, PT_STATUS(sp) + REG_S t2, PT_EPC(sp) + REG_S t3, PT_BADADDR(sp) + REG_S t4, PT_CAUSE(sp) + mv a0, sp + jal handle_trap + csrw mepc, a0 + pt_regs_pop sp + addi sp, sp, PT_SIZE_ON_STACK + mret +ENDPROC(mtrap_entry) diff --git a/arch/riscv/cpu/strap.S b/arch/riscv/cpu/strap.S new file mode 100644 index 0000000000..c1d684c194 --- /dev/null +++ b/arch/riscv/cpu/strap.S @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 FORTH-ICS/CARV + * Nick Kossifidis <mick@ics.forth.gr> + */ + +#include <asm/asm.h> +#include <asm/irq.h> +#include <linux/linkage.h> + +.section .text.strap_entry +ENTRY(strap_entry) + addi sp, sp, -PT_SIZE_ON_STACK + pt_regs_push sp + csrr t1, sstatus + csrr t2, sepc + csrr t3, stval + csrr t4, scause + + REG_S t1, PT_STATUS(sp) + REG_S t2, PT_EPC(sp) + REG_S t3, PT_BADADDR(sp) + REG_S t4, PT_CAUSE(sp) + mv a0, sp + jal handle_trap + csrw sepc, a0 + pt_regs_pop sp + addi sp, sp, PT_SIZE_ON_STACK + sret +ENDPROC(strap_entry) diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index 17fdc9445b..4a15423b7f 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -7,5 +7,6 @@ obj- += dummy.o pbl-$(CONFIG_BOARD_ERIZO_GENERIC) += erizo-generic.dtb.o pbl-$(CONFIG_BOARD_HIFIVE) += hifive-unmatched-a00.dtb.o \ hifive-unleashed-a00.dtb.o +pbl-$(CONFIG_BOARD_BEAGLEV) += jh7100-beaglev-starlight.dtb.o clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts diff --git a/arch/riscv/dts/jh7100-beaglev-starlight.dts b/arch/riscv/dts/jh7100-beaglev-starlight.dts new file mode 100644 index 0000000000..8b4c1ac0ea --- /dev/null +++ b/arch/riscv/dts/jh7100-beaglev-starlight.dts @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 + +/dts-v1/; + +#include "jh7100-beaglev-starlight.dtsi" +#include <dt-bindings/gpio/gpio.h> + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "beagle,beaglev-starlight-jh7100", "starfive,jh7100"; + model = "BeagleV Starlight Beta"; + + aliases { + serial0 = &uart3; + serial1 = &uart0; + }; + + chosen { + environment { + compatible = "barebox,environment"; + device-path = &qpsi_env; + status = "disabled"; /* QSPI writes don't work yet */ + }; + }; +}; + +&nor_flash { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "secondboot"; + reg = <0x0 0x10000>; + }; + + partition@10000 { + label = "ddrinit"; + reg = <0x10000 0x10000>; + }; + + partition@20000 { + label = "sbi"; + reg = <0x20000 0x1e0000>; + }; + + qpsi_env: partition@200000 { + label = "environment"; + reg = <0x200000 0x1e00000>; + }; + }; +}; diff --git a/arch/riscv/dts/jh7100-beaglev-starlight.dtsi b/arch/riscv/dts/jh7100-beaglev-starlight.dtsi new file mode 100644 index 0000000000..13238f087f --- /dev/null +++ b/arch/riscv/dts/jh7100-beaglev-starlight.dtsi @@ -0,0 +1,369 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "jh7100.dtsi" +#include <dt-bindings/gpio/gpio.h> + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "beagle,beaglev-starlight-jh7100", "starfive,jh7100"; + model = "BeagleV Starlight Beta"; + + aliases { + serial0 = &uart3; + serial1 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200"; + }; + + cpus { + timebase-frequency = <6250000>; + }; + + gpiopof: gpio-poweroff { + compatible = "gpio-poweroff"; + gpios = <&gpio 63 GPIO_ACTIVE_HIGH>; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + label = "beaglev:green:ack"; + gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x2 0x0>; + }; + + memory@3000000000 { + device_type = "memory"; + reg = <0x30 0x0 0x0 0x0>; + }; +}; + +&gmac { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rgmii>; + phy-mode = "rgmii-txid"; + nvmem-cell-names = "mac-address"; + nvmem-cells = <ðaddr>; +}; + +&gpio { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio>; +}; + +&sdio0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdio0>; + bus-width = <4>; + cap-sd-highspeed; + broken-cd; + no-sdio; + status = "okay"; +}; + +&sdio1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdio1>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&usb3 { + dr_mode = "host"; + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c0>; + status = "okay"; + + imx219@10 { + compatible = "imx219"; + reg = <0x10>; + reset-gpio = <&gpio 58 0>; + }; + + tps65086@5e { + compatible = "ti,tps65086"; + reg = <0x5e>; + gpio-controller; + #gpio-cells = <2>; + }; + + tda998x@70 { + compatible = "nxp,tda998x"; + reg = <0x70>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + seeed_plane_i2c@45 { + compatible = "seeed_panel"; + reg = <0x45>; + }; +}; + +&qspi { + nor_flash: nor-flash@0 { + compatible = "spi-flash"; + reg = <0>; + spi-max-frequency = <31250000>; + cdns,page-size = <256>; + cdns,block-size = <16>; + cdns,read-delay = <4>; + cdns,tshsl-ns = <1>; + cdns,tsd2d-ns = <1>; + cdns,tchsh-ns = <1>; + cdns,tslch-ns = <1>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + +&spi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi2>; + status = "okay"; + + spi_dev0: spi@0 { + compatible = "rohm,dh2228fv"; + spi-max-frequency = <10000000>; + reg = <0>; + status = "okay"; + }; +}; + +&qspi { + status = "okay"; +}; + +&spi2 { + status = "okay"; +}; + +&otp { + power-gpios = <&gpio 56 GPIO_ACTIVE_HIGH>; + #address-cells = <1>; + #size-cells = <1>; + + ethaddr: ethaddr@28 { + reg = <0x28 6>; + label = "mac-address"; + }; +}; + +&gpio { + pinctrl_uart0: uart0_pins { + pinctrl-single,pins = < + 0x358 0x2a /* GPIO40: uart0_pad_sin */ + 0x194 0x1 /* GPIO40: doen_HIGH */ + 0x198 0x7f /* GPIO41: dout_uart0_pad_sout */ + 0x19c 0x0 /* GPIO41: doen_LOW */ + 0x1a0 0x7e /* GPIO42: dout_uart0_pad_rtsn */ + 0x1a4 0x0 /* GPIO42: doen_LOW */ + 0x348 0x29 /* GPIO39: uart0_pad_ctsn */ + 0x18c 0x1 /* GPIO39: doen_HIGH */ + 0x16c 0x0 /* GPIO35: doen_LOW */ + 0x168 0x1 /* GPIO35: dout_HIGH */ + >; + }; + + pinctrl_i2c0: i2c0_pins { + pinctrl-single,pins = < + 0x240 0x0 /* GPIO62: dout_LOW */ + 0x238 0x0 /* GPIO61: dout_LOW */ + 0x244 0x80000008 /* GPIO62: doen_i2c0_pad_sck_oe + doen_reverse_(1) */ + 0x23c 0x80000009 /* GPIO61: doen_i2c0_pad_sda_oe + doen_reverse_(1) */ + 0x278 0x40 /* GPIO62: i2c0_pad_sck_in */ + 0x27c 0x3f /* GPIO61: i2c0_pad_sda_in */ + >; + }; + + pinctrl_i2c1: i2c1_pins { + pinctrl-single,pins = < + 0x1c8 0x0 /* GPIO47: dout_LOW */ + 0x1d0 0x0 /* GPIO48: dout_LOW */ + 0x1cc 0x8000000a /* GPIO47: doen_i2c1_pad_sck_oe + doen_reverse_(1) */ + 0x1d4 0x8000000b /* GPIO48: doen_i2c1_pad_sda_oe + doen_reverse_(1) */ + 0x280 0x31 /* GPIO47: i2c1_pad_sck_in */ + 0x284 0x32 /* GPIO48: i2c1_pad_sda_in */ + >; + }; + + pinctrl_i2c2: i2c2_pins { + pinctrl-single,pins = < + 0x230 0x0 /* GPIO60: dout_LOW */ + 0x228 0x0 /* GPIO59: dout_LOW */ + 0x234 0x8000000c /* GPIO60: doen_i2c2_pad_sck_oe + doen_reverse_(1) */ + 0x22c 0x8000000d /* GPIO59: doen_i2c2_pad_sda_oe + doen_reverse_(1) */ + 0x288 0x3e /* GPIO60: i2c2_pad_sck_in */ + 0x28c 0x3d /* GPIO59: i2c2_pad_sda_in */ + >; + }; + + pinctrl_spi2: spi2_pins { + pinctrl-single,pins = < + /* MISO */ + 0xa8 0x6f /* GPIO11: dout_spi2_pad_txd */ + 0xac 0x0 /* GPIO11: doen_LOW */ + /* MOSI */ + 0x320 0xe /* GPIO12: spi2_pad_rxd */ + 0xb4 0x1 /* GPIO12: doen_HIGH */ + /* SCLK */ + 0xe0 0x6c /* GPIO18: dout_spi2_pad_sck_out */ + 0xe4 0x0 /* GPIO18: doen_LOW */ + /* CS */ + 0xe8 0x6d /* GPIO19: dout_spi2_pad_ss_0_n */ + 0xec 0x0 /* GPIO19: doen_LOW */ + >; + + }; + + pinctrl_sdio0: sdio0_pins { + pinctrl-single,pins = < + 0x2b4 0x39 /* GPIO55: sdio0_pad_card_detect_n */ + 0x20c 0x1 /* GPIO55: doen_HIGH */ + 0x200 0x36 /* GPIO54: dout_sdio0_pad_cclk_out */ + 0x204 0x0 /* GPIO54: doen_LOW */ + 0x1fc 0x80000037 /* GPIO53: doen_sdio0_pad_ccmd_oe + doen_reverse_(1) */ + 0x1f8 0x38 /* GPIO53: dout_sdio0_pad_ccmd_out */ + 0x2bc 0x37 /* GPIO53: _sdio0_pad_ccmd_in */ + 0x1dc 0x80000039 /* GPIO49: doen_sdio0_pad_cdata_oe_bit0 + doen_reverse_(1) */ + 0x1d8 0x41 /* GPIO49: dout_sdio0_pad_cdata_out_bit0 */ + 0x2c0 0x33 /* GPIO49: sdio0_pad_cdata_in_bit0 */ + 0x1e4 0x8000003a /* GPIO50: doen_sdio0_pad_cdata_oe_bit1 + doen_reverse_(1) */ + 0x1e0 0x42 /* GPIO50: dout_sdio0_pad_cdata_out_bit1 */ + 0x2c4 0x34 /* GPIO50: sdio0_pad_cdata_in_bit1 */ + 0x1ec 0x8000003b /* GPIO51: doen_sdio0_pad_cdata_oe_bit2 + doen_reverse_(1) */ + 0x1e8 0x43 /* GPIO51: dout_sdio0_pad_cdata_out_bit2 */ + 0x2c8 0x35 /* GPIO51: sdio0_pad_cdata_in_bit2 */ + 0x1f4 0x8000003c /* GPIO52: doen_sdio0_pad_cdata_oe_bit3 + doen_reverse_(1) */ + 0x1f0 0x44 /* GPIO52: dout_sdio0_pad_cdata_out_bit3 */ + 0x2cc 0x36 /* GPIO52: sdio0_pad_cdata_in_bit3(52) */ + >; + }; + + pinctrl_sdio1: sdio1_pins { + pinctrl-single,pins = < + 0x158 0x4b /* GPIO33: dout_sdio1_pad_cclk_out */ + 0x15c 0x0 /* GPIO33: doen_LOW */ + 0x13c 0x8000004c /* GPIO29: doen_sdio1_pad_ccmd_oe + doen_reverse_(1) */ + 0x138 0x4d /* GPIO29: dout_sdio1_pad_ccmd_out */ + 0x2e8 0x1f /* GPIO29: sdio1_pad_ccmd_in */ + 0x174 0x8000004e /* GPIO36: doen_sdio1_pad_cdata_oe_bit0 + doen_reverse_(1) */ + 0x170 0x56 /* GPIO36: dout_sdio1_pad_cdata_out_bit0 */ + 0x2ec 0x26 /* GPIO36: sdio1_pad_cdata_in_bit0 */ + 0x144 0x8000004f /* GPIO30: doen_sdio1_pad_cdata_oe_bit1 + doen_reverse_(1) */ + 0x140 0x57 /* GPIO30: dout_sdio1_pad_cdata_out_bit1 */ + 0x2f0 0x20 /* GPIO30: sdio1_pad_cdata_in_bit1 */ + 0x164 0x80000050 /* GPIO34: doen_sdio1_pad_cdata_oe_bit2 + doen_reverse_(1) */ + 0x160 0x58 /* GPIO34: dout_sdio1_pad_cdata_out_bit2 */ + 0x2f4 0x24 /* GPIO34: sdio1_pad_cdata_in_bit2 */ + 0x14c 0x80000051 /* GPIO31: doen_sdio1_pad_cdata_oe_bit3 + doen_reverse_(1) */ + 0x148 0x59 /* GPIO31: dout_sdio1_pad_cdata_out_bit3 */ + 0x2f8 0x21 /* GPIO31: sdio1_pad_cdata_in_bit3 */ + >; + }; +}; + +&pinconf { + pinctrl_rgmii: rgmii_pins { + pinctrl-single,pins = < + 0x164 0xC30080 + 0x168 0x30080 + + 0x16c 0x30003 + 0x170 0x30003 + 0x174 0x30003 + 0x178 0x30003 + + 0x17c 0xC800003 + + 0x180 0x8000C0 + 0x184 0xC000C0 + 0x188 0xC000C0 + 0x18c 0xC000C0 + 0x190 0xC000C0 + 0x194 0xC000C0 + 0x198 0xC000C0 + >; + }; + + /* Force most pins to input. Taken from vendor's sys_funcshare_io_input_en */ + pinctrl_gpio: gpio_pins { + pinctrl-single,pins = < + 0x80 0xc000c0 /* gpio0 */ + 0x90 0xc000c0 /* gpio8-9 */ + 0x94 0xc000c0 /* gpio10-11 */ + 0x98 0xc000c0 /* gpio12 */ + 0xa0 0xc000c0 /* gpio16-17 */ + 0xa4 0xc000c0 /* gpio18-19 */ + 0xa8 0xc000c0 /* gpio20-21 */ + 0xac 0xc000c0 /* gpio22-23 */ + 0xb0 0xc000c0 /* gpio24-25 */ + 0xb4 0xc000c0 /* gpio26-27 */ + 0xb8 0xc000c0 /* gpio28-29 */ + 0xbc 0xc000c0 /* gpio30-31 */ + 0xc0 0xc000c0 /* gpio32-33 */ + 0xc4 0xc000c0 /* gpio34-35 */ + 0xcc 0xc000c0 /* gpio38-39 */ + 0xd0 0xc000c0 /* gpio40-41 */ + 0xd4 0xc000c0 /* gpio42-43 */ + 0xd8 0xc000c0 /* gpio44-45 */ + 0xdc 0xc000c0 /* gpio46-47 */ + 0xe0 0xc000c0 /* gpio48-49 */ + 0xe4 0xc000c0 /* gpio50-51 */ + 0xe8 0xc000c0 /* gpio52-53 */ + 0xec 0xc000c0 /* gpio54-55 */ + 0xf0 0xc000c0 /* gpio56-57 */ + 0xf4 0xc000c0 /* gpio58-59 */ + 0xf8 0xc000c0 /* gpio60-61 */ + 0xfc 0xc000c0 /* gpio62-63 */ + >; + }; +}; diff --git a/arch/riscv/dts/jh7100.dtsi b/arch/riscv/dts/jh7100.dtsi new file mode 100644 index 0000000000..e3990582af --- /dev/null +++ b/arch/riscv/dts/jh7100.dtsi @@ -0,0 +1,798 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <dt-bindings/reset-controller/starfive-jh7100.h> +#include <dt-bindings/clock/starfive-jh7100.h> + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "starfive,jh7100"; + + aliases { + spi0 = &qspi; + mmc0 = &sdio0; + mmc1 = &sdio1; + usb0 = &usb3; + }; + + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + compatible = "sifive,u74-mc", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0>; + riscv,isa = "rv64imafdc"; + starfive,itim = <&itim0>; + status = "okay"; + tlb-split; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + + cpu@1 { + compatible = "sifive,u74-mc", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <1>; + riscv,isa = "rv64imafdc"; + starfive,itim = <&itim1>; + status = "okay"; + tlb-split; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + + osc_sys: clock-osc-sys { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "osc_sys"; + }; + + osc_aud: clock-osc-audio { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + clock-output-names = "osc_aud"; + }; + + i2c0clk: i2c0clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <49500000>; + clock-output-names = "i2c0clk"; + }; + + i2c2clk: i2c2clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <49500000>; + clock-output-names = "i2c2clk"; + }; + + axiclk: axiclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <500000000>; + clock-output-names = "axiclk"; + }; + + ahb0clk: ahb0clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <250000000>; + }; + + apb1clk: apb1clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <125000000>; + }; + + apb2clk: apb2clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <125000000>; + }; + + jpuclk: jpuclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <333333333>; + }; + + vpuclk: vpuclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <400000000>; + }; + + qspi_clk: qspi-clk@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + + uartclk: uartclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + }; + + hs_uartclk: hs_uartclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <74250000>; + }; + + spiclk: spiclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + + pwmclk: pwmclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <125000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0x28000000>; + alignment = <0x0 0x1000>; + alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>; + linux,cma-default; + }; + + jpu_reserved: framebuffer@c9000000 { + reg = <0x0 0xc9000000 0x0 0x4000000>; + }; + + nvdla_reserved:framebuffer@d0000000 { + reg = <0x0 0xd0000000 0x0 0x28000000>; + }; + + vin_reserved: framebuffer@f9000000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x0 0xf9000000 0x0 0x1000000>; + }; + + sffb_reserved: framebuffer@fb000000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x0 0xfb000000 0x0 0x2000000>; + }; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + #clock-cells = <1>; + compatible = "simple-bus"; + ranges; + + intram0: sram@18000000 { + compatible = "mmio-sram"; + reg = <0x0 0x18000000 0x0 0x20000>; + }; + + intram1: sram@18080000 { + compatible = "mmio-sram"; + reg = <0x0 0x18080000 0x0 0x8000>; + }; + + ccache: cache-controller@2010000 { + cache-block-size = <64>; + cache-level = <2>; + cache-sets = <2048>; + cache-size = <2097152>; + cache-unified; + compatible = "sifive,fu540-c000-ccache", "starfive,ccache0", "cache"; + interrupt-parent = <&plic>; + interrupts = <128 131 129 130>; + /*next-level-cache = <&L40 &L36>;*/ + reg = <0x0 0x2010000 0x0 0x1000 0x0 0x8000000 0x0 0x2000000>; + reg-names = "control", "sideband"; + }; + + dtim: dtim@1000000 { + compatible = "starfive,dtim0"; + reg = <0x0 0x1000000 0x0 0x2000>; + reg-names = "mem"; + }; + + itim0: itim@1808000 { + compatible = "starfive,itim0"; + reg = <0x0 0x1808000 0x0 0x8000>; + reg-names = "mem"; + }; + + itim1: itim@1820000 { + compatible = "starfive,itim0"; + reg = <0x0 0x1820000 0x0 0x8000>; + reg-names = "mem"; + }; + + clint: clint@2000000 { + #interrupt-cells = <1>; + compatible = "riscv,clint0"; + interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 &cpu1_intc 3 &cpu1_intc 7>; + reg = <0x0 0x2000000 0x0 0x10000>; + reg-names = "control"; + }; + + plic: plic@c000000 { + #interrupt-cells = <1>; + compatible = "riscv,plic0"; + interrupt-controller; + interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9 &cpu1_intc 11 &cpu1_intc 9>; + reg = <0x0 0xc000000 0x0 0x4000000>; + reg-names = "control"; + riscv,max-priority = <7>; + riscv,ndev = <127>; + }; + + sysmain: syscon@11850000 { + compatible = "syscon"; + reg = <0x0 0x11850000 0x0 0x4000>; + }; + + pinconf: pinctrl@11858000 { + compatible = "pinctrl-single"; + reg = <0x0 0x11858000 0x0 0x4000>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + uart0: hs_serial@11870000 { + compatible = "snps,dw-apb-uart"; + interrupt-parent = <&plic>; + interrupts = <92>; + reg = <0x0 0x11870000 0x0 0x10000>; + reg-io-width = <4>; + reg-shift = <2>; + clocks = <&hs_uartclk>, <&apb1clk>; + clock-names = "baudclk", "apb_pclk"; + current-clock = <74250000>; + current-speed = <115200>; + status = "disabled"; + }; + + uart1: hs_serial@11880000 { + compatible = "snps,dw-apb-uart"; + interrupt-parent = <&plic>; + interrupts = <93>; + reg = <0x0 0x11880000 0x0 0x10000>; + reg-io-width = <4>; + reg-shift = <2>; + clocks = <&hs_uartclk>, <&apb1clk>; + clock-names = "baudclk", "apb_pclk"; + current-clock = <74250000>; + current-speed = <115200>; + status = "disabled"; + }; + + uart2: serial@12430000 { + compatible = "snps,dw-apb-uart"; + interrupt-parent = <&plic>; + interrupts = <72>; + reg = <0x0 0x12430000 0x0 0x10000>; + reg-io-width = <4>; + reg-shift = <2>; + clocks = <&uartclk>, <&apb2clk>; + clock-names = "baudclk", "apb_pclk"; + current-clock = <100000000>; + current-speed = <115200>; + status = "disabled"; + }; + + uart3: serial@12440000 { + compatible = "snps,dw-apb-uart", "starfive,uart0"; + interrupt-parent = <&plic>; + interrupts = <73>; + reg = <0x0 0x12440000 0x0 0x10000>; + reg-io-width = <4>; + reg-shift = <2>; + clocks = <&uartclk>, <&apb2clk>; + clock-names = "baudclk", "apb_pclk"; + current-clock = <100000000>; + current-speed = <115200>; + status = "disabled"; + }; + + nne50: nne@10800000 { + compatible = "starfive,nne50"; + reg = <0x0 0x10800000 0x0 0x10000>; + resets = <&rstgen RSTN_DLA_AXI>, + <&rstgen RSTN_DLANOC_AXI>, + <&rstgen RSTN_DLA_APB>, + <&rstgen RSTN_NNENOC_AXI>, + <&rstgen RSTN_DLASLV_AXI>; + + assigned-clocks = <&clkgen CLK_NNE_BUS>; + assigned-clocks-parents = <&clkgen CLK_CPU_AXI>; + status = "okay"; + }; + + dma2p: sgdma2p@100b0000 { + compatible = "starfive,axi-dma", "snps,axi-dma-1.01a"; + reg = <0x0 0x100b0000 0x0 0x10000>; + clocks = <&axiclk>, <&ahb0clk>; + clock-names = "core-clk", "cfgr-clk"; + resets = <&rstgen RSTN_DMA2PNOC_AXI>, <&rstgen RSTN_SGDMA2P_AXI>, <&rstgen RSTN_SGDMA2P_AHB>; + reset-names = "noc", "axi", "ahb"; + interrupt-parent = <&plic>; + interrupts = <2>; + dma-channels = <4>; + snps,dma-masters = <1>; + snps,data-width = <4>; + snps,block-size = <4096 4096 4096 4096>; + snps,priority = <0 1 2 3>; + snps,axi-max-burst-len = <128>; + status = "okay"; + }; + + dma1p: sgdma1p@10500000 { + compatible = "starfive,axi-dma", "snps,axi-dma-1.01a"; + reg = <0x0 0x10500000 0x0 0x10000>; + clocks = <&axiclk>, <&ahb0clk>; + clock-names = "core-clk", "cfgr-clk"; + resets = <&rstgen RSTN_SGDMA1P_AXI>; + interrupt-parent = <&plic>; + interrupts = <1>; + dma-channels = <16>; + snps,dma-masters = <1>; + snps,data-width = <3>; + snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>; + snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>; + snps,axi-max-burst-len = <64>; + status = "okay"; + }; + + usb3: usb@104c0000 { + compatible = "cdns,usb3"; + reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers + <0x0 0x104d0000 0x0 0x10000>, // memory area for DEVICE registers + <0x0 0x104e0000 0x0 0x10000>; // memory area for OTG/DRD registers + reg-names = "otg", "xhci", "dev"; + interrupt-parent = <&plic>; + interrupts = <43>, <44>, <52>; + interrupt-names = "otg", + "host", + "peripheral"; + phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy"; + maximum-speed = "super-speed"; + status = "disabled"; + }; + + gpio: gpio@11910000 { + compatible = "starfive,gpio0"; + interrupt-parent = <&plic>; + interrupts = <32>; + resets = <&rstgen RSTN_GPIO_APB>; + clocks = <&clkgen CLK_GPIO_APB>; + reg = <0x0 0x11910000 0x0 0x10000>; + reg-names = "control"; + interrupt-controller; + #gpio-cells = <2>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + i2c0: i2c@118b0000 { + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x0 0x118b0000 0x0 0x10000>; + interrupt-parent = <&plic>; + interrupts = <96>; + clocks = <&i2c0clk>; + clock-frequency = <100000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <500>; + i2c-scl-falling-time-ns = <500>; + scl-gpio = <&gpio 62 0>; + sda-gpio = <&gpio 61 0>; + status = "disabled"; + }; + + i2c1: i2c@118c0000 { + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x0 0x118c0000 0x0 0x10000>; + interrupt-parent = <&plic>; + interrupts = <97>; + clocks = <&i2c0clk>; + clock-frequency = <400000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <100>; + i2c-scl-falling-time-ns = <100>; + scl-gpio = <&gpio 47 0>; + sda-gpio = <&gpio 48 0>; + status = "disabled"; + }; + + i2c2: i2c@12450000 { + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x0 0x12450000 0x0 0x10000>; + interrupt-parent = <&plic>; + interrupts = <74>; + clocks = <&i2c2clk>; + clock-frequency = <100000>; + i2c-sda-hold-time-ns = <300>; + i2c-sda-falling-time-ns = <500>; + i2c-scl-falling-time-ns = <500>; + scl-gpio = <&gpio 60 0>; + sda-gpio = <&gpio 59 0>; + status = "disabled"; + }; + + trng: trng@118d0000 { + compatible = "starfive,vic-rng"; + reg = <0x0 0x118d0000 0x0 0x10000>; + interrupt-parent = <&plic>; + interrupts = <98>; + clocks = <&clkgen CLK_TRNG_APB>; + resets = <&rstgen RSTN_TRNG_APB>; + }; + + crypto: crypto@100d0000 { + compatible = "starfive,vic-sec"; + reg = <0x0 0x100d0000 0x0 0x20000>, + <0x0 0x11800234 0x0 0xc>; + reg-names = "secmem", "secclk"; + resets = <&rstgen RSTN_SEC_AHB>, <&rstgen RSTN_AES>, + <&rstgen RSTN_PKA>, <&rstgen RSTN_SHA>; + interrupt-parent = <&plic>; + interrupts = <31>; + clocks = <&osc_sys>; + }; + + /* gmac device configuration */ + stmmac_axi_setup: stmmac-axi-config { + snps,wr_osr_lmt = <0xf>; + snps,rd_osr_lmt = <0xf>; + snps,blen = <256 128 64 32 0 0 0>; + }; + + gmac: gmac@10020000 { + compatible = "starfive,stmmac"; + reg = <0x0 0x10020000 0x0 0x10000>; + interrupt-parent = <&plic>; + interrupts = <6 7>; + interrupt-names = "macirq", "eth_wake_irq"; + resets = <&rstgen RSTN_GMAC_AHB>; + reset-names = "stmmaceth"; + clocks = <&clkgen CLK_GMAC_AHB>, <&clkgen CLK_GMAC_PTP_REF>, + <&clkgen CLK_GMAC_GTX>; + clock-names = "stmmaceth", "ptp_ref", "tx"; + max-frame-size = <9000>; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; + rx-fifo-depth = <32768>; + tx-fifo-depth = <16384>; + snps,fixed-burst = <1>; + snps,no-pbl-x8 = <1>; + /*snps,force_sf_dma_mode;*/ + snps,force_thresh_dma_mode; + snps,axi-config = <&stmmac_axi_setup>; + starfive,sysmain = <&sysmain>; + }; + + nbdla: nvdla@11940000 { + compatible = "nvidia,nvdla_os_initial"; + interrupt-parent = <&plic>; + resets = <&rstgen RSTN_DLA_AXI>, + <&rstgen RSTN_DLANOC_AXI>, + <&rstgen RSTN_DLA_APB>, + <&rstgen RSTN_NNENOC_AXI>, + <&rstgen RSTN_DLASLV_AXI>; + interrupts = <22>; + memory-region = <&nvdla_reserved>; + reg = <0x0 0x11940000 0x0 0x40000>; + status = "okay"; + }; + + jpu: coadj12@11900000 { + compatible = "cm,codaj12-jpu-1"; + reg = <0x0 0x11900000 0x0 0x300>; + memory-region = <&jpu_reserved>; + interrupt-parent = <&plic>; + interrupts = <24>; + clocks = <&jpuclk>; + clock-names = "jpege"; + reg-names = "control"; + resets = <&rstgen RSTN_JPEG_AXI>, <&rstgen RSTN_JPEG_CCLK>, + <&rstgen RSTN_JPEG_APB>; + status = "okay"; + }; + + clkgen: clock-controller@11800000 { + compatible = "starfive,jh7100-clkgen"; + reg = <0x0 0x11800000 0x0 0x10000>; + clocks = <&osc_sys>, <&osc_aud>; + clock-names = "osc_sys", "osc_aud"; + #clock-cells = <1>; + }; + + vpu_dec: vpu_dec@118f0000 { + compatible = "cm,cm511-vpu"; + reg = <0 0x118f0000 0 0x10000>; + //memory-region = <&vpu_reserved>; + interrupt-parent = <&plic>; + interrupts = <23>; + clocks = <&vpuclk>; + clock-names = "vcodec"; + resets = <&rstgen RSTN_VDEC_AXI>, <&rstgen RSTN_VDECBRG_MAIN>, + <&rstgen RSTN_VDEC_BCLK>, <&rstgen RSTN_VDEC_CCLK>, + <&rstgen RSTN_VDEC_APB>; + status = "okay"; + }; + + vpu_enc: vpu_enc@118e0000 { + compatible = "cm,cm521-vpu"; + reg = <0x0 0x118e0000 0x0 0x4000>; + interrupt-parent = <&plic>; + interrupts = <26>; + clocks = <&vpuclk>; + clock-names = "vcodec"; + resets = <&rstgen RSTN_VENC_AXI>, <&rstgen RSTN_VENCBRG_MAIN>, + <&rstgen RSTN_VENC_BCLK>, <&rstgen RSTN_VENC_CCLK>, + <&rstgen RSTN_VENC_APB>; + reg-names = "control"; + }; + + wdt: watchdogm@12480000 { + compatible = "starfive,wdt"; + reg = <0x0 0x12480000 0x0 0x10000>; + clocks = <&clkgen CLK_WDTIMER_APB>,<&clkgen CLK_WDT_CORE>; + clock-names = "bus", "core"; + resets = <&rstgen RSTN_WDTIMER_APB>, <&rstgen RSTN_WDT>; + reset-names = "bus", "core"; + }; + + ptc: pwm@12490000 { + compatible = "starfive,pwm0"; + reg = <0x0 0x12490000 0x0 0x10000>; + reg-names = "control"; + sifive,approx-period = <100000000>; + clocks = <&pwmclk>; + #pwm-cells = <3>; + sifive,npwm = <8>; + + }; + + rstgen: reset-controller@11840000 { + compatible = "starfive,jh7100-rstgen"; + reg = <0x0 0x11840000 0x0 0x10000>; + #reset-cells = <1>; + }; + + spi2ahb { + #address-cells = <2>; + #size-cells = <2>; + ranges; + compatible = "starfive,spi2ahb"; + resets = <&rstgen RSTN_SPI2AHB_AHB>, <&rstgen RSTN_SPI2AHB_CORE>; + + qspi: spi@11860000 { + compatible = "cadence,qspi", "cdns,qspi-nor"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0x11860000 0x0 0x10000 0x0 0x20000000 0x0 0x20000000>; + interrupts = <3>; + interrupt-parent = <&plic>; + clocks = <&qspi_clk>; + cdns,fifo-depth = <256>; + cdns,fifo-width = <4>; + cdns,trigger-address = <0x00000000>; + status = "disabled"; + spi-max-frequency = <250000000>; + }; + + spi2: spi@12410000 { + compatible = "snps,dw-apb-ssi"; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&plic>; + interrupts = <70>; + reg = <0x0 0x12410000 0x0 0x10000>; + clocks = <&spiclk>; + status = "disabled"; + /* + num-cs = <1>; + cs-gpios = <&gpio 0 0>; + */ + }; + }; + + xrp@f0000000 { + compatible = "cdns,xrp"; + reg = <0x0 0xf0000000 0x0 0x01ffffff + 0x10 0x72000000 0x0 0x00001000 + 0x10 0x72001000 0x0 0x00fff000 + 0x0 0x124b0000 0x0 0x00010000>; + clocks = <&osc_sys>; + interrupt-parent = <&plic>; + firmware-name = "vp6_elf"; + resets = <&rstgen RSTN_VP6INTC_APB>; + dsp-irq = <19 20>; + dsp-irq-src = <0x20 0x21>; + intc-irq-mode = <1>; + intc-irq = <0 1>; + interrupts = <27 28>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x40000000 0x0 0x40000000 0x01000000 + 0xb0000000 0x10 0x70000000 0x3000000>; + dsp@0 { + }; + }; + + sdio0: sdio0@10000000 { + compatible = "starfive,jh7100-dw-mshc", "snps,dw-mshc"; + reg = <0x0 0x10000000 0x0 0x10000>; + interrupts = <4>; + interrupt-parent = <&plic>; + clocks = <&clkgen CLK_SDIO0_AHB>, <&clkgen CLK_SDIO0_CCLKINT>; + clock-names = "biu", "ciu"; + resets = <&rstgen RSTN_SDIO0_AHB>; + reset-names = "reset"; + clock-frequency = <100000000>; + max-frequency = <10000000>; + fifo-depth = <32>; + card-detect-delay = <300>; + fifo-watermark-aligned; + data-addr = <0>; + post-power-on-delay-ms = <200>; + status = "disabled"; + }; + + sdio1: sdio1@10010000 { + compatible = "starfive,jh7100-dw-mshc", "snps,dw-mshc"; + reg = <0x0 0x10010000 0x0 0x10000>; + interrupts = <5>; + interrupt-parent = <&plic>; + clocks = <&clkgen CLK_SDIO1_AHB>, <&clkgen CLK_SDIO1_CCLKINT>; + clock-names = "biu", "ciu"; + resets = <&rstgen RSTN_SDIO1_AHB>; + reset-names = "reset"; + clock-frequency = <100000000>; + max-frequency = <10000000>; + fifo-depth = <32>; + card-detect-delay = <300>; + fifo-watermark-aligned; + data-addr = <0>; + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + cap-mmc-hw-reset; + enable-sdio-wakeup; + keep-power-in-suspend; + cap-mmc-highspeed; + post-power-on-delay-ms = <200>; + status = "disabled"; + }; + + sfivefb: sfivefb@12000000 { + compatible = "starfive,vpp-lcdc"; + interrupt-parent = <&plic>; + interrupts = <101>, <103>; + interrupt-names = "lcdc_irq", "vpp1_irq"; + reg = <0x0 0x12000000 0x0 0x10000>, + <0x0 0x12100000 0x0 0x10000>, + <0x0 0x12040000 0x0 0x10000>, + <0x0 0x12080000 0x0 0x10000>, + <0x0 0x120c0000 0x0 0x10000>, + <0x0 0x12240000 0x0 0x10000>, + <0x0 0x12250000 0x0 0x10000>, + <0x0 0x12260000 0x0 0x10000>; + reg-names = "lcdc", "dsitx", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys"; + memory-region = <&sffb_reserved>; + clocks = <&uartclk>, <&apb2clk>; + clock-names = "baudclk", "apb_pclk"; + status = "okay"; + ddr-format = <4>;/* LCDC win_format WIN_FMT_RGB565 */ + }; + + vin_sysctl: vin_sysctl@19800000 { + compatible = "starfive,stf-vin"; + reg = <0x0 0x19800000 0x0 0x10000>, + <0x0 0x19810000 0x0 0x10000>, + <0x0 0x19820000 0x0 0x10000>, + <0x0 0x19830000 0x0 0x10000>, + <0x0 0x19840000 0x0 0x10000>, + <0x0 0x19870000 0x0 0x30000>, + <0x0 0x198a0000 0x0 0x30000>, + <0x0 0x11800000 0x0 0x10000>, + <0x0 0x11840000 0x0 0x10000>, + <0x0 0x11858000 0x0 0x10000>; + reg-names = "mipi0", "vclk", "vrst", "mipi1", "sctrl", + "isp0", "isp1", "tclk", "trst", "iopad"; + interrupt-parent = <&plic>; + interrupts = <119 109>; + memory-region = <&vin_reserved>; + /*defaule config for imx219 vin&isp*/ + format = <3>; /* SRC_CSI2RX_VIN_ISP */ + frame-width = <800>; + frame-height =<480>; + isp0_enable; + csi-lane = <2>; + csi-dlane-swaps = /bits/ 8 <1>,/bits/ 8 <2>,/bits/ 8 <3>,/bits/ 8 <4>; + csi-dlane-pn-swaps = /bits/ 8 <0>,/bits/ 8 <0>,/bits/ 8 <0>,/bits/ 8 <0>; + csi-clane-swap = /bits/ 8 <0>; + csi-clane-pn-swap = /bits/ 8 <0>; + csi-mipiID = <0>; + csi-width = <1920>; + csi-height = <1080>; + csi-dt = <0x2b>; + }; + + sfc_tmp: tmpsensor@124a0000 { + compatible = "sfc,tempsensor"; + reg = <0x0 0x124a0000 0x0 0x1000>; + interrupt-parent = <&plic>; + interrupts = <122>; + resets = <&rstgen RSTN_TEMP_APB>, <&rstgen RSTN_TEMP_SENSE>; + status = "okay"; + }; + + otp: otp@11810000 { + compatible = "starfive,fu740-otp"; + reg = <0x0 0x11810000 0x0 0x10000>; + fuse-count = <0x200>; + resets = <&rstgen RSTN_OTP_APB>; + clocks = <&clkgen CLK_OTP_APB>; + }; + }; +}; diff --git a/arch/riscv/include/asm/asm-offsets.h b/arch/riscv/include/asm/asm-offsets.h new file mode 100644 index 0000000000..d370ee36a1 --- /dev/null +++ b/arch/riscv/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include <generated/asm-offsets.h> diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h index bb1d15308b..abb3202427 100644 --- a/arch/riscv/include/asm/barebox-riscv.h +++ b/arch/riscv/include/asm/barebox-riscv.h @@ -19,14 +19,26 @@ #include <linux/compiler.h> #include <asm/sections.h> #include <asm/barebox-riscv-head.h> +#include <asm/system.h> unsigned long get_runtime_offset(void); void setup_c(void); void relocate_to_current_adr(void); void relocate_to_adr(unsigned long target); + +void sync_caches_for_execution(void); + void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long memsize, - void *boarddata); + void *boarddata, unsigned int flags); + +#define barebox_riscv_machine_entry(membase, memsize, boarddata) \ + barebox_riscv_entry(membase, memsize, boarddata, RISCV_M_MODE) + +#define barebox_riscv_supervisor_entry(membase, memsize, hartid, boarddata) do { \ + __asm__ volatile("mv tp, %0\n" : : "r"(hartid)); \ + barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE); \ +} while (0) unsigned long riscv_mem_ramoops_get(void); unsigned long riscv_mem_endmem_get(void); diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h new file mode 100644 index 0000000000..eff529307a --- /dev/null +++ b/arch/riscv/include/asm/barrier.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Based on arch/arm/include/asm/barrier.h + * + * Copyright (C) 2012 ARM Ltd. + * Copyright (C) 2013 Regents of the University of California + * Copyright (C) 2017 SiFive + */ + +#ifndef _ASM_RISCV_BARRIER_H +#define _ASM_RISCV_BARRIER_H + +#ifndef __ASSEMBLY__ + +#define nop() __asm__ __volatile__ ("nop") + +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") + +/* These barriers need to enforce ordering on both devices or memory. */ +#define mb() RISCV_FENCE(iorw,iorw) +#define rmb() RISCV_FENCE(ir,ir) +#define wmb() RISCV_FENCE(ow,ow) + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_RISCV_BARRIER_H */ diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h new file mode 100644 index 0000000000..9ff25740c6 --- /dev/null +++ b/arch/riscv/include/asm/cacheflush.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015 Regents of the University of California + */ + +#ifndef _ASM_RISCV_CACHEFLUSH_H +#define _ASM_RISCV_CACHEFLUSH_H + +static inline void local_flush_icache_all(void) +{ +#ifdef HAS_CACHE + asm volatile ("fence.i" ::: "memory"); +#endif +} + +#endif /* _ASM_RISCV_CACHEFLUSH_H */ diff --git a/arch/riscv/include/asm/debug_ll.h b/arch/riscv/include/asm/debug_ll.h index 6904460af9..b4caa0597a 100644 --- a/arch/riscv/include/asm/debug_ll.h +++ b/arch/riscv/include/asm/debug_ll.h @@ -12,13 +12,19 @@ #include <linux/kconfig.h> -#ifdef CONFIG_DEBUG_ERIZO +#ifdef CONFIG_DEBUG_LL_NS16550 +#if defined CONFIG_DEBUG_ERIZO #define DEBUG_LL_UART_ADDR 0x90000000 +#define DEBUG_LL_UART_CLK (24000000 / 16) +#elif defined CONFIG_DEBUG_STARFIVE +#define DEBUG_LL_UART_ADDR 0x12440000 +#define DEBUG_LL_UART_CLK (100000000 / 16) +#endif + #define DEBUG_LL_UART_SHIFT 2 #define DEBUG_LL_UART_IOSIZE32 -#define DEBUG_LL_UART_CLK (24000000 / 16) #define DEBUG_LL_UART_BPS CONFIG_BAUDRATE #define DEBUG_LL_UART_DIVISOR (DEBUG_LL_UART_CLK / DEBUG_LL_UART_BPS) diff --git a/arch/riscv/include/asm/dma.h b/arch/riscv/include/asm/dma.h index 4204653984..56bcf06cc4 100644 --- a/arch/riscv/include/asm/dma.h +++ b/arch/riscv/include/asm/dma.h @@ -1,44 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_DMA_MAPPING_H -#define _ASM_DMA_MAPPING_H +#ifndef _RISCV_ASM_DMA_H +#define _RISCV_ASM_DMA_H -#include <common.h> -#include <xfuncs.h> -#include <linux/build_bug.h> -#include <malloc.h> +#include <linux/types.h> -#ifdef CONFIG_MMU -#error DMA stubs need be replaced when using MMU and caches -#endif +struct dma_ops { + void *(*alloc_coherent)(size_t size, dma_addr_t *dma_handle); + void (*free_coherent)(void *vaddr, dma_addr_t dma_handle, size_t size); -static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) -{ - void *ret; + void (*flush_range)(dma_addr_t start, dma_addr_t end); + void (*inv_range)(dma_addr_t start, dma_addr_t end); +}; - ret = xmemalign(PAGE_SIZE, size); +/* Override for SoCs with cache-incoherent DMA masters */ +void dma_set_ops(const struct dma_ops *ops); - memset(ret, 0, size); +#define DMA_ALIGNMENT 64 - if (dma_handle) - *dma_handle = (dma_addr_t)ret; - - return ret; -} - -static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, - size_t size) -{ - free(vaddr); -} - -static inline void dma_sync_single_for_cpu(dma_addr_t address, size_t size, - enum dma_data_direction dir) -{ -} - -static inline void dma_sync_single_for_device(dma_addr_t address, size_t size, - enum dma_data_direction dir) -{ -} +#include <dma.h> #endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index 3cdea7fcac..795e670e3b 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -5,4 +5,14 @@ #include <asm-generic/io.h> +static inline void *phys_to_virt(unsigned long phys) +{ + return (void *)phys; +} + +static inline unsigned long virt_to_phys(volatile void *mem) +{ + return (unsigned long)mem; +} + #endif /* __ASM_RISCV_IO_H */ diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h new file mode 100644 index 0000000000..fde7589baa --- /dev/null +++ b/arch/riscv/include/asm/irq.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef RISCV_ASM_IRQ_H__ +#define RISCV_ASM_IRQ_H__ + +#include <asm/csr.h> +#include <asm/system.h> +#include <asm/asm.h> +#include <asm/asm-offsets.h> +#include <asm/ptrace.h> + +#ifndef __ASSEMBLY__ +#include <asm/barebox-riscv.h> +void strap_entry(void); +void mtrap_entry(void); +unsigned long handle_trap(struct pt_regs *regs); + +static inline void irq_init_vector(enum riscv_mode mode) +{ + switch (mode) { +#ifdef CONFIG_RISCV_EXCEPTIONS + case RISCV_S_MODE: + asm volatile ("csrw stvec, %0; csrw sie, zero" : : + "r"(strap_entry + get_runtime_offset())); + break; + case RISCV_M_MODE: + asm volatile ("csrw mtvec, %0; csrw mie, zero" : : + "r"(mtrap_entry + get_runtime_offset())); + break; +#endif + default: + break; + } +} + +#else + +.macro pt_regs_push ptr + REG_S ra, PT_RA(\ptr) /* x1 */ + REG_S sp, PT_SP(\ptr) /* x2 */ + REG_S gp, PT_GP(\ptr) /* x3 */ + REG_S tp, PT_TP(\ptr) /* x4 */ + REG_S t0, PT_T0(\ptr) /* x5 */ + REG_S t1, PT_T1(\ptr) /* x6 */ + REG_S t2, PT_T2(\ptr) /* x7 */ + REG_S s0, PT_S0(\ptr) /* x8/fp */ + REG_S s1, PT_S1(\ptr) /* x9 */ + REG_S a0, PT_A0(\ptr) /* x10 */ + REG_S a1, PT_A1(\ptr) /* x11 */ + REG_S a2, PT_A2(\ptr) /* x12 */ + REG_S a3, PT_A3(\ptr) /* x13 */ + REG_S a4, PT_A4(\ptr) /* x14 */ + REG_S a5, PT_A5(\ptr) /* x15 */ + REG_S a6, PT_A6(\ptr) /* x16 */ + REG_S a7, PT_A7(\ptr) /* x17 */ + REG_S s2, PT_S2(\ptr) /* x18 */ + REG_S s3, PT_S3(\ptr) /* x19 */ + REG_S s4, PT_S4(\ptr) /* x20 */ + REG_S s5, PT_S5(\ptr) /* x21 */ + REG_S s6, PT_S6(\ptr) /* x22 */ + REG_S s7, PT_S7(\ptr) /* x23 */ + REG_S s8, PT_S8(\ptr) /* x24 */ + REG_S s9, PT_S9(\ptr) /* x25 */ + REG_S s10, PT_S10(\ptr) /* x26 */ + REG_S s11, PT_S11(\ptr) /* x27 */ + REG_S t3, PT_T3(\ptr) /* x28 */ + REG_S t4, PT_T4(\ptr) /* x29 */ + REG_S t5, PT_T5(\ptr) /* x30 */ + REG_S t6, PT_T6(\ptr) /* x31 */ +.endm + +.macro pt_regs_pop ptr + REG_L ra, PT_RA(\ptr) /* x1 */ + REG_L sp, PT_SP(\ptr) /* x2 */ + REG_L gp, PT_GP(\ptr) /* x3 */ + REG_L tp, PT_TP(\ptr) /* x4 */ + REG_L t0, PT_T0(\ptr) /* x5 */ + REG_L t1, PT_T1(\ptr) /* x6 */ + REG_L t2, PT_T2(\ptr) /* x7 */ + REG_L s0, PT_S0(\ptr) /* x8/fp */ + REG_L s1, PT_S1(\ptr) /* x9 */ + REG_L a0, PT_A0(\ptr) /* x10 */ + REG_L a1, PT_A1(\ptr) /* x11 */ + REG_L a2, PT_A2(\ptr) /* x12 */ + REG_L a3, PT_A3(\ptr) /* x13 */ + REG_L a4, PT_A4(\ptr) /* x14 */ + REG_L a5, PT_A5(\ptr) /* x15 */ + REG_L a6, PT_A6(\ptr) /* x16 */ + REG_L a7, PT_A7(\ptr) /* x17 */ + REG_L s2, PT_S2(\ptr) /* x18 */ + REG_L s3, PT_S3(\ptr) /* x19 */ + REG_L s4, PT_S4(\ptr) /* x20 */ + REG_L s5, PT_S5(\ptr) /* x21 */ + REG_L s6, PT_S6(\ptr) /* x22 */ + REG_L s7, PT_S7(\ptr) /* x23 */ + REG_L s8, PT_S8(\ptr) /* x24 */ + REG_L s9, PT_S9(\ptr) /* x25 */ + REG_L s10, PT_S10(\ptr) /* x26 */ + REG_L s11, PT_S11(\ptr) /* x27 */ + REG_L t3, PT_T3(\ptr) /* x28 */ + REG_L t4, PT_T4(\ptr) /* x29 */ + REG_L t5, PT_T5(\ptr) /* x30 */ + REG_L t6, PT_T6(\ptr) /* x31 */ +.endm + +#endif + +#endif diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h new file mode 100644 index 0000000000..b5e792f666 --- /dev/null +++ b/arch/riscv/include/asm/ptrace.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2012 Regents of the University of California + */ + +#ifndef _ASM_RISCV_PTRACE_H +#define _ASM_RISCV_PTRACE_H + +#include <asm/csr.h> +#include <linux/compiler.h> + +#ifndef __ASSEMBLY__ + +struct pt_regs { + unsigned long epc; + unsigned long ra; + unsigned long sp; + unsigned long gp; + unsigned long tp; + unsigned long t0; + unsigned long t1; + unsigned long t2; + unsigned long s0; + unsigned long s1; + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long a7; + unsigned long s2; + unsigned long s3; + unsigned long s4; + unsigned long s5; + unsigned long s6; + unsigned long s7; + unsigned long s8; + unsigned long s9; + unsigned long s10; + unsigned long s11; + unsigned long t3; + unsigned long t4; + unsigned long t5; + unsigned long t6; + /* Supervisor/Machine CSRs */ + unsigned long status; + unsigned long badaddr; + unsigned long cause; +}; + +#ifdef CONFIG_64BIT +#define REG_FMT "%016lx" +#else +#define REG_FMT "%08lx" +#endif + +#define user_mode(regs) (((regs)->status & SR_PP) == 0) + +#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) +{ + return regs->epc; +} +static inline void instruction_pointer_set(struct pt_regs *regs, + unsigned long val) +{ + regs->epc = val; +} + +#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) +{ + return regs->sp; +} +static inline void user_stack_pointer_set(struct pt_regs *regs, + unsigned long val) +{ + regs->sp = val; +} + +/* Valid only for Kernel mode traps. */ +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + return regs->sp; +} + +/* Helpers for working with the frame pointer */ +static inline unsigned long frame_pointer(struct pt_regs *regs) +{ + return regs->s0; +} +static inline void frame_pointer_set(struct pt_regs *regs, + unsigned long val) +{ + regs->s0 = val; +} + +static inline unsigned long regs_return_value(struct pt_regs *regs) +{ + return regs->a0; +} + +static inline void regs_set_return_value(struct pt_regs *regs, + unsigned long val) +{ + regs->a0 = val; +} + +extern int regs_query_register_offset(const char *name); +extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n); + +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long frame_pointer); +int do_syscall_trace_enter(struct pt_regs *regs); +void do_syscall_trace_exit(struct pt_regs *regs); + +/** + * regs_get_register() - get register value from its offset + * @regs: pt_regs from which register value is gotten + * @offset: offset of the register. + * + * regs_get_register returns the value of a register whose offset from @regs. + * The @offset is the offset of the register in struct pt_regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, + unsigned int offset) +{ + if (unlikely(offset > MAX_REG_OFFSET)) + return 0; + + return *(unsigned long *)((unsigned long)regs + offset); +} +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_RISCV_PTRACE_H */ diff --git a/arch/riscv/include/asm/riscv_nmon.h b/arch/riscv/include/asm/riscv_nmon.h index caf213cdd8..8a44e216d7 100644 --- a/arch/riscv/include/asm/riscv_nmon.h +++ b/arch/riscv/include/asm/riscv_nmon.h @@ -16,13 +16,26 @@ #ifndef __ASM_RISCV_NMON_H #define __ASM_RISCV_NMON_H +#include <linux/kconfig.h> + #define CODE_ESC 0x1b -.macro nmon_outs msg +#ifndef __ASSEMBLY__ - la a1, \msg +extern void __barebox_nmon_entry(void); - jal _nmon_outs +static inline void barebox_nmon_entry(void) +{ + if (IS_ENABLED(CONFIG_NMON)) + __barebox_nmon_entry(); +} + +#else + +.macro nmon_outs msg + + lla a1, \msg + jal a2, _nmon_outs .endm @@ -73,7 +86,7 @@ nmon_main: li a0, 'q' bne s0, a0, 3f - jal _nmon_outc_a0 + jal a2, _nmon_outc_a0 j nmon_exit @@ -90,12 +103,12 @@ nmon_main: j nmon_main_help nmon_cmd_d: - jal _nmon_outc_a0 + jal a2, _nmon_outc_a0 li a0, ' ' - jal _nmon_outc_a0 + jal a2, _nmon_outc_a0 - jal _nmon_gethexw + jal a2, _nmon_gethexw nmon_outs msg_nl @@ -105,28 +118,28 @@ nmon_cmd_d: j nmon_main nmon_cmd_w: - jal _nmon_outc_a0 + jal a2, _nmon_outc_a0 li a0, ' ' - jal _nmon_outc_a0 + jal a2, _nmon_outc_a0 - jal _nmon_gethexw + jal a2, _nmon_gethexw move s2, s0 li a0, ' ' - jal _nmon_outc_a0 - jal _nmon_gethexw + jal a2, _nmon_outc_a0 + jal a2, _nmon_gethexw sw s0, 0(s2) j nmon_main nmon_cmd_g: - jal _nmon_outc_a0 + jal a2, _nmon_outc_a0 li a0, ' ' - jal _nmon_outc_a0 + jal a2, _nmon_outc_a0 - jal _nmon_gethexw + jal a2, _nmon_gethexw move s2, s0 nmon_outs msg_nl @@ -136,7 +149,7 @@ nmon_cmd_g: _nmon_outc_a0: debug_ll_outc_a0 - jr ra + jr a2 _nmon_outs: @@ -202,7 +215,7 @@ _get_hex_digit: move s0, t2 _nmon_jr_ra_exit: - jr ra + jr a2 msg_prompt: .asciz "\r\nnmon> " @@ -231,4 +244,6 @@ nmon_exit: .endm +#endif /* __ASSEMBLY__ */ + #endif /* __ASM_RISCV_NMON_H */ diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index ab1fc9a128..eb4018de38 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -9,9 +9,7 @@ #include <linux/types.h> -#ifdef CONFIG_RISCV_SBI enum sbi_ext_id { -#ifdef CONFIG_RISCV_SBI_V01 SBI_EXT_0_1_SET_TIMER = 0x0, SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, @@ -21,7 +19,7 @@ enum sbi_ext_id { SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, SBI_EXT_0_1_SHUTDOWN = 0x8, -#endif + SBI_EXT_BASE = 0x10, SBI_EXT_TIME = 0x54494D45, SBI_EXT_IPI = 0x735049, @@ -167,7 +165,5 @@ static inline unsigned long sbi_minor_version(void) } int sbi_err_map_linux_errno(int err); -#else /* CONFIG_RISCV_SBI */ -static inline int sbi_remote_fence_i(const unsigned long *hart_mask) { return -1; } -#endif /* CONFIG_RISCV_SBI */ + #endif /* _ASM_RISCV_SBI_H */ diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h new file mode 100644 index 0000000000..adf856f9e9 --- /dev/null +++ b/arch/riscv/include/asm/system.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_SYSTEM_H_ +#define __ASM_SYSTEM_H_ + +#ifndef __ASSEMBLY__ + +#define RISCV_MODE_MASK 0x3 +enum riscv_mode { + RISCV_U_MODE = 0, + RISCV_S_MODE = 1, + RISCV_HS_MODE = 2, + RISCV_M_MODE = 3, +}; + +static inline enum riscv_mode __riscv_mode(u32 flags) +{ + /* allow non-LTO builds to discard code for unused modes */ + if (!IS_ENABLED(CONFIG_RISCV_MULTI_MODE)) { + if (IS_ENABLED(CONFIG_RISCV_M_MODE)) + return RISCV_M_MODE; + if (IS_ENABLED(CONFIG_RISCV_S_MODE)) + return RISCV_S_MODE; + } + + return flags & RISCV_MODE_MASK; +} + +static inline long __riscv_hartid(u32 flags) +{ + long hartid = -1; + + switch (__riscv_mode(flags)) { + case RISCV_S_MODE: + __asm__ volatile("mv %0, tp\n" : "=r"(hartid) :); + break; + default: + /* unimplemented */ + break; + } + + return hartid; +} + +#ifndef __PBL__ +extern unsigned barebox_riscv_pbl_flags; + +static inline enum riscv_mode riscv_mode(void) +{ + return __riscv_mode(barebox_riscv_pbl_flags); +} + +static inline long riscv_hartid(void) +{ + return __riscv_hartid(barebox_riscv_pbl_flags); +} +#endif + +#endif + +#endif diff --git a/arch/riscv/include/asm/unwind.h b/arch/riscv/include/asm/unwind.h new file mode 100644 index 0000000000..9e5c8b5420 --- /dev/null +++ b/arch/riscv/include/asm/unwind.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef RISCV_ASM_UNWIND_H__ +#define RISCV_ASM_UNWIND_H__ + +struct pt_regs; + +void unwind_backtrace(struct pt_regs *regs); + +#endif diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index 22f382b71e..4b869690f1 100644 --- a/arch/riscv/lib/asm-offsets.c +++ b/arch/riscv/lib/asm-offsets.c @@ -5,8 +5,54 @@ */ #include <linux/kbuild.h> +#include <linux/kernel.h> +#include <asm/ptrace.h> + +#define STACK_ALIGN 16 int main(void) { + DEFINE(PT_SIZE, sizeof(struct pt_regs)); + OFFSET(PT_EPC, pt_regs, epc); + OFFSET(PT_RA, pt_regs, ra); + OFFSET(PT_FP, pt_regs, s0); + OFFSET(PT_S0, pt_regs, s0); + OFFSET(PT_S1, pt_regs, s1); + OFFSET(PT_S2, pt_regs, s2); + OFFSET(PT_S3, pt_regs, s3); + OFFSET(PT_S4, pt_regs, s4); + OFFSET(PT_S5, pt_regs, s5); + OFFSET(PT_S6, pt_regs, s6); + OFFSET(PT_S7, pt_regs, s7); + OFFSET(PT_S8, pt_regs, s8); + OFFSET(PT_S9, pt_regs, s9); + OFFSET(PT_S10, pt_regs, s10); + OFFSET(PT_S11, pt_regs, s11); + OFFSET(PT_SP, pt_regs, sp); + OFFSET(PT_TP, pt_regs, tp); + OFFSET(PT_A0, pt_regs, a0); + OFFSET(PT_A1, pt_regs, a1); + OFFSET(PT_A2, pt_regs, a2); + OFFSET(PT_A3, pt_regs, a3); + OFFSET(PT_A4, pt_regs, a4); + OFFSET(PT_A5, pt_regs, a5); + OFFSET(PT_A6, pt_regs, a6); + OFFSET(PT_A7, pt_regs, a7); + OFFSET(PT_T0, pt_regs, t0); + OFFSET(PT_T1, pt_regs, t1); + OFFSET(PT_T2, pt_regs, t2); + OFFSET(PT_T3, pt_regs, t3); + OFFSET(PT_T4, pt_regs, t4); + OFFSET(PT_T5, pt_regs, t5); + OFFSET(PT_T6, pt_regs, t6); + OFFSET(PT_GP, pt_regs, gp); + OFFSET(PT_STATUS, pt_regs, status); + OFFSET(PT_BADADDR, pt_regs, badaddr); + OFFSET(PT_CAUSE, pt_regs, cause); + + /* + * We allocate a pt_regs on the stack. This ensures the alignment is sane. + */ + DEFINE(PT_SIZE_ON_STACK, ALIGN(sizeof(struct pt_regs), STACK_ALIGN)); return 0; } diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 1b96edcd1b..6984f282be 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -3,11 +3,13 @@ #include <common.h> #include <bootm.h> +#include <asm/system.h> static int do_bootm_linux(struct image_data *data) { void (*fn)(unsigned long a0, unsigned long dtb, unsigned long a2); phys_addr_t devicetree; + long hartid = riscv_hartid(); int ret; fn = booti_load_image(data, &devicetree); @@ -23,7 +25,7 @@ static int do_bootm_linux(struct image_data *data) shutdown_barebox(); - fn(0, devicetree, 0); + fn(hartid >= 0 ? hartid : 0, devicetree, 0); return -EINVAL; } diff --git a/arch/riscv/lib/cpuinfo.c b/arch/riscv/lib/cpuinfo.c index 21b99a990a..2d9cee2a62 100644 --- a/arch/riscv/lib/cpuinfo.c +++ b/arch/riscv/lib/cpuinfo.c @@ -2,6 +2,7 @@ #include <common.h> #include <command.h> #include <asm/sbi.h> +#include <asm/system.h> static const char *implementations[] = { [0] = "\"Berkeley Boot Loader (BBL)\" ", @@ -12,34 +13,57 @@ static const char *implementations[] = { [5] = "\"Diosix\" ", }; +static const char *modes[] = { + [RISCV_U_MODE] = "U", + [RISCV_S_MODE] = "S", + [RISCV_HS_MODE] = "HS", + [RISCV_M_MODE] = "M", +}; + static int do_cpuinfo(int argc, char *argv[]) { const char *implementation = ""; + enum riscv_mode mode; unsigned long impid; - printf("SBI specification v%lu.%lu detected\n", - sbi_major_version(), sbi_minor_version()); + mode = riscv_mode() & RISCV_MODE_MASK; + + printf("%s barebox for %s-Mode\n", + IS_ENABLED(CONFIG_ARCH_RV64I) ? "RV64I" : "RV32I", + modes[mode]); + + switch (mode) { + case RISCV_S_MODE: + printf("Hart ID=%lu\n", riscv_hartid()); + if (!IS_ENABLED(CONFIG_RISCV_SBI)) + break; + printf("SBI specification v%lu.%lu detected\n", + sbi_major_version(), sbi_minor_version()); - if (sbi_spec_is_0_1()) - return 0; + if (sbi_spec_is_0_1()) + return 0; - impid = __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID); - if (impid < ARRAY_SIZE(implementations)) - implementation = implementations[impid]; + impid = __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID); + if (impid < ARRAY_SIZE(implementations)) + implementation = implementations[impid]; - printf("SBI implementation ID=0x%lx %sVersion=0x%lx\n", - impid, implementation, __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION)); + printf("SBI implementation ID=0x%lx %sVersion=0x%lx\n", + impid, implementation, __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION)); - printf("SBI Machine VENDORID=0x%lx ARCHID=0x%lx MIMPID=0x%lx\n", - __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID), - __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID), - __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID)); + printf("SBI Machine VENDORID=0x%lx ARCHID=0x%lx MIMPID=0x%lx\n", + __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID), + __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID), + __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID)); + break; + default: + break; + } return 0; } BAREBOX_CMD_START(cpuinfo) .cmd = do_cpuinfo, -BAREBOX_CMD_DESC("show CPU information") -BAREBOX_CMD_GROUP(CMD_GRP_INFO) - BAREBOX_CMD_END + BAREBOX_CMD_DESC("show CPU information") + BAREBOX_CMD_GROUP(CMD_GRP_INFO) +BAREBOX_CMD_END diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c index 2fc8818cd6..479d586afd 100644 --- a/arch/riscv/lib/reloc.c +++ b/arch/riscv/lib/reloc.c @@ -5,6 +5,7 @@ #include <linux/linkage.h> #include <asm/sections.h> #include <asm/barebox-riscv.h> +#include <asm/cacheflush.h> #include <debug_ll.h> #include <asm-generic/module.h> @@ -24,6 +25,11 @@ #define RISC_R_TYPE(x) ((x) & 0xFF) +void sync_caches_for_execution(void) +{ + local_flush_icache_all(); +} + void relocate_to_current_adr(void) { unsigned long offset; @@ -63,4 +69,6 @@ void relocate_to_current_adr(void) panic(""); } } + + sync_caches_for_execution(); } diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c index 973c9d9d0f..45a04fb821 100644 --- a/arch/riscv/lib/sbi.c +++ b/arch/riscv/lib/sbi.c @@ -6,6 +6,7 @@ */ #include <asm/sbi.h> +#include <asm/system.h> #include <linux/export.h> #include <errno.h> #include <init.h> @@ -53,6 +54,9 @@ static int sbi_init(void) { int ret; + if (riscv_mode() != RISCV_S_MODE) + return 0; + ret = sbi_get_spec_version(); if (ret > 0) sbi_spec_version = ret; diff --git a/arch/riscv/lib/setupc.S b/arch/riscv/lib/setupc.S index 5fdd81c2c3..d225186c79 100644 --- a/arch/riscv/lib/setupc.S +++ b/arch/riscv/lib/setupc.S @@ -46,6 +46,8 @@ ENTRY(relocate_to_adr) jal __memcpy + jal sync_caches_for_execution + REG_L a0, (SZREG * 1)(sp) jr a0 /* jump to relocated address */ copied: |