From 53be157e2682ab29ef6d27234e2a1f8ff19eb40a Mon Sep 17 00:00:00 2001 From: Zoltan HERPAI Date: Sun, 16 Dec 2018 11:05:58 +0100 Subject: [PATCH] riscv64: add new port RISC-V is a new CPU architecture aimed to be fully free and open. This target will add support for it, based on 4.19. Supports running on: - HiFive Unleashed (which is the most known devboard for this arch) - QEMU (support is available in mainline qemu) Further devboards are expected given the interest in this new arch. An SD-card image is generated, where the partitions are required to have specific type codes. Compared to earlier branches for this target, BBL support is removed, giving way for OpenSBI. Signed-off-by: Zoltan HERPAI --- target/linux/riscv64/Makefile | 23 + .../riscv64/base-files/etc/board.d/02_network | 18 + target/linux/riscv64/base-files/etc/inittab | 6 + .../riscv64/base-files/lib/preinit/80_debug | 9 + target/linux/riscv64/config-5.4 | 437 ++++++++++ target/linux/riscv64/image/Config.in | 5 + target/linux/riscv64/image/Makefile | 88 ++ .../riscv64/image/gen_riscv64_sdcard_img.sh | 49 ++ ...dded-support-for-the-Vera-board-root.patch | 804 ++++++++++++++++++ 9 files changed, 1439 insertions(+) create mode 100644 target/linux/riscv64/Makefile create mode 100644 target/linux/riscv64/base-files/etc/board.d/02_network create mode 100644 target/linux/riscv64/base-files/etc/inittab create mode 100644 target/linux/riscv64/base-files/lib/preinit/80_debug create mode 100644 target/linux/riscv64/config-5.4 create mode 100644 target/linux/riscv64/image/Config.in create mode 100644 target/linux/riscv64/image/Makefile create mode 100644 target/linux/riscv64/image/gen_riscv64_sdcard_img.sh create mode 100644 target/linux/riscv64/patches/0010-pcie-microsemi-added-support-for-the-Vera-board-root.patch diff --git a/target/linux/riscv64/Makefile b/target/linux/riscv64/Makefile new file mode 100644 index 0000000000..d44ae0cc50 --- /dev/null +++ b/target/linux/riscv64/Makefile @@ -0,0 +1,23 @@ +# +# Copyright (C) 2017 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=riscv64 +BOARD:=riscv64 +BOARDNAME:=RISC-V HiFive Unleashed / QEMU +FEATURES:=ext4 +MAINTAINER:=Zoltan HERPAI + +KERNEL_PATCHVER:=5.4 + +include $(INCLUDE_DIR)/target.mk + +define Target/Description + Build firmware images for the HiFive Unleashed +endef + +$(eval $(call BuildTarget)) diff --git a/target/linux/riscv64/base-files/etc/board.d/02_network b/target/linux/riscv64/base-files/etc/board.d/02_network new file mode 100644 index 0000000000..df48b431af --- /dev/null +++ b/target/linux/riscv64/base-files/etc/board.d/02_network @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Copyright (C) 2013-2015 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh + +board_config_update + +case "$(board_name)" in +*) + ucidef_set_interface_lan 'eth0' + ;; +esac + +board_config_flush + +exit 0 diff --git a/target/linux/riscv64/base-files/etc/inittab b/target/linux/riscv64/base-files/etc/inittab new file mode 100644 index 0000000000..c328b218da --- /dev/null +++ b/target/linux/riscv64/base-files/etc/inittab @@ -0,0 +1,6 @@ +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K shutdown +tts/0::askfirst:/usr/libexec/login.sh +ttyS0::askfirst:/usr/libexec/login.sh +ttySI0::askfirst:/usr/libexec/login.sh +tty1::askfirst:/usr/libexec/login.sh diff --git a/target/linux/riscv64/base-files/lib/preinit/80_debug b/target/linux/riscv64/base-files/lib/preinit/80_debug new file mode 100644 index 0000000000..087e86e0c3 --- /dev/null +++ b/target/linux/riscv64/base-files/lib/preinit/80_debug @@ -0,0 +1,9 @@ +#!/bin/sh +# Copyright (C) 2012-2015 OpenWrt.org + +riscv_debug() { + cat /proc/cpuinfo +} + +boot_hook_add preinit_main riscv_debug + diff --git a/target/linux/riscv64/config-5.4 b/target/linux/riscv64/config-5.4 new file mode 100644 index 0000000000..8b58723da9 --- /dev/null +++ b/target/linux/riscv64/config-5.4 @@ -0,0 +1,437 @@ +CONFIG_64BIT=y +CONFIG_64BIT_TIME=y +# CONFIG_ADIN_PHY is not set +# CONFIG_AL_FIC is not set +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_HAS_BINFMT_FLAT=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +CONFIG_ARCH_HAS_MMIOWB=y +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +# CONFIG_ARCH_RV32I is not set +CONFIG_ARCH_RV64I=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_INT128=y +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ASN1=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_ATA=y +CONFIG_ATA_VERBOSE_ERROR=y +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_CAVIUM_PTP=y +CONFIG_CC_CAN_LINK=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y +CONFIG_CLK_GEMGXL_MGMT=y +CONFIG_CLK_SIFIVE=y +CONFIG_CLK_SIFIVE_FU540_PRCI=y +CONFIG_CLK_U54_PRCI=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CLZ_TAB=y +CONFIG_CMDLINE="earlyprintk root=/dev/mmcblk0p2 rootwait console=ttySI0" +CONFIG_CMDLINE_FALLBACK=y +CONFIG_CMODEL_MEDANY=y +# CONFIG_CMODEL_MEDLOW is not set +CONFIG_COMMON_CLK=y +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +# CONFIG_COMMON_CLK_SI5341 is not set +CONFIG_COMPAT_BRK=y +CONFIG_COREDUMP=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +# CONFIG_COUNTER is not set +CONFIG_CPU_ISOLATION=y +CONFIG_CPU_RMAP=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CRC7=y +CONFIG_CRC_ITU_T=y +CONFIG_CRYPTO_ACOMP2=y +# CONFIG_CRYPTO_ADIANTUM is not set +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECHAINIV=y +# CONFIG_CRYPTO_ECRDSA is not set +# CONFIG_CRYPTO_ESSIV is not set +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_OFB is not set +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_STREEBOG is not set +# CONFIG_CRYPTO_XXHASH is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_MISC=y +# CONFIG_DEBUG_PLIST is not set +CONFIG_DEBUG_SECTION_MISMATCH=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DEVMEM=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_DECLARE_COHERENT=y +CONFIG_DNOTIFY=y +CONFIG_DTC=y +CONFIG_E1000E=y +CONFIG_EDAC_SUPPORT=y +# CONFIG_EEPROM_EE1004 is not set +CONFIG_ELF_CORE=y +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_EXFAT_FS is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_FAILOVER=y +CONFIG_FHANDLE=y +# CONFIG_FIELDBUS_DEV is not set +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FPU=y +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=2048 +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +# CONFIG_FS_VERITY is not set +# CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CPU_DEVICES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GLOB=y +CONFIG_GPIOLIB=y +# CONFIG_GPIO_AMD_FCH is not set +# CONFIG_GPIO_CADENCE is not set +# CONFIG_GPIO_GW_PLD is not set +# CONFIG_GVE is not set +# CONFIG_HABANA_AI is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_COPY_THREAD_TLS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUTEX_CMPXCHG=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_PCI=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_HEADER_TEST is not set +CONFIG_HID=y +# CONFIG_HID_CREATIVE_SB0540 is not set +CONFIG_HID_GENERIC=y +# CONFIG_HID_MACALLY is not set +# CONFIG_HID_MALTRON is not set +# CONFIG_HID_VIEWSONIC is not set +# CONFIG_HUGETLBFS is not set +CONFIG_HVC_DRIVER=y +# CONFIG_HVC_RISCV_SBI is not set +CONFIG_HZ_PERIODIC=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_HELPER_AUTO=y +# CONFIG_I2C_NVIDIA_GPU is not set +CONFIG_I2C_OCORES=y +# CONFIG_I3C is not set +# CONFIG_IGC is not set +# CONFIG_IKHEADERS is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_INIT_STACK_NONE=y +CONFIG_INPUT=y +# CONFIG_INPUT_GPIO_VIBRA is not set +# CONFIG_INPUT_MSM_VIBRATOR is not set +# CONFIG_INTERCONNECT is not set +# CONFIG_IONIC is not set +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +CONFIG_KASAN_STACK=1 +CONFIG_KEYS=y +# CONFIG_KEYS_REQUEST_CACHE is not set +# CONFIG_LCD_CLASS_DEVICE is not set +# CONFIG_LEDS_AN30259A is not set +# CONFIG_LEDS_LM3532 is not set +# CONFIG_LEDS_TRIGGER_AUDIO is not set +# CONFIG_LEDS_TRIGGER_PATTERN is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBFDT=y +CONFIG_LOCALVERSION_AUTO=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" +CONFIG_MACB=y +# CONFIG_MACB_PCI is not set +CONFIG_MACB_USE_HWSTAMP=y +CONFIG_MANDATORY_FILE_LOCKING=y +CONFIG_MAXPHYSMEM_128GB=y +# CONFIG_MAXPHYSMEM_2GB is not set +CONFIG_MDIO_BUS=y +# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MEMFD_CREATE=y +# CONFIG_MFD_LOCHNAGAR is not set +# CONFIG_MFD_MAX77650 is not set +# CONFIG_MFD_ROHM_BD70528 is not set +# CONFIG_MFD_STMFX is not set +# CONFIG_MFD_STPMIC1 is not set +# CONFIG_MFD_TQMX86 is not set +CONFIG_MICROSEMI_PHY=y +CONFIG_MIGRATION=y +# CONFIG_MISC_ALCOR_PCI is not set +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_SPI=y +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMIOWB=y +CONFIG_MODULES_USE_ELF_RELA=y +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODULE_SECTIONS=y +CONFIG_MPILIB=y +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +# CONFIG_MTD_HYPERBUS is not set +# CONFIG_MTD_RAW_NAND is not set +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_NAMESPACES=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NET_FAILOVER=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_NS=y +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NET_SCH_TAPRIO is not set +CONFIG_NET_VENDOR_GOOGLE=y +CONFIG_NET_VENDOR_PENSANDO=y +# CONFIG_NI_XGE_MANAGEMENT_ENET is not set +CONFIG_NLS=y +CONFIG_NR_CPUS=8 +# CONFIG_NULL_TTY is not set +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OID_REGISTRY=y +# CONFIG_PACKING is not set +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xffffffe000000000 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_PA_BITS=56 +CONFIG_PCI=y +CONFIG_PCIE_MICROSEMI=y +CONFIG_PCI_DEBUG=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +# CONFIG_PCI_MESON is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_PHYLIB=y +CONFIG_PHYS_ADDR_T_64BIT=y +# CONFIG_PHY_CADENCE_DP is not set +# CONFIG_PHY_CADENCE_DPHY is not set +# CONFIG_PHY_FSL_IMX8MQ_USB is not set +# CONFIG_PHY_MIXEL_MIPI_DPHY is not set +CONFIG_PID_NS=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set +CONFIG_PPS=y +# CONFIG_PRINTK_CALLER is not set +CONFIG_PRINTK_TIME=y +# CONFIG_PSI is not set +CONFIG_PTP_1588_CLOCK=y +# CONFIG_PVPANIC is not set +CONFIG_PWM=y +# CONFIG_PWM_SIFIVE is not set +CONFIG_PWM_SYSFS=y +CONFIG_R8169=y +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set +CONFIG_RATIONAL=y +CONFIG_RCU_NEED_SEGCBLIST=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_TRACE=y +CONFIG_RD_GZIP=y +CONFIG_REALTEK_PHY=y +# CONFIG_REED_SOLOMON_TEST is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_RFS_ACCEL=y +CONFIG_RISCV=y +CONFIG_RISCV_ISA_C=y +CONFIG_RISCV_TIMER=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_PMP=y +CONFIG_SATA_SIL24=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCSI=y +# CONFIG_SCSI_MYRS is not set +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_EARLYCON_RISCV_SBI is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_SIFIVE=y +CONFIG_SERIAL_SIFIVE_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SGL_ALLOC=y +CONFIG_SG_POOL=y +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +CONFIG_SIFIVE_PLIC=y +CONFIG_SLUB_DEBUG=y +CONFIG_SMP=y +CONFIG_SOC_SIFIVE=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +# CONFIG_SPI_MTK_QUADSPI is not set +CONFIG_SPI_SIFIVE=y +CONFIG_SRCU=y +CONFIG_STACKTRACE=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +# CONFIG_TEST_BLACKHOLE_DEV is not set +# CONFIG_TEST_MEMCAT_P is not set +# CONFIG_TEST_MEMINIT is not set +# CONFIG_TEST_STACKINIT is not set +# CONFIG_TEST_STRSCPY is not set +# CONFIG_TEST_VMALLOC is not set +# CONFIG_TEST_XARRAY is not set +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +# CONFIG_TI_CPSW_PHY_SEL is not set +CONFIG_TRACE_CLOCK=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_TUNE_GENERIC=y +CONFIG_UBSAN_ALIGNMENT=y +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_UNICODE is not set +CONFIG_UNIX_SCM=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +# CONFIG_USB_CONN_GPIO is not set +# CONFIG_USB_EHCI_FSL is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_HID=y +CONFIG_USB_NET_DRIVERS=y +CONFIG_USB_PCI=y +CONFIG_USB_STORAGE=y +CONFIG_USB_SUPPORT=y +# CONFIG_USB_UHCI_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +# CONFIG_USB_XHCI_PLATFORM is not set +# CONFIG_USERIO is not set +# CONFIG_USER_NS is not set +CONFIG_UTS_NS=y +# CONFIG_VALIDATE_FS_PARSER is not set +CONFIG_VA_BITS=39 +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_VIRTIO=y +CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_VIRTIO_MMIO=y +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set +CONFIG_VIRTIO_NET=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +CONFIG_X509_CERTIFICATE_PARSER=y +# CONFIG_XILINX_SDFEC is not set +CONFIG_XPS=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA32=y diff --git a/target/linux/riscv64/image/Config.in b/target/linux/riscv64/image/Config.in new file mode 100644 index 0000000000..244f78975b --- /dev/null +++ b/target/linux/riscv64/image/Config.in @@ -0,0 +1,5 @@ +config RISCV64_SD_BOOT_PARTSIZE + int "Boot (SD Card) filesystem partition size (in MB)" + depends on TARGET_riscv64 + default 32 + diff --git a/target/linux/riscv64/image/Makefile b/target/linux/riscv64/image/Makefile new file mode 100644 index 0000000000..89d5f28926 --- /dev/null +++ b/target/linux/riscv64/image/Makefile @@ -0,0 +1,88 @@ +# +# Copyright (C) 2020 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +FAT32_BLOCK_SIZE=1024 +FAT32_BLOCKS=$(shell echo $$(($(CONFIG_RISCV64_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) + +KERNEL_LOADADDR:=0x84000000 + +#define Build/Clean +# $(MAKE) -C bbl clean +#endef + +###### +#define Image/Prepare +# cp $(KDIR)/vmlinux.elf $(BIN_DIR)/$(IMG_PREFIX)-vmlinux.elf +# cp $(LINUX_DIR)/arch/riscv/boot/Image $(BIN_DIR)/$(IMG_PREFIX)-Image +#endef + +#define Build/sunxi-sdcard +# rm -f $@.boot +# mkfs.fat $@.boot -C $(FAT32_BLOCKS) +# +# mcopy -i $@.boot $(STAGING_DIR_IMAGE)/uenv-riscv64-boot.scr ::boot.scr +# mcopy -i $@.boot $(DTS_DIR)/hifive-unleashed-a00.dtb ::dtb +# mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage + +#endef + +define Image/Build/riscv-sdcard + rm -f $(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img + mkfs.fat $(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img -C $(FAT32_BLOCKS) + + mcopy -i $(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img $(STAGING_DIR_IMAGE)/uenv-riscv64-boot.scr ::boot.scr + mcopy -i $(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img $(DTS_DIR)/sifive/hifive-unleashed-a00.dtb ::dtb + mcopy -i $(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img $(LINUX_DIR)/arch/riscv/boot/Image ::Image + + ./gen_riscv64_sdcard_img.sh \ + $(BIN_DIR)/$(IMG_PREFIX)-$(PROFILE)-sdcard-vfat-$(1).img \ + $(KDIR_TMP)/$(IMG_PREFIX)-$(PROFILE)-boot.img \ + $(KDIR)/root.$(1) \ + $(CONFIG_RISCV64_SD_BOOT_PARTSIZE) \ + $(CONFIG_TARGET_ROOTFS_PARTSIZE) \ + $(STAGING_DIR)/fw_payload.fu540.bin + + gzip -f9 $(BIN_DIR)/$(IMG_PREFIX)-$(PROFILE)-sdcard-vfat-$(1).img +endef + +#OUTPUT="$1" +#BOOTFS="$2" +#ROOTFS="$3" +#BOOTFSSIZE="$4" +#ROOTFSSIZE="$5" +#UBOOT="$6" + +define Device/Default + PROFILES := Default +# DEVICE_VARS := SUNXI_DTS SUNXI_UBOOT + KERNEL_NAME := Image + KERNEL := kernel-bin | Image none + IMAGES := sdcard.img.gz + IMAGE/sdcard.img.gz := riscv-sdcard | append-metadata | gzip +endef + +define Device/sifive_unleashed + DEVICE_VENDOR := SiFive + DEVICE_MODEL := Unleashed + DEVICE_DTS := sifive/hifive-unleashed-a00 +# DEVICE_PACKAGES := kmod-r8169 kmod-rt2800-usb kmod-rtc-em3027 \ +# kmod-usb-storage wpad-mini + UBOOT := sifive_fu540 +endef + +TARGET_DEVICES += sifive_unleashed + +define Image/Build + #$(MAKE) -C bbl compile + $(call Image/Build/riscv-sdcard,$(1),$(IMG_PREFIX)-$(PROFILE)-sdcard.img) + +# $(CP) $(KDIR)/root.$(1) $(BIN_DIR)/ +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/riscv64/image/gen_riscv64_sdcard_img.sh b/target/linux/riscv64/image/gen_riscv64_sdcard_img.sh new file mode 100644 index 0000000000..30544f73b3 --- /dev/null +++ b/target/linux/riscv64/image/gen_riscv64_sdcard_img.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2020 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +set -ex +[ $# -eq 6 ] || { + echo "SYNTAX: $0 " + exit 1 +} + +BBL_UUID="2E54B353-1271-4842-806F-E436D6AF6985" # mandatory UUID for finding the SBL +KERNEL_UUID="C12A7328-F81F-11D2-BA4B-00A0C93EC93B" # this also stands for "bootable flag" +LINUX_UUID="0FC63DAF-8483-4772-8E79-3D69D8477DE4" + +BBL_SIZE=4 +OUTPUT="$1" +BOOTFS="$2" +ROOTFS="$3" +BOOTFSSIZE="$4" +ROOTFSSIZE="$5" +UBOOT="$6" + +FULLSIZE="$(($BBL_SIZE+$BOOTFSSIZE+$ROOTFSSIZE+3))" +echo "Full size is: ${FULLSIZE}M" + +BOOTFSOFFSET="$(($BBL_SIZE * 1048576 / 512 + 2048))" +BOOTFSEND="$(( ($BBL_SIZE+$BOOTFSSIZE) * 1048576 / 512 + 2048 ))" +echo "Bootfs is: $BOOTFSOFFSET - $BOOTFSEND" + +ROOTFSOFFSET="$((($BOOTFSSIZE+$BBL_SIZE) * 1048576 / 512 + 2048*2 ))" +ROOTFSEND="$((($BOOTFSSIZE+$BBL_SIZE+$ROOTFSSIZE) * 1048576 / 512 + 2048*2))" +echo "Rootfs is: $ROOTFSOFFSET - $ROOTFSEND" + + +dd if=/dev/zero of=$OUTPUT bs=1M count=$FULLSIZE + +#sgdisk --clear \ +/u/owrt3/riscv-201911/staging_dir/host/bin/sgdisk --clear \ + --new=1:2048:${BBL_SIZE}M --change-name=1:bootloader --typecode=1:${BBL_UUID} \ + --new=2:${BOOTFSOFFSET}:${BOOTFSEND} --change-name=2:kernel --typecode=2:${KERNEL_UUID} \ + --new=3:${ROOTFSOFFSET}:${ROOTFSEND} --change-name=3:root --typecode=3:${LINUX_UUID} $OUTPUT + +dd bs=512 if="$UBOOT" of="$OUTPUT" seek=2048 conv=notrunc +dd bs=512 if="$BOOTFS" of="$OUTPUT" seek="$BOOTFSOFFSET" conv=notrunc +dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFSOFFSET" conv=notrunc diff --git a/target/linux/riscv64/patches/0010-pcie-microsemi-added-support-for-the-Vera-board-root.patch b/target/linux/riscv64/patches/0010-pcie-microsemi-added-support-for-the-Vera-board-root.patch new file mode 100644 index 0000000000..47c75ead58 --- /dev/null +++ b/target/linux/riscv64/patches/0010-pcie-microsemi-added-support-for-the-Vera-board-root.patch @@ -0,0 +1,804 @@ +From 1fd6c8fbc07bec3c18771738ce4b2aad3ed228f2 Mon Sep 17 00:00:00 2001 +From: "Wesley W. Terpstra" +Date: Wed, 25 Apr 2018 12:10:15 -0700 +Subject: [PATCH 10/11] pcie-microsemi: added support for the Vera-board root + complex + +--- + drivers/pci/controller/Kconfig | 6 + + drivers/pci/controller/Makefile | 1 + + drivers/pci/controller/pcie-microsemi.c | 754 ++++++++++++++++++++++++++++++++ + 3 files changed, 761 insertions(+) + create mode 100644 drivers/pci/controller/pcie-microsemi.c + +diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig +index 028b2874..4458c119 100644 +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -278,5 +278,11 @@ config VMD + To compile this driver as a module, choose M here: the + module will be called vmd. + ++config PCIE_MICROSEMI ++ bool "Microsemi AXI PCIe host bridge support" ++ depends on OF || COMPILE_TEST ++ help ++ Say 'Y' here if you want kernel to support the Microsemi AXI PCIe ++ Host Bridge driver. + source "drivers/pci/controller/dwc/Kconfig" + endmenu +diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile +index d56a5074..c3b76ff2 100644 +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o + obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o + obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o + obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o ++obj-$(CONFIG_PCIE_MICROSEMI) += pcie-microsemi.o + obj-$(CONFIG_VMD) += vmd.o + # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW + obj-y += dwc/ +diff --git a/drivers/pci/controller/pcie-microsemi.c b/drivers/pci/controller/pcie-microsemi.c +new file mode 100644 +index 00000000..9e2abca2 +--- /dev/null ++++ b/drivers/pci/controller/pcie-microsemi.c +@@ -0,0 +1,754 @@ ++/* ++ * PCIe host controller driver for Microsemi AXI PCIe Bridge ++ * ++ * Copyright (c) 2018 - Microsemi. ++ * Author: Badal Nilawar ++ * ++ * Based on the Xilinx, Altera PCIe driver ++ * ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../pci.h" ++ ++/* ECAM definitions */ ++#define ECAM_BUS_NUM_SHIFT 20 ++#define ECAM_DEV_NUM_SHIFT 12 ++ ++/* Number of MSI IRQs */ ++#define MICROSEMI_NUM_MSI_IRQS 32 ++ ++/* PCIe Bridge Phy and Controller Phy offsets */ ++#define PCIE0_BRIDGE_PHY_ADDR_OFFSET 0x03004000u ++#define PCIE0_CRTL_PHY_ADDR_OFFSET 0x03006000u ++ ++#define PCIE0_BRIDGE_ADDR 0x03004000u ++#define PCIE0_CRTL_ADDR 0x03006000u ++ ++#define PCIE1_BRIDGE_ADDR 0x00008000u ++#define PCIE1_CRTL_ADDR 0x0000A000u ++ ++/* PCIe LTSSM State reg */ ++#define LTSSM_STATE 0x5c ++ ++/* PCIe LTSSM L0 state */ ++#define LTSSM_L0_STATE 0x10 ++ ++/* PCIe Controller Phy Regs */ ++#define SEC_ERROR_INT 0x28 ++#define SEC_ERROR_INT_MASK 0x2c ++#define DED_ERROR_INT 0x30 ++#define DED_ERROR_INT_MASK 0x34 ++#define ECC_CONTROL 0x38 ++#define PCIE_EVENT_INT 0x14c ++ ++/* PCIe Bridge Phy Regs */ ++#define IMASK_LOCAL 0x180 ++#define ISTATUS_LOCAL 0x184 ++#define IMASK_HOST 0x188 ++#define ISTATUS_HOST 0x18c ++#define ISTATUS_MSI 0x194 ++#define PCIE_PCI_IDS_DW1 0x9c ++ ++/* PCIe AXI slave table init defines */ ++#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u ++#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u ++#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u ++#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu ++#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u ++ ++#define ATR1_AXI4_SLV0_SRCADDR_PARAM 0x820u ++#define ATR1_AXI4_SLV0_SRC_ADDR 0x824u ++#define ATR1_AXI4_SLV0_TRSL_ADDR_LSB 0x828u ++#define ATR1_AXI4_SLV0_TRSL_ADDR_UDW 0x82cu ++#define ATR1_AXI4_SLV0_TRSL_PARAM 0x830u ++ ++/* PCIe Master table init defines */ ++#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u ++ ++/* Translated ID */ ++#define PCIE_TX_RX_INTERFACE 0x00000000u ++#define PCIE_CONFIG_INTERFACE 0x00000001u ++ ++/* PCIe Config space MSI capability structure */ ++#define PCIE_ENABLE_MSI 0x10000000u ++ ++/* MSI definitions */ ++#define MSI_MSG_ADDR 0x190u ++#define MSI_ENABLE (0x01u << 16) ++#define MSI_ENABLE_MULTI (MICROSEMI_NUM_MSI_IRQS << 20) ++ ++/* MSI Capability Structure */ ++#define MSI_CAP_CTRL 0xE0u ++#define MSI_MSG_ADDR_OFFSET 0xE4u ++#define MSI_MSG_UPPER_ADDR_OFFEST 0xE8u ++#define MSI_MSG_DATA 0xF0u ++ ++ ++ ++/******************************************************************************/ ++/*Enable PCIe local*/ ++#define PCIE_LOCAL_INT_ENABLE 0xF000000u ++ ++/******************************************************************************/ ++/* Clear PCIe interrupt events */ ++#define PCIE_EVENT_INT_DATA 0x00070007u ++#define PCIE_ECC_DISABLE 0x0F000000u ++#define PCIE_SEC_ERROR_INT_CLEAR 0x0000FFFFu ++#define PCIE_DED_ERROR_INT_CLEAR 0x0000FFFFu ++#define PCIE_ISTATUS_CLEAR 0xFFFFFFFFu ++#define PCIE_CLEAR 0x00000000u ++#define PCIE_SET 0x00000001u ++ ++#define ROOT_PORT_ENABLE 0x00000001u ++ ++#define NULL_POINTER 0x00000000u ++ ++/*****************************************************************************/ ++/* PCIe Controller 0 */ ++#define PF_PCIE_CTRL_0 0u ++/* PCIe Controller 1 */ ++#define PF_PCIE_CTRL_1 1u ++ ++/* It indicates that the ATR table is enabled */ ++#define PF_PCIE_ATR_TABLE_ENABLE 1u ++/* It indicates that the the ATR table is disabled */ ++#define PF_PCIE_ATR_TABLE_DISABLE 0u ++ ++ ++/** ++ * struct microsemi_pcie_port - PCIe port information ++ * @reg_base: IO Mapped Register Base ++ * @irq: Interrupt number ++ * @root_busno: Root Bus number ++ * @dev: Device pointer ++ * @msi_domain: MSI IRQ domain pointer ++ * @leg_domain: Legacy IRQ domain pointer ++ * @resources: Bus Resources ++ */ ++struct microsemi_pcie_port { ++ struct platform_device *pdev; ++ void __iomem *reg_base; ++ void __iomem *reg_base_apb; ++ void __iomem *reg_bridge_apb; ++ void __iomem *reg_ctrl_apb; ++ u32 irq; ++ u8 root_busno; ++ struct device *dev; ++ struct irq_domain *msi_domain; ++ struct irq_domain *leg_domain; ++ struct list_head resources; ++}; ++ ++static DECLARE_BITMAP(msi_irq_in_use, MICROSEMI_NUM_MSI_IRQS); ++ ++static inline u32 pcie_read(struct microsemi_pcie_port *port, u32 reg) ++{ ++ return readl(port->reg_base + reg); ++} ++ ++static inline void pcie_write(struct microsemi_pcie_port *port, ++ u32 val, u32 reg) ++{ ++ writel(val, port->reg_base + reg); ++} ++ ++static inline bool microsemi_pcie_link_up(struct microsemi_pcie_port *port) ++{ ++ return (readl(port->reg_ctrl_apb + LTSSM_STATE) ++ & LTSSM_L0_STATE) ? 1 : 0; ++} ++ ++/** ++ * microsemi_pcie_valid_device - Check if a valid device is present on bus ++ * @bus: PCI Bus structure ++ * @devfn: device/function ++ * ++ * Return: 'true' on success and 'false' if invalid device is found ++ */ ++static bool microsemi_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) ++{ ++ struct microsemi_pcie_port *port = bus->sysdata; ++ ++ /* Check if link is up when trying to access downstream ports */ ++ if (bus->number != port->root_busno) ++ if (!microsemi_pcie_link_up(port)) ++ return false; ++ ++ /* Only one device down on each root port */ ++ if (bus->number == port->root_busno && devfn > 0) ++ return false; ++ ++ return true; ++} ++ ++/** ++ * microsemi_pcie_map_bus - Get configuration base ++ * @bus: PCI Bus structure ++ * @devfn: Device/function ++ * @where: Offset from base ++ * ++ * Return: Base address of the configuration space needed to be ++ * accessed. ++ */ ++static void __iomem *microsemi_pcie_map_bus(struct pci_bus *bus, ++ unsigned int devfn, int where) ++{ ++ struct microsemi_pcie_port *port = bus->sysdata; ++ int relbus; ++ ++ ++ if (!microsemi_pcie_valid_device(bus, devfn)) ++ return NULL; ++ ++ relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | ++ (devfn << ECAM_DEV_NUM_SHIFT); ++ ++ ++ return port->reg_base + relbus + where; ++} ++ ++/* PCIe operations */ ++static struct pci_ops microsemi_pcie_ops = { ++ .map_bus = microsemi_pcie_map_bus, ++ .read = pci_generic_config_read, ++ .write = pci_generic_config_write, ++}; ++ ++/* MSI functions */ ++ ++/** ++ * microsemi_pcie_destroy_msi - Free MSI number ++ * @irq: IRQ to be freed ++ */ ++static void microsemi_pcie_destroy_msi(unsigned int irq) ++{ ++ struct msi_desc *msi; ++ struct microsemi_pcie_port *port; ++ struct irq_data *d = irq_get_irq_data(irq); ++ irq_hw_number_t hwirq = irqd_to_hwirq(d); ++ ++ if (!test_bit(hwirq, msi_irq_in_use)) { ++ msi = irq_get_msi_desc(irq); ++ port = msi_desc_to_pci_sysdata(msi); ++ dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); ++ } else { ++ clear_bit(hwirq, msi_irq_in_use); ++ } ++} ++ ++/** ++ * microsemi_pcie_assign_msi - Allocate MSI number ++ * ++ * Return: A valid IRQ on success and error value on failure. ++ */ ++static int microsemi_pcie_assign_msi(void) ++{ ++ int pos; ++ ++ pos = find_first_zero_bit(msi_irq_in_use, MICROSEMI_NUM_MSI_IRQS); ++ if (pos < MICROSEMI_NUM_MSI_IRQS) ++ set_bit(pos, msi_irq_in_use); ++ else ++ return -ENOSPC; ++ ++ return pos; ++} ++ ++/** ++ * microsemi_msi_teardown_irq - Destroy the MSI ++ * @chip: MSI Chip descriptor ++ * @irq: MSI IRQ to destroy ++ */ ++static void microsemi_msi_teardown_irq(struct msi_controller *chip, ++ unsigned int irq) ++{ ++ microsemi_pcie_destroy_msi(irq); ++ irq_dispose_mapping(irq); ++} ++ ++/** ++ * microsemi_pcie_msi_setup_irq - Setup MSI request ++ * @chip: MSI chip pointer ++ * @pdev: PCIe device pointer ++ * @desc: MSI descriptor pointer ++ * ++ * Return: '0' on success and error value on failure ++ */ ++static int microsemi_pcie_msi_setup_irq(struct msi_controller *chip, ++ struct pci_dev *pdev, ++ struct msi_desc *desc) ++{ ++ struct microsemi_pcie_port *port = pdev->bus->sysdata; ++ unsigned int irq; ++ int hwirq; ++ struct msi_msg msg; ++ ++ hwirq = microsemi_pcie_assign_msi(); ++ if (hwirq < 0) ++ return hwirq; ++ ++ irq = irq_create_mapping(port->msi_domain, hwirq); ++ if (!irq) ++ return -EINVAL; ++ ++ irq_set_msi_desc(irq, desc); ++ ++ msg.address_hi = 0; ++ msg.address_lo = MSI_MSG_ADDR; ++ msg.data = hwirq; ++ ++ pci_write_msi_msg(irq, &msg); ++ ++ return 0; ++} ++ ++/* MSI Chip Descriptor */ ++static struct msi_controller microsemi_pcie_msi_chip = { ++ .setup_irq = microsemi_pcie_msi_setup_irq, ++ .teardown_irq = microsemi_msi_teardown_irq, ++}; ++ ++/* HW Interrupt Chip Descriptor */ ++static struct irq_chip microsemi_msi_irq_chip = { ++ .name = "Microsemi PCIe MSI", ++ .irq_enable = pci_msi_unmask_irq, ++ .irq_disable = pci_msi_mask_irq, ++ .irq_mask = pci_msi_mask_irq, ++ .irq_unmask = pci_msi_unmask_irq, ++}; ++ ++/** ++ * microsemi_pcie_msi_map - Set the handler for the MSI and mark IRQ as valid ++ * @domain: IRQ domain ++ * @irq: Virtual IRQ number ++ * @hwirq: HW interrupt number ++ * ++ * Return: Always returns 0. ++ */ ++static int microsemi_pcie_msi_map(struct irq_domain *domain, unsigned int irq, ++ irq_hw_number_t hwirq) ++{ ++ irq_set_chip_and_handler(irq, ++ µsemi_msi_irq_chip, handle_simple_irq); ++ irq_set_chip_data(irq, domain->host_data); ++ ++ return 0; ++} ++ ++/* IRQ Domain operations */ ++static const struct irq_domain_ops msi_domain_ops = { ++ .map = microsemi_pcie_msi_map, ++}; ++ ++/** ++ * microsemi_pcie_enable_msi - Enable MSI support ++ * @port: PCIe port information ++ */ ++static void microsemi_pcie_enable_msi(struct microsemi_pcie_port *port) ++{ ++ u32 cap_ctrl; ++ ++ cap_ctrl = pcie_read(port, MSI_CAP_CTRL); ++ ++ pcie_write(port, cap_ctrl | MSI_ENABLE_MULTI | MSI_ENABLE, MSI_CAP_CTRL); ++ pcie_write(port, MSI_MSG_ADDR, MSI_MSG_ADDR_OFFSET); ++} ++ ++/* INTx Functions */ ++ ++/** ++ * microsemi_pcie_intx_map - Set the handler for the INTx and mark IRQ as valid ++ * @domain: IRQ domain ++ * @irq: Virtual IRQ number ++ * @hwirq: HW interrupt number ++ * ++ * Return: Always returns 0. ++ */ ++static int microsemi_pcie_intx_map(struct irq_domain *domain, unsigned int irq, ++ irq_hw_number_t hwirq) ++{ ++ irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); ++ irq_set_chip_data(irq, domain->host_data); ++ ++ return 0; ++} ++ ++/* INTx IRQ Domain operations */ ++static const struct irq_domain_ops intx_domain_ops = { ++ .map = microsemi_pcie_intx_map, ++ .xlate = pci_irqd_intx_xlate, ++}; ++ ++/* PCIe HW Functions */ ++ ++/** ++ * microsemi_pcie_intr_handler - Interrupt Service Handler ++ * @irq: IRQ number ++ * @data: PCIe port information ++ * ++ * Return: IRQ_HANDLED on success and IRQ_NONE on failure ++ */ ++static irqreturn_t microsemi_pcie_intr_handler(int irq, void *data) ++{ ++ struct microsemi_pcie_port *port = (struct microsemi_pcie_port *)data; ++ struct device *dev = port->dev; ++ unsigned long status; ++ unsigned long msi; ++ u32 bit; ++ u32 virq; ++ ++ ++ status = readl(port->reg_bridge_apb + ISTATUS_LOCAL); ++ ++ status = (status >> 24) & 0x0f; ++ for_each_set_bit(bit, &status, PCI_NUM_INTX) { ++ /* clear interrupts */ ++ writel(1 << (bit+24), ++ port->reg_bridge_apb + ISTATUS_LOCAL); ++ ++ virq = irq_find_mapping(port->leg_domain, bit); ++ ++ if (virq) ++ generic_handle_irq(virq); ++ else ++ dev_err(dev, "unexpected IRQ, INT%d\n", bit); ++ } ++ ++ status = readl(port->reg_bridge_apb + ISTATUS_LOCAL); ++ if ((status & 0x10000000) == 0x10000000) { ++ writel((1 << 28), port->reg_bridge_apb + ISTATUS_LOCAL); ++ msi = readl(port->reg_bridge_apb + ISTATUS_MSI); ++ for_each_set_bit(bit, &msi, MICROSEMI_NUM_MSI_IRQS) { ++ /* clear interrupts */ ++ writel((1 << bit), ++ port->reg_bridge_apb + ISTATUS_MSI); ++ virq = irq_find_mapping(port->msi_domain, bit); ++ if (virq) ++ generic_handle_irq(virq); ++ else ++ dev_err(dev, "unexpected IRQ, INT%d\n", bit); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/** ++ * microsemi_pcie_init_irq_domain - Initialize IRQ domain ++ * @port: PCIe port information ++ * ++ * Return: '0' on success and error value on failure ++ */ ++static int microsemi_pcie_init_irq_domain(struct microsemi_pcie_port *port) ++{ ++ struct device *dev = port->dev; ++ struct device_node *node = dev->of_node; ++ struct device_node *pcie_intc_node; ++ ++ /* Setup INTx */ ++ pcie_intc_node = of_get_next_child(node, NULL); ++ if (!pcie_intc_node) { ++ dev_err(dev, "No PCIe Intc node found\n"); ++ return -ENODEV; ++ } ++ dev_info(dev, "Intc node foundi %s\n", pcie_intc_node->name); ++ ++ port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, ++ &intx_domain_ops, ++ port); ++ if (!port->leg_domain) { ++ dev_err(dev, "Failed to get a INTx IRQ domain\n"); ++ return -ENODEV; ++ } ++ ++ /* Setup MSI */ ++ if (IS_ENABLED(CONFIG_PCI_MSI)) { ++ port->msi_domain = irq_domain_add_linear(node, ++ MICROSEMI_NUM_MSI_IRQS, ++ &msi_domain_ops, ++ µsemi_pcie_msi_chip); ++ if (!port->msi_domain) { ++ dev_err(dev, "Failed to get a MSI IRQ domain\n"); ++ return -ENODEV; ++ } ++ microsemi_pcie_enable_msi(port); ++ } ++ return 0; ++} ++ ++/** ++ * microsemi_pcie_init_port - Parse Device tree, Initialize hardware ++ * @port: PCIe port information ++ * ++ * Return: '0' on success and error value on failure ++ */ ++static int microsemi_pcie_init_port(struct microsemi_pcie_port *port) ++{ ++ struct device *dev = port->dev; ++ struct device_node *node = dev->of_node; ++ struct of_pci_range_parser parser; ++ struct of_pci_range range; ++ struct resource regs; ++ struct resource regs1; ++ resource_size_t size; ++ u32 bit, pf_bridge_id = 1; ++ const char *type; ++ int err; ++ ++ type = of_get_property(node, "device_type", NULL); ++ if (!type || strcmp(type, "pci")) { ++ dev_err(dev, "invalid \"device_type\" %s\n", type); ++ return -EINVAL; ++ } ++ ++ err = of_address_to_resource(node, 0, ®s); ++ if (err) { ++ dev_err(dev, "missing \"reg\" property\n"); ++ return err; ++ } ++ ++ port->reg_base = devm_pci_remap_cfg_resource(dev, ®s); ++ if (IS_ERR(port->reg_base)) ++ return PTR_ERR(port->reg_base); ++ ++ ++ err = of_address_to_resource(node, 1, ®s1); ++ if (err) { ++ dev_err(dev, "missing \"reg\" property\n"); ++ return err; ++ } ++ ++ ++ port->reg_base_apb = devm_ioremap_resource(dev, ®s1); ++ if (IS_ERR(port->reg_base_apb)) ++ return PTR_ERR(port->reg_base_apb); ++ ++ if (pf_bridge_id == 0) { ++ port->reg_bridge_apb = port->reg_base_apb + PCIE0_BRIDGE_ADDR; ++ port->reg_ctrl_apb = port->reg_base_apb + PCIE0_CRTL_ADDR; ++ } else { ++ port->reg_bridge_apb = port->reg_base_apb + PCIE1_BRIDGE_ADDR; ++ port->reg_ctrl_apb = port->reg_base_apb + PCIE1_CRTL_ADDR; ++ } ++ ++ port->irq = irq_of_parse_and_map(node, 0); ++ ++ err = devm_request_irq(dev, port->irq, microsemi_pcie_intr_handler, ++ IRQF_SHARED | IRQF_NO_THREAD, ++ "microsemi-pcie", port); ++ if (err) { ++ dev_err(dev, "unable to request irq %d\n", port->irq); ++ return err; ++ } ++ ++ ++ /* Clear and Disable interrupts */ ++ ++ writel(0x0f000000, port->reg_ctrl_apb + ECC_CONTROL); ++ writel(0x00070007, port->reg_ctrl_apb + PCIE_EVENT_INT); ++ writel(0x0000ffff, port->reg_ctrl_apb + SEC_ERROR_INT); ++ writel(0x0000ffff, port->reg_ctrl_apb + SEC_ERROR_INT_MASK); ++ writel(0x0000ffff, port->reg_ctrl_apb + DED_ERROR_INT); ++ writel(0x0000ffff, port->reg_ctrl_apb + DED_ERROR_INT_MASK); ++ ++ writel(0x00000000, port->reg_bridge_apb + IMASK_LOCAL); ++ writel(0xffffffff, port->reg_bridge_apb + ISTATUS_LOCAL); ++ writel(0x00000000, port->reg_bridge_apb + IMASK_HOST); ++ writel(0xffffffff, port->reg_bridge_apb + ISTATUS_HOST); ++ ++ dev_info(dev, "interrupt disabled\n"); ++ ++ /* Configure Address Translation Table 0 for pcie config space */ ++ ++ writel(PCIE_CONFIG_INTERFACE, ++ port->reg_bridge_apb + ATR0_AXI4_SLV0_TRSL_PARAM); ++ ++ size = resource_size(®s); ++ ++ bit = find_first_bit((const unsigned long *)&size, 64) - 1; ++ ++ writel((u32)regs.start | bit << 1 | 0x01, ++ port->reg_bridge_apb + ATR0_AXI4_SLV0_SRCADDR_PARAM); ++ ++// writel((u32)(regs.start >> 32), ++// port->reg_bridge_apb + ATR0_AXI4_SLV0_SRC_ADDR); ++ ++ writel((u32)regs.start, ++ port->reg_bridge_apb + ATR0_AXI4_SLV0_TRSL_ADDR_LSB); ++ ++// writel((u32)(regs.start >> 32), ++// port->reg_bridge_apb + ATR0_AXI4_SLV0_TRSL_ADDR_UDW); ++ ++ ++ if (of_pci_range_parser_init(&parser, node)) { ++ dev_err(dev, "missing \"ranges\" property\n"); ++ return -EINVAL; ++ } ++ ++ ++ for_each_of_pci_range(&parser, &range) { ++ switch (range.flags & IORESOURCE_TYPE_BITS) { ++ case IORESOURCE_MEM: ++ ++ size = range.size; ++ bit = find_first_bit((const unsigned long *)&size, 64) - 1; ++ ++ /* Configure Address Translation Table 1 for pcie mem space */ ++ ++ writel(PCIE_TX_RX_INTERFACE, ++ port->reg_bridge_apb + ATR1_AXI4_SLV0_TRSL_PARAM); ++ ++ writel((u32)range.cpu_addr | bit << 1 | 0x01, ++ port->reg_bridge_apb + ATR1_AXI4_SLV0_SRCADDR_PARAM); ++ ++// writel((u32)(range.cpu_addr >> 32), ++// port->reg_bridge_apb + ATR1_AXI4_SLV0_SRC_ADDR); ++ ++ writel((u32)range.pci_addr, ++ port->reg_bridge_apb + ATR1_AXI4_SLV0_TRSL_ADDR_LSB); ++ ++// writel((u32)(range.pci_addr >> 32), ++// port->reg_bridge_apb + ATR1_AXI4_SLV0_TRSL_ADDR_UDW); ++ ++ break; ++ } ++ ++ } ++ ++ ++ writel(readl(port->reg_bridge_apb + ATR0_PCIE_WIN0_SRCADDR_PARAM) ++ | 0x3E, ++ port->reg_bridge_apb + ATR0_PCIE_WIN0_SRCADDR_PARAM); ++ ++ writel(0, port->reg_bridge_apb + 0x604); ++ ++ writel((readl(port->reg_bridge_apb + PCIE_PCI_IDS_DW1) & 0xffff) ++ | (PCI_CLASS_BRIDGE_PCI << 16), ++ port->reg_bridge_apb + PCIE_PCI_IDS_DW1); ++ ++ pcie_write(port, 0x00ff0100, 0x18); ++ ++ /* Enable interrupts */ ++ writel(PCIE_ENABLE_MSI | PCIE_LOCAL_INT_ENABLE, ++ port->reg_bridge_apb + IMASK_LOCAL); ++ ++ ++ return 0; ++} ++ ++/** ++ * microsemi_pcie_probe - Probe function ++ * @pdev: Platform device pointer ++ * ++ * Return: '0' on success and error value on failure ++ */ ++static int microsemi_pcie_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct microsemi_pcie_port *port; ++ struct pci_bus *bus, *child; ++ struct pci_host_bridge *bridge; ++ int err; ++ resource_size_t iobase = 0; ++ LIST_HEAD(res); ++ ++ pr_err("%s In \n", __func__); ++ if (!dev->of_node) ++ return -ENODEV; ++ ++ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port)); ++ if (!bridge) ++ return -ENODEV; ++ ++ port = pci_host_bridge_priv(bridge); ++ ++ port->dev = dev; ++ port->pdev = pdev; ++ ++ err = microsemi_pcie_init_port(port); ++ if (err) { ++ dev_err(dev, "Pcie port initialization failed\n"); ++ return err; ++ } ++ ++ ++ err = microsemi_pcie_init_irq_domain(port); ++ if (err) { ++ dev_err(dev, "Failed creating IRQ Domain\n"); ++ return err; ++ } ++ ++ err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res, ++ &iobase); ++ if (err) { ++ dev_err(dev, "Getting bridge resources failed\n"); ++ return err; ++ } ++ ++ err = devm_request_pci_bus_resources(dev, &res); ++ if (err) ++ goto error; ++ ++ ++ list_splice_init(&res, &bridge->windows); ++ bridge->dev.parent = dev; ++ bridge->sysdata = port; ++ bridge->busnr = 0; ++ bridge->ops = µsemi_pcie_ops; ++ bridge->map_irq = of_irq_parse_and_map_pci; ++ bridge->swizzle_irq = pci_common_swizzle; ++ ++#ifdef CONFIG_PCI_MSI ++ microsemi_pcie_msi_chip.dev = dev; ++ bridge->msi = µsemi_pcie_msi_chip; ++#endif ++ err = pci_scan_root_bus_bridge(bridge); ++ dev_info(dev, "pci_scan_root_bus_bridge done\n"); ++ if (err < 0) ++ goto error; ++ ++ bus = bridge->bus; ++ ++ pci_assign_unassigned_bus_resources(bus); ++ list_for_each_entry(child, &bus->children, node) ++ pcie_bus_configure_settings(child); ++ pci_bus_add_devices(bus); ++ ++ return 0; ++ ++error: ++ pci_free_resource_list(&res); ++ return err; ++} ++ ++static const struct of_device_id microsemi_pcie_of_match[] = { ++ { .compatible = "ms-pf,axi-pcie-host", }, ++ {} ++}; ++ ++static struct platform_driver microsemi_pcie_driver = { ++ .driver = { ++ .name = "microsemi-pcie", ++ .of_match_table = microsemi_pcie_of_match, ++ .suppress_bind_attrs = true, ++ }, ++ .probe = microsemi_pcie_probe, ++}; ++builtin_platform_driver(microsemi_pcie_driver); +-- +2.7.4 + -- 2.30.2