riscv64: add new port
authorZoltan HERPAI <[email protected]>
Sun, 16 Dec 2018 10:05:58 +0000 (11:05 +0100)
committerZoltan HERPAI <[email protected]>
Wed, 29 Jul 2020 16:56:43 +0000 (18:56 +0200)
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 <[email protected]>
target/linux/riscv64/Makefile [new file with mode: 0644]
target/linux/riscv64/base-files/etc/board.d/02_network [new file with mode: 0644]
target/linux/riscv64/base-files/etc/inittab [new file with mode: 0644]
target/linux/riscv64/base-files/lib/preinit/80_debug [new file with mode: 0644]
target/linux/riscv64/config-5.4 [new file with mode: 0644]
target/linux/riscv64/image/Config.in [new file with mode: 0644]
target/linux/riscv64/image/Makefile [new file with mode: 0644]
target/linux/riscv64/image/gen_riscv64_sdcard_img.sh [new file with mode: 0644]
target/linux/riscv64/patches/0010-pcie-microsemi-added-support-for-the-Vera-board-root.patch [new file with mode: 0644]

diff --git a/target/linux/riscv64/Makefile b/target/linux/riscv64/Makefile
new file mode 100644 (file)
index 0000000..d44ae0c
--- /dev/null
@@ -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 <[email protected]>
+
+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 (file)
index 0000000..df48b43
--- /dev/null
@@ -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 (file)
index 0000000..c328b21
--- /dev/null
@@ -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 (file)
index 0000000..087e86e
--- /dev/null
@@ -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 (file)
index 0000000..8b58723
--- /dev/null
@@ -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 (file)
index 0000000..244f789
--- /dev/null
@@ -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 (file)
index 0000000..89d5f28
--- /dev/null
@@ -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 [email protected]
+#      mkfs.fat [email protected] -C $(FAT32_BLOCKS)
+#
+#      mcopy -i [email protected] $(STAGING_DIR_IMAGE)/uenv-riscv64-boot.scr ::boot.scr
+#      mcopy -i [email protected] $(DTS_DIR)/hifive-unleashed-a00.dtb ::dtb
+#      mcopy -i [email protected] $(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 (file)
index 0000000..30544f7
--- /dev/null
@@ -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 <file> <bbl/sbl image> <rootfs image> <bbl/sbl size> <rootfs size> <u-boot image>"
+    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 (file)
index 0000000..47c75ea
--- /dev/null
@@ -0,0 +1,804 @@
+From 1fd6c8fbc07bec3c18771738ce4b2aad3ed228f2 Mon Sep 17 00:00:00 2001
+From: "Wesley W. Terpstra" <[email protected]>
+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 <[email protected]>
++ *
++ * 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 <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/irqdomain.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/msi.h>
++#include <linux/of_address.h>
++#include <linux/of_pci.h>
++#include <linux/of_platform.h>
++#include <linux/of_irq.h>
++#include <linux/pci.h>
++#include <linux/platform_device.h>
++#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,
++                              &microsemi_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,
++                                              &microsemi_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, &regs);
++      if (err) {
++              dev_err(dev, "missing \"reg\" property\n");
++              return err;
++      }
++
++      port->reg_base = devm_pci_remap_cfg_resource(dev, &regs);
++      if (IS_ERR(port->reg_base))
++              return PTR_ERR(port->reg_base);
++
++
++      err = of_address_to_resource(node, 1, &regs1);
++      if (err) {
++              dev_err(dev, "missing \"reg\" property\n");
++              return err;
++      }
++
++
++      port->reg_base_apb = devm_ioremap_resource(dev, &regs1);
++      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(&regs);
++
++      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 = &microsemi_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 = &microsemi_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
+