From f587a55bc2006f4316383425d518b734e42bb4a2 Mon Sep 17 00:00:00 2001 From: GUI <39894654+GuEe-GUI@users.noreply.github.com> Date: Tue, 29 Mar 2022 11:08:25 +0800 Subject: [PATCH] [libcpu/aarch64] add gicv3 support and bsp/rockchip/rk3568 (#5722) * [libcpu/aarch64] add smp support * [libcpu/aarch64] rt_hw_trap_irq get irq instead of iar when using gicv2 * [libcpu/aarch64] disable irq/fiq when switch thread * [libcpu/aarch64] add gtimer frq set and stack align * [libcpu/aarch64] add gicv3 support and bsp/rockchip/rk3568 --- .github/workflows/action.yml | 1 + bsp/qemu-virt64-aarch64/.config | 62 +- bsp/qemu-virt64-aarch64/README.md | 10 +- bsp/qemu-virt64-aarch64/README_zh.md | 6 +- bsp/qemu-virt64-aarch64/driver/Kconfig | 18 +- bsp/qemu-virt64-aarch64/driver/board.c | 14 +- bsp/qemu-virt64-aarch64/driver/board.h | 58 +- bsp/qemu-virt64-aarch64/driver/drv_uart.c | 4 + bsp/qemu-virt64-aarch64/driver/drv_virtio.c | 62 ++ bsp/qemu-virt64-aarch64/driver/drv_virtio.h | 16 + bsp/qemu-virt64-aarch64/driver/virt.h | 81 ++ .../driver/virtio/drv_virtio_blk.c | 405 --------- .../driver/virtio/drv_virtio_blk.h | 85 -- .../driver/virtio/virtio.c | 274 ++++++ .../driver/virtio/virtio.h | 134 ++- .../driver/virtio/virtio_blk.c | 216 +++++ .../driver/virtio/virtio_blk.h | 61 ++ .../driver/virtio/virtio_mmio.c | 61 -- .../driver/virtio/virtio_mmio.h | 104 +-- .../driver/virtio/virtio_queue.h | 94 ++ bsp/qemu-virt64-aarch64/qemu.bat | 5 +- bsp/qemu-virt64-aarch64/qemu.sh | 5 +- bsp/qemu-virt64-aarch64/rtconfig.h | 35 +- bsp/raspberry-pi/raspi4-64/.config | 75 +- bsp/raspberry-pi/raspi4-64/driver/Kconfig | 4 + bsp/raspberry-pi/raspi4-64/driver/drv_wdt.c | 44 + bsp/raspberry-pi/raspi4-64/driver/mbox.c | 18 + bsp/raspberry-pi/raspi4-64/driver/mbox.h | 1 + bsp/raspberry-pi/raspi4-64/rtconfig.h | 32 +- bsp/rockchip/rk3568/.config | 653 ++++++++++++++ bsp/rockchip/rk3568/Kconfig | 29 + bsp/rockchip/rk3568/README.md | 55 ++ bsp/rockchip/rk3568/README_zh.md | 56 ++ bsp/rockchip/rk3568/SConscript | 14 + bsp/rockchip/rk3568/SConstruct | 29 + bsp/rockchip/rk3568/applications/SConscript | 9 + bsp/rockchip/rk3568/applications/main.c | 18 + bsp/rockchip/rk3568/driver/Kconfig | 58 ++ bsp/rockchip/rk3568/driver/SConscript | 19 + bsp/rockchip/rk3568/driver/board.c | 124 +++ bsp/rockchip/rk3568/driver/board.h | 24 + bsp/rockchip/rk3568/driver/drv_uart.c | 358 ++++++++ bsp/rockchip/rk3568/driver/drv_uart.h | 16 + bsp/rockchip/rk3568/driver/rk3568.h | 116 +++ bsp/rockchip/rk3568/link.lds | 143 +++ bsp/rockchip/rk3568/rtconfig.h | 188 ++++ bsp/rockchip/rk3568/rtconfig.py | 53 ++ include/rthw.h | 3 + libcpu/aarch64/common/SConscript | 4 - libcpu/aarch64/common/gic.c | 68 +- libcpu/aarch64/common/gic.h | 10 +- libcpu/aarch64/common/gicv3.c | 849 ++++++++++++++++++ libcpu/aarch64/common/gicv3.h | 77 ++ libcpu/aarch64/common/interrupt.c | 11 +- libcpu/aarch64/common/psci.c | 14 +- libcpu/aarch64/common/psci.h | 5 +- libcpu/aarch64/cortex-a/entry_point.S | 41 +- 57 files changed, 4108 insertions(+), 921 deletions(-) create mode 100644 bsp/qemu-virt64-aarch64/driver/drv_virtio.c create mode 100644 bsp/qemu-virt64-aarch64/driver/drv_virtio.h create mode 100644 bsp/qemu-virt64-aarch64/driver/virt.h delete mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c delete mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio.c create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h delete mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h create mode 100644 bsp/rockchip/rk3568/.config create mode 100644 bsp/rockchip/rk3568/Kconfig create mode 100644 bsp/rockchip/rk3568/README.md create mode 100644 bsp/rockchip/rk3568/README_zh.md create mode 100644 bsp/rockchip/rk3568/SConscript create mode 100644 bsp/rockchip/rk3568/SConstruct create mode 100644 bsp/rockchip/rk3568/applications/SConscript create mode 100644 bsp/rockchip/rk3568/applications/main.c create mode 100644 bsp/rockchip/rk3568/driver/Kconfig create mode 100644 bsp/rockchip/rk3568/driver/SConscript create mode 100644 bsp/rockchip/rk3568/driver/board.c create mode 100644 bsp/rockchip/rk3568/driver/board.h create mode 100644 bsp/rockchip/rk3568/driver/drv_uart.c create mode 100644 bsp/rockchip/rk3568/driver/drv_uart.h create mode 100644 bsp/rockchip/rk3568/driver/rk3568.h create mode 100644 bsp/rockchip/rk3568/link.lds create mode 100644 bsp/rockchip/rk3568/rtconfig.h create mode 100644 bsp/rockchip/rk3568/rtconfig.py create mode 100644 libcpu/aarch64/common/gicv3.c create mode 100644 libcpu/aarch64/common/gicv3.h diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index a1f6d6f51c..5b6fed8a79 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -167,6 +167,7 @@ jobs: - {RTT_BSP: "qemu-virt64-aarch64", RTT_TOOL_CHAIN: "sourcery-aarch64"} - {RTT_BSP: "raspberry-pi/raspi3-64", RTT_TOOL_CHAIN: "sourcery-aarch64"} - {RTT_BSP: "raspberry-pi/raspi4-64", RTT_TOOL_CHAIN: "sourcery-aarch64"} + - {RTT_BSP: "rockchip/rk3568", RTT_TOOL_CHAIN: "sourcery-aarch64"} steps: - uses: actions/checkout@v2 - name: Set up Python diff --git a/bsp/qemu-virt64-aarch64/.config b/bsp/qemu-virt64-aarch64/.config index 2bd46d496d..76f4b53481 100644 --- a/bsp/qemu-virt64-aarch64/.config +++ b/bsp/qemu-virt64-aarch64/.config @@ -96,17 +96,8 @@ CONFIG_RT_USING_USER_MAIN=y CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 CONFIG_RT_MAIN_THREAD_PRIORITY=10 # CONFIG_RT_USING_LEGACY is not set - -# -# C++ features -# -# CONFIG_RT_USING_CPLUSPLUS is not set - -# -# Command shell -# -CONFIG_RT_USING_FINSH=y CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y CONFIG_FINSH_USING_MSH=y CONFIG_FINSH_THREAD_NAME="tshell" CONFIG_FINSH_THREAD_PRIORITY=20 @@ -120,10 +111,6 @@ CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 - -# -# Device virtual file system -# CONFIG_RT_USING_DFS=y CONFIG_DFS_USING_POSIX=y CONFIG_DFS_USING_WORKDIR=y @@ -157,12 +144,15 @@ CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 CONFIG_RT_USING_DFS_DEVFS=y # CONFIG_RT_USING_DFS_ROMFS is not set # CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_FAL is not set # # Device Drivers # CONFIG_RT_USING_DEVICE_IPC=y -# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL_V1=y # CONFIG_RT_USING_SERIAL_V2 is not set @@ -202,7 +192,7 @@ CONFIG_RT_USING_ALARM=y # CONFIG_RT_USING_USB_DEVICE is not set # -# POSIX layer and C standard library +# C/C++ and POSIX layer # CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 @@ -226,36 +216,16 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # Socket is in the 'Network' category # +# CONFIG_RT_USING_CPLUSPLUS is not set # # Network # - -# -# Socket abstraction layer -# # CONFIG_RT_USING_SAL is not set - -# -# Network interface device -# # CONFIG_RT_USING_NETDEV is not set - -# -# light weight TCP/IP stack -# # CONFIG_RT_USING_LWIP is not set - -# -# AT commands -# # CONFIG_RT_USING_AT is not set -# -# VBUS(Virtual Software BUS) -# -# CONFIG_RT_USING_VBUS is not set - # # Utilities # @@ -264,6 +234,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set # CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set # # RT-Thread Utestcases @@ -277,6 +248,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # IoT - internet of things # +# CONFIG_PKG_USING_LWIP is not set # CONFIG_PKG_USING_LORAWAN_DRIVER is not set # CONFIG_PKG_USING_PAHOMQTT is not set # CONFIG_PKG_USING_UMQTT is not set @@ -293,6 +265,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_FREEMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_SIMPLE_XML is not set # CONFIG_PKG_USING_NANOPB is not set # @@ -332,6 +305,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_JOYLINK is not set # CONFIG_PKG_USING_EZ_IOT_OS is not set # CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set # CONFIG_PKG_USING_OTA_DOWNLOADER is not set # CONFIG_PKG_USING_IPMSG is not set # CONFIG_PKG_USING_LSSDP is not set @@ -539,7 +513,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_ARM_2D is not set # CONFIG_PKG_USING_MCUBOOT is not set # CONFIG_PKG_USING_TINYUSB is not set -# CONFIG_PKG_USING_USB_STACK is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set # # peripheral libraries and drivers @@ -563,6 +538,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set # CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set # CONFIG_PKG_USING_AGILE_BUTTON is not set # CONFIG_PKG_USING_AGILE_LED is not set # CONFIG_PKG_USING_AT24CXX is not set @@ -619,6 +595,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_SOFT_SERIAL is not set # CONFIG_PKG_USING_MB85RS16 is not set # CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_RFM300 is not set # # AI packages @@ -637,6 +614,10 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # miscellaneous packages # +# +# project laboratory +# + # # samples: kernel and components samples # @@ -669,6 +650,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set # CONFIG_PKG_USING_DSTR is not set # CONFIG_PKG_USING_TINYFRAME is not set # CONFIG_PKG_USING_KENDRYTE_DEMO is not set @@ -686,6 +668,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_DESIGN_PATTERN is not set # CONFIG_PKG_USING_CONTROLLER is not set # CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set CONFIG_SOC_VIRT64_AARCH64=y # @@ -696,5 +679,6 @@ CONFIG_RT_USING_UART0=y CONFIG_BSP_USING_RTC=y CONFIG_BSP_USING_ALARM=y CONFIG_BSP_USING_VIRTIO_BLK=y -CONFIG_RT_USING_VIRTIO_BLK0=y CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV2=y +# CONFIG_BSP_USING_GICV3 is not set diff --git a/bsp/qemu-virt64-aarch64/README.md b/bsp/qemu-virt64-aarch64/README.md index 32616794a5..b0999e61d8 100644 --- a/bsp/qemu-virt64-aarch64/README.md +++ b/bsp/qemu-virt64-aarch64/README.md @@ -19,9 +19,9 @@ Enter directory `rt-thread/bsp/qemu-virt64-aarch64` and input: scons ``` -## 2. Execution +## 3. Execution -The project execution tool is `qemu-system-aarch64` +The project execution tool is `qemu-system-aarch64`, the project can be configured to `Cortex-A53/A57/A72`, GIC supports `V2/V3` version, and `V2` of GIC can use 8 processors max. Download Windows platform from website: ``` @@ -33,7 +33,7 @@ sudo apt update sudo apt install qemu-system-arm ``` -Run qemu.bat or qemu.sh in terminal: +Please fixup the exec scripts if modify the default configuration of the project. Run qemu.bat or qemu.sh in terminal: ``` heap: [0x40042aa0 - 0x40142aa0] @@ -45,10 +45,10 @@ Hi, this is RT-Thread!! msh /> ``` -## 3. Condition +## 4. Condition | Driver | Condition | Remark | | ------ | --------- | ------ | | UART | Support | UART0 | | RTC | Support | - | -| VIRTIO BLK | Support | VIRTIO BLK0 | \ No newline at end of file +| VIRTIO BLK | Support | - | \ No newline at end of file diff --git a/bsp/qemu-virt64-aarch64/README_zh.md b/bsp/qemu-virt64-aarch64/README_zh.md index f9b38c0108..e723e83ac1 100644 --- a/bsp/qemu-virt64-aarch64/README_zh.md +++ b/bsp/qemu-virt64-aarch64/README_zh.md @@ -22,7 +22,7 @@ scons ## 3. 执行 -本工程执行环境为`qemu-system-aarch64`模拟器 +本工程执行环境为`qemu-system-aarch64`模拟器,工程可配置为使用`Cortex-A53/A57/A72`等芯片,GIC支持`V2/V3`版本,其中`V2`最多可配置8个处理器。 Windows平台下,可以在此获取到QEMU: ``` @@ -34,7 +34,7 @@ sudo apt update sudo apt install qemu-system-arm ``` -在终端执行qemu.bat或qemu.sh可以看到程序运行: +工程默认配置修改后请注意修改运行脚本。在终端执行qemu.bat或qemu.sh可以看到程序运行: ``` heap: [0x40042aa0 - 0x40142aa0] @@ -52,4 +52,4 @@ msh /> | ------ | ---- | :------: | | UART | 支持 | UART0 | | RTC | 支持 | - | -| VIRTIO BLK | 支持 | VIRTIO BLK0 | \ No newline at end of file +| VIRTIO BLK | 支持 | - | \ No newline at end of file diff --git a/bsp/qemu-virt64-aarch64/driver/Kconfig b/bsp/qemu-virt64-aarch64/driver/Kconfig index acf9f082ea..5d617eb42a 100644 --- a/bsp/qemu-virt64-aarch64/driver/Kconfig +++ b/bsp/qemu-virt64-aarch64/driver/Kconfig @@ -28,13 +28,19 @@ menu "AARCH64 qemu virt64 configs" bool "Using VirtIO BLK" default y - if BSP_USING_VIRTIO_BLK - config RT_USING_VIRTIO_BLK0 - bool "Enabel VirtIO BLK 0" - default y - endif - config BSP_USING_GIC bool default y + + choice + prompt "GIC Version" + default BSP_USING_GICV2 + + config BSP_USING_GICV2 + bool "GICv2" + + config BSP_USING_GICV3 + bool "GICv3" + endchoice + endmenu diff --git a/bsp/qemu-virt64-aarch64/driver/board.c b/bsp/qemu-virt64-aarch64/driver/board.c index 12e2a85269..7547bd75aa 100644 --- a/bsp/qemu-virt64-aarch64/driver/board.c +++ b/bsp/qemu-virt64-aarch64/driver/board.c @@ -17,6 +17,7 @@ #include "board.h" #include #include +#include #include #include #include @@ -29,8 +30,14 @@ struct mem_desc platform_mem_desc[] = {0x40000000, 0x80000000, 0x40000000, NORMAL_MEM}, {PL031_RTC_BASE, PL031_RTC_BASE + 0x1000, PL031_RTC_BASE, DEVICE_MEM}, {PL011_UART0_BASE, PL011_UART0_BASE + 0x1000, PL011_UART0_BASE, DEVICE_MEM}, - {VIRTIO_MMIO_BLK0_BASE, VIRTIO_MMIO_BLK0_BASE + 0x1000, VIRTIO_MMIO_BLK0_BASE, DEVICE_MEM}, + {VIRTIO_MMIO_BASE, VIRTIO_MMIO_BASE + VIRTIO_MAX_NR * VIRTIO_MMIO_SIZE, VIRTIO_MMIO_BASE, DEVICE_MEM}, +#ifdef BSP_USING_GICV2 {GIC_PL390_DISTRIBUTOR_PPTR, GIC_PL390_DISTRIBUTOR_PPTR + 0x1000, GIC_PL390_DISTRIBUTOR_PPTR, DEVICE_MEM}, +#endif +#ifdef BSP_USING_GICV3 + {GIC_PL500_DISTRIBUTOR_PPTR, GIC_PL500_DISTRIBUTOR_PPTR + 0x1000, GIC_PL500_DISTRIBUTOR_PPTR, DEVICE_MEM}, + {GIC_PL500_REDISTRIBUTOR_PPTR, GIC_PL500_REDISTRIBUTOR_PPTR + 0xf60000, GIC_PL500_REDISTRIBUTOR_PPTR, DEVICE_MEM}, +#endif }; const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]); @@ -58,7 +65,7 @@ void rt_hw_board_init(void) rt_hw_gtimer_init(); rt_thread_idle_sethook(idle_wfi); - arm_psci_init(RT_NULL, RT_NULL); + arm_psci_init(PSCI_METHOD_HVC, RT_NULL, RT_NULL); #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE) /* set console device */ @@ -113,6 +120,9 @@ void secondary_cpu_c_start(void) rt_hw_spin_lock(&_cpus_lock); arm_gic_cpu_init(0, platform_get_gic_cpu_base()); +#ifdef BSP_USING_GICV3 + arm_gic_redist_init(0, platform_get_gic_redist_base()); +#endif rt_hw_vector_init(); rt_hw_gtimer_local_enable(); arm_gic_umask(0, IRQ_ARM_IPI_KICK); diff --git a/bsp/qemu-virt64-aarch64/driver/board.h b/bsp/qemu-virt64-aarch64/driver/board.h index 0bf37a575c..63d0d69f67 100644 --- a/bsp/qemu-virt64-aarch64/driver/board.h +++ b/bsp/qemu-virt64-aarch64/driver/board.h @@ -6,72 +6,18 @@ * Change Logs: * Date Author Notes * 2017-5-30 Bernard the first version - * 2021-07-31 GuEe-GUI add ARM GIC definitions - * 2021-09-11 GuEe-GUI rename right macros for gic */ #ifndef BOARD_H__ #define BOARD_H__ -#include -#include -#include +#include extern unsigned char __bss_start; extern unsigned char __bss_end; #define RT_HW_HEAP_BEGIN (void*)&__bss_end -#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 1 * 1024 * 1024) - -#define __REG32(x) (*((volatile unsigned int *)(x))) - -#define VIRTIO_SPI_IRQ_BASE 32 - -/* Virtio BLK */ -#define VIRTIO_MMIO_BLK0_BASE 0x0a000000 -#define VIRTIO_MMIO_BLK0_SIZE 0x00000200 -#define VIRTIO_MMIO_BLK0_IRQ (VIRTIO_SPI_IRQ_BASE + 0x10) - -/* UART */ -#define PL011_UARTDR 0x000 -#define PL011_UARTFR 0x018 -#define PL011_UARTFR_TXFF_BIT 5 -#define PL011_UART0_BASE 0x09000000 -#define PL011_UART0_SIZE 0x00001000 -#define PL011_UART0_IRQNUM (VIRTIO_SPI_IRQ_BASE + 1) - -/* RTC */ -#define PL031_RTC_BASE 0x9010000 -#define PL031_RTC_SIZE 0x00001000 -#define PL031_RTC_IRQNUM (VIRTIO_SPI_IRQ_BASE + 2) - -/* DIST and CPU */ -#define GIC_PL390_DISTRIBUTOR_PPTR 0x08000000 -#define GIC_PL390_CONTROLLER_PPTR 0x08010000 - -#define MAX_HANDLERS 96 -#define GIC_IRQ_START 0 -/* number of interrupts on board */ -#define ARM_GIC_NR_IRQS 96 -/* only one GIC available */ -#define ARM_GIC_MAX_NR 1 - -/* ipi interrupt number */ -#define IRQ_ARM_IPI_KICK 0 -#define IRQ_ARM_IPI_CALL 1 - -#define IRQ_ARM_VTIMER 27 - -/* the basic constants and interfaces needed by gic */ -rt_inline rt_uint32_t platform_get_gic_dist_base(void) -{ - return GIC_PL390_DISTRIBUTOR_PPTR; -} - -rt_inline rt_uint32_t platform_get_gic_cpu_base(void) -{ - return GIC_PL390_CONTROLLER_PPTR; -} +#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024) void rt_hw_board_init(void); diff --git a/bsp/qemu-virt64-aarch64/driver/drv_uart.c b/bsp/qemu-virt64-aarch64/driver/drv_uart.c index 0d6cdaf15b..ac2a9f11ab 100644 --- a/bsp/qemu-virt64-aarch64/driver/drv_uart.c +++ b/bsp/qemu-virt64-aarch64/driver/drv_uart.c @@ -14,6 +14,10 @@ #include "board.h" +#define PL011_UARTDR 0x000 +#define PL011_UARTFR 0x018 +#define PL011_UARTFR_TXFF_BIT 5 + unsigned int readl(volatile void *addr) { return *(volatile unsigned int *)addr; diff --git a/bsp/qemu-virt64-aarch64/driver/drv_virtio.c b/bsp/qemu-virt64-aarch64/driver/drv_virtio.c new file mode 100644 index 0000000000..33f91ab725 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/driver/drv_virtio.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-11-11 GuEe-GUI the first version + */ + +#include + +#include +#ifdef BSP_USING_VIRTIO_BLK +#include +#endif + +#include + +static virtio_device_init_handler virtio_device_init_handlers[] = +{ +#ifdef BSP_USING_VIRTIO_BLK + [VIRTIO_DEVICE_ID_BLOCK] = rt_virtio_blk_init, +#endif +}; + +int rt_virtio_devices_init(void) +{ + int i; + rt_uint32_t irq = VIRTIO_IRQ_BASE; + rt_ubase_t mmio_base = VIRTIO_MMIO_BASE; + struct virtio_mmio_config *mmio_config; + virtio_device_init_handler init_handler; + + if (sizeof(virtio_device_init_handlers) == 0) + { + /* The compiler will optimize the codes after here. */ + return 0; + } + + for (i = 0; i < VIRTIO_MAX_NR; ++i, ++irq, mmio_base += VIRTIO_MMIO_SIZE) + { + mmio_config = (struct virtio_mmio_config *)mmio_base; + + if (mmio_config->magic != VIRTIO_MAGIC_VALUE || + mmio_config->version != RT_USING_VIRTIO_VERSION || + mmio_config->vendor_id != VIRTIO_VENDOR_ID) + { + continue; + } + + init_handler = virtio_device_init_handlers[mmio_config->device_id]; + + if (init_handler != RT_NULL) + { + init_handler((rt_ubase_t *)mmio_base, irq); + } + } + + return 0; +} +INIT_DEVICE_EXPORT(rt_virtio_devices_init); diff --git a/bsp/qemu-virt64-aarch64/driver/drv_virtio.h b/bsp/qemu-virt64-aarch64/driver/drv_virtio.h new file mode 100644 index 0000000000..954338a386 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/driver/drv_virtio.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-11-11 GuEe-GUI the first version + */ + +#ifndef __DRV_VIRTIO_H__ +#define __DRV_VIRTIO_H__ + +int rt_virtio_devices_init(void); + +#endif /* __DRV_VIRTIO_H__ */ diff --git a/bsp/qemu-virt64-aarch64/driver/virt.h b/bsp/qemu-virt64-aarch64/driver/virt.h new file mode 100644 index 0000000000..ed90db899d --- /dev/null +++ b/bsp/qemu-virt64-aarch64/driver/virt.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-17 GuEe-GUI the first version + */ + +#ifndef VIRT_H__ +#define VIRT_H__ + +#include + +/* UART */ +#define PL011_UART0_BASE 0x09000000 +#define PL011_UART0_SIZE 0x00001000 +#define PL011_UART0_IRQNUM (32 + 1) + +/* RTC */ +#define PL031_RTC_BASE 0x9010000 +#define PL031_RTC_SIZE 0x00001000 +#define PL031_RTC_IRQNUM (32 + 2) + +/* VirtIO */ +#define VIRTIO_MMIO_BASE 0x0a000000 +#define VIRTIO_MMIO_SIZE 0x00000200 +#define VIRTIO_MAX_NR 32 +#define VIRTIO_IRQ_BASE (32 + 16) +#define VIRTIO_VENDOR_ID 0x554d4551 /* "QEMU" */ + +/* GIC */ +#define MAX_HANDLERS 96 +#define GIC_IRQ_START 0 +#define ARM_GIC_NR_IRQS 96 +#define ARM_GIC_MAX_NR 1 + +#define IRQ_ARM_IPI_KICK 0 +#define IRQ_ARM_IPI_CALL 1 + +/* GICv2 */ +#define GIC_PL390_DISTRIBUTOR_PPTR 0x08000000 +#define GIC_PL390_CONTROLLER_PPTR 0x08010000 + +/* GICv3 */ +#define GIC_PL500_DISTRIBUTOR_PPTR GIC_PL390_DISTRIBUTOR_PPTR +#define GIC_PL500_REDISTRIBUTOR_PPTR 0x080a0000 +#define GIC_PL500_CONTROLLER_PPTR GIC_PL390_CONTROLLER_PPTR +#define GIC_PL500_ITS_PPTR 0x08080000 + +/* the basic constants and interfaces needed by gic */ +rt_inline rt_uint32_t platform_get_gic_dist_base(void) +{ +#ifdef BSP_USING_GICV2 + return GIC_PL390_DISTRIBUTOR_PPTR; +#else + return GIC_PL500_DISTRIBUTOR_PPTR; +#endif +} + +rt_inline rt_uint32_t platform_get_gic_redist_base(void) +{ + return GIC_PL500_REDISTRIBUTOR_PPTR; +} + +rt_inline rt_uint32_t platform_get_gic_cpu_base(void) +{ +#ifdef BSP_USING_GICV2 + return GIC_PL390_CONTROLLER_PPTR; +#else + return GIC_PL500_CONTROLLER_PPTR; +#endif +} + +rt_inline rt_uint32_t platform_get_gic_its_base(void) +{ + return GIC_PL500_ITS_PPTR; +} + +#endif diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c b/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c deleted file mode 100644 index 02e6b7986f..0000000000 --- a/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-9-16 GuEe-GUI the first version - */ - -#include -#include -#include -#include -#include - -#include "virtio.h" -#include "virtio_mmio.h" -#include "drv_virtio_blk.h" - -#ifdef BSP_USING_VIRTIO_BLK - -#ifdef RT_USING_VIRTIO_BLK0 -static struct virtio_blk blk0; -static struct virtio_blk_device virtio_blk_dev0; -#endif /* RT_USING_VIRTIO_BLK0 */ - -static int alloc_desc(struct virtio_blk *blk) -{ - int i; - for(i = 0; i < QUEUE_SIZE; i++) - { - if (blk->free[i]) - { - blk->free[i] = 0; - return i; - } - } - return -RT_ERROR; -} - -static void free_desc(struct virtio_blk *blk, int i) -{ - if (i >= QUEUE_SIZE) - { - rt_kprintf("Out of queue number"); - RT_ASSERT(0); - } - if (blk0.free[i]) - { - rt_kprintf("Already freed"); - RT_ASSERT(0); - } - blk->desc[i].addr = 0; - blk->desc[i].len = 0; - blk->desc[i].flags = 0; - blk->desc[i].next = 0; - blk->free[i] = 1; -} - -static void free_chain(struct virtio_blk *blk, int i) -{ - int flag, nxt; - for (;;) - { - flag = blk->desc[i].flags; - nxt = blk->desc[i].next; - - free_desc(blk, i); - - if (flag & VRING_DESC_F_NEXT) - { - i = nxt; - } - else - { - break; - } - } -} - -static int alloc3_desc(struct virtio_blk *blk, int *idx) -{ - for (int i = 0; i < 3; ++i) - { - idx[i] = alloc_desc(blk); - if (idx[i] < 0) - { - for (int j = 0; j < i; ++j) - { - free_desc(blk, idx[j]); - } - return -RT_ERROR; - } - } - return 0; -} - -static int virtio_blk_device_init(struct virtio_blk_device *virtio_blk_dev) -{ - uint32_t status = 0; - uint32_t max; - uint64_t features; - int i; - -#ifdef RT_USING_SMP - rt_spin_lock_init(&virtio_blk_dev->spinlock); -#endif - - if (virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_MAGIC_VALUE) != VIRTIO_MMIO_MAGIC || - virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_VERSION) != 1 || - virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DEVICE_ID) != 2 || - virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_VENDOR_ID) != VIRTIO_MMIO_VENDOR) - { - rt_kprintf("Could not find virtio disk"); - - return -RT_ERROR; - } - - status |= VIRTIO_STAT_ACKNOWLEDGE; - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); - - status |= VIRTIO_STAT_DRIVER; - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); - - /* negotiate features */ - features = virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DEVICE_FEATURES); - features &= ~(1 << VIRTIO_BLK_F_RO); - features &= ~(1 << VIRTIO_BLK_F_SCSI); - features &= ~(1 << VIRTIO_BLK_F_CONFIG_WCE); - features &= ~(1 << VIRTIO_BLK_F_MQ); - features &= ~(1 << VIRTIO_F_ANY_LAYOUT); - features &= ~(1 << VIRTIO_RING_F_EVENT_IDX); - features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC); - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DRIVER_FEATURES, features); - - /* tell device that feature negotiation is complete */ - status |= VIRTIO_STAT_FEATURES_OK; - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); - - /* tell device we're completely ready */ - status |= VIRTIO_STAT_DRIVER_OK; - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); - - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_GUEST_PAGE_SIZE, PAGE_SIZE); - - /* initialize queue 0 */ - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_SEL, 0); - - max = virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NUM_MAX); - if (max == 0) - { - rt_kprintf("Virtio disk has no queue 0"); - RT_ASSERT(0); - } - if (max < QUEUE_SIZE) - { - rt_kprintf("Virtio disk max queue too short"); - RT_ASSERT(0); - } - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NUM, QUEUE_SIZE); - - rt_memset(virtio_blk_dev->blk->pages, 0, sizeof(virtio_blk_dev->blk->pages)); - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_PFN, ((uint64_t)blk0.pages) >> PAGE_SHIFT); - - virtio_blk_dev->blk->desc = (struct virtq_desc *)virtio_blk_dev->blk->pages; - virtio_blk_dev->blk->avail = (struct virtq_avail *)(virtio_blk_dev->blk->pages + QUEUE_SIZE * sizeof(struct virtq_desc)); - virtio_blk_dev->blk->used = (struct virtq_used *)(virtio_blk_dev->blk->pages + PAGE_SIZE); - - /* all QUEUE_SIZE descriptors start out unused */ - for (i = 0; i < QUEUE_SIZE; ++i) - { - virtio_blk_dev->blk->free[i] = 1; - } - - return RT_EOK; -} - -static void virtio_blk_rw(struct virtio_blk_device *virtio_blk_dev, struct virtio_blk_buf *buf, int flag) -{ - struct virtio_blk *blk = virtio_blk_dev->blk; - uint64_t sector = buf->block_no * (VIRTIO_BLK_BUF_DATA_SIZE / 512); - int idx[3]; - struct virtio_blk_req *req; - -#ifdef RT_USING_SMP - rt_base_t level; - - level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock); -#endif - - /* allocate the three descriptors */ - for (;;) - { - if (alloc3_desc(blk, idx) == 0) - { - break; - } - } - - req = &(blk->ops[idx[0]]); - req->type = flag; - req->reserved = 0; - req->sector = sector; - - blk->desc[idx[0]].addr = (uint64_t)req; - blk->desc[idx[0]].len = sizeof(struct virtio_blk_req); - blk->desc[idx[0]].flags = VRING_DESC_F_NEXT; - blk->desc[idx[0]].next = idx[1]; - - blk->desc[idx[1]].addr = (uint64_t)buf->data; - blk->desc[idx[1]].len = VIRTIO_BLK_BUF_DATA_SIZE; - - blk->desc[idx[1]].flags = flag ? 0 : VRING_DESC_F_WRITE; - - blk->desc[idx[1]].flags |= VRING_DESC_F_NEXT; - blk->desc[idx[1]].next = idx[2]; - - /* device writes 0 on success */ - blk->info[idx[0]].status = 0xff; - blk->desc[idx[2]].addr = (uint64_t)&(blk->info[idx[0]].status); - blk->desc[idx[2]].len = 1; - /* device writes the status */ - blk->desc[idx[2]].flags = VRING_DESC_F_WRITE; - blk->desc[idx[2]].next = 0; - - /* record struct buf for virtio_blk_isr() */ - buf->valid = 1; - blk->info[idx[0]].buf = buf; - - /* tell the device the first index in our chain of descriptors */ - blk->avail->ring[blk->avail->idx % QUEUE_SIZE] = idx[0]; - - rt_hw_dsb(); - - /* tell the device another avail ring entry is available */ - blk->avail->idx += 1; - - rt_hw_dsb(); - - /* value is queue number */ - virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NOTIFY, 0); - - /* wait for virtio_blk_isr() to done */ - while (buf->valid == 1) - { -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level); -#endif - rt_thread_yield(); -#ifdef RT_USING_SMP - level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock); -#endif - } - - blk->info[idx[0]].buf = 0; - free_chain(blk, idx[0]); - -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level); -#endif -} - -static void virtio_blk_isr(int irqno, void *param) -{ - int id; - struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)param; - struct virtio_blk *blk = virtio_blk_dev->blk; - struct virtio_blk_buf *buf_tmp; - -#ifdef RT_USING_SMP - rt_base_t level; - - level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock); -#endif - - virtio_mmio_write32( - virtio_blk_dev->mmio_base, - VIRTIO_MMIO_INTERRUPT_ACK, - virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_INTERRUPT_STATUS) & 0x3); - - rt_hw_dsb(); - - /* - * the device increments disk.used->idx - * when it adds an entry to the used ring - */ - while (blk->used_idx != blk->used->idx) - { - rt_hw_dsb(); - id = blk->used->ring[blk->used_idx % QUEUE_SIZE].id; - - if (blk->info[id].status != 0) - { - rt_kprintf("Virtio BLK Status"); - RT_ASSERT(0); - } - - buf_tmp = blk->info[id].buf; - - /* done with buf */ - buf_tmp->valid = 0; - rt_thread_yield(); - - blk->used_idx += 1; - } - -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level); -#endif -} - -static rt_err_t virtio_blk_init(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_err_t virtio_blk_open(rt_device_t dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t virtio_blk_close(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_size_t virtio_blk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev; - struct virtio_blk_buf buf = - { - .block_no = (uint32_t)pos, - .data = (uint8_t *)buffer - }; - - virtio_blk_rw(virtio_blk_dev, &buf, VIRTIO_BLK_T_IN); - - return size; -} - -static rt_size_t virtio_blk_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev; - struct virtio_blk_buf buf = - { - .block_no = (uint32_t)pos, - .data = (uint8_t *)buffer - }; - - virtio_blk_rw(virtio_blk_dev, &buf, VIRTIO_BLK_T_OUT); - - return size; -} - -static rt_err_t virtio_blk_control(rt_device_t dev, int cmd, void *args) -{ - if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) - { - struct rt_device_blk_geometry *geometry; - - geometry = (struct rt_device_blk_geometry *)args; - if (geometry == RT_NULL) - { - return -RT_ERROR; - } - - geometry->bytes_per_sector = VIRTIO_BLK_BYTES_PER_SECTOR; - geometry->block_size = VIRTIO_BLK_BLOCK_SIZE; - geometry->sector_count = VIRTIO_BLK_SECTOR_COUNT; - } - - return RT_EOK; -} - -const static struct rt_device_ops virtio_blk_ops = -{ - virtio_blk_init, - virtio_blk_open, - virtio_blk_close, - virtio_blk_read, - virtio_blk_write, - virtio_blk_control -}; - -int rt_virtio_blk_init(void) -{ - rt_err_t status = RT_EOK; - -#ifdef RT_USING_VIRTIO_BLK0 - virtio_blk_dev0.parent.type = RT_Device_Class_Block; - virtio_blk_dev0.parent.ops = &virtio_blk_ops; - virtio_blk_dev0.blk = &blk0; - virtio_blk_dev0.mmio_base = (uint32_t *)VIRTIO_MMIO_BLK0_BASE; - - status = virtio_blk_device_init(&virtio_blk_dev0); - rt_device_register((rt_device_t)&virtio_blk_dev0, "virtio-blk0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE); - rt_hw_interrupt_install(VIRTIO_MMIO_BLK0_IRQ, virtio_blk_isr, &virtio_blk_dev0, "virtio-blk0"); - rt_hw_interrupt_umask(VIRTIO_MMIO_BLK0_IRQ); -#endif /* RT_USING_VIRTIO_BLK0 */ - - return status; -} -INIT_DEVICE_EXPORT(rt_virtio_blk_init); -#endif /* BSP_USING_VIRTIO_BLK */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h b/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h deleted file mode 100644 index 3ab23f7afe..0000000000 --- a/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-9-16 GuEe-GUI the first version - */ - -#ifndef DRV_VIRTIO_BLK_H__ -#define DRV_VIRTIO_BLK_H__ - -#include -#include -#include "virtio.h" - -#define VIRTIO_BLK_BUF_DATA_SIZE 512 -#define VIRTIO_BLK_BYTES_PER_SECTOR 512 -#define VIRTIO_BLK_BLOCK_SIZE 512 -#define VIRTIO_BLK_SECTOR_COUNT 0x40000 /* 128MB */ - -#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ -#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ -#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */ -#define VIRTIO_BLK_F_MQ 12 /* Support more than one vq */ - -#define VIRTIO_BLK_T_IN 0 /* Read the blk */ -#define VIRTIO_BLK_T_OUT 1 /* Write the blk */ - -#define VIRTIO_F_ANY_LAYOUT 27 -#define VIRTIO_RING_F_INDIRECT_DESC 28 -#define VIRTIO_RING_F_EVENT_IDX 29 - -struct virtio_blk_buf -{ - int valid; - uint32_t block_no; - uint8_t *data; -}; - -struct virtio_blk_req -{ - uint32_t type; - uint32_t reserved; - uint64_t sector; -}; - -/* - * virtio_blk must be a static variable because - * pages must consist of two contiguous pages of - * page-aligned physical memory - */ -struct virtio_blk -{ - char pages[2 * PAGE_SIZE]; - struct virtq_desc *desc; - struct virtq_avail *avail; - struct virtq_used *used; - - char free[QUEUE_SIZE]; - uint16_t used_idx; - struct - { - struct virtio_blk_buf *buf; - char status; - } info[QUEUE_SIZE]; - - struct virtio_blk_req ops[QUEUE_SIZE]; -} __attribute__ ((aligned (PAGE_SIZE))); - -struct virtio_blk_device -{ - struct rt_device parent; - struct virtio_blk *blk; - - uint32_t *mmio_base; -#ifdef RT_USING_SMP - struct rt_spinlock spinlock; -#endif -}; - -int rt_hw_virtio_blk_init(void); - -#endif /* DRV_VIRTIO_BLK_H__ */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio.c b/bsp/qemu-virt64-aarch64/driver/virtio/virtio.c new file mode 100644 index 0000000000..faf05eb297 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/driver/virtio/virtio.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-11-11 GuEe-GUI the first version + */ + +#include +#include + +#include + +rt_inline void _virtio_dev_check(struct virtio_device *dev) +{ + RT_ASSERT(dev != RT_NULL); + RT_ASSERT(dev->mmio_config != RT_NULL); +} + +void virtio_reset_device(struct virtio_device *dev) +{ + _virtio_dev_check(dev); + + dev->mmio_config->status = 0; +} + +void virtio_status_acknowledge_driver(struct virtio_device *dev) +{ + _virtio_dev_check(dev); + + dev->mmio_config->status |= VIRTIO_STATUS_ACKNOWLEDGE | VIRTIO_STATUS_DRIVER; +} + +void virtio_status_driver_ok(struct virtio_device *dev) +{ + _virtio_dev_check(dev); + + dev->mmio_config->status |= VIRTIO_STATUS_FEATURES_OK | VIRTIO_STATUS_DRIVER_OK; +} + +void virtio_interrupt_ack(struct virtio_device *dev, rt_uint32_t ack) +{ + _virtio_dev_check(dev); + + dev->mmio_config->interrupt_ack = ack; +} + +rt_err_t virtio_queue_init(struct virtio_device *dev, rt_uint32_t queue_index, rt_size_t ring_size) +{ + int i; + void *pages; + rt_ubase_t pages_paddr; + rt_size_t pages_total_size; + struct virtq *queue; + + _virtio_dev_check(dev); + + RT_ASSERT(dev->mmio_config->queue_num_max > 0); + RT_ASSERT(dev->mmio_config->queue_num_max > queue_index); + /* ring_size is power of 2 */ + RT_ASSERT(ring_size > 0); + RT_ASSERT(((ring_size - 1) & ring_size) == 0); + + queue = &dev->queues[queue_index]; + pages_total_size = VIRTIO_PAGE_ALIGN( + VIRTQ_DESC_TOTAL_SIZE(ring_size) + VIRTQ_AVAIL_TOTAL_SIZE(ring_size) + VIRTQ_USED_TOTAL_SIZE(ring_size)); + + pages = rt_malloc_align(pages_total_size, VIRTIO_PAGE_SIZE); + + if (pages == RT_NULL) + { + return -RT_ENOMEM; + } + + queue->free = rt_malloc(sizeof(rt_bool_t) * ring_size); + + if (queue->free == RT_NULL) + { + rt_free_align(pages); + return -RT_ENOMEM; + } + + rt_memset(pages, 0, pages_total_size); + pages_paddr = VIRTIO_VA2PA(pages); + + dev->mmio_config->guest_page_size = VIRTIO_PAGE_SIZE; + dev->mmio_config->queue_sel = queue_index; + dev->mmio_config->queue_num = ring_size; + dev->mmio_config->queue_align = VIRTIO_PAGE_SIZE; + dev->mmio_config->queue_pfn = pages_paddr >> VIRTIO_PAGE_SHIFT; + + queue->num = ring_size; + queue->desc = (struct virtq_desc *)pages_paddr; + queue->avail = (struct virtq_avail *)(pages_paddr + VIRTQ_DESC_TOTAL_SIZE(ring_size)); + queue->used = (struct virtq_used *)VIRTIO_PAGE_ALIGN( + (rt_ubase_t)&queue->avail->ring[ring_size] + VIRTQ_AVAIL_RES_SIZE); + + queue->used_idx = 0; + + /* All descriptors start out unused */ + for (i = 0; i < ring_size; ++i) + { + queue->free[i] = RT_TRUE; + } + + return RT_EOK; +} + +void virtio_queue_destroy(struct virtio_device *dev, rt_uint32_t queue_index) +{ + struct virtq *queue; + + _virtio_dev_check(dev); + + RT_ASSERT(dev->mmio_config->queue_num_max > 0); + RT_ASSERT(dev->mmio_config->queue_num_max > queue_index); + + queue = &dev->queues[queue_index]; + + RT_ASSERT(queue->num > 0); + + rt_free(queue->free); + rt_free_align((void *)queue->desc); + + dev->mmio_config->queue_sel = queue_index; + dev->mmio_config->queue_pfn = RT_NULL; + + queue->num = 0; + queue->desc = RT_NULL; + queue->avail = RT_NULL; + queue->used = RT_NULL; +} + +void virtio_queue_notify(struct virtio_device *dev, rt_uint32_t queue_index) +{ + _virtio_dev_check(dev); + + dev->mmio_config->queue_notify = queue_index; +} + +void virtio_submit_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index) +{ + rt_size_t ring_size; + struct virtq *queue; + + _virtio_dev_check(dev); + + queue = &dev->queues[queue_index]; + ring_size = queue->num; + + /* Tell the device the first index in our chain of descriptors */ + queue->avail->ring[queue->avail->idx % ring_size] = desc_index; + rt_hw_dsb(); + + /* Tell the device another avail ring entry is available */ + queue->avail->idx++; + rt_hw_dsb(); +} + +rt_uint16_t virtio_alloc_desc(struct virtio_device *dev, rt_uint32_t queue_index) +{ + int i; + rt_size_t ring_size; + struct virtq *queue; + + _virtio_dev_check(dev); + + RT_ASSERT(queue_index < RT_USING_VIRTIO_QUEUE_MAX_NR); + + queue = &dev->queues[queue_index]; + ring_size = queue->num; + + for (i = 0; i < ring_size; ++i) + { + if (queue->free[i]) + { + queue->free[i] = RT_FALSE; + + return (rt_uint16_t)i; + } + } + + return RT_UINT16_MAX; +} + +void virtio_free_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index) +{ + struct virtq *queue; + + _virtio_dev_check(dev); + + queue = &dev->queues[queue_index]; + + RT_ASSERT(queue_index + 1 < RT_USING_VIRTIO_QUEUE_MAX_NR); + RT_ASSERT(!queue->free[desc_index]); + + queue->desc[desc_index].addr = 0; + queue->desc[desc_index].len = 0; + queue->desc[desc_index].flags = 0; + queue->desc[desc_index].next = 0; + + queue->free[desc_index] = RT_TRUE; +} + +rt_err_t virtio_alloc_desc_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_size_t count, + rt_uint16_t *indexs) +{ + int i, j; + + _virtio_dev_check(dev); + + RT_ASSERT(indexs != RT_NULL); + + for (i = 0; i < count; ++i) + { + indexs[i] = virtio_alloc_desc(dev, queue_index); + + if (indexs[i] == RT_UINT16_MAX) + { + for (j = 0; j < i; ++j) + { + virtio_free_desc(dev, queue_index, indexs[j]); + } + + return -RT_ERROR; + } + } + + return RT_EOK; +} + +void virtio_free_desc_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index) +{ + rt_uint16_t flags, next; + struct virtq_desc *desc; + + _virtio_dev_check(dev); + + desc = &dev->queues[queue_index].desc[0]; + + for (;;) + { + flags = desc[desc_index].flags; + next = desc[desc_index].next; + + virtio_free_desc(dev, queue_index, desc_index); + + if (flags & VIRTQ_DESC_F_NEXT) + { + desc_index = next; + } + else + { + break; + } + } +} + +void virtio_fill_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index, + rt_uint64_t addr, rt_uint32_t len, rt_uint16_t flags, rt_uint16_t next) +{ + struct virtq_desc *desc; + + _virtio_dev_check(dev); + + desc = &dev->queues[queue_index].desc[desc_index]; + + desc->addr = addr; + desc->len = len; + desc->flags = flags; + desc->next = next; +} diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio.h b/bsp/qemu-virt64-aarch64/driver/virtio/virtio.h index e87b68cd88..8a1dffa8c7 100644 --- a/bsp/qemu-virt64-aarch64/driver/virtio/virtio.h +++ b/bsp/qemu-virt64-aarch64/driver/virtio/virtio.h @@ -6,55 +6,115 @@ * Change Logs: * Date Author Notes * 2021-9-16 GuEe-GUI the first version + * 2021-11-11 GuEe-GUI modify to virtio common interface */ -#ifndef VIRTIO_H__ -#define VIRTIO_H__ +#ifndef __VIRTIO_H__ +#define __VIRTIO_H__ -#include +#include +#include -#define PAGE_SIZE 4096 -#define PAGE_SHIFT 12 +#ifndef RT_USING_VIRTIO_VERSION +#define RT_USING_VIRTIO_VERSION 0x1 +#endif -#define VIRTIO_STAT_ACKNOWLEDGE 1 -#define VIRTIO_STAT_DRIVER 2 -#define VIRTIO_STAT_DRIVER_OK 4 -#define VIRTIO_STAT_FEATURES_OK 8 -#define VIRTIO_STAT_NEEDS_RESET 64 -#define VIRTIO_STAT_FAILED 128 +#ifndef RT_USING_VIRTIO_QUEUE_MAX_NR +#define RT_USING_VIRTIO_QUEUE_MAX_NR 4 +#endif -#define QUEUE_SIZE 8 +#include +#include -struct virtq_desc +#define VIRTIO_MAGIC_VALUE 0x74726976 /* "virt" */ + +#define VIRTIO_STATUS_ACKNOWLEDGE (1 << 0) +#define VIRTIO_STATUS_DRIVER (1 << 1) +#define VIRTIO_STATUS_DRIVER_OK (1 << 2) +#define VIRTIO_STATUS_FEATURES_OK (1 << 3) +#define VIRTIO_STATUS_NEEDS_RESET (1 << 6) +#define VIRTIO_STATUS_FAILED (1 << 7) + +#define VIRTIO_F_NOTIFY_ON_EMPTY 24 +#define VIRTIO_F_ANY_LAYOUT 27 +#define VIRTIO_F_RING_INDIRECT_DESC 28 +#define VIRTIO_F_RING_EVENT_IDX 29 +#define VIRTIO_F_VERSION_1 32 +#define VIRTIO_F_RING_PACKED 34 + +#define VIRTIO_VA2PA(vaddr) ((rt_ubase_t)vaddr) +#define VIRTIO_PAGE_SHIFT 12 +#define VIRTIO_PAGE_SIZE (1 << VIRTIO_PAGE_SHIFT) +#define VIRTIO_PAGE_ALIGN(addr) (RT_ALIGN(addr, VIRTIO_PAGE_SIZE)) + +enum { - uint64_t addr; - uint32_t len; - uint16_t flags; - uint16_t next; + /* virtio 1.0 */ + VIRTIO_DEVICE_ID_INVALID = 0, /* Invalid device */ + VIRTIO_DEVICE_ID_NET = 1, /* Net */ + VIRTIO_DEVICE_ID_BLOCK = 2, /* Block */ + VIRTIO_DEVICE_ID_CONSOLE = 3, /* Console */ + VIRTIO_DEVICE_ID_RNG = 4, /* Rng */ + VIRTIO_DEVICE_ID_BALLOON = 5, /* Balloon */ + VIRTIO_DEVICE_ID_IOMEM = 6, /* IO memory */ + VIRTIO_DEVICE_ID_RPMSG = 7, /* Remote processor messaging */ + VIRTIO_DEVICE_ID_SCSI = 8, /* SCSI */ + VIRTIO_DEVICE_ID_9P = 9, /* 9p console */ + VIRTIO_DEVICE_ID_MAC80211_WLAN = 10, /* Mac80211 wlan */ + VIRTIO_DEVICE_ID_RPROC_SERIAL = 11, /* Remoteproc serial link */ + VIRTIO_DEVICE_ID_CAIF = 12, /* CAIF */ + VIRTIO_DEVICE_ID_MEM_BALLOON = 13, /* Memory balloon */ + VIRTIO_DEVICE_ID_GPU = 16, /* GPU */ + VIRTIO_DEVICE_ID_TIME = 17, /* Timer/clock device */ + VIRTIO_DEVICE_ID_INPUT = 18, /* Input */ + /* virtio 1.1 */ + VIRTIO_DEVICE_ID_SOCKET = 19, /* Socket device */ + VIRTIO_DEVICE_ID_CRYPTO = 20, /* Crypto device */ + VIRTIO_DEVICE_ID_SIG_DIS_MOD = 21, /* Signal Distribution Module */ + VIRTIO_DEVICE_ID_PSTORE = 22, /* Pstore device */ + VIRTIO_DEVICE_ID_IOMMU = 23, /* IOMMU device */ + VIRTIO_DEVICE_ID_MEM = 24, /* Memory device */ + + VIRTIO_DEVICE_TYPE_SIZE }; -#define VRING_DESC_F_NEXT 1 // chained with another descriptor -#define VRING_DESC_F_WRITE 2 // device writes (vs read) - -struct virtq_avail +struct virtio_device { - uint16_t flags; // always zero - uint16_t idx; // driver will write ring[idx] next - uint16_t ring[QUEUE_SIZE]; // descriptor numbers of chain heads - uint16_t unused; + rt_uint32_t irq; + + struct virtq queues[RT_USING_VIRTIO_QUEUE_MAX_NR]; + union + { + rt_ubase_t *mmio_base; + struct virtio_mmio_config *mmio_config; + }; + +#ifdef RT_USING_SMP + struct rt_spinlock spinlock; +#endif + + void *priv; }; -struct virtq_used_elem -{ - uint32_t id; // index of start of completed descriptor chain - uint32_t len; -}; +typedef rt_err_t (*virtio_device_init_handler)(rt_ubase_t *mmio_base, rt_uint32_t irq); -struct virtq_used -{ - uint16_t flags; // always zero - uint16_t idx; // device increments when it adds a ring[] entry - struct virtq_used_elem ring[QUEUE_SIZE]; -}; +void virtio_reset_device(struct virtio_device *dev); +void virtio_status_acknowledge_driver(struct virtio_device *dev); +void virtio_status_driver_ok(struct virtio_device *dev); +void virtio_interrupt_ack(struct virtio_device *dev, rt_uint32_t ack); -#endif /* VIRTIO_H__ */ +rt_err_t virtio_queue_init(struct virtio_device *dev, rt_uint32_t queue_index, rt_size_t ring_size); +void virtio_queue_destroy(struct virtio_device *dev, rt_uint32_t queue_index); +void virtio_queue_notify(struct virtio_device *dev, rt_uint32_t queue_index); + +void virtio_submit_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index); + +rt_uint16_t virtio_alloc_desc(struct virtio_device *dev, rt_uint32_t queue_index); +void virtio_free_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index); +rt_err_t virtio_alloc_desc_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_size_t count, + rt_uint16_t *indexs); +void virtio_free_desc_chain(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index); +void virtio_fill_desc(struct virtio_device *dev, rt_uint32_t queue_index, rt_uint16_t desc_index, + rt_uint64_t addr, rt_uint32_t len, rt_uint16_t flags, rt_uint16_t next); + +#endif /* __VIRTIO_H__ */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c new file mode 100644 index 0000000000..aac6ff7511 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-9-16 GuEe-GUI the first version + * 2021-11-11 GuEe-GUI using virtio common interface + */ + +#include +#include +#include + +#include + +#ifdef BSP_USING_VIRTIO_BLK +static void virtio_blk_rw(struct virtio_blk_device *virtio_blk_dev, rt_off_t pos, void *buffer, int flags) +{ + rt_uint16_t idx[3]; + struct virtio_device *virtio_dev = &virtio_blk_dev->virtio_dev; + +#ifdef RT_USING_SMP + rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock); +#endif + + /* Allocate 3 descriptors */ + while (virtio_alloc_desc_chain(virtio_dev, 0, 3, idx)) + { + } + + virtio_blk_dev->info[idx[0]].status = 0xff; + virtio_blk_dev->info[idx[0]].valid = RT_TRUE; + virtio_blk_dev->info[idx[0]].req.type = flags; + virtio_blk_dev->info[idx[0]].req.ioprio = 0; + virtio_blk_dev->info[idx[0]].req.sector = pos * (VIRTIO_BLK_BUF_DATA_SIZE / 512); + + flags = flags == VIRTIO_BLK_T_OUT ? 0 : VIRTQ_DESC_F_WRITE; + + virtio_fill_desc(virtio_dev, 0, idx[0], + VIRTIO_VA2PA(&virtio_blk_dev->info[idx[0]].req), sizeof(struct virtio_blk_req), VIRTQ_DESC_F_NEXT, idx[1]); + + virtio_fill_desc(virtio_dev, 0, idx[1], + VIRTIO_VA2PA(buffer), VIRTIO_BLK_BUF_DATA_SIZE, flags | VIRTQ_DESC_F_NEXT, idx[2]); + + virtio_fill_desc(virtio_dev, 0, idx[2], + VIRTIO_VA2PA(&virtio_blk_dev->info[idx[0]].status), 1, VIRTQ_DESC_F_WRITE, 0); + + virtio_submit_chain(virtio_dev, 0, idx[0]); + + virtio_queue_notify(virtio_dev, 0); + + /* Wait for virtio_blk_isr() to done */ + while (virtio_blk_dev->info[idx[0]].valid) + { +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); +#endif + rt_thread_yield(); + +#ifdef RT_USING_SMP + level = rt_spin_lock_irqsave(&virtio_dev->spinlock); +#endif + } + + virtio_free_desc_chain(virtio_dev, 0, idx[0]); + +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); +#endif +} + +static rt_size_t virtio_blk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + virtio_blk_rw((struct virtio_blk_device *)dev, pos, buffer, VIRTIO_BLK_T_IN); + + return size; +} + +static rt_size_t virtio_blk_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + virtio_blk_rw((struct virtio_blk_device *)dev, pos, (void *)buffer, VIRTIO_BLK_T_OUT); + + return size; +} + +static rt_err_t virtio_blk_control(rt_device_t dev, int cmd, void *args) +{ + rt_err_t status = RT_EOK; + struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev; + + switch (cmd) + { + case RT_DEVICE_CTRL_BLK_GETGEOME: + { + struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *)args; + + if (geometry == RT_NULL) + { + status = -RT_ERROR; + break; + } + + geometry->bytes_per_sector = VIRTIO_BLK_BYTES_PER_SECTOR; + geometry->block_size = VIRTIO_BLK_BLOCK_SIZE; + geometry->sector_count = virtio_blk_dev->virtio_dev.mmio_config->config[0]; + } + break; + default: + break; + } + + return status; +} + +const static struct rt_device_ops virtio_blk_ops = +{ + RT_NULL, + RT_NULL, + RT_NULL, + virtio_blk_read, + virtio_blk_write, + virtio_blk_control +}; + +static void virtio_blk_isr(int irqno, void *param) +{ + rt_uint32_t id; + struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)param; + struct virtio_device *virtio_dev = &virtio_blk_dev->virtio_dev; + +#ifdef RT_USING_SMP + rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock); +#endif + + virtio_interrupt_ack(virtio_dev, virtio_dev->mmio_config->interrupt_status & 0x3); + rt_hw_dsb(); + + /* The device increments disk.used->idx when it adds an entry to the used ring */ + while (virtio_dev->queues[0].used_idx != virtio_dev->queues[0].used->idx) + { + rt_hw_dsb(); + id = virtio_dev->queues[0].used->ring[virtio_dev->queues[0].used_idx % VIRTIO_BLK_QUEUE_RING_SIZE].id; + + RT_ASSERT(virtio_blk_dev->info[id].status == 0); + + /* Done with buffer */ + virtio_blk_dev->info[id].valid = RT_FALSE; + rt_thread_yield(); + + virtio_dev->queues[0].used_idx++; + } + +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); +#endif +} + +rt_err_t rt_virtio_blk_init(rt_ubase_t *mmio_base, rt_uint32_t irq) +{ + static int dev_no = 0; + char dev_name[RT_NAME_MAX]; + struct virtio_device *virtio_dev; + struct virtio_blk_device *virtio_blk_dev; + + virtio_blk_dev = rt_malloc(sizeof(struct virtio_blk_device)); + + if (virtio_blk_dev == RT_NULL) + { + return -RT_ENOMEM; + } + + virtio_dev = &virtio_blk_dev->virtio_dev; + virtio_dev->irq = irq; + virtio_dev->mmio_base = mmio_base; + +#ifdef RT_USING_SMP + rt_spin_lock_init(&virtio_dev->spinlock); +#endif + + virtio_reset_device(virtio_dev); + virtio_status_acknowledge_driver(virtio_dev); + + /* Negotiate features */ + virtio_dev->mmio_config->driver_features = virtio_dev->mmio_config->device_features & ~( + (1 << VIRTIO_BLK_F_RO) | + (1 << VIRTIO_BLK_F_MQ) | + (1 << VIRTIO_BLK_F_SCSI) | + (1 << VIRTIO_BLK_F_CONFIG_WCE) | + (1 << VIRTIO_F_ANY_LAYOUT) | + (1 << VIRTIO_F_RING_EVENT_IDX) | + (1 << VIRTIO_F_RING_INDIRECT_DESC)); + + /* Tell device that feature negotiation is complete and we're completely ready */ + virtio_status_driver_ok(virtio_dev); + + /* Initialize queue 0 */ + if (virtio_queue_init(virtio_dev, 0, VIRTIO_BLK_QUEUE_RING_SIZE) != RT_EOK) + { + rt_free(virtio_blk_dev); + + return -RT_ENOMEM; + } + + virtio_blk_dev->parent.type = RT_Device_Class_Block; + virtio_blk_dev->parent.ops = &virtio_blk_ops; + + rt_snprintf(dev_name, RT_NAME_MAX, "%s%d", "virtio-blk", dev_no++); + + rt_hw_interrupt_install(irq, virtio_blk_isr, virtio_blk_dev, dev_name); + rt_hw_interrupt_umask(irq); + + return rt_device_register((rt_device_t)virtio_blk_dev, dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE); +} +#endif /* BSP_USING_VIRTIO_BLK */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h new file mode 100644 index 0000000000..dfc08a1c55 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-9-16 GuEe-GUI the first version + * 2021-11-11 GuEe-GUI using virtio common interface + */ + +#ifndef __VIRTIO_BLK_H__ +#define __VIRTIO_BLK_H__ + +#include + +#include + +#define VIRTIO_BLK_BUF_DATA_SIZE 512 +#define VIRTIO_BLK_BYTES_PER_SECTOR 512 +#define VIRTIO_BLK_BLOCK_SIZE 512 +#define VIRTIO_BLK_QUEUE_RING_SIZE 4 + +#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ +#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ +#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */ +#define VIRTIO_BLK_F_MQ 12 /* Support more than one vq */ + +#define VIRTIO_BLK_T_IN 0 /* Read the blk */ +#define VIRTIO_BLK_T_OUT 1 /* Write the blk */ +#define VIRTIO_BLK_T_SCSI_CMD 2 +#define VIRTIO_BLK_T_SCSI_CMD_OUT 3 +#define VIRTIO_BLK_T_FLUSH 4 +#define VIRTIO_BLK_T_FLUSH_OUT 5 + +struct virtio_blk_req +{ + rt_uint32_t type; + rt_uint32_t ioprio; + rt_uint64_t sector; +}; + +struct virtio_blk_device +{ + struct rt_device parent; + + struct virtio_device virtio_dev; + + struct + { + rt_bool_t valid; + rt_uint8_t status; + + struct virtio_blk_req req; + + } info[VIRTIO_BLK_QUEUE_RING_SIZE]; +}; + +rt_err_t rt_virtio_blk_init(rt_ubase_t *mmio_base, rt_uint32_t irq); + +#endif /* __VIRTIO_BLK_H__ */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c deleted file mode 100644 index 72328bf61c..0000000000 --- a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-9-16 GuEe-GUI the first version - */ - -#include -#include - -#include "virtio_mmio.h" - -void virtio_mmio_print_configs(uint32_t *device_base) -{ - rt_kprintf("MagicValue:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_MAGIC_VALUE)); - rt_kprintf("Version:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_VERSION)); - rt_kprintf("DeviceID:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_DEVICE_ID)); - rt_kprintf("VendorID:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_VENDOR_ID)); - rt_kprintf("DeviceFeatures0:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES)); - rt_kprintf("DeviceFeaturesSel0:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES_SEL)); - - virtio_mmio_write32(device_base, VIRTIO_MMIO_HOST_FEATURES_SEL, 1); - rt_hw_dsb(); - - rt_kprintf("DeviceFeatures1:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES)); - rt_kprintf("DriverFeatures:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_FEATURES)); - rt_kprintf("DriverFeaturesSel:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_FEATURES_SEL)); - rt_kprintf("PageSize:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_PAGE_SIZE)); - - virtio_mmio_write32(device_base, VIRTIO_MMIO_QUEUE_SEL, 0); - rt_hw_dsb(); - - rt_kprintf("QueueSel:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_SEL)); - rt_kprintf("QueueNumMax:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM_MAX)); - rt_kprintf("QueueNum:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM)); - - virtio_mmio_write32(device_base, VIRTIO_MMIO_QUEUE_SEL, 1); - rt_hw_dsb(); - - rt_kprintf("QueueSel:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_SEL)); - rt_kprintf("QueueNumMax1:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM_MAX)); - rt_kprintf("QueueNum1:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM)); - rt_kprintf("QueueAlign:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_ALIGN)); - rt_kprintf("QueuePFN:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_PFN)); - rt_kprintf("QueueReady:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_READY)); - rt_kprintf("QueueNotify:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NOTIFY)); - rt_kprintf("InterruptStatus:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_INTERRUPT_STATUS)); - rt_kprintf("InterruptACK:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_INTERRUPT_ACK)); - rt_kprintf("Status:\t\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_STATUS)); - rt_kprintf("QueueDescLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_DESC_LOW)); - rt_kprintf("QueueDescHigh:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_DESC_HIGH)); - rt_kprintf("QueueDriverLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_AVAIL_LOW)); - rt_kprintf("QueueDriverHigh:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_AVAIL_HIGH)); - rt_kprintf("QueueDeviceLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_USED_LOW)); - rt_kprintf("QueueDeviceHigh:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_USED_HIGH)); - rt_kprintf("ConfigGeneration:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_CONFIG_GENERATION)); - rt_kprintf("Config:\t\t\t 0x%x\n", virtio_mmio_read32(device_base,VIRTIO_MMIO_CONFIG)); -} diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h index fd7611aa85..4082aa6682 100644 --- a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h +++ b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h @@ -6,70 +6,52 @@ * Change Logs: * Date Author Notes * 2021-9-16 GuEe-GUI the first version + * 2021-11-11 GuEe-GUI modify to virtio common interface */ -#ifndef VIRTIO_MMIO_H -#define VIRTIO_MMIO_H +#ifndef __VIRTIO_MMIO_H__ +#define __VIRTIO_MMIO_H__ -#include -#include +#include -#define VIRTIO_MMIO_MAGIC 0x74726976 -#define VIRTIO_MMIO_VENDOR 0x554d4551 - -#define VIRTIO_MMIO_MAGIC_VALUE 0x000 /* VIRTIO_MMIO_MAGIC */ -#define VIRTIO_MMIO_VERSION 0x004 /* version: 1 is legacy */ -#define VIRTIO_MMIO_DEVICE_ID 0x008 /* device type: 1 is net, 2 is disk */ -#define VIRTIO_MMIO_VENDOR_ID 0x00c /* VIRTIO_MMIO_VENDOR */ -#define VIRTIO_MMIO_DEVICE_FEATURES 0x010 -#define VIRTIO_MMIO_DRIVER_FEATURES 0x020 -#define VIRTIO_MMIO_HOST_FEATURES 0x010 -#define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 -#define VIRTIO_MMIO_GUEST_FEATURES 0x020 -#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024 -#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 /* version 1 only */ -#define VIRTIO_MMIO_QUEUE_SEL 0x030 -#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 -#define VIRTIO_MMIO_QUEUE_NUM 0x038 -#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c /* version 1 only */ -#define VIRTIO_MMIO_QUEUE_PFN 0x040 /* version 1 only */ -#define VIRTIO_MMIO_QUEUE_READY 0x044 /* requires version 2 */ -#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 -#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 -#define VIRTIO_MMIO_INTERRUPT_ACK 0x064 -#define VIRTIO_MMIO_STATUS 0x070 -#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 /* requires version 2 */ -#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 /* requires version 2 */ -#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090 /* requires version 2 */ -#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094 /* requires version 2 */ -#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0 /* requires version 2 */ -#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4 /* requires version 2 */ -#define VIRTIO_MMIO_CONFIG_GENERATION 0x100 /* requires version 2 */ -#define VIRTIO_MMIO_CONFIG 0x100 -#define VIRTIO_MMIO_INT_VRING (1 << 0) -#define VIRTIO_MMIO_INT_CONFIG (1 << 1) -#define VIRTIO_MMIO_VRING_ALIGN 4096 - -static inline uint32_t virtio_mmio_read32(uint32_t *base, size_t offset) +struct virtio_mmio_config { - return *((volatile uint32_t*) (((uintptr_t) base) + offset)); -} + rt_uint32_t magic; /* [0x00] Magic value */ + rt_uint32_t version; /* [0x04] Device version number */ + rt_uint32_t device_id; /* [0x08] Virtio Subsystem Device ID */ + rt_uint32_t vendor_id; /* [0x0c] Virtio Subsystem Vendor ID */ + rt_uint32_t device_features; /* [0x10] Flags representing features the device supports */ + rt_uint32_t device_features_sel; /* [0x14] Device (host) features word selection. */ + rt_uint32_t res0[2]; /* [0x18] */ + rt_uint32_t driver_features; /* [0x20] Device features understood and activated by the driver */ + rt_uint32_t driver_features_sel; /* [0x24] Activated (guest) features word selection */ + rt_uint32_t guest_page_size; /* [0x28] Guest page size, this value should be a power of 2 */ + rt_uint32_t res1[1]; /* [0x2c] */ + rt_uint32_t queue_sel; /* [0x30] Virtual queue index */ + rt_uint32_t queue_num_max; /* [0x34] Maximum virtual queue size */ + rt_uint32_t queue_num; /* [0x38] Virtual queue size */ + rt_uint32_t queue_align; /* [0x3c] Used Ring alignment in the virtual queue */ + rt_uint32_t queue_pfn; /* [0x40] Guest physical page number of the virtual queue */ + rt_uint32_t queue_ready; /* [0x44] Virtual queue ready bit */ + rt_uint32_t res2[2]; /* [0x48] */ + rt_uint32_t queue_notify; /* [0x50] Queue notifier */ + rt_uint32_t res3[3]; /* [0x54] */ + rt_uint32_t interrupt_status; /* [0x60] Interrupt status */ + rt_uint32_t interrupt_ack; /* [0x64] Interrupt acknowledge */ + rt_uint32_t res4[2]; /* [0x68] */ + rt_uint32_t status; /* [0x70] Device status */ + rt_uint32_t res5[3]; /* [0x74] */ + rt_uint32_t queue_desc_low; /* [0x80] Virtual queue’s Descriptor Area 64 bit long physical address */ + rt_uint32_t queue_desc_high; /* [0x84] */ + rt_uint32_t res6[2]; /* [0x88] */ + rt_uint32_t queue_driver_low; /* [0x90] Virtual queue’s Driver Area 64 bit long physical address */ + rt_uint32_t queue_driver_high; /* [0x94] */ + rt_uint32_t res7[2]; /* [0x98] */ + rt_uint32_t queue_device_low; /* [0xa0] Virtual queue’s Device Area 64 bit long physical address */ + rt_uint32_t queue_device_high; /* [0xa4] */ + rt_uint32_t res8[21]; /* [0xa8] */ + rt_uint32_t config_generation; /* [0xfc] Configuration atomicity value */ + rt_uint32_t config[]; /* [0x100+] Configuration space */ +} __attribute__((packed)); -static inline uint16_t virtio_mmio_read16(uint32_t *base, size_t offset) -{ - return *((volatile uint16_t*) (((uintptr_t) base) + offset)); -} - -static inline uint8_t virtio_mmio_read8(uint32_t *base, size_t offset) -{ - return *((volatile uint8_t*) (((uintptr_t) base) + offset)); -} - -static inline void virtio_mmio_write32(uint32_t *base, size_t offset, uint32_t val) -{ - *((volatile uint32_t*) (((uintptr_t) base) + offset)) = val; -} - -void virtio_mmio_print_configs(uint32_t *device_base); - -#endif /* VIRTIO_MMIO_H */ +#endif /* __VIRTIO_MMIO_H__ */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h new file mode 100644 index 0000000000..ba8d5d4268 --- /dev/null +++ b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-11-11 GuEe-GUI the first version + */ + +#ifndef __VIRTIO_QUEUE_H__ +#define __VIRTIO_QUEUE_H__ + +#include + +#define VIRTQ_DESC_F_NEXT 1 /* This marks a buffer as continuing via the next field. */ +#define VIRTQ_DESC_F_WRITE 2 /* This marks a buffer as write-only (otherwise read-only). */ +#define VIRTQ_DESC_F_INDIRECT 4 /* This means the buffer contains a list of buffer descriptors. */ + +/* + * The device uses this in used->flags to advise the driver: don't kick me + * when you add a buffer. It's unreliable, so it's simply an optimization. + */ +#define VIRTQ_USED_F_NO_NOTIFY 1 + +/* + * The driver uses this in avail->flags to advise the device: don't + * interrupt me when you consume a buffer. It's unreliable, so it's + * simply an optimization. + */ +#define VIRTQ_AVAIL_F_NO_INTERRUPT 1 + +/* Virtqueue descriptors: 16 bytes. These can chain together via "next". */ +struct virtq_desc +{ + rt_uint64_t addr; /* Address (guest-physical). */ + rt_uint32_t len; /* Length. */ + rt_uint16_t flags; /* The flags as indicated above. */ + rt_uint16_t next; /* We chain unused descriptors via this, too */ +}; + +struct virtq_avail +{ + rt_uint16_t flags; /* Notifications */ + rt_uint16_t idx; /* Where the driver would put the next descriptor entry in the ring (modulo the queue size) */ + rt_uint16_t ring[]; + + /* + * Only if VIRTIO_F_RING_EVENT_IDX + * rt_uint16_t used_event; + */ +}; + +struct virtq_used_elem +{ + rt_uint32_t id; /* Index of start of used descriptor chain. */ + rt_uint32_t len; /* Total length of the descriptor chain which was written to. */ +}; + +struct virtq_used +{ + rt_uint16_t flags; + rt_uint16_t idx; + struct virtq_used_elem ring[]; + + /* + * Only if VIRTIO_F_RING_EVENT_IDX + * rt_uint16_t avail_event; + */ +}; + +struct virtq +{ + rt_uint32_t num; + + struct virtq_desc *desc; + struct virtq_avail *avail; + struct virtq_used *used; + + /* Helper of driver */ + rt_uint32_t used_idx; + rt_bool_t *free; +}; + +#define VIRTQ_DESC_TOTAL_SIZE(ring_size) (sizeof(struct virtq_desc) * (ring_size)) +/* flags, idx, used_event + ring * ring_size */ +#define VIRTQ_AVAIL_TOTAL_SIZE(ring_size) (sizeof(rt_uint16_t) * 3 + sizeof(rt_uint16_t) * (ring_size)) +/* flags, idx, avail_event + ring * ring_size */ +#define VIRTQ_USED_TOTAL_SIZE(ring_size) (sizeof(rt_uint16_t) * 3 + sizeof(struct virtq_used_elem) * (ring_size)) + +#define VIRTQ_AVAIL_RES_SIZE (sizeof(rt_uint16_t)) /* used_event */ +#define VIRTQ_USED_RES_SIZE (sizeof(rt_uint16_t)) /* avail_event */ + +#endif /* __VIRTIO_QUEUE_H__ */ diff --git a/bsp/qemu-virt64-aarch64/qemu.bat b/bsp/qemu-virt64-aarch64/qemu.bat index 708bd271c5..0e078cfe15 100644 --- a/bsp/qemu-virt64-aarch64/qemu.bat +++ b/bsp/qemu-virt64-aarch64/qemu.bat @@ -3,5 +3,6 @@ if exist sd.bin goto run qemu-img create -f raw sd.bin 64M :run -qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic ^ --drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 +qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic ^ +-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 ^ +-netdev user,id=net0 -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1 diff --git a/bsp/qemu-virt64-aarch64/qemu.sh b/bsp/qemu-virt64-aarch64/qemu.sh index 677d640b01..34886682ee 100644 --- a/bsp/qemu-virt64-aarch64/qemu.sh +++ b/bsp/qemu-virt64-aarch64/qemu.sh @@ -1,5 +1,6 @@ if [ ! -f "sd.bin" ]; then dd if=/dev/zero of=sd.bin bs=1024 count=65536 fi -qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic \ --drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 +qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic \ +-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \ +-netdev user,id=net0 -device virtio-net-device,netdev=net0,bus=virtio-mmio-bus.1 diff --git a/bsp/qemu-virt64-aarch64/rtconfig.h b/bsp/qemu-virt64-aarch64/rtconfig.h index 2aefe60171..51cb859f2a 100644 --- a/bsp/qemu-virt64-aarch64/rtconfig.h +++ b/bsp/qemu-virt64-aarch64/rtconfig.h @@ -61,14 +61,8 @@ #define RT_USING_USER_MAIN #define RT_MAIN_THREAD_STACK_SIZE 8192 #define RT_MAIN_THREAD_PRIORITY 10 - -/* C++ features */ - - -/* Command shell */ - -#define RT_USING_FINSH #define RT_USING_MSH +#define RT_USING_FINSH #define FINSH_USING_MSH #define FINSH_THREAD_NAME "tshell" #define FINSH_THREAD_PRIORITY 20 @@ -80,9 +74,6 @@ #define MSH_USING_BUILT_IN_COMMANDS #define FINSH_USING_DESCRIPTION #define FINSH_ARG_MAX 10 - -/* Device virtual file system */ - #define RT_USING_DFS #define DFS_USING_POSIX #define DFS_USING_WORKDIR @@ -109,6 +100,9 @@ /* Device Drivers */ #define RT_USING_DEVICE_IPC +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_RB_BUFSZ 64 @@ -119,7 +113,7 @@ /* Using USB */ -/* POSIX layer and C standard library */ +/* C/C++ and POSIX layer */ #define RT_LIBC_DEFAULT_TIMEZONE 8 @@ -131,22 +125,9 @@ /* Socket is in the 'Network' category */ + /* Network */ -/* Socket abstraction layer */ - - -/* Network interface device */ - - -/* light weight TCP/IP stack */ - - -/* AT commands */ - - -/* VBUS(Virtual Software BUS) */ - /* Utilities */ @@ -215,6 +196,8 @@ /* miscellaneous packages */ +/* project laboratory */ + /* samples: kernel and components samples */ @@ -229,7 +212,7 @@ #define BSP_USING_RTC #define BSP_USING_ALARM #define BSP_USING_VIRTIO_BLK -#define RT_USING_VIRTIO_BLK0 #define BSP_USING_GIC +#define BSP_USING_GICV2 #endif diff --git a/bsp/raspberry-pi/raspi4-64/.config b/bsp/raspberry-pi/raspi4-64/.config index a2c217c07a..d5b8d6e0a5 100644 --- a/bsp/raspberry-pi/raspi4-64/.config +++ b/bsp/raspberry-pi/raspi4-64/.config @@ -94,17 +94,8 @@ CONFIG_RT_USING_USER_MAIN=y CONFIG_RT_MAIN_THREAD_STACK_SIZE=4096 CONFIG_RT_MAIN_THREAD_PRIORITY=10 # CONFIG_RT_USING_LEGACY is not set - -# -# C++ features -# -# CONFIG_RT_USING_CPLUSPLUS is not set - -# -# Command shell -# -CONFIG_RT_USING_FINSH=y CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y CONFIG_FINSH_USING_MSH=y CONFIG_FINSH_THREAD_NAME="tshell" CONFIG_FINSH_THREAD_PRIORITY=20 @@ -118,10 +109,6 @@ CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 - -# -# Device virtual file system -# CONFIG_RT_USING_DFS=y CONFIG_DFS_USING_POSIX=y CONFIG_DFS_USING_WORKDIR=y @@ -156,6 +143,7 @@ CONFIG_RT_USING_DFS_DEVFS=y # CONFIG_RT_USING_DFS_ROMFS is not set # CONFIG_RT_USING_DFS_RAMFS is not set # CONFIG_RT_USING_DFS_NFS is not set +# CONFIG_RT_USING_FAL is not set # # Device Drivers @@ -209,7 +197,7 @@ CONFIG_RT_USING_WDT=y # CONFIG_RT_USING_USB_DEVICE is not set # -# POSIX layer and C standard library +# C/C++ and POSIX layer # CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 @@ -233,25 +221,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # Socket is in the 'Network' category # - -# -# Interprocess Communication (IPC) -# -# CONFIG_RT_USING_POSIX_PIPE is not set -# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set -# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set - -# -# Socket is in the 'Network' category -# +# CONFIG_RT_USING_CPLUSPLUS is not set # # Network # - -# -# Socket abstraction layer -# CONFIG_RT_USING_SAL=y CONFIG_SAL_INTERNET_CHECK=y @@ -261,10 +235,6 @@ CONFIG_SAL_INTERNET_CHECK=y CONFIG_SAL_USING_LWIP=y # CONFIG_SAL_USING_POSIX is not set CONFIG_SAL_SOCKETS_NUM=16 - -# -# Network interface device -# CONFIG_RT_USING_NETDEV=y CONFIG_NETDEV_USING_IFCONFIG=y CONFIG_NETDEV_USING_PING=y @@ -274,14 +244,13 @@ CONFIG_NETDEV_USING_AUTO_DEFAULT=y CONFIG_NETDEV_IPV4=1 CONFIG_NETDEV_IPV6=0 # CONFIG_NETDEV_IPV6_SCOPES is not set - -# -# light weight TCP/IP stack -# CONFIG_RT_USING_LWIP=y +# CONFIG_RT_USING_LWIP_LOCAL_VERSION is not set # CONFIG_RT_USING_LWIP141 is not set CONFIG_RT_USING_LWIP203=y # CONFIG_RT_USING_LWIP212 is not set +# CONFIG_RT_USING_LWIP_LATEST is not set +CONFIG_RT_USING_LWIP_VER_NUM=0x20003 # CONFIG_RT_USING_LWIP_IPV6 is not set CONFIG_RT_LWIP_MEM_ALIGNMENT=4 CONFIG_RT_LWIP_IGMP=y @@ -331,18 +300,9 @@ CONFIG_LWIP_NETIF_LOOPBACK=0 # CONFIG_RT_LWIP_STATS is not set # CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set CONFIG_RT_LWIP_USING_PING=y -# CONFIG_RT_LWIP_DEBUG is not set - -# -# AT commands -# -# CONFIG_RT_USING_AT is not set # CONFIG_LWIP_USING_DHCPD is not set - -# -# VBUS(Virtual Software BUS) -# -# CONFIG_RT_USING_VBUS is not set +# CONFIG_RT_LWIP_DEBUG is not set +# CONFIG_RT_USING_AT is not set # # Utilities @@ -354,6 +314,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set # CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set # # RT-Thread Utestcases @@ -367,6 +328,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # # IoT - internet of things # +# CONFIG_PKG_USING_LWIP is not set # CONFIG_PKG_USING_LORAWAN_DRIVER is not set # CONFIG_PKG_USING_PAHOMQTT is not set # CONFIG_PKG_USING_UMQTT is not set @@ -383,6 +345,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_PKG_USING_FREEMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_SIMPLE_XML is not set # CONFIG_PKG_USING_NANOPB is not set # @@ -422,6 +385,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_PKG_USING_JOYLINK is not set # CONFIG_PKG_USING_EZ_IOT_OS is not set # CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set # CONFIG_PKG_USING_OTA_DOWNLOADER is not set # CONFIG_PKG_USING_IPMSG is not set # CONFIG_PKG_USING_LSSDP is not set @@ -629,8 +593,8 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_PKG_USING_ARM_2D is not set # CONFIG_PKG_USING_MCUBOOT is not set # CONFIG_PKG_USING_TINYUSB is not set -# CONFIG_PKG_USING_USB_STACK is not set -# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set # # peripheral libraries and drivers @@ -654,6 +618,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_PKG_USING_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set # CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set # CONFIG_PKG_USING_AGILE_BUTTON is not set # CONFIG_PKG_USING_AGILE_LED is not set # CONFIG_PKG_USING_AT24CXX is not set @@ -710,6 +675,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_PKG_USING_SOFT_SERIAL is not set # CONFIG_PKG_USING_MB85RS16 is not set # CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_RFM300 is not set # # AI packages @@ -728,6 +694,10 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # miscellaneous packages # +# +# project laboratory +# + # # samples: kernel and components samples # @@ -760,6 +730,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set # CONFIG_PKG_USING_DSTR is not set # CONFIG_PKG_USING_TINYFRAME is not set # CONFIG_PKG_USING_KENDRYTE_DEMO is not set @@ -777,6 +748,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y # CONFIG_PKG_USING_DESIGN_PATTERN is not set # CONFIG_PKG_USING_CONTROLLER is not set # CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set CONFIG_BCM2711_SOC=y # @@ -793,6 +765,7 @@ CONFIG_RT_USING_UART0=y # CONFIG_RT_USING_UART4 is not set # CONFIG_RT_USING_UART5 is not set CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV2=y CONFIG_BSP_USING_PIN=y CONFIG_BSP_USING_CORETIMER=y # CONFIG_BSP_USING_SYSTIMER is not set diff --git a/bsp/raspberry-pi/raspi4-64/driver/Kconfig b/bsp/raspberry-pi/raspi4-64/driver/Kconfig index 1eaf56faca..ec2a36d289 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/Kconfig +++ b/bsp/raspberry-pi/raspi4-64/driver/Kconfig @@ -31,6 +31,10 @@ menu "Hardware Drivers Config" bool default y + config BSP_USING_GICV2 + bool + default y + config BSP_USING_PIN bool "Using PIN" select RT_USING_PIN diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_wdt.c b/bsp/raspberry-pi/raspi4-64/driver/drv_wdt.c index 0d2a854ab8..ac7d1addb8 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_wdt.c +++ b/bsp/raspberry-pi/raspi4-64/driver/drv_wdt.c @@ -10,6 +10,8 @@ #include #include "drv_wdt.h" +#include "drv_gpio.h" +#include "mbox.h" #include "raspi4.h" #ifdef BSP_USING_WDT @@ -122,6 +124,48 @@ int rt_hw_wdt_init(void) } INIT_DEVICE_EXPORT(rt_hw_wdt_init); +void poweroff(void) +{ + unsigned long r; + + rt_kprintf("poweroff...\n"); + + /* power off devices one by one */ + for (r = 0; r < 16; ++r) + { + bcm271x_mbox_poweroff_devices(r); + } + + /* power off gpio pins (but not VCC pins) */ + GPIO_REG_GPFSEL0(GPIO_BASE) = 0; + GPIO_REG_GPFSEL1(GPIO_BASE) = 0; + GPIO_REG_GPFSEL2(GPIO_BASE) = 0; + GPIO_REG_GPFSEL3(GPIO_BASE) = 0; + GPIO_REG_GPFSEL4(GPIO_BASE) = 0; + GPIO_REG_GPFSEL5(GPIO_BASE) = 0; + GPIO_REG_GPPUD(GPIO_BASE) = 0; + rt_thread_mdelay(150); + + GPIO_REG_GPPUDCLK0(GPIO_BASE) = 0xffffffff; + GPIO_REG_GPPUDCLK1(GPIO_BASE) = 0xffffffff; + rt_thread_mdelay(150); + + /* flush GPIO setup */ + GPIO_REG_GPPUDCLK0(GPIO_BASE) = 0; + GPIO_REG_GPPUDCLK1(GPIO_BASE) = 0; + + /* power off the SoC (GPU + CPU), partition 63 used to indicate halt */ + r = PM_RSTS; + r &= ~0xfffffaaa; + r |= 0x555; + PM_RSTS |= PM_PASSWORD | r; + PM_WDOG |= PM_PASSWORD | 0x0A; + PM_RSTC |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET; + + while (1) {}; +} +MSH_CMD_EXPORT(poweroff, poweroff...); + void reboot(void) { unsigned int r; diff --git a/bsp/raspberry-pi/raspi4-64/driver/mbox.c b/bsp/raspberry-pi/raspi4-64/driver/mbox.c index 6d1c276d78..c497c6365f 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/mbox.c +++ b/bsp/raspberry-pi/raspi4-64/driver/mbox.c @@ -53,6 +53,24 @@ int mbox_call(unsigned char ch, int mmu_enable) return 0; } +int bcm271x_mbox_poweroff_devices(int id) +{ + mbox[0] = 8 * 4; /* length of the message */ + mbox[1] = MBOX_REQUEST; /* this is a request message */ + + mbox[2] = MBOX_TAG_SETPOWER; /* set power state */ + mbox[3] = 8; /* buffer size */ + mbox[4] = 8; /* len */ + + mbox[5] = (unsigned int)id; /* device id */ + mbox[6] = 0; /* bit 0: off, bit 1: no wait */ + + mbox[7] = MBOX_TAG_LAST; + mbox_call(8, MBOX_CH_PROP); + + return 0; +} + int bcm271x_mbox_get_touch(void) { mbox[0] = 8 * 4; // length of the message diff --git a/bsp/raspberry-pi/raspi4-64/driver/mbox.h b/bsp/raspberry-pi/raspi4-64/driver/mbox.h index c13170afba..c3c73c339f 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/mbox.h +++ b/bsp/raspberry-pi/raspi4-64/driver/mbox.h @@ -161,6 +161,7 @@ enum #define PWM_CLK_ID (0x00000000a) int mbox_call(unsigned char ch, int mmu_enable); +int bcm271x_mbox_poweroff_devices(int id); int bcm271x_mbox_get_touch(void); int bcm271x_notify_reboot(void); int bcm271x_notify_xhci_reset(void); diff --git a/bsp/raspberry-pi/raspi4-64/rtconfig.h b/bsp/raspberry-pi/raspi4-64/rtconfig.h index 3091cbfa2e..9d7fa35137 100644 --- a/bsp/raspberry-pi/raspi4-64/rtconfig.h +++ b/bsp/raspberry-pi/raspi4-64/rtconfig.h @@ -56,14 +56,8 @@ #define RT_USING_USER_MAIN #define RT_MAIN_THREAD_STACK_SIZE 4096 #define RT_MAIN_THREAD_PRIORITY 10 - -/* C++ features */ - - -/* Command shell */ - -#define RT_USING_FINSH #define RT_USING_MSH +#define RT_USING_FINSH #define FINSH_USING_MSH #define FINSH_THREAD_NAME "tshell" #define FINSH_THREAD_PRIORITY 20 @@ -75,9 +69,6 @@ #define MSH_USING_BUILT_IN_COMMANDS #define FINSH_USING_DESCRIPTION #define FINSH_ARG_MAX 10 - -/* Device virtual file system */ - #define RT_USING_DFS #define DFS_USING_POSIX #define DFS_USING_WORKDIR @@ -125,7 +116,7 @@ /* Using USB */ -/* POSIX layer and C standard library */ +/* C/C++ and POSIX layer */ #define RT_LIBC_DEFAULT_TIMEZONE 8 @@ -137,9 +128,8 @@ /* Socket is in the 'Network' category */ -/* Network */ -/* Socket abstraction layer */ +/* Network */ #define RT_USING_SAL #define SAL_INTERNET_CHECK @@ -148,9 +138,6 @@ #define SAL_USING_LWIP #define SAL_SOCKETS_NUM 16 - -/* Network interface device */ - #define RT_USING_NETDEV #define NETDEV_USING_IFCONFIG #define NETDEV_USING_PING @@ -158,11 +145,9 @@ #define NETDEV_USING_AUTO_DEFAULT #define NETDEV_IPV4 1 #define NETDEV_IPV6 0 - -/* light weight TCP/IP stack */ - #define RT_USING_LWIP #define RT_USING_LWIP203 +#define RT_USING_LWIP_VER_NUM 0x20003 #define RT_LWIP_MEM_ALIGNMENT 4 #define RT_LWIP_IGMP #define RT_LWIP_ICMP @@ -203,12 +188,6 @@ #define LWIP_NETIF_LOOPBACK 0 #define RT_LWIP_USING_PING -/* AT commands */ - - -/* VBUS(Virtual Software BUS) */ - - /* Utilities */ #define RT_USING_RYM @@ -278,6 +257,8 @@ /* miscellaneous packages */ +/* project laboratory */ + /* samples: kernel and components samples */ @@ -292,6 +273,7 @@ #define BSP_USING_UART #define RT_USING_UART0 #define BSP_USING_GIC +#define BSP_USING_GICV2 #define BSP_USING_PIN #define BSP_USING_CORETIMER #define BSP_USING_WDT diff --git a/bsp/rockchip/rk3568/.config b/bsp/rockchip/rk3568/.config new file mode 100644 index 0000000000..cdd09053ce --- /dev/null +++ b/bsp/rockchip/rk3568/.config @@ -0,0 +1,653 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 + +# +# kservice optimization +# +# CONFIG_RT_KSERVICE_USING_STDLIB is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +# CONFIG_RT_PRINTF_LONGLONG is not set +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BSET_MODE is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_MEMTRACE=y +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +CONFIG_RT_USING_DEVICE_OPS=y +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart2" +CONFIG_RT_VER_NUM=0x40100 +CONFIG_ARCH_CPU_64BIT=y +# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_ARCH_ARMV8=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 +# CONFIG_RT_USING_DFS is not set +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +# CONFIG_RT_USING_POSIX_FS is not set +# CONFIG_RT_USING_POSIX_DELAY is not set +# CONFIG_RT_USING_POSIX_CLOCK is not set +# CONFIG_RT_USING_POSIX_TIMER is not set +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set + +# +# PainterEngine: A cross-platform graphics application framework written in C language +# +# CONFIG_PKG_USING_PAINTERENGINE is not set +# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ULOG_FILE is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# POSIX extension functions +# +# CONFIG_PKG_USING_POSIX_GETLINE is not set +# CONFIG_PKG_USING_POSIX_WCWIDTH is not set +# CONFIG_PKG_USING_POSIX_ITOA is not set +# CONFIG_PKG_USING_POSIX_STRINGS is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_RT_USING_ARDUINO is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_BL_MCU_SDK is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_RFM300 is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_UKAL is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +CONFIG_SOC_RK3568=y + +# +# Hardware Drivers Config +# +CONFIG_BSP_USING_UART=y +# CONFIG_RT_USING_UART0 is not set +# CONFIG_RT_USING_UART1 is not set +CONFIG_RT_USING_UART2=y +# CONFIG_RT_USING_UART3 is not set +# CONFIG_RT_USING_UART4 is not set +# CONFIG_RT_USING_UART5 is not set +# CONFIG_RT_USING_UART6 is not set +# CONFIG_RT_USING_UART7 is not set +# CONFIG_RT_USING_UART8 is not set +# CONFIG_RT_USING_UART9 is not set +CONFIG_BSP_USING_GIC=y +CONFIG_BSP_USING_GICV3=y diff --git a/bsp/rockchip/rk3568/Kconfig b/bsp/rockchip/rk3568/Kconfig new file mode 100644 index 0000000000..b784130e0a --- /dev/null +++ b/bsp/rockchip/rk3568/Kconfig @@ -0,0 +1,29 @@ +mainmenu "RT-Thread Project Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" + +config SOC_RK3568 + bool + select ARCH_ARMV8 + select ARCH_CPU_64BIT + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +source "$BSP_DIR/driver/Kconfig" diff --git a/bsp/rockchip/rk3568/README.md b/bsp/rockchip/rk3568/README.md new file mode 100644 index 0000000000..6522e5a738 --- /dev/null +++ b/bsp/rockchip/rk3568/README.md @@ -0,0 +1,55 @@ +# RK3568 BSP Introduction + +[中文页](README_zh.md) | English + +## 1. Introduction + +RK3568 is a general-purpose SOC, quad-core 64-bit Cortex-A55 processor, with 22nm lithography process, has frequency up to 2.0GHz and Mali G52 GPU, support 4K decoding and 1080P encoding. Support mangy interfaces such as SATA/PCIE/USB3.0, an 0.8T NPU for lightweight AI applications. Support dual Gigabit Ethernet ports, LPDDR4 memory, etc. + +This project ported RT-Thread on RK3568, you can use the RADXA ROCK 3A version of the RK3568 in low-priced, which can even replace the Raspberry Pi 4B. + +## 2. Compiling + +Usage ARM Developer GNU ToolChain, it support Linux and Windows: +``` +https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/ +``` +Download the `xxx-aarch64-none-elf` of x86_64 hosted platform, set the `RTT_EXEC_PATH` is system environment after decompress the binary. + +Enter directory `rt-thread/bsp/qemu-virt64-aarch64` and input: +``` +scons +``` + +## 3. Execution + +RK3568 has different Kernel install methods according to different boardsit, recommend to install into the SD card: ([Official](https://wiki.t-firefly.com/en/ROC-RK3568-PC/hardware_doc.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/install/microSD)). + +After install Kernel, storage the `rtthread.bin` to EFI partition (the second partition), and add this line in the front of `boot.cmd` in this partition: +```shell +fatload mmc 1:1 0x208000 /rtthread.bin;dcache flush;go 0x208000 +``` +After modifying the script, build a binary script `boot.scr ` in this partition: +```shell +# Install the uboot-mkimage package on Linux, or use MSYS2 to install the u-boot-tools package on Windows +mkimage -C none -A arm -T script -d boot.cmd boot.scr +``` + +According to different boards, the serial port can support up to UART0~9, this project uses UART2 ([Official](https://wiki.t-firefly.com/en/ROC-RK3568-PC/debug.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/dev/serial-console)) by default, the baud rate is 1500000, please make sure that the serial port used supports this baud rate. + +``` +heap: [0x002663f0 - 0x042663f0] + + \ | / +- RT - Thread Operating System + / | \ 4.1.0 build Mar 19 2022 17:17:29 + 2006 - 2022 Copyright by RT-Thread team +Hi, this is RT-Thread!! +msh /> +``` + +## 4. Condition + +| Driver | Condition | Remark | +| ------ | --------- | ------ | +| UART | Support | UART0~9 | diff --git a/bsp/rockchip/rk3568/README_zh.md b/bsp/rockchip/rk3568/README_zh.md new file mode 100644 index 0000000000..e4ed2bf4a6 --- /dev/null +++ b/bsp/rockchip/rk3568/README_zh.md @@ -0,0 +1,56 @@ +# RK3568 板级支持包说明 + +中文页 | [English](README.md) + +## 1. 简介 + +RK3568 是一款定位中高端的通用型 SOC,采用 22nm 制程工艺,集成四核 2GHz,Cortex-A55 架构和 Mali G52 GPU,支持 4K 解码和 1080P 编码。支持 SATA/PCIE/USB3.0 等各类型外围接口,内置独立的 0.8T NPU,可用于轻量级 AI 应用。支持双千兆以太网口,LPDDR4 内存等。 + +这份 RT-Thread BSP是针对 RK3568 的一份移植。开发者可选择使用 RADXA ROCK 3A 版本的 RK3568 廉价体验,其甚至可超量替代树莓派4B。 + +## 2. 编译说明 + +建议使用ARM Developer GNU交叉编译工具链,目前支持Linux/Windows平台: +``` +https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/ +``` +下载x86_64 Hosted平台下载对应的`xxx-aarch64-none-elf`二进制包,解压后设置`RTT_EXEC_PATH`环境变量为该编译器的bin目录下即可。 + +进入到`rt-thread/bsp/rockchip/rk3568`目录进行输入: +``` +scons +``` +可以看到正常生成`rtthread.elf`与`rtthread.bin`文件。 + +## 3. 执行 + +RK3568 根据不同的开发板实现有不同的 Kernel 烧写方式,推荐烧录进 SD 卡:([官方板](https://wiki.t-firefly.com/zh_CN/ROC-RK3568-PC/hardware_doc.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/install/microSD))。 + +在烧写完 Kernel 后,将`rtthread.bin`放入 EFI 分区(第二分区),并在该分区的`boot.cmd`最前面中添加如下行: +```shell +fatload mmc 1:1 0x208000 /rtthread.bin;dcache flush;go 0x208000 +``` +修改脚本后,在该分区生成二进制脚本`boot.scr`: +```shell +# Linux 下安装 uboot-mkimage 软件包,Windows 下使用 MSYS2 安装 u-boot-tools 软件包 +mkimage -C none -A arm -T script -d boot.cmd boot.scr +``` + +根据不同的开发板实现串口最多可支持到 UART0~9,本工程默认使用 UART2([官方板](https://wiki.t-firefly.com/zh_CN/ROC-RK3568-PC/debug.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/dev/serial-console)),波特率 1500000,请确保使用的串口支持该波特率。 + +``` +heap: [0x002663f0 - 0x042663f0] + + \ | / +- RT - Thread Operating System + / | \ 4.1.0 build Mar 19 2022 17:17:29 + 2006 - 2022 Copyright by RT-Thread team +Hi, this is RT-Thread!! +msh /> +``` + +## 4.支持情况 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | UART0~9 | diff --git a/bsp/rockchip/rk3568/SConscript b/bsp/rockchip/rk3568/SConscript new file mode 100644 index 0000000000..744d8d7821 --- /dev/null +++ b/bsp/rockchip/rk3568/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/rockchip/rk3568/SConstruct b/bsp/rockchip/rk3568/SConstruct new file mode 100644 index 0000000000..ec6fe0187f --- /dev/null +++ b/bsp/rockchip/rk3568/SConstruct @@ -0,0 +1,29 @@ +import os +import sys +import rtconfig + +from rtconfig import RTT_ROOT + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/rockchip/rk3568/applications/SConscript b/bsp/rockchip/rk3568/applications/SConscript new file mode 100644 index 0000000000..c583d3016e --- /dev/null +++ b/bsp/rockchip/rk3568/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/rk3568/applications/main.c b/bsp/rockchip/rk3568/applications/main.c new file mode 100644 index 0000000000..780e49d091 --- /dev/null +++ b/bsp/rockchip/rk3568/applications/main.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + +#include + +int main(int argc, char** argv) +{ + rt_kprintf("Hi, this is RT-Thread!!\n"); + + return 0; +} diff --git a/bsp/rockchip/rk3568/driver/Kconfig b/bsp/rockchip/rk3568/driver/Kconfig new file mode 100644 index 0000000000..55041eba5b --- /dev/null +++ b/bsp/rockchip/rk3568/driver/Kconfig @@ -0,0 +1,58 @@ +menu "Hardware Drivers Config" + + menuconfig BSP_USING_UART + bool "Using UART" + select RT_USING_SERIAL + default y + + if BSP_USING_UART + config RT_USING_UART0 + bool "Enable UART 0" + default n + + config RT_USING_UART1 + bool "Enable UART 1" + default n + + config RT_USING_UART2 + bool "Enable UART 2" + default y + + config RT_USING_UART3 + bool "Enable UART 3" + default n + + config RT_USING_UART4 + bool "Enable UART 4" + default n + + config RT_USING_UART5 + bool "Enable UART 5" + default n + + config RT_USING_UART6 + bool "Enable UART 6" + default n + + config RT_USING_UART7 + bool "Enable UART 7" + default n + + config RT_USING_UART8 + bool "Enable UART 8" + default n + + config RT_USING_UART9 + bool "Enable UART 9" + default n + endif + + config BSP_USING_GIC + bool + default y + + config BSP_USING_GICV3 + bool + default y + +endmenu diff --git a/bsp/rockchip/rk3568/driver/SConscript b/bsp/rockchip/rk3568/driver/SConscript new file mode 100644 index 0000000000..17f80c100b --- /dev/null +++ b/bsp/rockchip/rk3568/driver/SConscript @@ -0,0 +1,19 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +list = os.listdir(cwd) +CPPPATH = [cwd] +objs = [] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) +objs = objs + group + +Return('objs') diff --git a/bsp/rockchip/rk3568/driver/board.c b/bsp/rockchip/rk3568/driver/board.c new file mode 100644 index 0000000000..42e112745d --- /dev/null +++ b/bsp/rockchip/rk3568/driver/board.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +struct mem_desc platform_mem_desc[] = +{ + {0x200000, 0x80000000, 0x200000, NORMAL_MEM}, + {UART0_MMIO_BASE, UART0_MMIO_BASE + 0x10000, UART0_MMIO_BASE, DEVICE_MEM}, + {UART1_MMIO_BASE, UART1_MMIO_BASE + 0x90000, UART1_MMIO_BASE, DEVICE_MEM}, + {GIC_PL600_DISTRIBUTOR_PPTR, GIC_PL600_DISTRIBUTOR_PPTR + 0x10000, GIC_PL600_DISTRIBUTOR_PPTR, DEVICE_MEM}, + {GIC_PL600_REDISTRIBUTOR_PPTR, GIC_PL600_REDISTRIBUTOR_PPTR + 0xc0000, GIC_PL600_REDISTRIBUTOR_PPTR, DEVICE_MEM}, +}; + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]); + +void idle_wfi(void) +{ + __asm__ volatile ("wfi"); +} + +void rt_hw_board_init(void) +{ + rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size); + rt_hw_mmu_init(); + + /* initialize hardware interrupt */ + rt_hw_interrupt_init(); + /* initialize uart */ + rt_hw_uart_init(); + /* initialize timer for os tick */ + rt_hw_gtimer_init(); + + rt_thread_idle_sethook(idle_wfi); + + arm_psci_init(PSCI_METHOD_SMC, RT_NULL, RT_NULL); + +#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE) + /* set console device */ + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef RT_USING_HEAP + /* initialize memory system */ + rt_kprintf("heap: [0x%08x - 0x%08x]\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); + rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#ifdef RT_USING_SMP + /* install IPI handle */ + rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler); + arm_gic_umask(0, IRQ_ARM_IPI_KICK); +#endif +} + +void reboot(void) +{ + arm_psci_system_reboot(); +} +MSH_CMD_EXPORT(reboot, reboot...); + +#ifdef RT_USING_SMP +rt_uint64_t rt_cpu_mpidr_early[] = +{ + [0] = 0x81000000, + [1] = 0x81000100, + [2] = 0x81000200, + [3] = 0x81000300, +}; + +void rt_hw_secondary_cpu_up(void) +{ + int i; + extern void secondary_cpu_start(void); + + for (i = 1; i < RT_CPUS_NR; ++i) + { + arm_psci_cpu_on(rt_cpu_mpidr_early[i], (rt_uint64_t)secondary_cpu_start); + } +} + +void secondary_cpu_c_start(void) +{ + rt_hw_mmu_init(); + rt_hw_spin_lock(&_cpus_lock); + + arm_gic_cpu_init(0, platform_get_gic_cpu_base()); + arm_gic_redist_init(0, platform_get_gic_redist_base()); + rt_hw_vector_init(); + rt_hw_gtimer_local_enable(); + arm_gic_umask(0, IRQ_ARM_IPI_KICK); + + rt_kprintf("\rcall cpu %d on success\n", rt_hw_cpu_id()); + + rt_system_scheduler_start(); +} + +void rt_hw_secondary_cpu_idle_exec(void) +{ + __WFE(); +} +#endif diff --git a/bsp/rockchip/rk3568/driver/board.h b/bsp/rockchip/rk3568/driver/board.h new file mode 100644 index 0000000000..d2900cf405 --- /dev/null +++ b/bsp/rockchip/rk3568/driver/board.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +extern unsigned char __bss_start; +extern unsigned char __bss_end; + +#define RT_HW_HEAP_BEGIN (void *)&__bss_end +#define RT_HW_HEAP_END (void *)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024) + +void rt_hw_board_init(void); + +#endif /* __BOARD_H__ */ diff --git a/bsp/rockchip/rk3568/driver/drv_uart.c b/bsp/rockchip/rk3568/driver/drv_uart.c new file mode 100644 index 0000000000..477c2f077d --- /dev/null +++ b/bsp/rockchip/rk3568/driver/drv_uart.c @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include +#include + +#include + +/* + * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the + * LCR is written whilst busy. If it is, then a busy detect interrupt is + * raised, the LCR needs to be rewritten and the uart status register read. + */ + +#define UART_RX 0 /* In: Receive buffer */ +#define UART_TX 0 /* Out: Transmit buffer */ + +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ + +#define UART_IER 1 /* Out: Interrupt Enable Register */ +#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ + +#define UART_SSR 0x22 /* In: Software Reset Register */ +#define UART_USR 0x1f /* UART Status Register */ + +#define UART_LCR 3 /* Out: Line Control Register */ +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ +#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ +#define UART_LCR_PARITY 0x8 /* Parity Enable */ +#define UART_LCR_STOP 0x4 /* Stop bits: 0=1 bit, 1=2 bits */ +#define UART_LCR_WLEN8 0x3 /* Wordlength: 8 bits */ + +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_MCR_RTS 0x02 /* RTS complement */ + +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_BI 0x10 /* Break interrupt indicator */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ + +#define UART_IIR 2 /* In: Interrupt ID Register */ +#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ +#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ +#define UART_IIR_RX_TIMEOUT 0x0c /* OMAP RX Timeout interrupt */ + +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_FCR_EN_FIFO 0x01 /* Enable the FIFO */ +#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ +#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ + +#define UART_REG_SHIFT 0x2 /* Register Shift*/ +#define UART_INPUT_CLK 24000000 + +struct hw_uart_device +{ + rt_ubase_t hw_base; + rt_uint32_t irqno; +#ifdef RT_USING_SMP + struct rt_spinlock spinlock; +#endif +}; + +#define BSP_DEFINE_UART_DEVICE(no) \ +static struct hw_uart_device _uart##no##_device = \ +{ \ + UART##no##_MMIO_BASE, \ + UART##no##_IRQ \ +}; \ +static struct rt_serial_device _serial##no; + +#ifdef RT_USING_UART0 +BSP_DEFINE_UART_DEVICE(0); +#endif + +#ifdef RT_USING_UART1 +BSP_DEFINE_UART_DEVICE(1); +#endif + +#ifdef RT_USING_UART2 +BSP_DEFINE_UART_DEVICE(2); +#endif + +#ifdef RT_USING_UART3 +BSP_DEFINE_UART_DEVICE(3); +#endif + +#ifdef RT_USING_UART4 +BSP_DEFINE_UART_DEVICE(4); +#endif + +#ifdef RT_USING_UART5 +BSP_DEFINE_UART_DEVICE(5); +#endif + +#ifdef RT_USING_UART6 +BSP_DEFINE_UART_DEVICE(6); +#endif + +#ifdef RT_USING_UART7 +BSP_DEFINE_UART_DEVICE(7); +#endif + +#ifdef RT_USING_UART8 +BSP_DEFINE_UART_DEVICE(8); +#endif + +#ifdef RT_USING_UART9 +BSP_DEFINE_UART_DEVICE(9); +#endif + +rt_inline rt_uint32_t dw8250_read32(rt_ubase_t addr, rt_ubase_t offset) +{ + return *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))); +} + +rt_inline void dw8250_write32(rt_ubase_t addr, rt_ubase_t offset, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))) = value; + + if (offset == UART_LCR) + { + int tries = 1000; + + /* Make sure LCR write wasn't ignored */ + while (tries--) + { + unsigned int lcr = dw8250_read32(addr, UART_LCR); + + if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) + { + return; + } + + dw8250_write32(addr, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + dw8250_read32(addr, UART_RX); + + *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))) = value; + } + } +} + +static rt_err_t dw8250_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + rt_base_t base, rate; + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + base = uart->hw_base; + +#ifdef RT_USING_SMP + rt_spin_lock_init(&uart->spinlock); +#endif + + /* Resset UART */ + dw8250_write32(base, UART_SSR, 1); + dw8250_write32(base, UART_SSR, 0); + + dw8250_write32(base, UART_IER, !UART_IER_RDI); + dw8250_write32(base, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + + /* Disable flow ctrl */ + dw8250_write32(base, UART_MCR, 0); + /* Clear RTS */ + dw8250_write32(base, UART_MCR, dw8250_read32(base, UART_MCR) | UART_MCR_RTS); + + rate = UART_INPUT_CLK / 16 / serial->config.baud_rate; + + /* Enable access DLL & DLH */ + dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) | UART_LCR_DLAB); + dw8250_write32(base, UART_DLL, (rate & 0xff)); + dw8250_write32(base, UART_DLM, (rate & 0xff00) >> 8); + /* Clear DLAB bit */ + dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_DLAB)); + + dw8250_write32(base, UART_LCR, (dw8250_read32(base, UART_LCR) & (~UART_LCR_WLEN8)) | UART_LCR_WLEN8); + dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_STOP)); + dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_PARITY)); + + dw8250_write32(base, UART_IER, UART_IER_RDI); + + return RT_EOK; +} + +static rt_err_t dw8250_uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* Disable rx irq */ + dw8250_write32(uart->hw_base, UART_IER, !UART_IER_RDI); + rt_hw_interrupt_mask(uart->irqno); + break; + + case RT_DEVICE_CTRL_SET_INT: + /* Enable rx irq */ + dw8250_write32(uart->hw_base, UART_IER, UART_IER_RDI); + rt_hw_interrupt_umask(uart->irqno); + break; + } + + return RT_EOK; +} + +static int dw8250_uart_putc(struct rt_serial_device *serial, char c) +{ + rt_base_t base; + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + base = uart->hw_base; + + while ((dw8250_read32(base, UART_USR) & 0x2) == 0) + { + } + + dw8250_write32(base, UART_TX, c); + + return 1; +} + +static int dw8250_uart_getc(struct rt_serial_device *serial) +{ + int ch = -1; + rt_base_t base; + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + base = uart->hw_base; + + if ((dw8250_read32(base, UART_LSR) & 0x1)) + { + ch = dw8250_read32(base, UART_RX) & 0xff; + } + + return ch; +} + +static const struct rt_uart_ops _uart_ops = +{ + dw8250_uart_configure, + dw8250_uart_control, + dw8250_uart_putc, + dw8250_uart_getc, +}; + +static void rt_hw_uart_isr(int irqno, void *param) +{ + unsigned int iir, status; + struct rt_serial_device *serial = (struct rt_serial_device *)param; + struct hw_uart_device *uart = (struct hw_uart_device *)serial->parent.user_data; + + iir = dw8250_read32(uart->hw_base, UART_IIR); + + /* If don't do this in non-DMA mode then the "RX TIMEOUT" interrupt will fire forever. */ + if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) + { +#ifdef RT_USING_SMP + rt_base_t level = rt_spin_lock_irqsave(&uart->spinlock); +#endif + + status = dw8250_read32(uart->hw_base, UART_LSR); + + if (!(status & (UART_LSR_DR | UART_LSR_BI))) + { + dw8250_read32(uart->hw_base, UART_RX); + } + +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&uart->spinlock, level); +#endif + } + + if (!(iir & UART_IIR_NO_INT)) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + } + + if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) + { + /* Clear the USR */ + dw8250_read32(uart->hw_base, UART_USR); + + return; + } +} + +int rt_hw_uart_init(void) +{ + struct hw_uart_device *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + config.baud_rate = 1500000; + +#define BSP_INSTALL_UART_DEVICE(no) \ + uart = &_uart##no##_device; \ + _serial##no.ops = &_uart_ops; \ + _serial##no.config = config; \ + rt_hw_serial_register(&_serial##no, "uart" #no, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); \ + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial##no, "uart" #no); + +#ifdef RT_USING_UART0 + BSP_INSTALL_UART_DEVICE(0); +#endif + +#ifdef RT_USING_UART1 + BSP_INSTALL_UART_DEVICE(1); +#endif + +#ifdef RT_USING_UART2 + BSP_INSTALL_UART_DEVICE(2); +#endif + +#ifdef RT_USING_UART3 + BSP_INSTALL_UART_DEVICE(3); +#endif + +#ifdef RT_USING_UART4 + BSP_INSTALL_UART_DEVICE(4); +#endif + +#ifdef RT_USING_UART5 + BSP_INSTALL_UART_DEVICE(5); +#endif + +#ifdef RT_USING_UART6 + BSP_INSTALL_UART_DEVICE(6); +#endif + +#ifdef RT_USING_UART7 + BSP_INSTALL_UART_DEVICE(7); +#endif + +#ifdef RT_USING_UART8 + BSP_INSTALL_UART_DEVICE(8); +#endif + +#ifdef RT_USING_UART9 + BSP_INSTALL_UART_DEVICE(9); +#endif + + return 0; +} diff --git a/bsp/rockchip/rk3568/driver/drv_uart.h b/bsp/rockchip/rk3568/driver/drv_uart.h new file mode 100644 index 0000000000..acc6ac0ea4 --- /dev/null +++ b/bsp/rockchip/rk3568/driver/drv_uart.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __DRV_UART_H__ +#define __DRV_UART_H__ + +int rt_hw_uart_init(void); + +#endif /* __DRV_UART_H__ */ diff --git a/bsp/rockchip/rk3568/driver/rk3568.h b/bsp/rockchip/rk3568/driver/rk3568.h new file mode 100644 index 0000000000..f248463323 --- /dev/null +++ b/bsp/rockchip/rk3568/driver/rk3568.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __RK3568_H__ +#define __RK3568_H__ + +/* UART */ +#define UART_MMIO_BASE 0xfe650000 +#define UART0_MMIO_BASE 0xfdd50000 +#define UART1_MMIO_BASE (UART_MMIO_BASE + 0) +#define UART2_MMIO_BASE (UART_MMIO_BASE + 0x10000) +#define UART3_MMIO_BASE (UART_MMIO_BASE + 0x20000) +#define UART4_MMIO_BASE (UART_MMIO_BASE + 0x30000) +#define UART5_MMIO_BASE (UART_MMIO_BASE + 0x40000) +#define UART6_MMIO_BASE (UART_MMIO_BASE + 0x50000) +#define UART7_MMIO_BASE (UART_MMIO_BASE + 0x60000) +#define UART8_MMIO_BASE (UART_MMIO_BASE + 0x70000) +#define UART9_MMIO_BASE (UART_MMIO_BASE + 0x80000) + +#define UART_MMIO_SIZE 0x100 + +#define UART_IRQ_BASE (32 + 116) +#define UART0_IRQ (UART_IRQ_BASE + 0) +#define UART1_IRQ (UART_IRQ_BASE + 1) +#define UART2_IRQ (UART_IRQ_BASE + 2) +#define UART3_IRQ (UART_IRQ_BASE + 3) +#define UART4_IRQ (UART_IRQ_BASE + 4) +#define UART5_IRQ (UART_IRQ_BASE + 5) +#define UART6_IRQ (UART_IRQ_BASE + 6) +#define UART7_IRQ (UART_IRQ_BASE + 7) +#define UART8_IRQ (UART_IRQ_BASE + 8) +#define UART9_IRQ (UART_IRQ_BASE + 9) + +/* GPIO */ +#define GPIO0_MMIO_BASE 0xfdd60000 +#define GPIO1_MMIO_BASE 0xfe740000 +#define GPIO2_MMIO_BASE 0xfe750000 +#define GPIO3_MMIO_BASE 0xfe760000 +#define GPIO4_MMIO_BASE 0xfe770000 + +#define GPIO_MMIO_SIZE 0x100 + +#define GPIO_IRQ_BASE (32 + 33) +#define GPIO0_IRQ (GPIO_IRQ_BASE + 0) +#define GPIO1_IRQ (GPIO_IRQ_BASE + 1) +#define GPIO2_IRQ (GPIO_IRQ_BASE + 2) +#define GPIO3_IRQ (GPIO_IRQ_BASE + 3) +#define GPIO4_IRQ (GPIO_IRQ_BASE + 4) + +/* MMC */ +#define MMC0_MMIO_BASE 0xfe310000 /* sdhci */ +#define MMC1_MMIO_BASE 0xfe2b0000 /* sdmmc0 */ +#define MMC2_MMIO_BASE 0xfe2c0000 /* sdmmc1 */ +#define MMC3_MMIO_BASE 0xfe000000 /* sdmmc2 */ + +#define MMC0_MMIO_SIZE 0x10000 +#define MMC_MMIO_SIZE 0x4000 + +#define MMC0_IRQ (32 + 19) +#define MMC1_IRQ (32 + 98) +#define MMC2_IRQ (32 + 99) +#define MMC3_IRQ (32 + 100) + +/* Ethernet */ +#define GMAC0_MMIO_BASE 0xfe2a0000 +#define GMAC1_MMIO_BASE 0xfe010000 + +#define GMAC_MMIO_SIZE 0x10000 + +#define GMAC0_MAC_IRQ (32 + 27) +#define GMAC0_WAKE_IRQ (32 + 24) +#define GMAC1_MAC_IRQ (32 + 32) +#define GMAC1_WAKE_IRQ (32 + 29) + +/* GIC */ +#define MAX_HANDLERS 256 +#define GIC_IRQ_START 0 +#define ARM_GIC_NR_IRQS 256 +#define ARM_GIC_MAX_NR 1 + +#define IRQ_ARM_IPI_KICK 0 +#define IRQ_ARM_IPI_CALL 1 + +#define GIC_PL600_DISTRIBUTOR_PPTR 0xfd400000 +#define GIC_PL600_REDISTRIBUTOR_PPTR 0xfd460000 +#define GIC_PL600_CONTROLLER_PPTR RT_NULL +#define GIC_PL600_ITS_PPTR 0xfd440000 + +rt_inline rt_uint32_t platform_get_gic_dist_base(void) +{ + return GIC_PL600_DISTRIBUTOR_PPTR; +} + +rt_inline rt_uint32_t platform_get_gic_redist_base(void) +{ + return GIC_PL600_REDISTRIBUTOR_PPTR; +} + +rt_inline rt_uint32_t platform_get_gic_cpu_base(void) +{ + return GIC_PL600_CONTROLLER_PPTR; +} + +rt_inline rt_uint32_t platform_get_gic_its_base(void) +{ + return GIC_PL600_ITS_PPTR; +} + +#endif /* __RK3568_H__ */ diff --git a/bsp/rockchip/rk3568/link.lds b/bsp/rockchip/rk3568/link.lds new file mode 100644 index 0000000000..406e8c4a6c --- /dev/null +++ b/bsp/rockchip/rk3568/link.lds @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 bernard first version + */ + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) + +SECTIONS +{ + . = 0x208000; + . = ALIGN(4096); + .text : + { + KEEP(*(.text.entrypoint)) /* The entry point */ + *(.vectors) + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + *(COMMON) + + /* section information for finsh shell */ + . = ALIGN(16); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(16); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(16); + + /* section information for initial. */ + . = ALIGN(16); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(16); + + . = ALIGN(16); + _etext = .; + } + + .eh_frame_hdr : + { + *(.eh_frame_hdr) + *(.eh_frame_entry) + } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + + . = ALIGN(16); + .data : + { + *(.data) + *(.data.*) + + *(.data1) + *(.data1.*) + + . = ALIGN(16); + _gp = ABSOLUTE(.); /* Base of small data */ + + *(.sdata) + *(.sdata.*) + } + + . = ALIGN(16); + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } + + . = ALIGN(16); + .bss : + { + PROVIDE(__bss_start = .); + *(.bss) + *(.bss.*) + *(.dynbss) + + . = ALIGN(16); + PROVIDE(__bss_end = .); + } + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} + +__bss_size = SIZEOF(.bss); diff --git a/bsp/rockchip/rk3568/rtconfig.h b/bsp/rockchip/rk3568/rtconfig.h new file mode 100644 index 0000000000..5b3909cd14 --- /dev/null +++ b/bsp/rockchip/rk3568/rtconfig.h @@ -0,0 +1,188 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 4096 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 4096 + +/* kservice optimization */ + +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_MEMHEAP +#define RT_MEMHEAP_FAST_MODE +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_MEMTRACE +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_DEVICE_OPS +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart2" +#define RT_VER_NUM 0x40100 +#define ARCH_CPU_64BIT +#define ARCH_ARMV8 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_PIN + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* POSIX (Portable Operating System Interface) layer */ + + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* PainterEngine: A cross-platform graphics application framework written in C language */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* POSIX extension functions */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + + +/* AI packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + +#define SOC_RK3568 + +/* Hardware Drivers Config */ + +#define BSP_USING_UART +#define RT_USING_UART2 +#define BSP_USING_GIC +#define BSP_USING_GICV3 + +#endif diff --git a/bsp/rockchip/rk3568/rtconfig.py b/bsp/rockchip/rk3568/rtconfig.py new file mode 100644 index 0000000000..aad7072dbc --- /dev/null +++ b/bsp/rockchip/rk3568/rtconfig.py @@ -0,0 +1,53 @@ +import os + +# toolchains options +ARCH ='aarch64' +CPU ='cortex-a' +CROSS_TOOL ='gcc' + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.join(os.getcwd(), '..', '..', '..') + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +PLATFORM = 'gcc' +EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'aarch64-none-elf-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -g -march=armv8-a -mtune=cortex-a55' + CFLAGS = DEVICE + ' -Wall' + AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__' + LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + +DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' diff --git a/include/rthw.h b/include/rthw.h index 5672a8f992..bf497b4c3f 100644 --- a/include/rthw.h +++ b/include/rthw.h @@ -26,6 +26,9 @@ extern "C" { /* * Some macros define */ +#ifndef HWREG64 +#define HWREG64(x) (*((volatile rt_uint64_t *)(x))) +#endif #ifndef HWREG32 #define HWREG32(x) (*((volatile rt_uint32_t *)(x))) #endif diff --git a/libcpu/aarch64/common/SConscript b/libcpu/aarch64/common/SConscript index 915b9d29aa..72fb8e26c3 100644 --- a/libcpu/aarch64/common/SConscript +++ b/libcpu/aarch64/common/SConscript @@ -6,10 +6,6 @@ Import('rtconfig') cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') - -if not GetDepend('BSP_USING_GIC'): - SrcRemove(src, 'gic.c') - CPPPATH = [cwd] group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH) diff --git a/libcpu/aarch64/common/gic.c b/libcpu/aarch64/common/gic.c index 7a2c368d23..95a710c480 100644 --- a/libcpu/aarch64/common/gic.c +++ b/libcpu/aarch64/common/gic.c @@ -9,20 +9,25 @@ * 2014-04-03 Grissiom many enhancements * 2018-11-22 Jesven add rt_hw_ipi_send() * add rt_hw_ipi_handler_install() + * 2022-03-08 GuEe-GUI add BSP bind SPI CPU self support */ #include #include +#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) + #include #include +#include + struct arm_gic { rt_uint64_t offset; /* the first interrupt index in the vector table */ rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ - rt_uint64_t cpu_hw_base; /* the base addrees of the gic cpu interface */ + rt_uint64_t cpu_hw_base; /* the base address of the gic cpu interface */ }; /* 'ARM_GIC_MAX_NR' is the number of cores */ @@ -30,33 +35,33 @@ static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; /** Macro to access the Generic Interrupt Controller Interface (GICC) */ -#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00U) -#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04U) -#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08U) -#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0cU) -#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10U) -#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14U) -#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18U) -#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFCU) +#define GIC_CPU_CTRL(hw_base) HWREG32((hw_base) + 0x00U) +#define GIC_CPU_PRIMASK(hw_base) HWREG32((hw_base) + 0x04U) +#define GIC_CPU_BINPOINT(hw_base) HWREG32((hw_base) + 0x08U) +#define GIC_CPU_INTACK(hw_base) HWREG32((hw_base) + 0x0cU) +#define GIC_CPU_EOI(hw_base) HWREG32((hw_base) + 0x10U) +#define GIC_CPU_RUNNINGPRI(hw_base) HWREG32((hw_base) + 0x14U) +#define GIC_CPU_HIGHPRI(hw_base) HWREG32((hw_base) + 0x18U) +#define GIC_CPU_IIDR(hw_base) HWREG32((hw_base) + 0xFCU) /** Macro to access the Generic Interrupt Controller Distributor (GICD) */ -#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) -#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004U) -#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080U + ((n)/32U) * 4U) -#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100U + ((n)/32U) * 4U) -#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180U + ((n)/32U) * 4U) -#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200U + ((n)/32U) * 4U) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280U + ((n)/32U) * 4U) -#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300U + ((n)/32U) * 4U) -#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380U + ((n)/32U) * 4U) -#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400U + ((n)/4U) * 4U) -#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800U + ((n)/4U) * 4U) -#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U) -#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00U) -#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U) -#define GIC_DIST_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U) -#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8U) +#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) +#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U) +#define GIC_DIST_IGROUP(hw_base, n) HWREG32((hw_base) + 0x080U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_SET(hw_base, n) HWREG32((hw_base) + 0x100U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x180U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_SET(hw_base, n) HWREG32((hw_base) + 0x200U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) HWREG32((hw_base) + 0x280U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_SET(hw_base, n) HWREG32((hw_base) + 0x300U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x380U + ((n)/32U) * 4U) +#define GIC_DIST_PRI(hw_base, n) HWREG32((hw_base) + 0x400U + ((n)/4U) * 4U) +#define GIC_DIST_TARGET(hw_base, n) HWREG32((hw_base) + 0x800U + ((n)/4U) * 4U) +#define GIC_DIST_CONFIG(hw_base, n) HWREG32((hw_base) + 0xc00U + ((n)/16U) * 4U) +#define GIC_DIST_SOFTINT(hw_base) HWREG32((hw_base) + 0xf00U) +#define GIC_DIST_CPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf10U + ((n)/4U) * 4U) +#define GIC_DIST_SPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf20U + ((n)/4U) * 4U) +#define GIC_DIST_ICPIDR2(hw_base) HWREG32((hw_base) + 0xfe8U) static unsigned int _gic_max_irq; @@ -179,7 +184,7 @@ void arm_gic_clear_pending_irq(rt_uint64_t index, int irq) } } -void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config) +void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config) { rt_uint64_t icfgr; rt_uint64_t shift; @@ -323,6 +328,8 @@ void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_ui GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = ((filter_list & 0x3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (irq & 0x0FUL); + + __DSB(); } rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index) @@ -341,8 +348,8 @@ rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index) void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group) { - uint32_t igroupr; - uint32_t shift; + rt_uint32_t igroupr; + rt_uint32_t shift; RT_ASSERT(index < ARM_GIC_MAX_NR); RT_ASSERT(group <= 1U); @@ -373,6 +380,10 @@ int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start) unsigned int gic_type, i; rt_uint64_t cpumask = 1U << 0U; +#ifdef ARM_SPI_BIND_CPU_ID + cpumask = 1U << ARM_SPI_BIND_CPU_ID; +#endif + RT_ASSERT(index < ARM_GIC_MAX_NR); _gic_table[index].dist_hw_base = dist_base; @@ -502,3 +513,4 @@ long gic_dump(void) } MSH_CMD_EXPORT(gic_dump, show gic status); +#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) */ diff --git a/libcpu/aarch64/common/gic.h b/libcpu/aarch64/common/gic.h index 54ab2bda18..7ea0d6d3af 100644 --- a/libcpu/aarch64/common/gic.h +++ b/libcpu/aarch64/common/gic.h @@ -11,9 +11,9 @@ #ifndef __GIC_H__ #define __GIC_H__ -#include -#include -#include +#include + +#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) int arm_gic_get_active_irq(rt_uint64_t index); void arm_gic_ack(rt_uint64_t index, int irq); @@ -25,7 +25,7 @@ rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); void arm_gic_set_pending_irq(rt_uint64_t index, int irq); void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); -void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config); +void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config); rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); void arm_gic_clear_active(rt_uint64_t index, int irq); @@ -59,5 +59,7 @@ int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); void arm_gic_dump_type(rt_uint64_t index); void arm_gic_dump(rt_uint64_t index); +#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) */ + #endif diff --git a/libcpu/aarch64/common/gicv3.c b/libcpu/aarch64/common/gicv3.c new file mode 100644 index 0000000000..67010f1d57 --- /dev/null +++ b/libcpu/aarch64/common/gicv3.c @@ -0,0 +1,849 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2014-04-03 Grissiom many enhancements + * 2018-11-22 Jesven add rt_hw_ipi_send() + * add rt_hw_ipi_handler_install() + * 2022-03-08 GuEe-GUI add BSP bind SPI CPU self support + * add GICv3 AArch64 system register interface + * modify arm_gic_redist_init() args + * modify arm_gic_cpu_init() args + * modify arm_gic_send_affinity_sgi() args + * remove arm_gic_redist_address_set() + * remove arm_gic_cpu_interface_address_set() + * remove arm_gic_secondary_cpu_init() + * remove get_main_cpu_affval() + * remove arm_gic_cpumask_to_affval() + */ + +#include +#include + +#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) + +#include +#include + +#include + +#ifndef ARM_SPI_BIND_CPU_ID +#define ARM_SPI_BIND_CPU_ID 0 +#endif + +#ifndef RT_USING_SMP +#define RT_CPUS_NR 1 +extern int rt_hw_cpu_id(void); +#else +extern rt_uint64_t rt_cpu_mpidr_early[]; +#endif /* RT_USING_SMP */ + +struct arm_gic +{ + rt_uint64_t offset; /* the first interrupt index in the vector table */ + rt_uint64_t redist_hw_base[RT_CPUS_NR]; /* the pointer of the gic redistributor */ + rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ + rt_uint64_t cpu_hw_base[RT_CPUS_NR]; /* the base address of the gic cpu interface */ +}; + +/* 'ARM_GIC_MAX_NR' is the number of cores */ +static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; +static unsigned int _gic_max_irq; + +#define GET_GICV3_REG(reg, out) __asm__ volatile ("mrs %0, " reg:"=r"(out)::"memory"); +#define SET_GICV3_REG(reg, in) __asm__ volatile ("msr " reg ", %0"::"r"(in):"memory"); + +/* AArch64 System register interface to GICv3 */ +#define ICC_IAR0_EL1 "S3_0_C12_C8_0" +#define ICC_IAR1_EL1 "S3_0_C12_C12_0" +#define ICC_EOIR0_EL1 "S3_0_C12_C8_1" +#define ICC_EOIR1_EL1 "S3_0_C12_C12_1" +#define ICC_HPPIR0_EL1 "S3_0_C12_C8_2" +#define ICC_HPPIR1_EL1 "S3_0_C12_C12_2" +#define ICC_BPR0_EL1 "S3_0_C12_C8_3" +#define ICC_BPR1_EL1 "S3_0_C12_C12_3" +#define ICC_DIR_EL1 "S3_0_C12_C11_1" +#define ICC_PMR_EL1 "S3_0_C4_C6_0" +#define ICC_RPR_EL1 "S3_0_C12_C11_3" +#define ICC_CTLR_EL1 "S3_0_C12_C12_4" +#define ICC_CTLR_EL3 "S3_6_C12_C12_4" +#define ICC_SRE_EL1 "S3_0_C12_C12_5" +#define ICC_SRE_EL2 "S3_4_C12_C9_5" +#define ICC_SRE_EL3 "S3_6_C12_C12_5" +#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6" +#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7" +#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7" +#define ICC_SGI0R_EL1 "S3_0_C12_C11_7" +#define ICC_SGI1R_EL1 "S3_0_C12_C11_5" +#define ICC_ASGI1R_EL1 "S3_0_C12_C11_6" + +/* Macro to access the Distributor Control Register (GICD_CTLR) */ +#define GICD_CTLR_RWP (1 << 31) +#define GICD_CTLR_E1NWF (1 << 7) +#define GICD_CTLR_DS (1 << 6) +#define GICD_CTLR_ARE_NS (1 << 5) +#define GICD_CTLR_ARE_S (1 << 4) +#define GICD_CTLR_ENGRP1S (1 << 2) +#define GICD_CTLR_ENGRP1NS (1 << 1) +#define GICD_CTLR_ENGRP0 (1 << 0) + +/* Macro to access the Redistributor Control Register (GICR_CTLR) */ +#define GICR_CTLR_UWP (1 << 31) +#define GICR_CTLR_DPG1S (1 << 26) +#define GICR_CTLR_DPG1NS (1 << 25) +#define GICR_CTLR_DPG0 (1 << 24) +#define GICR_CTLR_RWP (1 << 3) +#define GICR_CTLR_IR (1 << 2) +#define GICR_CTLR_CES (1 << 1) +#define GICR_CTLR_EnableLPI (1 << 0) + +/* Macro to access the Generic Interrupt Controller Interface (GICC) */ +#define GIC_CPU_CTRL(hw_base) HWREG32((hw_base) + 0x00U) +#define GIC_CPU_PRIMASK(hw_base) HWREG32((hw_base) + 0x04U) +#define GIC_CPU_BINPOINT(hw_base) HWREG32((hw_base) + 0x08U) +#define GIC_CPU_INTACK(hw_base) HWREG32((hw_base) + 0x0cU) +#define GIC_CPU_EOI(hw_base) HWREG32((hw_base) + 0x10U) +#define GIC_CPU_RUNNINGPRI(hw_base) HWREG32((hw_base) + 0x14U) +#define GIC_CPU_HIGHPRI(hw_base) HWREG32((hw_base) + 0x18U) +#define GIC_CPU_IIDR(hw_base) HWREG32((hw_base) + 0xFCU) + +/* Macro to access the Generic Interrupt Controller Distributor (GICD) */ +#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) +#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U) +#define GIC_DIST_IGROUP(hw_base, n) HWREG32((hw_base) + 0x080U + ((n) / 32U) * 4U) +#define GIC_DIST_ENABLE_SET(hw_base, n) HWREG32((hw_base) + 0x100U + ((n) / 32U) * 4U) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x180U + ((n) / 32U) * 4U) +#define GIC_DIST_PENDING_SET(hw_base, n) HWREG32((hw_base) + 0x200U + ((n) / 32U) * 4U) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) HWREG32((hw_base) + 0x280U + ((n) / 32U) * 4U) +#define GIC_DIST_ACTIVE_SET(hw_base, n) HWREG32((hw_base) + 0x300U + ((n) / 32U) * 4U) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x380U + ((n) / 32U) * 4U) +#define GIC_DIST_PRI(hw_base, n) HWREG32((hw_base) + 0x400U + ((n) / 4U) * 4U) +#define GIC_DIST_TARGET(hw_base, n) HWREG32((hw_base) + 0x800U + ((n) / 4U) * 4U) +#define GIC_DIST_CONFIG(hw_base, n) HWREG32((hw_base) + 0xc00U + ((n) / 16U) * 4U) +#define GIC_DIST_SOFTINT(hw_base) HWREG32((hw_base) + 0xf00U) +#define GIC_DIST_CPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf10U + ((n) / 4U) * 4U) +#define GIC_DIST_SPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf20U + ((n) / 4U) * 4U) +#define GIC_DIST_ICPIDR2(hw_base) HWREG32((hw_base) + 0xfe8U) +#define GIC_DIST_IROUTER(hw_base, n) HWREG64((hw_base) + 0x6000U + (n) * 8U) + +/* SGI base address is at 64K offset from Redistributor base address */ +#define GIC_RSGI_OFFSET 0x10000 + +/* Macro to access the Generic Interrupt Controller Redistributor (GICR) */ +#define GIC_RDIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) +#define GIC_RDIST_IIDR(hw_base) HWREG32((hw_base) + 0x004U) +#define GIC_RDIST_TYPER(hw_base) HWREG64((hw_base) + 0x008U) +#define GIC_RDIST_TSTATUSR(hw_base) HWREG32((hw_base) + 0x010U) +#define GIC_RDIST_WAKER(hw_base) HWREG32((hw_base) + 0x014U) +#define GIC_RDIST_SETLPIR(hw_base) HWREG32((hw_base) + 0x040U) +#define GIC_RDIST_CLRLPIR(hw_base) HWREG32((hw_base) + 0x048U) +#define GIC_RDIST_PROPBASER(hw_base) HWREG32((hw_base) + 0x070U) +#define GIC_RDIST_PENDBASER(hw_base) HWREG32((hw_base) + 0x078U) +#define GIC_RDIST_INVLPIR(hw_base) HWREG32((hw_base) + 0x0A0U) +#define GIC_RDIST_INVALLR(hw_base) HWREG32((hw_base) + 0x0B0U) +#define GIC_RDIST_SYNCR(hw_base) HWREG32((hw_base) + 0x0C0U) + +#define GIC_RDISTSGI_IGROUPR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n) * 4U) +#define GIC_RDISTSGI_ISENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x100U) +#define GIC_RDISTSGI_ICENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x180U) +#define GIC_RDISTSGI_ISPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x200U) +#define GIC_RDISTSGI_ICPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x280U) +#define GIC_RDISTSGI_ISACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x300U) +#define GIC_RDISTSGI_ICACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x380U) +#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U) +#define GIC_RDISTSGI_ICFGR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) +#define GIC_RDISTSGI_ICFGR1(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) +#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n) * 4) +#define GIC_RDISTSGI_NSACR(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) + +int arm_gic_get_active_irq(rt_uint64_t index) +{ + int irq; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + GET_GICV3_REG(ICC_IAR1_EL1, irq); + + irq = (irq & 0x1ffffff) + _gic_table[index].offset; + return irq; +} + +void arm_gic_ack(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(irq >= 0); + + __DSB(); + SET_GICV3_REG(ICC_EOIR1_EL1, irq); +} + +void arm_gic_mask(rt_uint64_t index, int irq) +{ + rt_uint64_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq < 32) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + GIC_RDISTSGI_ICENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; + } + else + { + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_umask(rt_uint64_t index, int irq) +{ + rt_uint64_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq < 32) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + GIC_RDISTSGI_ISENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask; + } + else + { + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq) +{ + rt_uint64_t pend; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq >= 16) + { + pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1; + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4) * 8)) & 0xff; + /* No CPU identification offered */ + if (pend != 0) + { + pend = 1; + } + else + { + pend = 0; + } + } + + return pend; +} + +void arm_gic_set_pending_irq(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq >= 16) + { + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1 << (irq % 32); + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + /* Forward the interrupt to the CPU interface that requested it */ + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000); + } +} + +void arm_gic_clear_pending_irq(rt_uint64_t index, int irq) +{ + rt_uint64_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq >= 16) + { + mask = 1 << (irq % 32); + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } + else + { + mask = 1 << ((irq % 4) * 8); + GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config) +{ + rt_uint64_t icfgr; + rt_uint64_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq); + shift = (irq % 16) << 1; + + icfgr &= (~(3 << shift)); + icfgr |= (config << shift); + + GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr; +} + +rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> ((irq % 16) >> 1)); +} + +void arm_gic_clear_active(rt_uint64_t index, int irq) +{ + rt_uint64_t mask = 1 << (irq % 32); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +/* Set up the cpu mask for the specific interrupt */ +void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask) +{ + rt_uint64_t old_tgt; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); + + old_tgt &= ~(0x0ff << ((irq % 4) * 8)); + old_tgt |= cpumask << ((irq % 4) * 8); + + GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; +} + +rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + return (GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) >> ((irq % 4) * 8)) & 0xff; +} + +void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority) +{ + rt_uint64_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq < 32) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + mask = GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq); + mask &= ~(0xff << ((irq % 4) * 8)); + mask |= ((priority & 0xff) << ((irq % 4) * 8)); + GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) = mask; + } + else + { + mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq); + mask &= ~(0xff << ((irq % 4) * 8)); + mask |= ((priority & 0xff) << ((irq % 4) * 8)); + GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + if (irq < 32) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + return (GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) >> ((irq % 4) * 8)) & 0xff; + } + else + { + return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4) * 8)) & 0xff; + } +} + +void arm_gic_set_system_register_enable_mask(rt_uint64_t index, rt_uint64_t value) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + value &= 0xff; + /* set priority mask */ + SET_GICV3_REG(ICC_SRE_EL1, value); + __ISB(); +} + +rt_uint64_t arm_gic_get_system_register_enable_mask(rt_uint64_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + rt_uint64_t value; + + GET_GICV3_REG(ICC_SRE_EL1, value); + return value; +} + +void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + priority &= 0xff; + /* set priority mask */ + SET_GICV3_REG(ICC_PMR_EL1, priority); +} + +rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + rt_uint64_t priority; + + GET_GICV3_REG(ICC_PMR_EL1, priority); + return priority; +} + +void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point) +{ + index = index; + binary_point &= 0x7; + + SET_GICV3_REG(ICC_BPR1_EL1, binary_point); +} + +rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index) +{ + rt_uint64_t binary_point; + + index = index; + GET_GICV3_REG(ICC_BPR1_EL1, binary_point); + return binary_point; +} + +rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq) +{ + rt_uint64_t pending, active; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1; + pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1; + + return ((active << 1) | pending); +} + +#ifdef RT_USING_SMP +void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint64_t cpu_masks[], rt_uint64_t routing_mode) +{ + const int cpu_mask_cpu_max_nr = sizeof(cpu_masks[0]) * 8; + rt_uint64_t int_id = (irq & 0xf) << 24; + rt_uint64_t irm = routing_mode << 40; /* Interrupt Routing Mode */ + + if (routing_mode == GICV3_ROUTED_TO_SPEC) + { + int cpu_id, cpu_mask_bit, i, cpu_masks_nr = RT_CPUS_NR / cpu_mask_cpu_max_nr; + rt_uint16_t target_list; + rt_uint64_t rs = 0; /* Range Selector */ + rt_uint64_t affinity_val, next_affinity_val; + + if (cpu_masks_nr * cpu_mask_cpu_max_nr != RT_CPUS_NR) + { + ++cpu_masks_nr; + } + + for (i = cpu_id = 0; i < cpu_masks_nr;) + { + /* No cpu in this mask */ + if (cpu_masks[i] == 0) + { + ++i; + cpu_id += cpu_mask_cpu_max_nr; + continue; + } + + /* Get last cpu affinity value */ + affinity_val = rt_cpu_mpidr_early[cpu_id] & 0xff00ffff00ULL; + + /* Read 16 cpus information */ + for (cpu_mask_bit = 0; cpu_mask_bit < 16; ++cpu_mask_bit, ++cpu_id) + { + /* MPIDR_EL1: aff3[39:32], aff2[23:16], aff1[15:8] */ + next_affinity_val = rt_cpu_mpidr_early[cpu_id] & 0xff00ffff00ULL; + + /* Affinity value is different, read end */ + if (affinity_val != next_affinity_val) + { + break; + } + } + + /* Get all valid cpu mask */ + target_list = (0xffff >> (16 - cpu_mask_bit)) & cpu_masks[i]; + /* Clear read mask */ + cpu_masks[i] >>= cpu_mask_bit; + /* ICC_SGI1R_EL1: aff3[55:48], aff2[39:32], aff1[23:16] */ + affinity_val <<= 8; + + __DSB(); + /* Interrupts routed to the PEs specified by Aff3.Aff2.Aff1.. */ + SET_GICV3_REG(ICC_SGI1R_EL1, affinity_val | (rs << 44) | irm | int_id | target_list); + __ISB(); + + /* Check if reset the range selector */ + rs = affinity_val != next_affinity_val ? 0 : rs + 1; + } + } + else + { + __DSB(); + /* Interrupts routed to all PEs in the system, excluding "self". */ + SET_GICV3_REG(ICC_SGI1R_EL1, irm | int_id); + __ISB(); + } +} +#endif /* RT_USING_SMP */ + +rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index) +{ + rt_uint64_t irq; + RT_ASSERT(index < ARM_GIC_MAX_NR); + + index = index; + GET_GICV3_REG(ICC_HPPIR1_EL1, irq); + + return irq; +} + +rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index) +{ + rt_uint64_t ret = 0; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + if (_gic_table[index].cpu_hw_base != RT_NULL) + { + ret = GIC_CPU_IIDR(_gic_table[index].cpu_hw_base); + } + + return ret; +} + +void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group) +{ + rt_uint64_t igroupr; + rt_uint64_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(group <= 1); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq); + shift = (irq % 32); + igroupr &= (~(1U << shift)); + igroupr |= ((group & 0x1U) << shift); + + GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr; +} + +rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0); + + return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32)) & 0x1UL; +} + +static int arm_gicv3_wait_rwp(rt_uint64_t index, rt_uint64_t irq) +{ + rt_uint64_t rwp_bit; + rt_uint64_t base; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + if (irq < 32) + { + rt_int32_t cpu_id = rt_hw_cpu_id(); + + base = _gic_table[index].redist_hw_base[cpu_id]; + rwp_bit = GICR_CTLR_RWP; + } + else + { + base = _gic_table[index].dist_hw_base; + rwp_bit = GICD_CTLR_RWP; + } + + while (HWREG32(base) & rwp_bit) + { + } + + return 0; +} + +int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start) +{ + int i; + unsigned int gic_type; + rt_uint64_t main_cpu_affinity_val; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].dist_hw_base = dist_base; + _gic_table[index].offset = irq_start; + + + /* Find out how many interrupts are supported. */ + gic_type = GIC_DIST_TYPE(dist_base); + _gic_max_irq = ((gic_type & 0x1f) + 1) * 32; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (_gic_max_irq > 1020) + { + _gic_max_irq = 1020; + } + if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ + { + _gic_max_irq = ARM_GIC_NR_IRQS; + } + + GIC_DIST_CTRL(dist_base) = 0; + /* Wait for register write pending */ + arm_gicv3_wait_rwp(0, 32); + + /* Set all global interrupts to be level triggered, active low. */ + for (i = 32; i < _gic_max_irq; i += 16) + { + GIC_DIST_CONFIG(dist_base, i) = 0; + } + + arm_gicv3_wait_rwp(0, 32); + +#ifdef RT_USING_SMP + main_cpu_affinity_val = rt_cpu_mpidr_early[ARM_SPI_BIND_CPU_ID]; +#else + __asm__ volatile ("mrs %0, mpidr_el1":"=r"(main_cpu_affinity_val)); +#endif + + /* aff3[39:32], aff2[23:16], aff1[15:8], aff0[7:0] */ + main_cpu_affinity_val &= 0xff00ffffffULL; + + /* Set all global interrupts to this CPU only. */ + for (i = 32; i < _gic_max_irq; i++) + { + GIC_DIST_IROUTER(dist_base, i) = main_cpu_affinity_val | (GICV3_ROUTED_TO_SPEC << 31); + } + + arm_gicv3_wait_rwp(0, 32); + + /* Set priority on spi interrupts. */ + for (i = 32; i < _gic_max_irq; i += 4) + { + GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0; + } + + arm_gicv3_wait_rwp(0, 32); + /* Disable all interrupts. */ + for (i = 0; i < _gic_max_irq; i += 32) + { + GIC_DIST_PENDING_CLEAR(dist_base, i) = 0xffffffff; + GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff; + } + + arm_gicv3_wait_rwp(0, 32); + /* All interrupts defaults to IGROUP1(IRQ). */ + for (i = 0; i < _gic_max_irq; i += 32) + { + GIC_DIST_IGROUP(dist_base, i) = 0xffffffff; + } + + arm_gicv3_wait_rwp(0, 32); + + /* + * The Distributor control register (GICD_CTLR) must be configured to enable the interrupt groups and to set the routing mode. + * Enable Affinity routing (ARE bits) The ARE bits in GICD_CTLR control whether affinity routing is enabled. + * If affinity routing is not enabled, GICv3 can be configured for legacy operation. + * Whether affinity routing is enabled or not can be controlled separately for Secure and Non-secure state. + * Enables GICD_CTLR contains separate enable bits for Group 0, Secure Group 1 and Non-secure Group 1: + * GICD_CTLR.EnableGrp1S enables distribution of Secure Group 1 interrupts. + * GICD_CTLR.EnableGrp1NS enables distribution of Non-secure Group 1 interrupts. + * GICD_CTLR.EnableGrp0 enables distribution of Group 0 interrupts. + */ + GIC_DIST_CTRL(dist_base) = GICD_CTLR_ARE_NS | GICD_CTLR_ENGRP1NS; + + return 0; +} + +int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base) +{ + int i; + int cpu_id = rt_hw_cpu_id(); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + redist_base += cpu_id * (2 << 16); + _gic_table[index].redist_hw_base[cpu_id] = redist_base; + + /* redistributor enable */ + GIC_RDIST_WAKER(redist_base) &= ~(1 << 1); + while (GIC_RDIST_WAKER(redist_base) & (1 << 2)) + { + } + + /* Disable all sgi and ppi interrupt */ + GIC_RDISTSGI_ICENABLER0(redist_base) = 0xffffffff; + arm_gicv3_wait_rwp(0, 0); + + /* Clear all inetrrupt pending */ + GIC_RDISTSGI_ICPENDR0(redist_base) = 0xffffffff; + + /* the corresponding interrupt is Group 1 or Non-secure Group 1. */ + GIC_RDISTSGI_IGROUPR0(redist_base, 0) = 0xffffffff; + GIC_RDISTSGI_IGRPMODR0(redist_base, 0) = 0xffffffff; + + /* Configure default priorities for SGI 0:15 and PPI 16:31. */ + for (i = 0; i < 32; i += 4) + { + GIC_RDISTSGI_IPRIORITYR(redist_base, i) = 0xa0a0a0a0U; + } + + /* Trigger level for PPI interrupts*/ + GIC_RDISTSGI_ICFGR1(redist_base) = 0; + return 0; +} + +int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base) +{ + rt_uint64_t value; + int cpu_id = rt_hw_cpu_id(); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].cpu_hw_base[cpu_id] = cpu_base; + + value = arm_gic_get_system_register_enable_mask(index); + value |= (1 << 0); + arm_gic_set_system_register_enable_mask(index, value); + SET_GICV3_REG(ICC_CTLR_EL1, 0); + + arm_gic_set_interface_prior_mask(index, 0xff); + + /* Enable group1 interrupt */ + value = 1; + SET_GICV3_REG(ICC_IGRPEN1_EL1, value); + + arm_gic_set_binary_point(0, 0); + + /* ICC_BPR0_EL1 determines the preemption group for both Group 0 and Group 1 interrupts. */ + value = 1; /* ICC_BPR0_EL1 determines the preemption group for both Group 0 and Group 1 interrupts.*/ + value |= 1 << 18; /* Targeted SGIs with affinity level 0 values of 0 - 255 are supported. */ + SET_GICV3_REG(ICC_CTLR_EL1, value); + + return 0; +} + +void arm_gic_dump_type(rt_uint64_t index) +{ + unsigned int gic_type; + + gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); + rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", + (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf, + _gic_table[index].dist_hw_base, + _gic_max_irq, + gic_type & (1 << 10) ? "has" : "no", + gic_type); +} + +void arm_gic_dump(rt_uint64_t index) +{ + int i; + unsigned int val; + + val = arm_gic_get_high_pending_irq(0); + rt_kprintf("--- high pending priority: %d(%08x)\n", val, val); + + rt_kprintf("--- hw mask ---\n"); + for (i = 0; i < _gic_max_irq / 32; ++i) + { + rt_kprintf("0x%08x, ", GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, i * 32)); + } + + rt_kprintf("\b\b\n--- hw pending ---\n"); + for (i = 0; i < _gic_max_irq / 32; ++i) + { + rt_kprintf("0x%08x, ", GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, i * 32)); + } + + rt_kprintf("\b\b\n--- hw active ---\n"); + for (i = 0; i < _gic_max_irq / 32; ++i) + { + rt_kprintf("0x%08x, ", GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, i * 32)); + } + + rt_kprintf("\b\b\n"); +} + +long gic_dump(void) +{ + arm_gic_dump_type(0); + arm_gic_dump(0); + + return 0; +} +MSH_CMD_EXPORT(gic_dump, show gic status); + +#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) */ diff --git a/libcpu/aarch64/common/gicv3.h b/libcpu/aarch64/common/gicv3.h new file mode 100644 index 0000000000..0cb6bda03a --- /dev/null +++ b/libcpu/aarch64/common/gicv3.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2014-04-03 Grissiom many enhancements + * 2018-11-22 Jesven add rt_hw_ipi_send() + * add rt_hw_ipi_handler_install() + */ + +#ifndef __GICV3_H__ +#define __GICV3_H__ + +#include + +#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) + +#define GICV3_ROUTED_TO_ALL 1UL +#define GICV3_ROUTED_TO_SPEC 0UL + +int arm_gic_get_active_irq(rt_uint64_t index); +void arm_gic_ack(rt_uint64_t index, int irq); + +void arm_gic_mask(rt_uint64_t index, int irq); +void arm_gic_umask(rt_uint64_t index, int irq); + +rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); +void arm_gic_set_pending_irq(rt_uint64_t index, int irq); +void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); + +void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config); +rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); + +void arm_gic_clear_active(rt_uint64_t index, int irq); + +void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask); +rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq); + +void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority); +rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq); + +void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority); +rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index); + +void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point); +rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index); + +rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq); + +#ifdef RT_USING_SMP +void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint64_t cpu_masks[], rt_uint64_t routing_mode); +#endif + +rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index); + +rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index); + +void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group); +rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq); + +int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id); +int arm_gic_cpu_interface_address_set(rt_uint64_t index, rt_uint64_t interface_addr, int cpu_id); + +int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start); +int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base); +int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); + +void arm_gic_dump_type(rt_uint64_t index); +void arm_gic_dump(rt_uint64_t index); + +#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) */ + +#endif + diff --git a/libcpu/aarch64/common/interrupt.c b/libcpu/aarch64/common/interrupt.c index f31003b2c0..c5db2d46af 100644 --- a/libcpu/aarch64/common/interrupt.c +++ b/libcpu/aarch64/common/interrupt.c @@ -13,6 +13,7 @@ #include #include "interrupt.h" #include "gic.h" +#include "gicv3.h" #include "armv8.h" #include "mmu.h" #include "cpuport.h" @@ -52,6 +53,9 @@ void rt_hw_interrupt_init(void) /* initialize ARM GIC */ arm_gic_dist_init(0, platform_get_gic_dist_base(), GIC_IRQ_START); arm_gic_cpu_init(0, platform_get_gic_cpu_base()); +#ifdef BSP_USING_GICV3 + arm_gic_redist_init(0, platform_get_gic_redist_base()); +#endif #endif } @@ -346,7 +350,11 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) { #ifdef BSP_USING_GIC +#ifdef BSP_USING_GICV2 arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0); +#else + arm_gic_send_affinity_sgi(0, ipi_vector, (rt_uint64_t *)&cpu_mask, GICV3_ROUTED_TO_SPEC); +#endif #else int i; @@ -359,8 +367,9 @@ void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) IPI_MAILBOX_SET(i) = 1 << ipi_vector; } } -#endif + __DSB(); +#endif } void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) diff --git a/libcpu/aarch64/common/psci.c b/libcpu/aarch64/common/psci.c index 400db977ee..65e84ebf0a 100644 --- a/libcpu/aarch64/common/psci.c +++ b/libcpu/aarch64/common/psci.c @@ -29,11 +29,19 @@ static psci_call_handle psci_call = psci_smc_call; static uint64_t shutdown_args[3] = {0, 0, 0}; static uint64_t reboot_args[3] = {0, 0, 0}; -void arm_psci_init(uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args) +void arm_psci_init(uint64_t method, uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args) { - if (rt_hw_get_current_el() < 2) + switch (method) { - psci_call = psci_hvc_call; + case PSCI_METHOD_SMC: + psci_call = psci_smc_call; + break; + case PSCI_METHOD_HVC: + if (rt_hw_get_current_el() < 2) + { + psci_call = psci_hvc_call; + } + break; } if (platform_shutdown_args != RT_NULL) diff --git a/libcpu/aarch64/common/psci.h b/libcpu/aarch64/common/psci.h index e8b2e3129d..999489a801 100644 --- a/libcpu/aarch64/common/psci.h +++ b/libcpu/aarch64/common/psci.h @@ -18,6 +18,9 @@ */ #define PSCI_VER_0_2 0x00000002 +#define PSCI_METHOD_SMC 3 +#define PSCI_METHOD_HVC 2 + /* PSCI 0.2 interface */ #define PSCI_0_2_FN_BASE 0x84000000 #define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n)) @@ -114,7 +117,7 @@ #define PSCI_RET_DISABLED (-8) #define PSCI_RET_INVALID_ADDRESS (-9) -void arm_psci_init(uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args); +void arm_psci_init(uint64_t method, uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args); uint32_t arm_psci_get_version(); uint32_t arm_psci_get_affinity_info(uint64_t target_affinity, uint64_t lowest_affinity_level); diff --git a/libcpu/aarch64/cortex-a/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S index 5bf2b8a3a6..c605a41631 100644 --- a/libcpu/aarch64/cortex-a/entry_point.S +++ b/libcpu/aarch64/cortex-a/entry_point.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -11,19 +11,28 @@ */ #include "rtconfig.h" -.section ".text.entrypoint","ax" #define SECONDARY_STACK_SIZE 4096 +.section ".text.entrypoint","ax" + .globl _start .globl secondary_cpu_start _start: +#ifdef RT_USING_SMP mrs x1, mpidr_el1 - and x1, x1, #0xff - cbnz x1, cpu_idle /* If cpu id > 0, stop slave cores */ + adr x4, .boot_cpu_mpidr + str x1, [x4] + dsb sy +#endif + + bl __asm_flush_dcache_all /* The kernel and data must flush to DDR */ secondary_cpu_start: #ifdef RT_USING_SMP + adr x4, .boot_cpu_mpidr + ldr x4, [x4] + dsb sy /* Read cpu mpidr_el1 */ mrs x1, mpidr_el1 @@ -34,6 +43,7 @@ secondary_cpu_start: cpu_id_confirm: add x2, x2, #1 /* Next cpu id inc */ ldr x3, [x0], #8 + dsb sy cmp x3, #0 beq cpu_idle /* Mean that `rt_cpu_mpidr_early' table is end */ cmp x3, x1 @@ -42,7 +52,8 @@ cpu_id_confirm: /* Get cpu id success */ sub x0, x2, #1 msr tpidr_el1, x0 /* Save cpu id global */ - cbz x0, cpu_setup /* Only go to cpu_setup when cpu id = 0 */ + cmp x3, x4 /* If it is boot cpu */ + beq boot_cpu_setup /* Set current cpu's stack top */ sub x0, x0, #1 @@ -53,14 +64,9 @@ cpu_id_confirm: b cpu_check_el #else msr tpidr_el1, xzr - b cpu_setup #endif /* RT_USING_SMP */ -cpu_idle: - wfe - b cpu_idle - -cpu_setup: +boot_cpu_setup: ldr x1, =_start cpu_check_el: @@ -75,7 +81,7 @@ cpu_check_el: mov x2, #(1 << 0) /* EL0 and EL1 are in Non-Secure state */ orr x2, x2, #(1 << 4) /* RES1 */ orr x2, x2, #(1 << 5) /* RES1 */ - orr x2, x2, #(1 << 7) /* SMC instructions are undefined at EL1 and above */ + bic x2, x2, #(1 << 7) /* SMC instructions are enabled at EL1 and above */ orr x2, x2, #(1 << 8) /* HVC instructions are enabled at EL1 and above */ orr x2, x2, #(1 << 10) /* The next lower level is AArch64 */ msr scr_el3, x2 @@ -91,7 +97,7 @@ cpu_check_el: eret cpu_not_in_el3: /* Running at EL2 or EL1 */ - cmp x0, #4 /* EL1 = 0100 */ + cmp x0, #4 /* EL1 = 0100 */ beq cpu_in_el1 cpu_in_el2: @@ -159,9 +165,16 @@ clean_bss_check: jump_to_entry: b rtthread_startup - b cpu_idle /* For failsafe, halt this core too */ + +cpu_idle: + wfe + b cpu_idle #ifdef RT_USING_SMP +.align 3 +.boot_cpu_mpidr: + .quad 0x0 + .align 12 .secondary_cpu_stack: .space (SECONDARY_STACK_SIZE * (RT_CPUS_NR - 1))