Просмотр исходного кода

[smart/aarch64] code sync (#6750)

* [smart/aarch64] sync aarch64
Shell 3 лет назад
Родитель
Сommit
e8504c7cf1
100 измененных файлов с 4166 добавлено и 8415 удалено
  1. 67 286
      bsp/qemu-virt64-aarch64/.config
  2. 6 2
      bsp/qemu-virt64-aarch64/Kconfig
  3. 18 4
      bsp/qemu-virt64-aarch64/SConstruct
  4. 21 1
      bsp/qemu-virt64-aarch64/applications/console.c
  5. 1 1
      bsp/qemu-virt64-aarch64/applications/graphic.c
  6. 4 4
      bsp/qemu-virt64-aarch64/applications/main.c
  7. 2 2
      bsp/qemu-virt64-aarch64/applications/mnt.c
  8. 1 1
      bsp/qemu-virt64-aarch64/applications/pin.c
  9. 0 19
      bsp/qemu-virt64-aarch64/driver/SConscript
  10. 0 147
      bsp/qemu-virt64-aarch64/driver/board.c
  11. 0 24
      bsp/qemu-virt64-aarch64/driver/board.h
  12. 0 206
      bsp/qemu-virt64-aarch64/driver/drv_rtc.c
  13. 0 324
      bsp/qemu-virt64-aarch64/driver/virtio/virtio.c
  14. 0 141
      bsp/qemu-virt64-aarch64/driver/virtio/virtio.h
  15. 0 240
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c
  16. 0 106
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h
  17. 0 734
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_console.c
  18. 0 96
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_console.h
  19. 0 923
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.c
  20. 0 412
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.h
  21. 0 438
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.c
  22. 0 145
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.h
  23. 0 932
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_input_event_codes.h
  24. 0 57
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h
  25. 0 303
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.c
  26. 0 115
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.h
  27. 0 97
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h
  28. 14 1
      bsp/qemu-virt64-aarch64/drivers/Kconfig
  29. 1 1
      bsp/qemu-virt64-aarch64/drivers/SConscript
  30. 120 0
      bsp/qemu-virt64-aarch64/drivers/board.c
  31. 36 0
      bsp/qemu-virt64-aarch64/drivers/board.h
  32. 8 2
      bsp/qemu-virt64-aarch64/drivers/drv_gpio.c
  33. 0 0
      bsp/qemu-virt64-aarch64/drivers/drv_gpio.h
  34. 123 0
      bsp/qemu-virt64-aarch64/drivers/drv_rtc.c
  35. 0 0
      bsp/qemu-virt64-aarch64/drivers/drv_rtc.h
  36. 46 0
      bsp/qemu-virt64-aarch64/drivers/drv_timer.c
  37. 16 0
      bsp/qemu-virt64-aarch64/drivers/drv_timer.h
  38. 45 49
      bsp/qemu-virt64-aarch64/drivers/drv_uart.c
  39. 4 4
      bsp/qemu-virt64-aarch64/drivers/drv_uart.h
  40. 9 0
      bsp/qemu-virt64-aarch64/drivers/drv_virtio.c
  41. 0 0
      bsp/qemu-virt64-aarch64/drivers/drv_virtio.h
  42. 36 0
      bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c
  43. 18 4
      bsp/qemu-virt64-aarch64/drivers/virt.h
  44. 68 110
      bsp/qemu-virt64-aarch64/link.lds
  45. 9 0
      bsp/qemu-virt64-aarch64/qemu-debug.bat
  46. 7 0
      bsp/qemu-virt64-aarch64/qemu-debug.sh
  47. 1 1
      bsp/qemu-virt64-aarch64/qemu-graphic.bat
  48. 1 1
      bsp/qemu-virt64-aarch64/qemu-graphic.sh
  49. 1 1
      bsp/qemu-virt64-aarch64/qemu.sh
  50. 43 88
      bsp/qemu-virt64-aarch64/rtconfig.h
  51. 20 32
      bsp/qemu-virt64-aarch64/rtconfig.py
  52. 15 176
      bsp/raspberry-pi/raspi3-64/.config
  53. 5 0
      bsp/raspberry-pi/raspi3-64/Kconfig
  54. 4 2
      bsp/raspberry-pi/raspi3-64/driver/board.c
  55. 5 0
      bsp/raspberry-pi/raspi3-64/driver/board.h
  56. 3 2
      bsp/raspberry-pi/raspi3-64/driver/drv_fb.c
  57. 3 16
      bsp/raspberry-pi/raspi3-64/rtconfig.h
  58. 2 2
      bsp/raspberry-pi/raspi3-64/rtconfig.py
  59. 2 2
      bsp/raspberry-pi/raspi4-32/rtconfig.py
  60. 5 0
      bsp/raspberry-pi/raspi4-64/driver/board.h
  61. 2 2
      bsp/raspberry-pi/raspi4-64/rtconfig.py
  62. 2 2
      bsp/rockchip/rk3568/driver/board.c
  63. 5 0
      bsp/rockchip/rk3568/driver/board.h
  64. 2 0
      bsp/rockchip/rk3568/driver/rk3568.h
  65. 3 3
      bsp/rockchip/rk3568/rtconfig.py
  66. 486 486
      bsp/wch/risc-v/Libraries/ch32_drivers/drv_hwtimer.c
  67. 148 148
      bsp/wch/risc-v/Libraries/ch32_drivers/drv_hwtimer.h
  68. 963 963
      bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.c
  69. 40 40
      bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.h
  70. 2 1
      components/drivers/fdt/inc/dtb_node.h
  71. 49 35
      components/drivers/fdt/libfdt/fdt.h
  72. 1 2
      components/drivers/tty/pty.c
  73. 2 0
      libcpu/Kconfig
  74. 42 45
      libcpu/aarch64/common/armv8.h
  75. 46 0
      libcpu/aarch64/common/asm-fpu.h
  76. 57 0
      libcpu/aarch64/common/backtrace.c
  77. 22 0
      libcpu/aarch64/common/backtrace.h
  78. 3 2
      libcpu/aarch64/common/cache.S
  79. 23 0
      libcpu/aarch64/common/cache.h
  80. 53 21
      libcpu/aarch64/common/cache_ops.c
  81. 307 182
      libcpu/aarch64/common/context_gcc.S
  82. 65 0
      libcpu/aarch64/common/cp15.h
  83. 292 34
      libcpu/aarch64/common/cpu.c
  84. 63 0
      libcpu/aarch64/common/cpu.h
  85. 73 52
      libcpu/aarch64/common/cpu_gcc.S
  86. 21 0
      libcpu/aarch64/common/cpu_ops_common.h
  87. 70 0
      libcpu/aarch64/common/cpu_psci.c
  88. 80 0
      libcpu/aarch64/common/cpu_spin_table.c
  89. 7 15
      libcpu/aarch64/common/cpuport.h
  90. 13 0
      libcpu/aarch64/common/entry_point.h
  91. 232 0
      libcpu/aarch64/common/exception.c
  92. 45 42
      libcpu/aarch64/common/gic.c
  93. 3 6
      libcpu/aarch64/common/gic.h
  94. 15 2
      libcpu/aarch64/common/gicv3.c
  95. 1 1
      libcpu/aarch64/common/gicv3.h
  96. 2 2
      libcpu/aarch64/common/gtimer.c
  97. 6 1
      libcpu/aarch64/common/gtimer.h
  98. 16 0
      libcpu/aarch64/common/hypercall.c
  99. 27 0
      libcpu/aarch64/common/hypercall.h
  100. 87 74
      libcpu/aarch64/common/interrupt.c

+ 67 - 286
bsp/qemu-virt64-aarch64/.config

@@ -11,7 +11,7 @@ CONFIG_RT_NAME_MAX=16
 # CONFIG_RT_USING_SMART is not set
 CONFIG_RT_USING_SMP=y
 CONFIG_RT_CPUS_NR=4
-CONFIG_RT_ALIGN_SIZE=4
+CONFIG_RT_ALIGN_SIZE=8
 # CONFIG_RT_THREAD_PRIORITY_8 is not set
 CONFIG_RT_THREAD_PRIORITY_32=y
 # CONFIG_RT_THREAD_PRIORITY_256 is not set
@@ -22,16 +22,17 @@ 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_SYSTEM_THREAD_STACK_SIZE=4096
+CONFIG_IDLE_THREAD_STACK_SIZE=8192
+CONFIG_SYSTEM_THREAD_STACK_SIZE=8192
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
-CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=8192
 
 #
 # kservice optimization
 #
-# CONFIG_RT_KSERVICE_USING_STDLIB is not set
+CONFIG_RT_KSERVICE_USING_STDLIB=y
+# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set
 # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
 # CONFIG_RT_USING_TINY_FFS is not set
 CONFIG_RT_KPRINTF_USING_LONGLONG=y
@@ -67,8 +68,9 @@ CONFIG_RT_USING_SMALL_MEM=y
 CONFIG_RT_USING_MEMHEAP=y
 CONFIG_RT_MEMHEAP_FAST_MODE=y
 # CONFIG_RT_MEMHEAP_BEST_MODE is not set
-CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y
-# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
+# CONFIG_RT_USING_SMALL_MEM_AS_HEAP is not set
+CONFIG_RT_USING_MEMHEAP_AS_HEAP=y
+CONFIG_RT_USING_MEMHEAP_AUTO_BINDING=y
 # CONFIG_RT_USING_SLAB_AS_HEAP is not set
 # CONFIG_RT_USING_USERHEAP is not set
 # CONFIG_RT_USING_NOHEAP is not set
@@ -82,9 +84,9 @@ CONFIG_RT_USING_HEAP=y
 CONFIG_RT_USING_DEVICE=y
 CONFIG_RT_USING_DEVICE_OPS=y
 # CONFIG_RT_USING_DM is not set
-# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_INTERRUPT_INFO=y
 CONFIG_RT_USING_CONSOLE=y
-CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLEBUF_SIZE=256
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
 CONFIG_RT_VER_NUM=0x50000
 CONFIG_ARCH_CPU_64BIT=y
@@ -92,7 +94,9 @@ CONFIG_RT_USING_CACHE=y
 # CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
 # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 # CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_MM_MMU=y
 CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_MMU=y
 CONFIG_ARCH_ARMV8=y
 
 #
@@ -110,9 +114,9 @@ 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_HISTORY_LINES=10
 CONFIG_FINSH_USING_SYMTAB=y
-CONFIG_FINSH_CMD_SIZE=80
+CONFIG_FINSH_CMD_SIZE=256
 CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
 CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
@@ -121,9 +125,9 @@ CONFIG_FINSH_ARG_MAX=10
 CONFIG_RT_USING_DFS=y
 CONFIG_DFS_USING_POSIX=y
 CONFIG_DFS_USING_WORKDIR=y
-CONFIG_DFS_FILESYSTEMS_MAX=2
-CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
-CONFIG_DFS_FD_MAX=16
+CONFIG_DFS_FILESYSTEMS_MAX=4
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=8
+CONFIG_DFS_FD_MAX=32
 # CONFIG_RT_USING_DFS_MNTTABLE is not set
 CONFIG_RT_USING_DFS_ELMFAT=y
 
@@ -149,11 +153,10 @@ CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
 CONFIG_RT_DFS_ELM_REENTRANT=y
 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_ROMFS=y
 # CONFIG_RT_USING_DFS_CROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
 # CONFIG_RT_USING_DFS_TMPFS is not set
-# CONFIG_RT_USING_DFS_NFS is not set
 # CONFIG_RT_USING_FAL is not set
 
 #
@@ -162,13 +165,13 @@ CONFIG_RT_USING_DFS_DEVFS=y
 CONFIG_RT_USING_DEVICE_IPC=y
 CONFIG_RT_UNAMED_PIPE_NUMBER=64
 CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
-CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096
+CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192
 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
-# CONFIG_RT_SERIAL_USING_DMA is not set
-CONFIG_RT_SERIAL_RB_BUFSZ=64
+CONFIG_RT_SERIAL_USING_DMA=y
+CONFIG_RT_SERIAL_RB_BUFSZ=256
 # CONFIG_RT_USING_CAN is not set
 # CONFIG_RT_USING_HWTIMER is not set
 # CONFIG_RT_USING_CPUTIME is not set
@@ -177,16 +180,16 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
 CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_ADC is not set
 # CONFIG_RT_USING_DAC is not set
-# CONFIG_RT_USING_NULL is not set
-# CONFIG_RT_USING_ZERO is not set
-# CONFIG_RT_USING_RANDOM is not set
+CONFIG_RT_USING_NULL=y
+CONFIG_RT_USING_ZERO=y
+CONFIG_RT_USING_RANDOM=y
 # 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_FDT is not set
 CONFIG_RT_USING_RTC=y
-CONFIG_RT_USING_ALARM=y
+# CONFIG_RT_USING_ALARM is not set
 # CONFIG_RT_USING_SOFT_RTC is not set
 # CONFIG_RT_USING_SDIO is not set
 # CONFIG_RT_USING_SPI is not set
@@ -198,9 +201,17 @@ CONFIG_RT_USING_ALARM=y
 # 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_DEV_BUS is not set
+CONFIG_RT_USING_DEV_BUS=y
 # CONFIG_RT_USING_WIFI is not set
-# CONFIG_RT_USING_VIRTIO is not set
+CONFIG_RT_USING_VIRTIO=y
+CONFIG_RT_USING_VIRTIO10=y
+CONFIG_RT_USING_VIRTIO_MMIO_ALIGN=y
+CONFIG_RT_USING_VIRTIO_BLK=y
+# CONFIG_RT_USING_VIRTIO_NET is not set
+CONFIG_RT_USING_VIRTIO_CONSOLE=y
+CONFIG_RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR=4
+CONFIG_RT_USING_VIRTIO_GPU=y
+CONFIG_RT_USING_VIRTIO_INPUT=y
 
 #
 # Using USB
@@ -217,9 +228,17 @@ 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_FS=y
+CONFIG_RT_USING_POSIX_DEVIO=y
+CONFIG_RT_USING_POSIX_STDIO=y
+CONFIG_RT_USING_POSIX_POLL=y
+CONFIG_RT_USING_POSIX_SELECT=y
+# CONFIG_RT_USING_POSIX_SOCKET is not set
+CONFIG_RT_USING_POSIX_TERMIOS=y
+# CONFIG_RT_USING_POSIX_AIO is not set
+# CONFIG_RT_USING_POSIX_MMAN is not set
+CONFIG_RT_USING_POSIX_DELAY=y
+CONFIG_RT_USING_POSIX_CLOCK=y
 # CONFIG_RT_USING_POSIX_TIMER is not set
 # CONFIG_RT_USING_PTHREADS is not set
 # CONFIG_RT_USING_MODULE is not set
@@ -227,7 +246,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # Interprocess Communication (IPC)
 #
-# CONFIG_RT_USING_POSIX_PIPE is not set
+CONFIG_RT_USING_POSIX_PIPE=y
+CONFIG_RT_USING_POSIX_PIPE_SIZE=512
 # CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set
 # CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
 
@@ -239,83 +259,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # Network
 #
-CONFIG_RT_USING_SAL=y
-CONFIG_SAL_INTERNET_CHECK=y
-
-#
-# Docking with protocol stacks
-#
-CONFIG_SAL_USING_LWIP=y
-# CONFIG_SAL_USING_AT is not set
-# CONFIG_SAL_USING_TLS is not set
-CONFIG_SAL_USING_POSIX=y
-CONFIG_RT_USING_NETDEV=y
-CONFIG_NETDEV_USING_IFCONFIG=y
-CONFIG_NETDEV_USING_PING=y
-CONFIG_NETDEV_USING_NETSTAT=y
-CONFIG_NETDEV_USING_AUTO_DEFAULT=y
-# CONFIG_NETDEV_USING_IPV6 is not set
-CONFIG_NETDEV_IPV4=1
-CONFIG_NETDEV_IPV6=0
-# CONFIG_NETDEV_IPV6_SCOPES is not set
-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 is not set
-CONFIG_RT_LWIP_ICMP=y
-# CONFIG_RT_LWIP_SNMP is not set
-CONFIG_RT_LWIP_DNS=y
-CONFIG_RT_LWIP_DHCP=y
-CONFIG_IP_SOF_BROADCAST=1
-CONFIG_IP_SOF_BROADCAST_RECV=1
-
-#
-# Static IPv4 Address
-#
-CONFIG_RT_LWIP_IPADDR="192.168.1.30"
-CONFIG_RT_LWIP_GWADDR="192.168.1.1"
-CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
-CONFIG_RT_LWIP_UDP=y
-CONFIG_RT_LWIP_TCP=y
-CONFIG_RT_LWIP_RAW=y
-# CONFIG_RT_LWIP_PPP is not set
-CONFIG_RT_MEMP_NUM_NETCONN=8
-CONFIG_RT_LWIP_PBUF_NUM=16
-CONFIG_RT_LWIP_RAW_PCB_NUM=4
-CONFIG_RT_LWIP_UDP_PCB_NUM=4
-CONFIG_RT_LWIP_TCP_PCB_NUM=4
-CONFIG_RT_LWIP_TCP_SEG_NUM=40
-CONFIG_RT_LWIP_TCP_SND_BUF=8196
-CONFIG_RT_LWIP_TCP_WND=8196
-CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
-CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8
-CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=4096
-# CONFIG_LWIP_NO_RX_THREAD is not set
-# CONFIG_LWIP_NO_TX_THREAD is not set
-CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12
-CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=4096
-CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8
-CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
-CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
-CONFIG_LWIP_NETIF_LINK_CALLBACK=1
-CONFIG_SO_REUSE=1
-CONFIG_LWIP_SO_RCVTIMEO=1
-CONFIG_LWIP_SO_SNDTIMEO=1
-CONFIG_LWIP_SO_RCVBUF=1
-CONFIG_LWIP_SO_LINGER=0
-# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
-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_LWIP_USING_DHCPD is not set
-# CONFIG_RT_LWIP_DEBUG is not set
+# 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
 
 #
@@ -426,7 +372,6 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_PKG_USING_SMALL_MODBUS is not set
 # CONFIG_PKG_USING_NET_SERVER is not set
 # CONFIG_PKG_USING_ZFTP is not set
-# CONFIG_PKG_USING_WOL is not set
 
 #
 # security packages
@@ -517,6 +462,7 @@ CONFIG_RT_LWIP_USING_PING=y
 # 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
@@ -550,6 +496,7 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_PKG_USING_CBOX is not set
 # CONFIG_PKG_USING_SNOWFLAKE is not set
 # CONFIG_PKG_USING_HASH_MATCH is not set
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
 # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
 # CONFIG_PKG_USING_VOFA_PLUS is not set
 
@@ -626,83 +573,11 @@ CONFIG_RT_LWIP_USING_PING=y
 #
 # peripheral libraries and drivers
 #
-
-#
-# sensors drivers
-#
-# CONFIG_PKG_USING_FINGERPRINT is not set
-# CONFIG_PKG_USING_LSM6DSM is not set
-# CONFIG_PKG_USING_LSM6DSL is not set
-# CONFIG_PKG_USING_LPS22HB is not set
-# CONFIG_PKG_USING_HTS221 is not set
-# CONFIG_PKG_USING_LSM303AGR is not set
-# CONFIG_PKG_USING_BME280 is not set
-# CONFIG_PKG_USING_BME680 is not set
-# CONFIG_PKG_USING_BMA400 is not set
-# CONFIG_PKG_USING_BMI160_BMX160 is not set
-# CONFIG_PKG_USING_SPL0601 is not set
-# CONFIG_PKG_USING_MS5805 is not set
-# CONFIG_PKG_USING_DA270 is not set
-# CONFIG_PKG_USING_DF220 is not set
-# CONFIG_PKG_USING_HSHCAL001 is not set
-# CONFIG_PKG_USING_BH1750 is not set
-# CONFIG_PKG_USING_MPU6XXX is not set
-# CONFIG_PKG_USING_AHT10 is not set
-# CONFIG_PKG_USING_AP3216C is not set
-# CONFIG_PKG_USING_TSL4531 is not set
-# CONFIG_PKG_USING_DS18B20 is not set
-# CONFIG_PKG_USING_DHT11 is not set
-# CONFIG_PKG_USING_DHTXX is not set
-# CONFIG_PKG_USING_GY271 is not set
-# CONFIG_PKG_USING_GP2Y10 is not set
-# CONFIG_PKG_USING_SGP30 is not set
-# CONFIG_PKG_USING_HDC1000 is not set
-# CONFIG_PKG_USING_BMP180 is not set
-# CONFIG_PKG_USING_BMP280 is not set
-# CONFIG_PKG_USING_SHTC1 is not set
-# CONFIG_PKG_USING_BMI088 is not set
-# CONFIG_PKG_USING_HMC5883 is not set
-# CONFIG_PKG_USING_MAX6675 is not set
-# CONFIG_PKG_USING_TMP1075 is not set
-# CONFIG_PKG_USING_SR04 is not set
-# CONFIG_PKG_USING_CCS811 is not set
-# CONFIG_PKG_USING_PMSXX is not set
-# CONFIG_PKG_USING_RT3020 is not set
-# CONFIG_PKG_USING_MLX90632 is not set
-# CONFIG_PKG_USING_MLX90393 is not set
-# CONFIG_PKG_USING_MLX90392 is not set
-# CONFIG_PKG_USING_MLX90397 is not set
-# CONFIG_PKG_USING_MS5611 is not set
-# CONFIG_PKG_USING_MAX31865 is not set
-# CONFIG_PKG_USING_VL53L0X is not set
-# CONFIG_PKG_USING_INA260 is not set
-# CONFIG_PKG_USING_MAX30102 is not set
-# CONFIG_PKG_USING_INA226 is not set
-# CONFIG_PKG_USING_LIS2DH12 is not set
-# CONFIG_PKG_USING_HS300X is not set
-# CONFIG_PKG_USING_ZMOD4410 is not set
-# CONFIG_PKG_USING_ISL29035 is not set
-# CONFIG_PKG_USING_MMC3680KJ is not set
-# CONFIG_PKG_USING_QMP6989 is not set
-# CONFIG_PKG_USING_BALANCE is not set
+# 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_AD7746 is not set
 # CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-
-#
-# touch drivers
-#
-# CONFIG_PKG_USING_GT9147 is not set
-# CONFIG_PKG_USING_GT1151 is not set
-# CONFIG_PKG_USING_GT917S is not set
-# CONFIG_PKG_USING_GT911 is not set
-# CONFIG_PKG_USING_FT6206 is not set
-# CONFIG_PKG_USING_FT5426 is not set
-# CONFIG_PKG_USING_FT6236 is not set
-# CONFIG_PKG_USING_XPT2046_TOUCH is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
 # CONFIG_PKG_USING_AS7341 is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
 # CONFIG_PKG_USING_ESP_IDF is not set
@@ -729,9 +604,12 @@ CONFIG_RT_LWIP_USING_PING=y
 # 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
@@ -781,7 +659,6 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_PKG_USING_RFM300 is not set
 # CONFIG_PKG_USING_IO_INPUT_FILTER is not set
 # CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
 
 #
 # AI packages
@@ -796,12 +673,6 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_PKG_USING_QUEST is not set
 # CONFIG_PKG_USING_NAXOS is not set
 
-#
-# Signal Processing and Control Algorithm Packages
-#
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_UKAL is not set
-
 #
 # miscellaneous packages
 #
@@ -853,6 +724,7 @@ CONFIG_RT_LWIP_USING_PING=y
 # 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
@@ -879,10 +751,12 @@ CONFIG_RT_LWIP_USING_PING=y
 #
 # Sensors
 #
-# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
 # CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
@@ -967,7 +841,6 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
@@ -979,44 +852,11 @@ CONFIG_RT_LWIP_USING_PING=y
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
-# CONFIG_PKG_USING_SEEED_ITG3200 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
-# CONFIG_PKG_USING_SEEED_MP503 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
 
 #
 # Display
 #
 # CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-# CONFIG_PKG_USING_SEEED_TM1637 is not set
 
 #
 # Timing
@@ -1044,7 +884,6 @@ CONFIG_RT_LWIP_USING_PING=y
 #
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
 
 #
 # Other
@@ -1065,77 +904,19 @@ CONFIG_RT_LWIP_USING_PING=y
 #
 # Uncategorized
 #
-
-#
-# Privated Packages of RealThread
-#
-# CONFIG_PKG_USING_CODEC is not set
-# CONFIG_PKG_USING_PLAYER is not set
-# CONFIG_PKG_USING_MPLAYER is not set
-# CONFIG_PKG_USING_PERSIMMON_SRC is not set
-# CONFIG_PKG_USING_JS_PERSIMMON is not set
-# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
-
-#
-# Network Utilities
-#
-# CONFIG_PKG_USING_MDNS is not set
-# CONFIG_PKG_USING_UPNP is not set
-# CONFIG_PKG_USING_WICED is not set
-# CONFIG_PKG_USING_CLOUDSDK is not set
-# CONFIG_PKG_USING_POWER_MANAGER is not set
-# CONFIG_PKG_USING_RT_OTA is not set
-# CONFIG_PKG_USING_RTINSIGHT is not set
-# CONFIG_PKG_USING_SMARTCONFIG is not set
-# CONFIG_PKG_USING_RTX is not set
-# CONFIG_RT_USING_TESTCASE is not set
-# CONFIG_PKG_USING_NGHTTP2 is not set
-# CONFIG_PKG_USING_AVS is not set
-# CONFIG_PKG_USING_ALI_LINKKIT is not set
-# CONFIG_PKG_USING_STS is not set
-# CONFIG_PKG_USING_DLMS is not set
-# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
-# CONFIG_PKG_USING_ZBAR is not set
-# CONFIG_PKG_USING_MCF is not set
-# CONFIG_PKG_USING_URPC is not set
-# CONFIG_PKG_USING_DCM is not set
-# CONFIG_PKG_USING_EMQ is not set
-# CONFIG_PKG_USING_CFGM is not set
-# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
-# CONFIG_PKG_USING_SMODULE is not set
-# CONFIG_PKG_USING_SNFD is not set
-# CONFIG_PKG_USING_UDBD is not set
-# CONFIG_PKG_USING_BENCHMARK is not set
-# CONFIG_PKG_USING_UBJSON is not set
-# CONFIG_PKG_USING_DATATYPE is not set
-# CONFIG_PKG_USING_FASTFS is not set
-# CONFIG_PKG_USING_RIL is not set
-# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
-# CONFIG_PKG_USING_WATCH_APP_FWK is not set
-# CONFIG_PKG_USING_GUI_TEST is not set
-# CONFIG_PKG_USING_PMEM is not set
-# CONFIG_PKG_USING_LWRDP is not set
-# CONFIG_PKG_USING_MASAN is not set
-# CONFIG_PKG_USING_BSDIFF_LIB is not set
-# CONFIG_PKG_USING_PRC_DIFF is not set
-
-#
-# RT-Thread Smart
-#
-# CONFIG_PKG_USING_UKERNEL is not set
-# CONFIG_PKG_USING_TRACE_AGENT is not set
 CONFIG_SOC_VIRT64_AARCH64=y
 
 #
 # AARCH64 qemu virt64 configs
 #
+CONFIG_BSP_SUPPORT_FPU=y
 CONFIG_BSP_USING_UART=y
 CONFIG_RT_USING_UART0=y
 CONFIG_BSP_USING_RTC=y
-CONFIG_BSP_USING_ALARM=y
+# CONFIG_BSP_USING_ALARM is not set
 CONFIG_BSP_USING_PIN=y
 CONFIG_BSP_USING_VIRTIO_BLK=y
-CONFIG_BSP_USING_VIRTIO_NET=y
+# CONFIG_BSP_USING_VIRTIO_NET is not set
 CONFIG_BSP_USING_VIRTIO_CONSOLE=y
 CONFIG_BSP_USING_VIRTIO_GPU=y
 CONFIG_BSP_USING_VIRTIO_INPUT=y

+ 6 - 2
bsp/qemu-virt64-aarch64/Kconfig

@@ -21,10 +21,14 @@ source "$PKGS_DIR/Kconfig"
 config SOC_VIRT64_AARCH64
     bool
     select ARCH_ARMV8
-    select RT_USING_CACHE
     select ARCH_CPU_64BIT
+    select ARCH_ARM_MMU
+    select RT_USING_CACHE
     select RT_USING_COMPONENTS_INIT
     select RT_USING_USER_MAIN
+    select RT_USING_GIC
+    select BSP_USING_GIC
+    select ARCH_MM_MMU
     default y
 
-source "$BSP_DIR/driver/Kconfig"
+source "$BSP_DIR/drivers/Kconfig"

+ 18 - 4
bsp/qemu-virt64-aarch64/SConstruct

@@ -1,19 +1,33 @@
 import os
 import sys
 import rtconfig
+import re
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.join(os.getcwd(), '..', '..')
 
-from rtconfig import RTT_ROOT
 
 sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
 from building import *
 
 TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+TRACE_CONFIG = ""
+
+content = ""
+with open("rtconfig.h") as f:
+	for line in f.readlines():
+		if line.find("RT_BACKTRACE_FUNCTION_NAME") != -1:
+			for token in line.split(" "):
+				if re.match(r'RT_BACKTRACE_FUNCTION_NAME$', token, flags=0):
+					TRACE_CONFIG = " "
 
 DefaultEnvironment(tools=[])
 env = Environment(tools = ['mingw'],
-    AS   = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
-    CC   = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
-    CXX  = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
+    AS   = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS + TRACE_CONFIG,
+    CC   = rtconfig.CC, CFLAGS = rtconfig.CFLAGS + TRACE_CONFIG,
+    CXX  = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS  + TRACE_CONFIG,
     AR   = rtconfig.AR, ARFLAGS = '-rc',
     LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
 env.PrependENVPath('PATH', rtconfig.EXEC_PATH)

+ 21 - 1
bsp/qemu-virt64-aarch64/applications/console.c

@@ -10,9 +10,13 @@
 
 #include <rtthread.h>
 
+#if defined(RT_USING_POSIX_DEVIO) && defined(RT_USING_SMART)
+#include <console.h>
+#endif
+
 #include <virtio_console.h>
 
-int console_init()
+static int console_init()
 {
     rt_err_t status = RT_EOK;
     rt_device_t device = rt_device_find("virtio-console0");
@@ -44,7 +48,23 @@ static int console(int argc, char **argv)
         {
             rt_kprintf("console change to %s\n", argv[2]);
             rt_console_set_device(argv[2]);
+
+        #ifdef RT_USING_POSIX_DEVIO
+            {
+                rt_device_t dev = rt_device_find(argv[2]);
+
+                if (dev != RT_NULL)
+                {
+                    #ifdef RT_USING_SMART
+                        console_set_iodev(dev);
+                    #else
+                        rt_kprintf("TODO not supported\n");
+                    #endif
+                }
+            }
+        #else
             finsh_set_device(argv[2]);
+        #endif /* RT_USING_POSIX_DEVIO */
         }
         else
         {

+ 1 - 1
bsp/qemu-virt64-aarch64/applications/graphic.c

@@ -114,7 +114,7 @@ void graphic_thread(void *param)
 
             rt_device_control(device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
 
-            while (i < sizeof(cursor) / sizeof(rt_uint32_t))
+            while (i < sizeof(cursor) / 4)
             {
                 /* R: 0x4c G: 0xaf B: 0x50 A: 0.8 */
                 ((rt_uint32_t *)cursor)[i] = 0xcc4caf50;

+ 4 - 4
bsp/qemu-virt64-aarch64/applications/main.c

@@ -5,14 +5,14 @@
  *
  * Change Logs:
  * Date           Author       Notes
- * 2017-5-30      Bernard      the first version
+ * 2020/10/7      bernard      the first version
  */
 
-#include <rtthread.h>
+#include <stdio.h>
 
-int main(int argc, char** argv)
+int main(void)
 {
-    rt_kprintf("Hi, this is RT-Thread!!\n");
+    printf("hello rt-thread\n");
 
     return 0;
 }

+ 2 - 2
bsp/qemu-virt64-aarch64/applications/mnt.c

@@ -5,7 +5,7 @@
  *
  * Change Logs:
  * Date           Author       Notes
- * 2017-5-30      bernard      the first version
+ * 2021/08/19     bernard      the first version
  */
 
 #include <rtthread.h>
@@ -15,7 +15,7 @@
 
 int mnt_init(void)
 {
-    if(rt_device_find("virtio-blk0"))
+    if (rt_device_find("virtio-blk0"))
     {
         /* mount virtio-blk as root directory */
         if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0)

+ 1 - 1
bsp/qemu-virt64-aarch64/applications/pin.c

@@ -21,7 +21,7 @@ void qemu_gpio3_key_poweroff(void *args)
     rt_hw_cpu_shutdown();
 }
 
-int pin_init()
+static int pin_init()
 {
     rt_pin_attach_irq(3, PIN_IRQ_MODE_FALLING, qemu_gpio3_key_poweroff, RT_NULL);
     rt_pin_irq_enable(3, RT_TRUE);

+ 0 - 19
bsp/qemu-virt64-aarch64/driver/SConscript

@@ -1,19 +0,0 @@
-# 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')

+ 0 - 147
bsp/qemu-virt64-aarch64/driver/board.c

@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author         Notes
- * 2019-07-29     zdzn           first version
- * 2021-07-31     GuEe-GUI       config the memory/io address map
- * 2021-09-11     GuEe-GUI       remove do-while in rt_hw_timer_isr
- * 2021-12-28     GuEe-GUI       add smp support
- */
-
-#include <rthw.h>
-#include <rtthread.h>
-
-#include "board.h"
-#include <mmu.h>
-#include <gic.h>
-#include <gicv3.h>
-#include <psci.h>
-#include <gtimer.h>
-#include <cpuport.h>
-#include <interrupt.h>
-
-#include "drv_uart.h"
-
-struct mem_desc platform_mem_desc[] =
-{
-    {0x40000000, 0x80000000, 0x40000000, NORMAL_MEM},
-    {PL031_RTC_BASE, PL031_RTC_BASE + 0x1000, PL031_RTC_BASE, DEVICE_MEM},
-    {PL061_GPIO_BASE, PL061_GPIO_BASE + 0x1000, PL061_GPIO_BASE, DEVICE_MEM},
-    {PL011_UART0_BASE, PL011_UART0_BASE + 0x1000, PL011_UART0_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]);
-
-void idle_wfi(void)
-{
-    asm volatile ("wfi");
-}
-
-/**
- *  Initialize the Hardware related stuffs. Called from rtthread_startup()
- *  after interrupt disabled.
- */
-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_HVC, 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 poweroff(void)
-{
-    arm_psci_system_off();
-}
-MSH_CMD_EXPORT(poweroff, poweroff...);
-
-void rt_hw_cpu_shutdown()
-{
-    rt_kprintf("shutdown...\n");
-
-    poweroff();
-}
-
-void reboot(void)
-{
-    arm_psci_system_reboot();
-}
-MSH_CMD_EXPORT(reboot, reboot...);
-
-#ifdef RT_USING_SMP
-void rt_hw_secondary_cpu_up(void)
-{
-    int i;
-    extern void secondary_cpu_start(void);
-    extern rt_uint64_t rt_cpu_mpidr_early[];
-
-    for (i = 1; i < RT_CPUS_NR; ++i)
-    {
-        arm_psci_cpu_on(rt_cpu_mpidr_early[i], (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());
-#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);
-
-    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

+ 0 - 24
bsp/qemu-virt64-aarch64/driver/board.h

@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2006-2021, 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 <virt.h>
-
-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

+ 0 - 206
bsp/qemu-virt64-aarch64/driver/drv_rtc.c

@@ -1,206 +0,0 @@
-/*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author         Notes
- * 2021-11-4      GuEe-GUI       first version
- * 2022-07-15     GuEe-GUI       add alarm ops support
- */
-
-#include <rthw.h>
-#include <rtthread.h>
-#include <rtdevice.h>
-#include <sys/time.h>
-#include <board.h>
-
-#include "drv_rtc.h"
-
-#ifdef BSP_USING_RTC
-
-#define RTC_DR      0x00    /* data read register */
-#define RTC_MR      0x04    /* match register */
-#define RTC_LR      0x08    /* data load register */
-#define RTC_CR      0x0c    /* control register */
-#define RTC_IMSC    0x10    /* interrupt mask and set register */
-#define RTC_RIS     0x14    /* raw interrupt status register */
-#define RTC_MIS     0x18    /* masked interrupt status register */
-#define RTC_ICR     0x1c    /* interrupt clear register */
-
-#define RTC_CR_OPEN     1
-#define RTC_CR_CLOSE    0
-#define RTC_BIT_AI      (1 << 0)    /* Alarm interrupt bit */
-#define RTC_BIT_PI      (1 << 1)    /* Periodic interrupt bit. ST variants only. */
-
-static rt_rtc_dev_t _rtc_device;
-#ifdef RT_USING_ALARM
-static struct rt_rtc_wkalarm _wkalarm;
-#endif
-
-rt_inline rt_uint32_t pl031_read32(rt_ubase_t offset)
-{
-    return (*((volatile unsigned int *)(PL031_RTC_BASE + offset)));
-}
-
-rt_inline void pl031_write32(rt_ubase_t offset, rt_uint32_t value)
-{
-    (*((volatile unsigned int *)(PL031_RTC_BASE + offset))) = value;
-}
-
-static rt_err_t pl031_rtc_init(void)
-{
-    pl031_write32(RTC_CR, RTC_CR_OPEN);
-
-    return RT_EOK;
-}
-
-static rt_err_t pl031_get_secs(time_t *sec)
-{
-    if (sec != RT_NULL)
-    {
-        *(rt_uint32_t *)sec = pl031_read32(RTC_DR);
-
-        return RT_EOK;
-    }
-
-    return -RT_EINVAL;
-}
-
-static rt_err_t pl031_set_secs(time_t *sec)
-{
-    if (sec != RT_NULL)
-    {
-        pl031_write32(RTC_LR, *(rt_uint32_t *)sec);
-
-        return RT_EOK;
-    }
-
-    return -RT_EINVAL;
-}
-
-#ifdef RT_USING_ALARM
-static rt_err_t pl031_set_alarm(struct rt_rtc_wkalarm *alarm)
-{
-    if (alarm != RT_NULL)
-    {
-        rt_uint32_t imsc, time;
-
-        _wkalarm.enable = alarm->enable;
-        _wkalarm.tm_hour = alarm->tm_hour;
-        _wkalarm.tm_min = alarm->tm_min;
-        _wkalarm.tm_sec = alarm->tm_sec;
-
-        time = pl031_read32(RTC_DR);
-
-        /* Back to 08:00 today */
-        time = time / (3600 * 24) * (3600 * 24);
-
-        /* Get alarm time */
-        time += alarm->tm_hour * 3600 + alarm->tm_min * 60 + alarm->tm_sec;
-
-        pl031_write32(RTC_MR, time);
-
-        /* Clear any pending alarm interrupts. */
-        pl031_write32(RTC_ICR, RTC_BIT_AI);
-
-        imsc = pl031_read32(RTC_IMSC);
-
-        if (alarm->enable)
-        {
-            pl031_write32(RTC_IMSC, imsc | RTC_BIT_AI);
-        }
-        else
-        {
-            pl031_write32(RTC_IMSC, imsc & ~RTC_BIT_AI);
-        }
-
-        return RT_EOK;
-    }
-
-    return -RT_EINVAL;
-}
-
-static rt_err_t pl031_get_alarm(struct rt_rtc_wkalarm *alarm)
-{
-    if (alarm != RT_NULL)
-    {
-        *alarm = _wkalarm;
-
-        return RT_EOK;
-    }
-
-    return -RT_EINVAL;
-}
-#endif /* RT_USING_ALARM */
-
-static rt_err_t pl031_get_timeval(struct timeval *tv)
-{
-    if (tv != RT_NULL)
-    {
-        tv->tv_sec = pl031_read32(RTC_DR);
-
-        return RT_EOK;
-    }
-
-    return -RT_EINVAL;
-}
-
-static rt_err_t pl031_set_timeval(struct timeval *tv)
-{
-    if (tv != RT_NULL)
-    {
-        pl031_write32(RTC_LR, *(rt_uint32_t *)tv->tv_sec);
-
-        return RT_EOK;
-    }
-
-    return -RT_EINVAL;
-}
-
-static const struct rt_rtc_ops rtc_ops =
-{
-    .init       = pl031_rtc_init,
-    .get_secs   = pl031_get_secs,
-    .set_secs   = pl031_set_secs,
-#ifdef RT_USING_ALARM
-    .get_alarm  = pl031_get_alarm,
-    .set_alarm  = pl031_set_alarm,
-#else
-    .get_alarm  = RT_NULL,
-    .set_alarm  = RT_NULL,
-#endif
-    .get_timeval = pl031_get_timeval,
-    .set_timeval = pl031_set_timeval,
-};
-
-#ifdef RT_USING_ALARM
-static void rt_hw_rtc_isr(int irqno, void *param)
-{
-    rt_uint32_t rtcmis = pl031_read32(RTC_MIS);
-
-    if (rtcmis & RTC_BIT_AI)
-    {
-        pl031_write32(RTC_ICR, RTC_BIT_AI);
-
-        rt_alarm_update(&_rtc_device.parent, 1);
-    }
-}
-#endif /* RT_USING_ALARM */
-
-int rt_hw_rtc_init(void)
-{
-    _rtc_device.ops = &rtc_ops;
-
-    /* register a rtc device */
-    rt_hw_rtc_register(&_rtc_device, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL);
-
-#ifdef RT_USING_ALARM
-    rt_hw_interrupt_install(PL031_RTC_IRQNUM, rt_hw_rtc_isr, RT_NULL, "rtc");
-    rt_hw_interrupt_umask(PL031_RTC_IRQNUM);
-#endif /* RT_USING_ALARM */
-
-    return 0;
-}
-INIT_DEVICE_EXPORT(rt_hw_rtc_init);
-#endif /* BSP_USING_RTC */

+ 0 - 324
bsp/qemu-virt64-aarch64/driver/virtio/virtio.c

@@ -1,324 +0,0 @@
-/*
- * 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 <rtthread.h>
-#include <cpuport.h>
-
-#include <virtio.h>
-
-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 status;
-
-    _virtio_dev_check(dev);
-
-    status = dev->mmio_config->interrupt_status;
-
-    if (status != 0)
-    {
-        dev->mmio_config->interrupt_ack = status;
-    }
-}
-
-rt_bool_t virtio_has_feature(struct virtio_device *dev, rt_uint32_t feature_bit)
-{
-    _virtio_dev_check(dev);
-
-    return !!(dev->mmio_config->device_features & (1UL << feature_bit));
-}
-
-rt_err_t virtio_queues_alloc(struct virtio_device *dev, rt_size_t queues_num)
-{
-    _virtio_dev_check(dev);
-
-    dev->queues = rt_malloc(sizeof(struct virtq) * queues_num);
-
-    if (dev->queues != RT_NULL)
-    {
-        dev->queues_num = queues_num;
-
-        return RT_EOK;
-    }
-
-    return -RT_ENOMEM;
-}
-
-void virtio_queues_free(struct virtio_device *dev)
-{
-    if (dev->queues != RT_NULL)
-    {
-        dev->queues_num = 0;
-        rt_free(dev->queues);
-    }
-}
-
-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_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);
-
-    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 = VIRTIO_VA2PA(pages) >> VIRTIO_PAGE_SHIFT;
-
-    queue->num = ring_size;
-    queue->desc = (struct virtq_desc *)((rt_ubase_t)pages);
-    queue->avail = (struct virtq_avail *)(((rt_ubase_t)pages) + 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;
-    }
-
-    queue->free_count = ring_size;
-
-    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;
-    struct virtq *queue;
-
-    _virtio_dev_check(dev);
-
-    RT_ASSERT(queue_index < dev->queues_num);
-
-    queue = &dev->queues[queue_index];
-
-    if (queue->free_count > 0)
-    {
-        rt_size_t ring_size = queue->num;
-
-        for (i = 0; i < ring_size; ++i)
-        {
-            if (queue->free[i])
-            {
-                queue->free[i] = RT_FALSE;
-                queue->free_count--;
-
-                return (rt_uint16_t)i;
-            }
-        }
-    }
-
-    return VIRTQ_INVALID_DESC_ID;
-}
-
-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 < dev->queues_num);
-    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;
-
-    queue->free_count++;
-}
-
-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);
-
-    if (dev->queues[queue_index].free_count < count)
-    {
-        return -RT_ERROR;
-    }
-
-    for (i = 0; i < count; ++i)
-    {
-        indexs[i] = virtio_alloc_desc(dev, queue_index);
-
-        if (indexs[i] == VIRTQ_INVALID_DESC_ID)
-        {
-            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;
-}

+ 0 - 141
bsp/qemu-virt64-aarch64/driver/virtio/virtio.h

@@ -1,141 +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
- * 2021-11-11     GuEe-GUI     modify to virtio common interface
- */
-
-#ifndef __VIRTIO_H__
-#define __VIRTIO_H__
-
-#include <rthw.h>
-#include <rtdef.h>
-
-#ifndef RT_USING_VIRTIO_VERSION
-#define RT_USING_VIRTIO_VERSION 0x1
-#endif
-
-#include <virtio_mmio.h>
-#include <virtio_queue.h>
-
-#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_PA2VA(paddr)         ((rt_ubase_t)paddr)
-#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
-{
-    /* 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 1.2 */
-    VIRTIO_DEVICE_ID_AUDIO          = 25,   /* Audio device */
-    VIRTIO_DEVICE_ID_FS             = 26,   /* File system device */
-    VIRTIO_DEVICE_ID_PMEM           = 27,   /* PMEM device */
-    VIRTIO_DEVICE_ID_RPMB           = 28,   /* RPMB device */
-    VIRTIO_DEVICE_ID_MAC80211_HWSIM = 29,   /* Mac80211 hwsim wireless simulation device */
-    VIRTIO_DEVICE_ID_VIDEO_ENCODER  = 30,   /* Video encoder device */
-    VIRTIO_DEVICE_ID_VIDEO_DECODER  = 31,   /* Video decoder device */
-    VIRTIO_DEVICE_ID_SCMI           = 32,   /* SCMI device */
-    VIRTIO_DEVICE_ID_NITRO_SEC_MOD  = 33,   /* NitroSecureModule */
-    VIRTIO_DEVICE_ID_I2C_ADAPTER    = 34,   /* I2C adapter */
-    VIRTIO_DEVICE_ID_WATCHDOG       = 35,   /* Watchdog */
-    VIRTIO_DEVICE_ID_CAN            = 36,   /* CAN device */
-    VIRTIO_DEVICE_ID_DMABUF         = 37,   /* Virtio dmabuf */
-    VIRTIO_DEVICE_ID_PARAM_SERV     = 38,   /* Parameter Server */
-    VIRTIO_DEVICE_ID_AUDIO_POLICY   = 39,   /* Audio policy device */
-    VIRTIO_DEVICE_ID_BT             = 40,   /* Bluetooth device */
-    VIRTIO_DEVICE_ID_GPIO           = 41,   /* GPIO device */
-    VIRTIO_DEVICE_ID_RDMA           = 42,   /* RDMA device */
-
-    VIRTIO_DEVICE_TYPE_SIZE
-};
-
-struct virtio_device
-{
-    rt_uint32_t irq;
-
-    struct virtq *queues;
-    rt_size_t queues_num;
-
-    union
-    {
-        rt_ubase_t *mmio_base;
-        struct virtio_mmio_config *mmio_config;
-    };
-
-#ifdef RT_USING_SMP
-    struct rt_spinlock spinlock;
-#endif
-
-    void *priv;
-};
-
-typedef rt_err_t (*virtio_device_init_handler)(rt_ubase_t *mmio_base, rt_uint32_t irq);
-
-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_bool_t virtio_has_feature(struct virtio_device *dev, rt_uint32_t feature_bit);
-
-rt_err_t virtio_queues_alloc(struct virtio_device *dev, rt_size_t queues_num);
-void virtio_queues_free(struct virtio_device *dev);
-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__ */

+ 0 - 240
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.c

@@ -1,240 +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
- * 2021-11-11     GuEe-GUI     using virtio common interface
- */
-
-#include <rthw.h>
-#include <rtthread.h>
-#include <cpuport.h>
-
-#ifdef BSP_USING_VIRTIO_BLK
-
-#include <virtio_blk.h>
-
-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))
-    {
-#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_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, VIRTIO_BLK_QUEUE, 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, VIRTIO_BLK_QUEUE, idx[1],
-            VIRTIO_VA2PA(buffer), VIRTIO_BLK_BUF_DATA_SIZE, flags | VIRTQ_DESC_F_NEXT, idx[2]);
-
-    virtio_fill_desc(virtio_dev, VIRTIO_BLK_QUEUE, idx[2],
-            VIRTIO_VA2PA(&virtio_blk_dev->info[idx[0]].status), sizeof(rt_uint8_t), VIRTQ_DESC_F_WRITE, 0);
-
-    virtio_submit_chain(virtio_dev, VIRTIO_BLK_QUEUE, idx[0]);
-
-    virtio_queue_notify(virtio_dev, VIRTIO_BLK_QUEUE);
-
-    /* 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, VIRTIO_BLK_QUEUE, 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->config->capacity;
-        }
-        break;
-    default:
-        status = -RT_EINVAL;
-        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;
-    struct virtq *queue = &virtio_dev->queues[VIRTIO_BLK_QUEUE];
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    virtio_interrupt_ack(virtio_dev);
-    rt_hw_dsb();
-
-    /* The device increments disk.used->idx when it adds an entry to the used ring */
-    while (queue->used_idx != queue->used->idx)
-    {
-        rt_hw_dsb();
-        id = queue->used->ring[queue->used_idx % queue->num].id;
-
-        RT_ASSERT(virtio_blk_dev->info[id].status == 0);
-
-        /* Done with buffer */
-        virtio_blk_dev->info[id].valid = RT_FALSE;
-
-        queue->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;
-
-    virtio_blk_dev->config = (struct virtio_blk_config *)virtio_dev->mmio_config->config;
-
-#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);
-
-    if (virtio_queues_alloc(virtio_dev, 1) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    /* Initialize queue 0 */
-    if (virtio_queue_init(virtio_dev, 0, VIRTIO_BLK_QUEUE_RING_SIZE) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    virtio_blk_dev->parent.type = RT_Device_Class_Block;
-    virtio_blk_dev->parent.ops  = &virtio_blk_ops;
-
-    rt_snprintf(dev_name, RT_NAME_MAX, "virtio-blk%d", 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);
-
-_alloc_fail:
-
-    if (virtio_blk_dev != RT_NULL)
-    {
-        virtio_queues_free(virtio_dev);
-        rt_free(virtio_blk_dev);
-    }
-    return -RT_ENOMEM;
-}
-#endif /* BSP_USING_VIRTIO_BLK */

+ 0 - 106
bsp/qemu-virt64-aarch64/driver/virtio/virtio_blk.h

@@ -1,106 +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
- * 2021-11-11     GuEe-GUI     using virtio common interface
- */
-
-#ifndef __VIRTIO_BLK_H__
-#define __VIRTIO_BLK_H__
-
-#include <rtdef.h>
-
-#include <virtio.h>
-
-#define VIRTIO_BLK_QUEUE            0
-#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_config
-{
-    rt_uint64_t capacity;
-    rt_uint32_t size_max;
-    rt_uint32_t seg_max;
-
-    struct virtio_blk_geometry
-    {
-        rt_uint16_t cylinders;
-        rt_uint8_t heads;
-        rt_uint8_t sectors;
-    } geometry;
-
-    rt_uint32_t blk_size;
-
-    struct virtio_blk_topology
-    {
-        /* # Of logical blocks per physical block (log2) */
-        rt_uint8_t physical_block_exp;
-        /* Offset of first aligned logical block */
-        rt_uint8_t alignment_offset;
-        /* Suggested minimum I/O size in blocks */
-        rt_uint16_t min_io_size;
-        /* Optimal (suggested maximum) I/O size in blocks */
-        rt_uint32_t opt_io_size;
-    } topology;
-
-    rt_uint8_t writeback;
-    rt_uint8_t unused0;
-    rt_uint16_t num_queues;
-    rt_uint32_t max_discard_sectors;
-    rt_uint32_t max_discard_seg;
-    rt_uint32_t discard_sector_alignment;
-    rt_uint32_t max_write_zeroes_sectors;
-    rt_uint32_t max_write_zeroes_seg;
-    rt_uint8_t write_zeroes_may_unmap;
-    rt_uint8_t unused1[3];
-    rt_uint32_t max_secure_erase_sectors;
-    rt_uint32_t max_secure_erase_seg;
-    rt_uint32_t secure_erase_sector_alignment;
-} __attribute__((packed));
-
-struct virtio_blk_device
-{
-    struct rt_device parent;
-
-    struct virtio_device virtio_dev;
-
-    struct virtio_blk_config *config;
-
-    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__ */

+ 0 - 734
bsp/qemu-virt64-aarch64/driver/virtio/virtio_console.c

@@ -1,734 +0,0 @@
-/*
- * 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 <rthw.h>
-#include <rtthread.h>
-#include <cpuport.h>
-
-#ifdef BSP_USING_VIRTIO_CONSOLE
-
-#include <virtio_console.h>
-
-struct port_device
-{
-    struct rt_device parent;
-
-    rt_list_t node;
-    rt_uint32_t port_id;
-    rt_bool_t rx_notify;
-    rt_bool_t need_destroy;
-
-    struct virtio_console_device *console;
-
-    struct virtq *queue_rx, *queue_tx;
-    rt_uint32_t queue_rx_index, queue_tx_index;
-
-#ifdef RT_USING_SMP
-    struct rt_spinlock spinlock_rx, spinlock_tx;
-#endif
-
-    struct
-    {
-        char rx_char, tx_char;
-    } info[VIRTIO_CONSOLE_QUEUE_SIZE];
-};
-
-static void virtio_console_send_ctrl(struct virtio_console_device *virtio_console_dev,
-        struct virtio_console_control *ctrl)
-{
-    rt_uint16_t id;
-    void *addr;
-    struct virtio_device *virtio_dev = &virtio_console_dev->virtio_dev;
-    struct virtq *queue_ctrl_tx;
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    queue_ctrl_tx = &virtio_dev->queues[VIRTIO_CONSOLE_QUEUE_CTRL_TX];
-
-    id = queue_ctrl_tx->avail->idx % queue_ctrl_tx->num;
-    addr = &virtio_console_dev->info[id].tx_ctrl;
-
-    rt_memcpy(addr, ctrl, sizeof(struct virtio_console_control));
-
-    virtio_free_desc(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_TX, id);
-
-    virtio_fill_desc(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_TX, id,
-            VIRTIO_VA2PA(addr), sizeof(struct virtio_console_control), 0, 0);
-
-    virtio_submit_chain(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_TX, id);
-
-    virtio_queue_notify(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_TX);
-
-    virtio_alloc_desc(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_TX);
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-}
-
-static rt_err_t virtio_console_port_create(struct virtio_console_device *virtio_console_dev,
-    const struct rt_device_ops *ops)
-{
-    rt_uint32_t port_id;
-    char dev_name[RT_NAME_MAX];
-    struct port_device *port_dev, *prev_port_dev = RT_NULL;
-    struct virtio_device *virtio_dev = &virtio_console_dev->virtio_dev;
-
-    if (virtio_console_dev->port_nr > 0 && !virtio_has_feature(virtio_dev, VIRTIO_CONSOLE_F_MULTIPORT))
-    {
-        return -RT_ENOSYS;
-    }
-
-    if (virtio_console_dev->port_nr >= virtio_console_dev->max_port_nr)
-    {
-        return -RT_EFULL;
-    }
-
-    port_id = 0;
-
-    /* The port device list is always ordered, so just find next number for id */
-    rt_list_for_each_entry(port_dev, &virtio_console_dev->port_head, node)
-    {
-        if (port_dev->port_id != port_id)
-        {
-            break;
-        }
-        ++port_id;
-        prev_port_dev = port_dev;
-    }
-
-    port_dev = rt_malloc(sizeof(struct port_device));
-
-    if (port_dev == RT_NULL)
-    {
-        return -RT_ENOMEM;
-    }
-
-    port_dev->parent.type = RT_Device_Class_Char;
-    port_dev->parent.ops  = ops;
-
-    port_dev->parent.rx_indicate = RT_NULL;
-    port_dev->parent.tx_complete = RT_NULL;
-
-    rt_list_init(&port_dev->node);
-    port_dev->port_id = port_id;
-    port_dev->need_destroy = RT_FALSE;
-    port_dev->rx_notify = RT_TRUE;
-    port_dev->console = virtio_console_dev;
-    port_dev->queue_rx_index = VIRTIO_CONSOLE_PORT_QUEUE_INDEX(port_dev->port_id, VIRTIO_CONSOLE_QUEUE_DATA_RX);
-    port_dev->queue_tx_index = VIRTIO_CONSOLE_PORT_QUEUE_INDEX(port_dev->port_id, VIRTIO_CONSOLE_QUEUE_DATA_TX);
-    port_dev->queue_rx = &virtio_dev->queues[port_dev->queue_rx_index];
-    port_dev->queue_tx = &virtio_dev->queues[port_dev->queue_tx_index];
-
-#ifdef RT_USING_SMP
-    rt_spin_lock_init(&port_dev->spinlock_rx);
-    rt_spin_lock_init(&port_dev->spinlock_tx);
-#endif
-
-    rt_snprintf(dev_name, RT_NAME_MAX, "vport%dp%d", virtio_console_dev->console_id, port_id);
-
-    if (rt_device_register((rt_device_t)port_dev, dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX) != RT_EOK)
-    {
-        rt_free(port_dev);
-
-        return -RT_ERROR;
-    }
-
-    if (prev_port_dev != RT_NULL)
-    {
-        rt_list_insert_after(&prev_port_dev->node, &port_dev->node);
-    }
-    else
-    {
-        /* Port0 */
-        rt_list_insert_after(&virtio_console_dev->port_head, &port_dev->node);
-    }
-
-    virtio_console_dev->port_nr++;
-
-    return RT_EOK;
-}
-
-static void virtio_console_port_destroy(struct virtio_console_device *virtio_console_dev,
-        struct port_device *port_dev)
-{
-    struct virtio_console_control set_ctrl;
-
-    set_ctrl.id = port_dev->port_id;
-    set_ctrl.event = VIRTIO_CONSOLE_PORT_OPEN;
-    set_ctrl.value = 0;
-
-    virtio_console_send_ctrl(virtio_console_dev, &set_ctrl);
-
-    virtio_console_dev->port_nr--;
-
-    rt_list_remove(&port_dev->node);
-
-    rt_device_unregister((rt_device_t)port_dev);
-
-    rt_free(port_dev);
-}
-
-static rt_err_t virtio_console_port_init(rt_device_t dev)
-{
-    rt_uint16_t id;
-    rt_uint16_t idx[VIRTIO_CONSOLE_QUEUE_SIZE];
-    rt_uint16_t rx_queue_index, tx_queue_index;
-    struct port_device *port_dev = (struct port_device *)dev;
-    struct virtio_console_device *virtio_console_dev = port_dev->console;
-    struct virtio_device *virtio_dev = &virtio_console_dev->virtio_dev;
-    struct virtq *queue_rx, *queue_tx;
-
-    rx_queue_index = VIRTIO_CONSOLE_PORT_QUEUE_INDEX(port_dev->port_id, VIRTIO_CONSOLE_QUEUE_DATA_RX);
-    tx_queue_index = VIRTIO_CONSOLE_PORT_QUEUE_INDEX(port_dev->port_id, VIRTIO_CONSOLE_QUEUE_DATA_TX);
-
-    queue_rx = &virtio_dev->queues[rx_queue_index];
-    queue_tx = &virtio_dev->queues[tx_queue_index];
-
-    virtio_alloc_desc_chain(virtio_dev, rx_queue_index, queue_rx->num, idx);
-    virtio_alloc_desc_chain(virtio_dev, tx_queue_index, queue_tx->num, idx);
-
-    for (id = 0; id < queue_rx->num; ++id)
-    {
-        void *addr = &port_dev->info[id].rx_char;
-
-        virtio_fill_desc(virtio_dev, rx_queue_index, id,
-                VIRTIO_VA2PA(addr), sizeof(char), VIRTQ_DESC_F_WRITE, 0);
-
-        queue_rx->avail->ring[id] = id;
-    }
-    rt_hw_dsb();
-
-    queue_rx->avail->flags = 0;
-    queue_rx->avail->idx = queue_rx->num;
-
-    queue_rx->used_idx = queue_rx->used->idx;
-
-    queue_tx->avail->flags = VIRTQ_AVAIL_F_NO_INTERRUPT;
-    queue_tx->avail->idx = 0;
-
-    virtio_queue_notify(virtio_dev, rx_queue_index);
-
-    if (virtio_has_feature(virtio_dev, VIRTIO_CONSOLE_F_MULTIPORT))
-    {
-        struct virtio_console_control set_ctrl;
-
-        set_ctrl.id = VIRTIO_CONSOLE_PORT_BAD_ID;
-        set_ctrl.event = VIRTIO_CONSOLE_DEVICE_READY;
-        set_ctrl.value = 1;
-
-        virtio_console_send_ctrl(virtio_console_dev, &set_ctrl);
-    }
-
-    return RT_EOK;
-}
-
-static rt_err_t virtio_console_port_open(rt_device_t dev, rt_uint16_t oflag)
-{
-    struct port_device *port_dev = (struct port_device *)dev;
-
-    /* Can't use by others, just support only one */
-    if (port_dev->parent.ref_count > 1)
-    {
-        return -RT_EBUSY;
-    }
-
-    if (port_dev->port_id == 0 && virtio_has_feature(&port_dev->console->virtio_dev, VIRTIO_CONSOLE_F_MULTIPORT))
-    {
-        /* Port0 is reserve in multiport */
-        return -RT_ERROR;
-    }
-
-    port_dev->rx_notify = RT_TRUE;
-
-    return RT_EOK;
-}
-
-static rt_err_t virtio_console_port_close(rt_device_t dev)
-{
-    struct port_device *port_dev = (struct port_device *)dev;
-
-    if (port_dev->need_destroy)
-    {
-        virtio_console_port_destroy(port_dev->console, port_dev);
-
-        /*
-         * We released the device memory in virtio_console_port_destroy,
-         * rt_device_close has not finished yet, make the return value
-         * to empty so that rt_device_close will not access the device memory.
-         */
-        return -RT_EEMPTY;
-    }
-
-    port_dev->rx_notify = RT_FALSE;
-
-    return RT_EOK;
-}
-
-static rt_size_t virtio_console_port_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
-{
-    rt_off_t i = 0;
-    rt_uint16_t id;
-    rt_uint32_t len;
-    struct port_device *port_dev = (struct port_device *)dev;
-    struct virtio_device *virtio_dev = &port_dev->console->virtio_dev;
-    rt_uint32_t queue_rx_index = port_dev->queue_rx_index;
-    struct virtq *queue_rx = port_dev->queue_rx;
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&port_dev->spinlock_rx);
-#endif
-
-    while (i < size)
-    {
-        if (queue_rx->used_idx == queue_rx->used->idx)
-        {
-            break;
-        }
-        rt_hw_dsb();
-
-        id = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].id;
-        len = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].len;
-
-        if (len > sizeof(char))
-        {
-            rt_kprintf("%s: Receive buffer's size = %u is too big!\n", port_dev->parent.parent.name, len);
-            len = sizeof(char);
-        }
-
-        *((char *)buffer + i) = port_dev->info[id].rx_char;
-
-        queue_rx->used_idx++;
-
-        virtio_submit_chain(virtio_dev, queue_rx_index, id);
-
-        virtio_queue_notify(virtio_dev, queue_rx_index);
-
-        i += len;
-    }
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&port_dev->spinlock_rx, level);
-#endif
-
-    size = i;
-
-    return size;
-}
-
-static rt_size_t virtio_console_port_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
-{
-    char ch = 0;
-    rt_off_t i = 0;
-    rt_uint16_t id;
-    struct port_device *port_dev = (struct port_device *)dev;
-    struct virtio_device *virtio_dev = &port_dev->console->virtio_dev;
-    rt_uint32_t queue_tx_index = port_dev->queue_tx_index;
-    struct virtq *queue_tx = port_dev->queue_tx;
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&port_dev->spinlock_tx);
-#endif
-
-    while (i < size || ch == '\r')
-    {
-        id = queue_tx->avail->idx % queue_tx->num;
-
-        /* Keep the way until 'new line' are unified */
-        if (ch != '\r')
-        {
-            ch = *((const char *)buffer + i);
-        }
-        else
-        {
-            i -= sizeof(char);
-        }
-
-        port_dev->info[id].tx_char = ch;
-
-        ch = (ch == '\n' ? '\r' : 0);
-
-        virtio_free_desc(virtio_dev, queue_tx_index, id);
-
-        virtio_fill_desc(virtio_dev, queue_tx_index, id,
-                VIRTIO_VA2PA(&port_dev->info[id].tx_char), sizeof(char), 0, 0);
-
-        virtio_submit_chain(virtio_dev, queue_tx_index, id);
-
-        virtio_queue_notify(virtio_dev, queue_tx_index);
-
-        virtio_alloc_desc(virtio_dev, queue_tx_index);
-
-        i += sizeof(char);
-    }
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&port_dev->spinlock_tx, level);
-#endif
-
-    return size;
-}
-
-static rt_err_t virtio_console_port_control(rt_device_t dev, int cmd, void *args)
-{
-    rt_err_t status = RT_EOK;
-    struct port_device *port_dev = (struct port_device *)dev;
-
-    switch (cmd)
-    {
-    case RT_DEVICE_CTRL_CLR_INT:
-        /* Disable RX */
-        port_dev->rx_notify = RT_FALSE;
-        break;
-    case RT_DEVICE_CTRL_SET_INT:
-        /* Enable RX */
-        port_dev->rx_notify = RT_TRUE;
-        break;
-    case VIRTIO_DEVICE_CTRL_CONSOLE_PORT_DESTROY:
-        {
-            port_dev->need_destroy = RT_TRUE;
-            port_dev->rx_notify = RT_FALSE;
-        }
-        break;
-    default:
-        status = -RT_EINVAL;
-        break;
-    }
-
-    return status;
-}
-
-const static struct rt_device_ops virtio_console_port_ops =
-{
-    virtio_console_port_init,
-    virtio_console_port_open,
-    virtio_console_port_close,
-    virtio_console_port_read,
-    virtio_console_port_write,
-    virtio_console_port_control
-};
-
-static rt_err_t virtio_console_init(rt_device_t dev)
-{
-    struct virtio_console_device *virtio_console_dev = (struct virtio_console_device *)dev;
-    struct virtio_device *virtio_dev = &virtio_console_dev->virtio_dev;
-
-    if (virtio_has_feature(virtio_dev, VIRTIO_CONSOLE_F_MULTIPORT))
-    {
-        rt_uint16_t id;
-        rt_uint16_t idx[VIRTIO_CONSOLE_QUEUE_SIZE];
-        struct virtq *queue_ctrl_rx, *queue_ctrl_tx;
-
-        queue_ctrl_rx = &virtio_dev->queues[VIRTIO_CONSOLE_QUEUE_CTRL_RX];
-        queue_ctrl_tx = &virtio_dev->queues[VIRTIO_CONSOLE_QUEUE_CTRL_TX];
-
-        virtio_alloc_desc_chain(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_RX, queue_ctrl_rx->num, idx);
-        virtio_alloc_desc_chain(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_TX, queue_ctrl_tx->num, idx);
-
-        for (id = 0; id < queue_ctrl_rx->num; ++id)
-        {
-            void *addr = &virtio_console_dev->info[id].rx_ctrl;
-
-            virtio_fill_desc(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_RX, id,
-                    VIRTIO_VA2PA(addr), sizeof(struct virtio_console_control), VIRTQ_DESC_F_WRITE, 0);
-
-            queue_ctrl_rx->avail->ring[id] = id;
-        }
-        rt_hw_dsb();
-
-        queue_ctrl_rx->avail->flags = 0;
-        queue_ctrl_rx->avail->idx = queue_ctrl_rx->num;
-
-        queue_ctrl_rx->used_idx = queue_ctrl_rx->used->idx;
-
-        queue_ctrl_tx->avail->flags = VIRTQ_AVAIL_F_NO_INTERRUPT;
-        queue_ctrl_tx->avail->idx = 0;
-
-        virtio_queue_notify(virtio_dev, VIRTIO_CONSOLE_QUEUE_CTRL_RX);
-    }
-
-    return virtio_console_port_create(virtio_console_dev, &virtio_console_port_ops);
-}
-
-static rt_err_t virtio_console_control(rt_device_t dev, int cmd, void *args)
-{
-    rt_err_t status = RT_EOK;
-    struct virtio_console_device *virtio_console_dev = (struct virtio_console_device *)dev;
-
-    switch (cmd)
-    {
-    case VIRTIO_DEVICE_CTRL_CONSOLE_PORT_CREATE:
-        status = virtio_console_port_create(virtio_console_dev, &virtio_console_port_ops);
-        break;
-    default:
-        status = -RT_EINVAL;
-        break;
-    }
-
-    return status;
-}
-
-const static struct rt_device_ops virtio_console_ops =
-{
-    virtio_console_init,
-    RT_NULL,
-    RT_NULL,
-    RT_NULL,
-    RT_NULL,
-    virtio_console_control
-};
-
-static void virtio_console_isr(int irqno, void *param)
-{
-    rt_uint32_t id;
-    rt_uint32_t len;
-    struct port_device *port_dev;
-    struct virtio_console_device *virtio_console_dev = (struct virtio_console_device *)param;
-    struct virtio_device *virtio_dev = &virtio_console_dev->virtio_dev;
-    const char *dev_name = virtio_console_dev->parent.parent.name;
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    virtio_interrupt_ack(virtio_dev);
-    rt_hw_dsb();
-
-    do {
-        struct virtq *queue_rx;
-        struct virtio_console_control *ctrl, set_ctrl;
-
-        if (!virtio_has_feature(virtio_dev, VIRTIO_CONSOLE_F_MULTIPORT))
-        {
-            break;
-        }
-
-        queue_rx = &virtio_dev->queues[VIRTIO_CONSOLE_QUEUE_CTRL_RX];
-
-        if (queue_rx->used_idx == queue_rx->used->idx)
-        {
-            break;
-        }
-        rt_hw_dsb();
-
-        id = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].id;
-        len = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].len;
-
-        queue_rx->used_idx++;
-
-        if (len != sizeof(struct virtio_console_control))
-        {
-            rt_kprintf("%s: Invalid ctrl!\n", dev_name);
-            break;
-        }
-
-        ctrl = &virtio_console_dev->info[id].rx_ctrl;
-
-        switch (ctrl->event)
-        {
-        case VIRTIO_CONSOLE_PORT_ADD:
-            {
-                set_ctrl.id = ctrl->id;
-                set_ctrl.event = VIRTIO_CONSOLE_PORT_READY;
-                set_ctrl.value = 1;
-
-            #ifdef RT_USING_SMP
-                rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-            #endif
-
-                virtio_console_send_ctrl(virtio_console_dev, &set_ctrl);
-
-            #ifdef RT_USING_SMP
-                level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-            #endif
-            }
-            break;
-        case VIRTIO_CONSOLE_PORT_REMOVE:
-            break;
-        case VIRTIO_CONSOLE_RESIZE:
-            break;
-        case VIRTIO_CONSOLE_PORT_OPEN:
-            {
-                set_ctrl.id = ctrl->id;
-                set_ctrl.event = VIRTIO_CONSOLE_PORT_OPEN;
-                set_ctrl.value = 1;
-
-            #ifdef RT_USING_SMP
-                rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-            #endif
-
-                virtio_console_send_ctrl(virtio_console_dev, &set_ctrl);
-
-            #ifdef RT_USING_SMP
-                level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-            #endif
-            }
-            break;
-        case VIRTIO_CONSOLE_PORT_NAME:
-            break;
-        default:
-            rt_kprintf("%s: Unsupport ctrl[id: %d, event: %d, value: %d]!\n",
-                    dev_name, ctrl->id, ctrl->event, ctrl->value);
-            break;
-        }
-
-    } while (0);
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-
-    rt_list_for_each_entry(port_dev, &virtio_console_dev->port_head, node)
-    {
-        rt_uint32_t queue_rx_index = port_dev->queue_rx_index;
-        struct virtq *queue_rx = port_dev->queue_rx;
-
-#ifdef RT_USING_SMP
-        rt_base_t level = rt_spin_lock_irqsave(&port_dev->spinlock_rx);
-#endif
-
-        if (queue_rx->used_idx != queue_rx->used->idx)
-        {
-            rt_hw_dsb();
-
-            id = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].id;
-            len = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].len;
-
-            if (port_dev->parent.rx_indicate != RT_NULL && port_dev->rx_notify)
-            {
-            #ifdef RT_USING_SMP
-                rt_spin_unlock_irqrestore(&port_dev->spinlock_rx, level);
-            #endif
-                /* rx_indicate call virtio_console_port_read to inc used_idx */
-                port_dev->parent.rx_indicate(&port_dev->parent, len);
-
-            #ifdef RT_USING_SMP
-                level = rt_spin_lock_irqsave(&port_dev->spinlock_rx);
-            #endif
-            }
-            else
-            {
-                queue_rx->used_idx++;
-
-                virtio_submit_chain(virtio_dev, queue_rx_index, id);
-
-                virtio_queue_notify(virtio_dev, queue_rx_index);
-            }
-        }
-
-#ifdef RT_USING_SMP
-        rt_spin_unlock_irqrestore(&port_dev->spinlock_rx, level);
-#endif
-    }
-}
-
-rt_err_t rt_virtio_console_init(rt_ubase_t *mmio_base, rt_uint32_t irq)
-{
-    int i;
-    rt_size_t queues_num;
-    static int dev_no = 0;
-    char dev_name[RT_NAME_MAX];
-    struct virtio_device *virtio_dev;
-    struct virtio_console_device *virtio_console_dev;
-
-    RT_ASSERT(RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR > 0);
-
-    virtio_console_dev = rt_malloc(sizeof(struct virtio_console_device));
-
-    if (virtio_console_dev == RT_NULL)
-    {
-        goto _alloc_fail;
-    }
-
-    virtio_dev = &virtio_console_dev->virtio_dev;
-    virtio_dev->irq = irq;
-    virtio_dev->mmio_base = mmio_base;
-
-    virtio_console_dev->config = (struct virtio_console_config *)virtio_dev->mmio_config->config;
-
-#ifdef RT_USING_SMP
-    rt_spin_lock_init(&virtio_dev->spinlock);
-#endif
-
-    virtio_reset_device(virtio_dev);
-    virtio_status_acknowledge_driver(virtio_dev);
-
-    virtio_dev->mmio_config->driver_features = virtio_dev->mmio_config->device_features & ~(
-            (1 << VIRTIO_F_RING_EVENT_IDX) |
-            (1 << VIRTIO_F_RING_INDIRECT_DESC));
-
-    virtio_status_driver_ok(virtio_dev);
-
-    if (!virtio_has_feature(virtio_dev, VIRTIO_CONSOLE_F_MULTIPORT))
-    {
-        virtio_console_dev->max_port_nr = 1;
-        queues_num = 2;
-    }
-    else
-    {
-        if (virtio_console_dev->config->max_nr_ports > RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR)
-        {
-            virtio_console_dev->max_port_nr = RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR;
-            virtio_console_dev->config->max_nr_ports = virtio_console_dev->max_port_nr;
-        }
-        else
-        {
-            virtio_console_dev->max_port_nr = virtio_console_dev->config->max_nr_ports;
-        }
-
-        queues_num = VIRTIO_CONSOLE_PORT_QUEUE_INDEX(virtio_console_dev->max_port_nr, VIRTIO_CONSOLE_QUEUE_DATA_RX);
-    }
-
-    if (virtio_queues_alloc(virtio_dev, queues_num) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    for (i = 0; i < virtio_dev->queues_num; ++i)
-    {
-        if (virtio_queue_init(virtio_dev, i, VIRTIO_CONSOLE_QUEUE_SIZE) != RT_EOK)
-        {
-            for (; i >= 0; --i)
-            {
-                virtio_queue_destroy(virtio_dev, i);
-            }
-            goto _alloc_fail;
-        }
-    }
-
-    virtio_console_dev->parent.type = RT_Device_Class_Char;
-    virtio_console_dev->parent.ops  = &virtio_console_ops;
-
-    virtio_console_dev->parent.rx_indicate = RT_NULL;
-    virtio_console_dev->parent.tx_complete = RT_NULL;
-
-    virtio_console_dev->console_id = dev_no;
-    virtio_console_dev->port_nr = 0;
-    rt_list_init(&virtio_console_dev->port_head);
-
-    rt_snprintf(dev_name, RT_NAME_MAX, "virtio-console%d", dev_no++);
-
-    rt_hw_interrupt_install(irq, virtio_console_isr, virtio_console_dev, dev_name);
-    rt_hw_interrupt_umask(irq);
-
-    return rt_device_register((rt_device_t)virtio_console_dev, dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
-
-_alloc_fail:
-
-    if (virtio_console_dev != RT_NULL)
-    {
-        virtio_queues_free(virtio_dev);
-        rt_free(virtio_console_dev);
-    }
-    return -RT_ENOMEM;
-}
-#endif /* BSP_USING_VIRTIO_CONSOLE */

+ 0 - 96
bsp/qemu-virt64-aarch64/driver/virtio/virtio_console.h

@@ -1,96 +0,0 @@
-/*
- * 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_CONSOLE_H__
-#define __VIRTIO_CONSOLE_H__
-
-#include <rtdef.h>
-
-#include <virtio.h>
-
-#ifndef RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR
-#define RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR 4
-#endif
-
-#define VIRTIO_CONSOLE_QUEUE_DATA_RX    0
-#define VIRTIO_CONSOLE_QUEUE_DATA_TX    1
-#define VIRTIO_CONSOLE_QUEUE_CTRL_RX    2
-#define VIRTIO_CONSOLE_QUEUE_CTRL_TX    3
-#define VIRTIO_CONSOLE_QUEUE_SIZE       64
-
-/* Every port has data rx & tx, and port0 has ctrl rx & tx in multiport */
-#define VIRTIO_CONSOLE_PORT_QUEUE_INDEX(id, queue)  ((id) * 2 + (!!(id)) * 2 + (queue))
-
-#define VIRTIO_CONSOLE_PORT_BAD_ID      (~(rt_uint32_t)0)
-
-#define VIRTIO_CONSOLE_F_SIZE           0   /* Does host provide console size? */
-#define VIRTIO_CONSOLE_F_MULTIPORT      1   /* Does host provide multiple ports? */
-#define VIRTIO_CONSOLE_F_EMERG_WRITE    2   /* Does host support emergency write? */
-
-struct virtio_console_config
-{
-    rt_uint16_t cols;
-    rt_uint16_t rows;
-    rt_uint32_t max_nr_ports;
-    rt_uint32_t emerg_wr;
-} __attribute__((packed));
-
-struct virtio_console_control
-{
-    rt_uint32_t id;     /* Port number */
-    rt_uint16_t event;  /* The kind of control event */
-    rt_uint16_t value;  /* Extra information for the event */
-};
-
-enum virtio_console_control_event
-{
-    VIRTIO_CONSOLE_DEVICE_READY = 0,
-    VIRTIO_CONSOLE_PORT_ADD,
-    VIRTIO_CONSOLE_PORT_REMOVE,
-    VIRTIO_CONSOLE_PORT_READY,
-    VIRTIO_CONSOLE_CONSOLE_PORT,
-    VIRTIO_CONSOLE_RESIZE,
-    VIRTIO_CONSOLE_PORT_OPEN,
-    VIRTIO_CONSOLE_PORT_NAME,
-};
-
-struct virtio_console_resize
-{
-    rt_uint16_t cols;
-    rt_uint16_t rows;
-};
-
-struct virtio_console_device
-{
-    struct rt_device parent;
-
-    struct virtio_device virtio_dev;
-
-    rt_uint32_t console_id;
-    rt_size_t port_nr;
-    rt_size_t max_port_nr;
-    rt_list_t port_head;
-    struct virtio_console_config *config;
-
-    struct
-    {
-        struct virtio_console_control rx_ctrl, tx_ctrl;
-    } info[VIRTIO_CONSOLE_QUEUE_SIZE];
-};
-
-rt_err_t rt_virtio_console_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
-
-enum
-{
-    VIRTIO_DEVICE_CTRL_CONSOLE_PORT_CREATE  = 0x20,
-    VIRTIO_DEVICE_CTRL_CONSOLE_PORT_DESTROY,
-};
-
-#endif /* __VIRTIO_CONSOLE_H__ */

+ 0 - 923
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.c

@@ -1,923 +0,0 @@
-/*
- * 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 <rthw.h>
-#include <rtthread.h>
-#include <cpuport.h>
-
-#ifdef BSP_USING_VIRTIO_GPU
-
-#include <virtio_gpu.h>
-
-static struct virtio_gpu_device *_primary_virtio_gpu_dev = RT_NULL;
-
-static rt_ubase_t _pixel_format_convert(rt_ubase_t format, rt_bool_t to_virtio_gpu_format)
-{
-    rt_ubase_t ret = 0;
-
-    if (to_virtio_gpu_format)
-    {
-        switch (format)
-        {
-        case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-            ret = VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM;
-            break;
-        case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
-            ret = VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM;
-            break;
-        case RTGRAPHIC_PIXEL_FORMAT_ABGR888:
-            ret = VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM;
-            break;
-        default:
-            break;
-        }
-    }
-    else
-    {
-        switch (format)
-        {
-        case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
-            ret = RTGRAPHIC_PIXEL_FORMAT_RGB888;
-            break;
-        case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
-            ret = RTGRAPHIC_PIXEL_FORMAT_ARGB888;
-            break;
-        case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
-            ret = RTGRAPHIC_PIXEL_FORMAT_ABGR888;
-            break;
-        default:
-            break;
-        }
-    }
-
-    return ret;
-}
-
-static void virtio_gpu_ctrl_send_command(struct virtio_gpu_device *virtio_gpu_dev,
-        const void *cmd, rt_size_t cmd_len, void *res, rt_size_t res_len)
-{
-    rt_uint16_t idx[2];
-    void *addr = &virtio_gpu_dev->gpu_request;
-    void *ret_res = ((rt_uint8_t *)addr + cmd_len);
-    struct virtio_device *virtio_dev = &virtio_gpu_dev->virtio_dev;
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    while (virtio_alloc_desc_chain(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, 2, idx))
-    {
-#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
-    }
-
-    rt_memcpy(&virtio_gpu_dev->gpu_request, cmd, cmd_len);
-
-    virtio_fill_desc(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, idx[0],
-            VIRTIO_VA2PA(addr), cmd_len, VIRTQ_DESC_F_NEXT, idx[1]);
-
-    virtio_fill_desc(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, idx[1],
-            VIRTIO_VA2PA(addr) + cmd_len, res_len, VIRTQ_DESC_F_WRITE, 0);
-
-    rt_memset(ret_res, 0, res_len);
-
-    virtio_gpu_dev->info[idx[0]].ctrl_valid = RT_TRUE;
-
-    virtio_submit_chain(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, idx[0]);
-
-    virtio_queue_notify(virtio_dev, VIRTIO_GPU_QUEUE_CTRL);
-
-    while (virtio_gpu_dev->info[idx[0]].ctrl_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, VIRTIO_GPU_QUEUE_CTRL, idx[0]);
-
-    rt_memcpy(res, ret_res, res_len);
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-}
-
-static void virtio_gpu_cursor_send_command(struct virtio_gpu_device *virtio_gpu_dev,
-        const void *cmd, rt_size_t cmd_len)
-{
-    rt_uint16_t id;
-    void *addr;
-    struct virtio_device *virtio_dev = &virtio_gpu_dev->virtio_dev;
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    while ((id = virtio_alloc_desc(virtio_dev, VIRTIO_GPU_QUEUE_CURSOR)) == VIRTQ_INVALID_DESC_ID)
-    {
-#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
-    }
-
-    addr = &virtio_gpu_dev->info[id].cursor_cmd;
-    virtio_gpu_dev->info[id].cursor_valid = RT_TRUE;
-
-    rt_memcpy(addr, cmd, cmd_len);
-
-    virtio_fill_desc(virtio_dev, VIRTIO_GPU_QUEUE_CURSOR, id, VIRTIO_VA2PA(addr), cmd_len, 0, 0);
-
-    virtio_submit_chain(virtio_dev, VIRTIO_GPU_QUEUE_CURSOR, id);
-
-    virtio_queue_notify(virtio_dev, VIRTIO_GPU_QUEUE_CURSOR);
-
-    while (virtio_gpu_dev->info[id].cursor_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(virtio_dev, VIRTIO_GPU_QUEUE_CURSOR, id);
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-}
-
-static rt_err_t virtio_gpu_create_2d_resource(struct virtio_gpu_device *virtio_gpu_dev, enum virtio_gpu_formats format,
-        rt_uint32_t *resource_id, rt_uint32_t width, rt_uint32_t height)
-{
-    struct virtio_gpu_ctrl_hdr res;
-    struct virtio_gpu_resource_create_2d req;
-
-    *resource_id = ++virtio_gpu_dev->next_resource_id;
-
-    req.hdr.type = VIRTIO_GPU_CMD_RESOURCE_CREATE_2D;
-    req.resource_id = *resource_id;
-    req.format = format;
-    req.width = width;
-    req.height = height;
-
-    virtio_gpu_ctrl_send_command(virtio_gpu_dev, &req, sizeof(req), &res, sizeof(res));
-
-    if (res.type == VIRTIO_GPU_RESP_OK_NODATA)
-    {
-        return RT_EOK;
-    }
-
-    return -RT_ERROR;
-}
-
-static rt_err_t virtio_gpu_unref_resource(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t resource_id)
-{
-    struct virtio_gpu_ctrl_hdr res;
-    struct virtio_gpu_resource_unref req;
-
-    rt_memset(&req, 0, sizeof(req));
-
-    req.hdr.type = VIRTIO_GPU_CMD_RESOURCE_UNREF;
-    req.resource_id = resource_id;
-
-    virtio_gpu_ctrl_send_command(virtio_gpu_dev, &req, sizeof(req), &res, sizeof(res));
-
-    if (res.type == VIRTIO_GPU_RESP_OK_NODATA)
-    {
-        return RT_EOK;
-    }
-
-    return -RT_ERROR;
-}
-
-static rt_err_t virtio_gpu_attach_backing_resource(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t resource_id,
-        void *buffer, rt_size_t size)
-{
-    struct virtio_gpu_ctrl_hdr res;
-    struct
-    {
-        struct virtio_gpu_resource_attach_backing req;
-        struct virtio_gpu_mem_entry mem;
-    } req;
-
-    rt_memset(&req, 0, sizeof(req));
-
-    req.req.hdr.type = VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING;
-    req.req.resource_id = resource_id;
-    req.req.nr_entries = 1;
-
-    req.mem.addr = VIRTIO_VA2PA(buffer);
-    req.mem.length = size;
-
-    virtio_gpu_ctrl_send_command(virtio_gpu_dev, &req, sizeof(req), &res, sizeof(res));
-
-    if (res.type == VIRTIO_GPU_RESP_OK_NODATA)
-    {
-        return RT_EOK;
-    }
-
-    return -RT_ERROR;
-}
-
-static rt_err_t virtio_gpu_set_scanout(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t scanout_id,
-        rt_uint32_t resource_id, rt_uint32_t width, rt_uint32_t height)
-{
-    struct virtio_gpu_ctrl_hdr res;
-    struct virtio_gpu_set_scanout req;
-
-    rt_memset(&req, 0, sizeof(req));
-
-    req.hdr.type = VIRTIO_GPU_CMD_SET_SCANOUT;
-    req.r.x = 0;
-    req.r.y = 0;
-    req.r.width = width;
-    req.r.height = height;
-    req.scanout_id = scanout_id;
-    req.resource_id = resource_id;
-
-    virtio_gpu_ctrl_send_command(virtio_gpu_dev, &req, sizeof(req), &res, sizeof(res));
-
-    if (res.type == VIRTIO_GPU_RESP_OK_NODATA)
-    {
-        return RT_EOK;
-    }
-
-    return -RT_ERROR;
-}
-
-static rt_err_t virtio_gpu_flush_resource(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t resource_id,
-        rt_uint32_t x, rt_uint32_t y, rt_uint32_t width, rt_uint32_t height)
-{
-    struct virtio_gpu_ctrl_hdr res;
-    struct virtio_gpu_resource_flush req;
-
-    rt_memset(&req, 0, sizeof(req));
-
-    req.hdr.type = VIRTIO_GPU_CMD_RESOURCE_FLUSH;
-    req.r.x = x;
-    req.r.y = y;
-    req.r.width = width;
-    req.r.height = height;
-    req.resource_id = resource_id;
-
-    virtio_gpu_ctrl_send_command(virtio_gpu_dev, &req, sizeof(req), &res, sizeof(res));
-
-    if (res.type == VIRTIO_GPU_RESP_OK_NODATA)
-    {
-        return RT_EOK;
-    }
-
-    return -RT_ERROR;
-}
-
-static rt_err_t virtio_gpu_transfer_to_host_2d(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t resource_id,
-        rt_uint32_t x, rt_uint32_t y, rt_uint32_t width, rt_uint32_t height, rt_uint32_t offset)
-{
-    struct virtio_gpu_ctrl_hdr res;
-    struct virtio_gpu_transfer_to_host_2d req;
-
-    rt_memset(&req, 0, sizeof(req));
-
-    req.hdr.type = VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D;
-    req.r.x = x;
-    req.r.y = y;
-    req.r.width = width;
-    req.r.height = height;
-    req.offset = offset;
-    req.resource_id = resource_id;
-
-    virtio_gpu_ctrl_send_command(virtio_gpu_dev, &req, sizeof(req), &res, sizeof(res));
-
-    if (res.type == VIRTIO_GPU_RESP_OK_NODATA)
-    {
-        return RT_EOK;
-    }
-
-    return -RT_ERROR;
-}
-
-static rt_err_t virtio_gpu_gfx_flush_2d(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t resource_id,
-        rt_uint32_t x, rt_uint32_t y, rt_uint32_t width, rt_uint32_t height)
-{
-    rt_err_t status = virtio_gpu_transfer_to_host_2d(virtio_gpu_dev, resource_id, x, y, width, height, 0);
-
-    if (status == RT_EOK)
-    {
-        status = virtio_gpu_flush_resource(virtio_gpu_dev, resource_id, x, y, width, height);
-    }
-
-    return status;
-}
-
-static rt_err_t virtio_gpu_update_cursor(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t scanout_id,
-        rt_uint32_t resource_id, rt_uint32_t hot_x, rt_uint32_t hot_y)
-{
-    struct virtio_gpu_update_cursor req;
-
-    rt_memset(&req, 0, sizeof(req));
-
-    req.hdr.type = VIRTIO_GPU_CMD_UPDATE_CURSOR;
-    req.pos.scanout_id = scanout_id;
-    req.resource_id = resource_id;
-    req.hot_x = hot_x;
-    req.hot_y = hot_y;
-
-    virtio_gpu_cursor_send_command(virtio_gpu_dev, &req, sizeof(req));
-
-    return RT_EOK;
-}
-
-static rt_err_t virtio_gpu_cursor_move(struct virtio_gpu_device *virtio_gpu_dev, rt_uint32_t scanout_id,
-        rt_uint32_t resource_id, rt_uint32_t x, rt_uint32_t y)
-{
-    struct virtio_gpu_update_cursor req;
-
-    rt_memset(&req, 0, sizeof(req));
-
-    req.hdr.type = VIRTIO_GPU_CMD_MOVE_CURSOR;
-    req.pos.scanout_id = scanout_id;
-    req.pos.x = x;
-    req.pos.y = y;
-    req.resource_id = resource_id;
-
-    virtio_gpu_cursor_send_command(virtio_gpu_dev, &req, sizeof(req));
-
-    return RT_EOK;
-}
-
-static rt_err_t virtio_gpu_cursor_set_img(struct virtio_gpu_device *virtio_gpu_dev, void *img)
-{
-    rt_err_t status;
-
-    rt_memcpy(virtio_gpu_dev->cursor_img, img, VIRTIO_GPU_CURSOR_IMG_SIZE);
-
-    status = virtio_gpu_attach_backing_resource(virtio_gpu_dev,
-            virtio_gpu_dev->cursor_resource_id, virtio_gpu_dev->cursor_img, VIRTIO_GPU_CURSOR_IMG_SIZE);
-
-    if (status != RT_EOK)
-    {
-        return status;
-    }
-
-    status = virtio_gpu_transfer_to_host_2d(virtio_gpu_dev, virtio_gpu_dev->cursor_resource_id,
-            0, 0, VIRTIO_GPU_CURSOR_WIDTH, VIRTIO_GPU_CURSOR_HEIGHT, 0);
-
-    return status;
-}
-
-static rt_err_t virtio_gpu_get_display_info(struct virtio_gpu_device *virtio_gpu_dev)
-{
-    int i;
-    struct virtio_gpu_ctrl_hdr req;
-    struct virtio_gpu_resp_display_info info;
-
-    rt_memset(&req, 0, sizeof(req));
-    req.type = VIRTIO_GPU_CMD_GET_DISPLAY_INFO;
-
-    virtio_gpu_ctrl_send_command(virtio_gpu_dev, &req, sizeof(req), &info, sizeof(info));
-
-    if (info.hdr.type != VIRTIO_GPU_RESP_OK_DISPLAY_INFO)
-    {
-        return -RT_ERROR;
-    }
-
-    for (i = 0; i < VIRTIO_GPU_MAX_SCANOUTS; ++i)
-    {
-        if (info.pmodes[i].enabled)
-        {
-            if (virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID)
-            {
-                rt_memcpy(&virtio_gpu_dev->pmode, &info.pmodes[i], sizeof(virtio_gpu_dev->pmode));
-                virtio_gpu_dev->pmode_id = i;
-            }
-        }
-    }
-
-    return RT_EOK;
-}
-
-static rt_err_t virtio_gpu_init(rt_device_t dev)
-{
-    rt_err_t status;
-    struct virtio_gpu_device *virtio_gpu_dev = (struct virtio_gpu_device *)dev;
-    struct virtio_device *virtio_dev = &virtio_gpu_dev->virtio_dev;
-    struct virtq *queue_ctrl, *queue_cursor;
-
-    queue_ctrl = &virtio_dev->queues[VIRTIO_GPU_QUEUE_CTRL];
-    queue_cursor = &virtio_dev->queues[VIRTIO_GPU_QUEUE_CURSOR];
-
-    queue_ctrl->avail->flags = 0;
-    queue_cursor->avail->flags = 0;
-
-    status = virtio_gpu_get_display_info(virtio_gpu_dev);
-
-    if (virtio_gpu_dev->pmode_id != VIRTIO_GPU_INVALID_PMODE_ID && _primary_virtio_gpu_dev == RT_NULL)
-    {
-        /* This device is ready */
-        _primary_virtio_gpu_dev = virtio_gpu_dev;
-    }
-
-    return status;
-}
-
-static rt_size_t virtio_gpu_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
-{
-    struct virtio_gpu_device *virtio_gpu_dev = (struct virtio_gpu_device *)dev;
-
-    if (virtio_gpu_dev->framebuffer == RT_NULL || pos + size >= virtio_gpu_dev->smem_len)
-    {
-        return 0;
-    }
-
-    rt_mutex_take(&virtio_gpu_dev->rw_mutex, RT_WAITING_FOREVER);
-
-    rt_memcpy(buffer, (rt_uint8_t *)virtio_gpu_dev->framebuffer + pos, size);
-
-    rt_mutex_release(&virtio_gpu_dev->rw_mutex);
-
-    return size;
-}
-
-static rt_size_t virtio_gpu_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
-{
-    struct virtio_gpu_device *virtio_gpu_dev = (struct virtio_gpu_device *)dev;
-
-    if (virtio_gpu_dev->framebuffer == RT_NULL || pos + size >= virtio_gpu_dev->smem_len)
-    {
-        return 0;
-    }
-
-    rt_mutex_take(&virtio_gpu_dev->rw_mutex, RT_WAITING_FOREVER);
-
-    rt_memcpy((rt_uint8_t *)virtio_gpu_dev->framebuffer + pos, buffer, size);
-
-    rt_mutex_release(&virtio_gpu_dev->rw_mutex);
-
-    return size;
-}
-
-static rt_err_t virtio_gpu_control(rt_device_t dev, int cmd, void *args)
-{
-    rt_err_t status = RT_EOK;
-    struct virtio_gpu_device *virtio_gpu_dev = (struct virtio_gpu_device *)dev;
-
-    switch (cmd)
-    {
-    case VIRTIO_DEVICE_CTRL_GPU_SET_PRIMARY:
-
-        _primary_virtio_gpu_dev = virtio_gpu_dev;
-
-        return status;
-    }
-
-    if (args == RT_NULL)
-    {
-        return -RT_ERROR;
-    }
-
-    switch (cmd)
-    {
-    case RTGRAPHIC_CTRL_RECT_UPDATE:
-        {
-            struct rt_device_rect_info *info = (struct rt_device_rect_info *)args;
-
-            if (virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID)
-            {
-                status = -RT_ERROR;
-                break;
-            }
-
-            status = virtio_gpu_gfx_flush_2d(virtio_gpu_dev, virtio_gpu_dev->display_resource_id,
-                    info->x, info->y, info->width, info->height);
-        }
-        break;
-    case RTGRAPHIC_CTRL_GET_INFO:
-        {
-            struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
-
-            info->pixel_format      = _pixel_format_convert((rt_ubase_t)args, RT_FALSE);
-            info->bits_per_pixel    = VIRTIO_GPU_FORMAT_BPP;
-            info->pitch             = virtio_gpu_dev->pmode.r.width * VIRTIO_GPU_FORMAT_PIXEL;
-            info->width             = virtio_gpu_dev->pmode.r.width;
-            info->height            = virtio_gpu_dev->pmode.r.height;
-            info->framebuffer       = virtio_gpu_dev->framebuffer;
-            info->smem_len          = virtio_gpu_dev->smem_len;
-        }
-        break;
-    case VIRTIO_DEVICE_CTRL_GPU_CREATE_2D:
-
-        virtio_gpu_dev->format = _pixel_format_convert((rt_ubase_t)args, RT_TRUE);
-
-        if (virtio_gpu_dev->format == 0 || virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID)
-        {
-            status = -RT_ERROR;
-            break;
-        }
-
-        status = virtio_gpu_create_2d_resource(virtio_gpu_dev, virtio_gpu_dev->format,
-                &virtio_gpu_dev->display_resource_id, virtio_gpu_dev->pmode.r.width, virtio_gpu_dev->pmode.r.height);
-
-        if (status != RT_EOK)
-        {
-            break;
-        }
-
-        virtio_gpu_dev->smem_len =
-                virtio_gpu_dev->pmode.r.width * virtio_gpu_dev->pmode.r.height * VIRTIO_GPU_FORMAT_PIXEL;
-        virtio_gpu_dev->smem_len = RT_ALIGN(virtio_gpu_dev->smem_len, VIRTIO_PAGE_SIZE);
-        virtio_gpu_dev->framebuffer = rt_malloc_align(virtio_gpu_dev->smem_len, VIRTIO_PAGE_SIZE);
-
-        if (virtio_gpu_dev->framebuffer == RT_NULL)
-        {
-            virtio_gpu_unref_resource(virtio_gpu_dev, virtio_gpu_dev->display_resource_id);
-
-            status = -RT_ENOMEM;
-            break;
-        }
-
-        status = virtio_gpu_attach_backing_resource(virtio_gpu_dev,
-                virtio_gpu_dev->display_resource_id, virtio_gpu_dev->framebuffer, virtio_gpu_dev->smem_len);
-
-        if (status != RT_EOK)
-        {
-            break;
-        }
-
-        status = virtio_gpu_set_scanout(virtio_gpu_dev, virtio_gpu_dev->pmode_id, virtio_gpu_dev->display_resource_id,
-                virtio_gpu_dev->pmode.r.width, virtio_gpu_dev->pmode.r.height);
-
-        break;
-    case VIRTIO_DEVICE_CTRL_CURSOR_SETUP:
-
-        if (virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID)
-        {
-            status = -RT_ERROR;
-            break;
-        }
-
-        rt_mutex_take(&virtio_gpu_dev->ops_mutex, RT_WAITING_FOREVER);
-
-        status = virtio_gpu_create_2d_resource(virtio_gpu_dev, virtio_gpu_dev->format,
-                &virtio_gpu_dev->cursor_resource_id, VIRTIO_GPU_CURSOR_WIDTH, VIRTIO_GPU_CURSOR_HEIGHT);
-
-        if (status != RT_EOK)
-        {
-            goto _cursor_setup_end;
-        }
-
-        status = virtio_gpu_cursor_set_img(virtio_gpu_dev, args);
-
-        if (status != RT_EOK)
-        {
-            goto _cursor_setup_end;
-        }
-
-        virtio_gpu_dev->cursor_x = 0;
-        virtio_gpu_dev->cursor_y = 0;
-
-        status = virtio_gpu_update_cursor(virtio_gpu_dev, virtio_gpu_dev->pmode_id, virtio_gpu_dev->cursor_resource_id,
-            virtio_gpu_dev->cursor_x, virtio_gpu_dev->cursor_y);
-
-        if (status == RT_EOK)
-        {
-            virtio_gpu_dev->cursor_enable = RT_TRUE;
-        }
-
-_cursor_setup_end:
-        rt_mutex_release(&virtio_gpu_dev->ops_mutex);
-
-        break;
-    case VIRTIO_DEVICE_CTRL_CURSOR_SET_IMG:
-
-        if (virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID || !virtio_gpu_dev->cursor_enable)
-        {
-            status = -RT_ERROR;
-            break;
-        }
-
-        rt_mutex_take(&virtio_gpu_dev->ops_mutex, RT_WAITING_FOREVER);
-
-        status = virtio_gpu_cursor_set_img(virtio_gpu_dev, args);
-
-        if (status != RT_EOK)
-        {
-            goto _cursor_set_img_end;
-        }
-
-        status = virtio_gpu_update_cursor(virtio_gpu_dev, virtio_gpu_dev->pmode_id, virtio_gpu_dev->cursor_resource_id,
-            virtio_gpu_dev->cursor_x, virtio_gpu_dev->cursor_y);
-
-_cursor_set_img_end:
-        rt_mutex_release(&virtio_gpu_dev->ops_mutex);
-
-        break;
-    case VIRTIO_DEVICE_CTRL_CURSOR_MOVE:
-
-        if (virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID || !virtio_gpu_dev->cursor_enable)
-        {
-            status = -RT_ERROR;
-            break;
-        }
-
-        rt_mutex_take(&virtio_gpu_dev->ops_mutex, RT_WAITING_FOREVER);
-
-        virtio_gpu_dev->cursor_x = ((rt_uint32_t *)args)[0];
-        virtio_gpu_dev->cursor_y = ((rt_uint32_t *)args)[1];
-
-        status = virtio_gpu_cursor_move(virtio_gpu_dev, virtio_gpu_dev->pmode_id, virtio_gpu_dev->cursor_resource_id,
-            virtio_gpu_dev->cursor_x, virtio_gpu_dev->cursor_y);
-
-        rt_mutex_release(&virtio_gpu_dev->ops_mutex);
-
-        break;
-    default:
-        status = -RT_EINVAL;
-        break;
-    }
-
-    return status;
-}
-
-const static struct rt_device_ops virtio_gpu_ops =
-{
-    virtio_gpu_init,
-    RT_NULL,
-    RT_NULL,
-    virtio_gpu_read,
-    virtio_gpu_write,
-    virtio_gpu_control
-};
-
-static void virtio_gpu_set_pixel(const char *pixel, int x, int y)
-{
-    rt_uint8_t *fb;
-    struct virtio_gpu_device *virtio_gpu_dev = _primary_virtio_gpu_dev;
-
-    if (virtio_gpu_dev == RT_NULL || virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID)
-    {
-        return;
-    }
-
-    fb = (rt_uint8_t *)virtio_gpu_dev->framebuffer;
-    fb += (y * virtio_gpu_dev->pmode.r.width + x) * VIRTIO_GPU_FORMAT_PIXEL;
-    *((rt_uint32_t *)fb) = *((rt_uint32_t *)pixel);
-}
-
-static void virtio_gpu_get_pixel(char *pixel, int x, int y)
-{
-    rt_uint8_t *fb;
-    struct virtio_gpu_device *virtio_gpu_dev = _primary_virtio_gpu_dev;
-
-    if (virtio_gpu_dev == RT_NULL || virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID)
-    {
-        return;
-    }
-
-    fb = (rt_uint8_t *)virtio_gpu_dev->framebuffer;
-    *((rt_uint32_t *)pixel) = *(fb + (y * virtio_gpu_dev->pmode.r.width + x) * VIRTIO_GPU_FORMAT_PIXEL);
-}
-
-static void virtio_gpu_draw_hline(const char *pixel, int x1, int x2, int y)
-{
-    int i;
-    rt_uint8_t *fb;
-    rt_uint32_t color = *((rt_uint32_t *)pixel);
-    struct virtio_gpu_device *virtio_gpu_dev = _primary_virtio_gpu_dev;
-
-    if (virtio_gpu_dev == RT_NULL || virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID ||
-        x1 < 0 || x2 < 0 || y < 0)
-    {
-        return;
-    }
-
-    if (x1 > x2)
-    {
-        x1 ^= x2;
-        x2 ^= x1;
-        x1 ^= x2;
-    }
-
-    fb = (rt_uint8_t *)virtio_gpu_dev->framebuffer;
-    fb += (y * virtio_gpu_dev->pmode.r.width + x1) * VIRTIO_GPU_FORMAT_PIXEL;
-
-    for (i = x1; i < x2; ++i)
-    {
-        *((rt_uint32_t *)fb) = color;
-
-        fb += VIRTIO_GPU_FORMAT_PIXEL;
-    }
-}
-
-static void virtio_gpu_draw_vline(const char *pixel, int x, int y1, int y2)
-{
-    int i;
-    rt_uint8_t *fb;
-    rt_uint16_t pitch;
-    rt_uint32_t color = *((rt_uint32_t *)pixel);
-    struct virtio_gpu_device *virtio_gpu_dev = _primary_virtio_gpu_dev;
-
-    if (virtio_gpu_dev == RT_NULL || virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID ||
-        x < 0 || y1 < 0 || y2 < 0)
-    {
-        return;
-    }
-
-    if (y1 > y2)
-    {
-        y1 ^= y2;
-        y2 ^= y1;
-        y1 ^= y2;
-    }
-
-    fb = (rt_uint8_t *)virtio_gpu_dev->framebuffer;
-    fb += (y1 * virtio_gpu_dev->pmode.r.width + x) * VIRTIO_GPU_FORMAT_PIXEL;
-
-    pitch = virtio_gpu_dev->pmode.r.width * VIRTIO_GPU_FORMAT_PIXEL;
-
-    for (i = y1; i < y2; ++i)
-    {
-        *((rt_uint32_t *)fb) = color;
-
-        fb += pitch;
-    }
-}
-
-static void virtio_gpu_blit_line(const char *pixel, int x, int y, rt_size_t size)
-{
-    int i;
-    rt_uint8_t *fb;
-    rt_uint32_t *colors = (rt_uint32_t *)pixel;
-    struct virtio_gpu_device *virtio_gpu_dev = _primary_virtio_gpu_dev;
-
-    if (virtio_gpu_dev == RT_NULL || virtio_gpu_dev->pmode_id == VIRTIO_GPU_INVALID_PMODE_ID || x < 0 || y < 0)
-    {
-        return;
-    }
-
-    fb = (rt_uint8_t *)virtio_gpu_dev->framebuffer;
-    fb += (y * virtio_gpu_dev->pmode.r.width + x) * VIRTIO_GPU_FORMAT_PIXEL;
-
-    for (i = 0; i < size; ++i)
-    {
-        *((rt_uint32_t *)fb) = *colors++;
-        fb += VIRTIO_GPU_FORMAT_PIXEL;
-    }
-}
-
-static struct rt_device_graphic_ops virtio_gpu_graphic_ops =
-{
-    virtio_gpu_set_pixel,
-    virtio_gpu_get_pixel,
-    virtio_gpu_draw_hline,
-    virtio_gpu_draw_vline,
-    virtio_gpu_blit_line
-};
-
-static void virtio_gpu_isr(int irqno, void *param)
-{
-    rt_uint16_t id;
-    struct virtio_gpu_device *virtio_gpu_dev = (struct virtio_gpu_device *)param;
-    struct virtio_device *virtio_dev = &virtio_gpu_dev->virtio_dev;
-    struct virtq *queue_ctrl = &virtio_dev->queues[VIRTIO_GPU_QUEUE_CTRL];
-    struct virtq *queue_cursor = &virtio_dev->queues[VIRTIO_GPU_QUEUE_CURSOR];
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    virtio_interrupt_ack(virtio_dev);
-    rt_hw_dsb();
-
-    while (queue_ctrl->used_idx != queue_ctrl->used->idx)
-    {
-        rt_hw_dsb();
-        id = queue_ctrl->used->ring[queue_ctrl->used_idx % queue_ctrl->num].id;
-
-        virtio_gpu_dev->info[id].ctrl_valid = RT_FALSE;
-
-        queue_ctrl->used_idx++;
-    }
-
-    while (queue_cursor->used_idx != queue_cursor->used->idx)
-    {
-        rt_hw_dsb();
-        id = queue_cursor->used->ring[queue_cursor->used_idx % queue_cursor->num].id;
-
-        virtio_gpu_dev->info[id].cursor_valid = RT_FALSE;
-
-        queue_cursor->used_idx++;
-    }
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-}
-
-rt_err_t rt_virtio_gpu_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_gpu_device *virtio_gpu_dev;
-
-    virtio_gpu_dev = rt_malloc(sizeof(struct virtio_gpu_device));
-
-    if (virtio_gpu_dev == RT_NULL)
-    {
-        goto _alloc_fail;
-    }
-
-    virtio_dev = &virtio_gpu_dev->virtio_dev;
-    virtio_dev->irq = irq;
-    virtio_dev->mmio_base = mmio_base;
-
-    virtio_gpu_dev->pmode_id = VIRTIO_GPU_INVALID_PMODE_ID;
-    virtio_gpu_dev->display_resource_id = 0;
-    virtio_gpu_dev->cursor_resource_id = 0;
-    virtio_gpu_dev->next_resource_id = 0;
-    virtio_gpu_dev->framebuffer = RT_NULL;
-    virtio_gpu_dev->smem_len = 0;
-    virtio_gpu_dev->cursor_enable = RT_FALSE;
-
-#ifdef RT_USING_SMP
-    rt_spin_lock_init(&virtio_dev->spinlock);
-#endif
-
-    virtio_reset_device(virtio_dev);
-    virtio_status_acknowledge_driver(virtio_dev);
-
-    virtio_dev->mmio_config->driver_features = virtio_dev->mmio_config->device_features & ~(
-            (1 << VIRTIO_F_RING_EVENT_IDX) |
-            (1 << VIRTIO_F_RING_INDIRECT_DESC));
-
-    virtio_status_driver_ok(virtio_dev);
-
-    if (virtio_queues_alloc(virtio_dev, 2) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    if (virtio_queue_init(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, VIRTIO_GPU_QUEUE_SIZE) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    if (virtio_queue_init(virtio_dev, VIRTIO_GPU_QUEUE_CURSOR, VIRTIO_GPU_QUEUE_SIZE) != RT_EOK)
-    {
-        virtio_queue_destroy(virtio_dev, VIRTIO_GPU_QUEUE_CTRL);
-
-        goto _alloc_fail;
-    }
-
-    virtio_gpu_dev->parent.type = RT_Device_Class_Graphic;
-    virtio_gpu_dev->parent.ops  = &virtio_gpu_ops;
-    virtio_gpu_dev->parent.user_data = &virtio_gpu_graphic_ops;
-
-    rt_snprintf(dev_name, RT_NAME_MAX, "virtio-gpu%d", dev_no++);
-
-    rt_mutex_init(&virtio_gpu_dev->rw_mutex, dev_name, RT_IPC_FLAG_PRIO);
-    rt_mutex_init(&virtio_gpu_dev->ops_mutex, dev_name, RT_IPC_FLAG_PRIO);
-
-    rt_hw_interrupt_install(irq, virtio_gpu_isr, virtio_gpu_dev, dev_name);
-    rt_hw_interrupt_umask(irq);
-
-    return rt_device_register((rt_device_t)virtio_gpu_dev, dev_name, RT_DEVICE_FLAG_RDWR);
-
-_alloc_fail:
-
-    if (virtio_gpu_dev != RT_NULL)
-    {
-        virtio_queues_free(virtio_dev);
-        rt_free(virtio_gpu_dev);
-    }
-    return -RT_ENOMEM;
-}
-#endif /* BSP_USING_VIRTIO_GPU */

+ 0 - 412
bsp/qemu-virt64-aarch64/driver/virtio/virtio_gpu.h

@@ -1,412 +0,0 @@
-/*
- * 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_GPU_H__
-#define __VIRTIO_GPU_H__
-
-#include <rtdef.h>
-
-#include <virtio.h>
-
-#define VIRTIO_GPU_QUEUE_CTRL       0
-#define VIRTIO_GPU_QUEUE_CURSOR     1
-#define VIRTIO_GPU_QUEUE_SIZE       32
-
-#define VIRTIO_GPU_F_VIRGL          0   /* VIRTIO_GPU_CMD_CTX_*, VIRTIO_GPU_CMD_*_3D */
-#define VIRTIO_GPU_F_EDID           1   /* VIRTIO_GPU_CMD_GET_EDID */
-#define VIRTIO_GPU_F_RESOURCE_UUID  2   /* VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID */
-#define VIRTIO_GPU_F_RESOURCE_BLOB  3   /* VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB */
-#define VIRTIO_GPU_F_CONTEXT_INIT   4   /* VIRTIO_GPU_CMD_CREATE_CONTEXT with context_init and multiple timelines */
-
-#define VIRTIO_GPU_EVENT_DISPLAY    (1 << 0)
-
-#define VIRTIO_GPU_FORMAT_BPP       32
-#define VIRTIO_GPU_FORMAT_PIXEL     4
-#define VIRTIO_GPU_CURSOR_WIDTH     64
-#define VIRTIO_GPU_CURSOR_HEIGHT    64
-#define VIRTIO_GPU_CURSOR_IMG_SIZE  (VIRTIO_GPU_CURSOR_WIDTH * VIRTIO_GPU_CURSOR_HEIGHT * VIRTIO_GPU_FORMAT_PIXEL)
-#define VIRTIO_GPU_INVALID_PMODE_ID RT_UINT32_MAX
-
-/* GPU control */
-
-struct virtio_gpu_config
-{
-    rt_uint32_t events_read;
-    rt_uint32_t events_clear;
-    rt_uint32_t num_scanouts;   /* 1 ~ 16 */
-    rt_uint32_t reserved;
-};
-
-enum virtio_gpu_ctrl_type
-{
-    VIRTIO_GPU_UNDEFINED = 0,
-
-    /* 2d commands */
-    VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100,
-    VIRTIO_GPU_CMD_RESOURCE_CREATE_2D,
-    VIRTIO_GPU_CMD_RESOURCE_UNREF,
-    VIRTIO_GPU_CMD_SET_SCANOUT,
-    VIRTIO_GPU_CMD_RESOURCE_FLUSH,
-    VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D,
-    VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING,
-    VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING,
-    VIRTIO_GPU_CMD_GET_CAPSET_INFO,
-    VIRTIO_GPU_CMD_GET_CAPSET,
-    VIRTIO_GPU_CMD_GET_EDID,
-    VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID,
-    VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB,
-    VIRTIO_GPU_CMD_SET_SCANOUT_BLOB,
-
-    /* 3d commands */
-    VIRTIO_GPU_CMD_CTX_CREATE = 0x0200,
-    VIRTIO_GPU_CMD_CTX_DESTROY,
-    VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE,
-    VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE,
-    VIRTIO_GPU_CMD_RESOURCE_CREATE_3D,
-    VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D,
-    VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D,
-    VIRTIO_GPU_CMD_SUBMIT_3D,
-    VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB,
-    VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB,
-
-    /* cursor commands */
-    VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300,
-    VIRTIO_GPU_CMD_MOVE_CURSOR,
-
-    /* success responses */
-    VIRTIO_GPU_RESP_OK_NODATA = 0x1100,
-    VIRTIO_GPU_RESP_OK_DISPLAY_INFO,
-    VIRTIO_GPU_RESP_OK_CAPSET_INFO,
-    VIRTIO_GPU_RESP_OK_CAPSET,
-    VIRTIO_GPU_RESP_OK_EDID,
-    VIRTIO_GPU_RESP_OK_RESOURCE_UUID,
-    VIRTIO_GPU_RESP_OK_MAP_INFO,
-
-    /* error responses */
-    VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200,
-    VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY,
-    VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID,
-    VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID,
-    VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID,
-    VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER,
-};
-
-#define VIRTIO_GPU_FLAG_FENCE (1 << 0)
-
-struct virtio_gpu_ctrl_hdr
-{
-    rt_uint32_t type;
-    rt_uint32_t flags;
-    rt_uint64_t fence_id;
-    rt_uint32_t ctx_id;
-    rt_uint8_t ring_idx;
-    rt_uint8_t padding[3];
-};
-
-#define VIRTIO_GPU_MAX_SCANOUTS 16
-
-struct virtio_gpu_rect
-{
-    rt_uint32_t x;
-    rt_uint32_t y;
-    rt_uint32_t width;
-    rt_uint32_t height;
-};
-
-struct virtio_gpu_resp_display_info
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    struct virtio_gpu_display_one
-    {
-        struct virtio_gpu_rect r;
-        rt_uint32_t enabled;
-        rt_uint32_t flags;
-    } pmodes[VIRTIO_GPU_MAX_SCANOUTS];
-};
-
-struct virtio_gpu_get_edid
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t scanout;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_resp_edid
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t size;
-    rt_uint32_t padding;
-    rt_uint8_t edid[1024];
-};
-
-enum virtio_gpu_formats
-{
-    VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1,
-    VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2,
-    VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3,
-    VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4,
-
-    VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67,
-    VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68,
-
-    VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121,
-    VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134,
-};
-
-struct virtio_gpu_resource_create_2d
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t format;
-    rt_uint32_t width;
-    rt_uint32_t height;
-};
-
-struct virtio_gpu_resource_unref
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_set_scanout
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    struct virtio_gpu_rect r;
-    rt_uint32_t scanout_id;
-    rt_uint32_t resource_id;
-};
-
-struct virtio_gpu_resource_flush
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    struct virtio_gpu_rect r;
-    rt_uint32_t resource_id;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_transfer_to_host_2d
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    struct virtio_gpu_rect r;
-    rt_uint64_t offset;
-    rt_uint32_t resource_id;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_resource_attach_backing
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t nr_entries;
-};
-
-struct virtio_gpu_mem_entry
-{
-    rt_uint64_t addr;
-    rt_uint32_t length;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_resource_detach_backing
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_get_capset_info
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t capset_index;
-    rt_uint32_t padding;
-};
-
-#define VIRTIO_GPU_CAPSET_VIRGL         1
-#define VIRTIO_GPU_CAPSET_VIRGL2        2
-#define VIRTIO_GPU_CAPSET_GFXSTREAM     3
-#define VIRTIO_GPU_CAPSET_VENUS         4
-#define VIRTIO_GPU_CAPSET_CROSS_DOMAIN  5
-
-struct virtio_gpu_resp_capset_info
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t capset_id;
-    rt_uint32_t capset_max_version;
-    rt_uint32_t capset_max_size;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_get_capset
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t capset_id;
-    rt_uint32_t capset_version;
-};
-
-struct virtio_gpu_resp_capset
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint8_t capset_data[];
-};
-
-struct virtio_gpu_resource_assign_uuid
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_resp_resource_uuid
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint8_t uuid[16];
-};
-
-#define VIRTIO_GPU_BLOB_MEM_GUEST             0x0001
-#define VIRTIO_GPU_BLOB_MEM_HOST3D            0x0002
-#define VIRTIO_GPU_BLOB_MEM_HOST3D_GUEST      0x0003
-
-#define VIRTIO_GPU_BLOB_FLAG_USE_MAPPABLE     0x0001
-#define VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE    0x0002
-#define VIRTIO_GPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004
-
-struct virtio_gpu_resource_create_blob
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t blob_mem;
-    rt_uint32_t blob_flags;
-    rt_uint32_t nr_entries;
-    rt_uint64_t blob_id;
-    rt_uint64_t size;
-};
-
-struct virtio_gpu_set_scanout_blob
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    struct virtio_gpu_rect r;
-    rt_uint32_t scanout_id;
-    rt_uint32_t resource_id;
-    rt_uint32_t width;
-    rt_uint32_t height;
-    rt_uint32_t format;
-    rt_uint32_t padding;
-    rt_uint32_t strides[4];
-    rt_uint32_t offsets[4];
-};
-
-#define VIRTIO_GPU_CONTEXT_INIT_CAPSET_ID_MASK 0x000000ff
-struct virtio_gpu_ctx_create
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t nlen;
-    rt_uint32_t context_init;
-    char debug_name[64];
-};
-
-struct virtio_gpu_resource_map_blob
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t padding;
-    rt_uint64_t offset;
-};
-
-#define VIRTIO_GPU_MAP_CACHE_MASK      0x0f
-#define VIRTIO_GPU_MAP_CACHE_NONE      0x00
-#define VIRTIO_GPU_MAP_CACHE_CACHED    0x01
-#define VIRTIO_GPU_MAP_CACHE_UNCACHED  0x02
-#define VIRTIO_GPU_MAP_CACHE_WC        0x03
-
-struct virtio_gpu_resp_map_info
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t map_info;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_resource_unmap_blob
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    rt_uint32_t resource_id;
-    rt_uint32_t padding;
-};
-
-/* GPU cursor */
-
-struct virtio_gpu_cursor_pos
-{
-    rt_uint32_t scanout_id;
-    rt_uint32_t x;
-    rt_uint32_t y;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_update_cursor
-{
-    struct virtio_gpu_ctrl_hdr hdr;
-    struct virtio_gpu_cursor_pos pos;
-    rt_uint32_t resource_id;
-    rt_uint32_t hot_x;
-    rt_uint32_t hot_y;
-    rt_uint32_t padding;
-};
-
-struct virtio_gpu_device
-{
-    struct rt_device parent;
-
-    struct virtio_device virtio_dev;
-
-    /* Current display's info */
-    struct virtio_gpu_display_one pmode;
-    enum virtio_gpu_formats format;
-    rt_uint32_t pmode_id;
-    rt_uint32_t cursor_x, cursor_y;
-    rt_uint32_t display_resource_id;
-    rt_uint32_t cursor_resource_id;
-    rt_uint32_t next_resource_id;
-
-    /* Display framebuffer */
-    struct rt_mutex rw_mutex;
-    void *framebuffer;
-    rt_uint32_t smem_len;
-
-    /* Cursor image info */
-    rt_bool_t cursor_enable;
-    struct rt_mutex ops_mutex;
-    rt_uint8_t cursor_img[VIRTIO_GPU_CURSOR_IMG_SIZE];
-
-    /* GPU request info */
-    struct virtio_gpu_resp_display_info gpu_request;
-
-    struct
-    {
-        rt_bool_t ctrl_valid;
-        rt_bool_t cursor_valid;
-
-        struct virtio_gpu_update_cursor cursor_cmd;
-    } info[VIRTIO_GPU_QUEUE_SIZE];
-};
-
-rt_err_t rt_virtio_gpu_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
-
-enum
-{
-    VIRTIO_DEVICE_CTRL_GPU_SET_PRIMARY      = 0x20,
-    VIRTIO_DEVICE_CTRL_GPU_CREATE_2D,
-
-    VIRTIO_DEVICE_CTRL_CURSOR_SETUP,
-    VIRTIO_DEVICE_CTRL_CURSOR_SET_IMG,
-    VIRTIO_DEVICE_CTRL_CURSOR_MOVE,
-};
-
-#endif /* __VIRTIO_GPU_H__ */

+ 0 - 438
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.c

@@ -1,438 +0,0 @@
-/*
- * 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 <rthw.h>
-#include <rtthread.h>
-#include <cpuport.h>
-
-#ifdef BSP_USING_VIRTIO_INPUT
-
-#include <virtio_input.h>
-
-static void _set_bit(rt_uint32_t nr, volatile rt_ubase_t *addr)
-{
-    rt_ubase_t mask = BIT_MASK(nr);
-    rt_ubase_t *p = ((rt_ubase_t *)addr) + BIT_WORD(nr);
-
-    *p  |= mask;
-}
-
-static rt_size_t virtio_input_cfg_select(struct virtio_input_device *virtio_input_dev,
-        rt_uint8_t select, rt_uint8_t subsel)
-{
-    struct virtio_input_config *config = virtio_input_dev->config;
-
-    rt_hw_dsb();
-    config->select = select;
-    config->subsel = subsel;
-    rt_hw_dsb();
-
-    return config->size;
-}
-
-static void virtio_input_cfg_bits(struct virtio_input_device *virtio_input_dev,
-        rt_uint8_t select, rt_uint8_t subsel, rt_ubase_t *bits, rt_uint32_t bitcount)
-{
-    int i;
-    rt_uint32_t bit;
-    rt_uint8_t bytes;
-    rt_uint8_t *virtio_bits;
-    void *config_base = virtio_input_dev->config;
-    rt_off_t offset = (rt_size_t)&((struct virtio_input_config *)0)->bitmap;
-
-    bytes = virtio_input_cfg_select(virtio_input_dev, select, subsel);
-
-    if (bytes == 0)
-    {
-        return;
-    }
-
-    if (bitcount > bytes * 8)
-    {
-        bitcount = bytes * 8;
-    }
-
-    /*
-     * Bitmap in virtio config space is a simple stream of bytes,
-     * with the first byte carrying bits 0-7, second bits 8-15 and
-     * so on.
-     */
-    virtio_bits = rt_malloc(bytes);
-
-    if (virtio_bits == RT_NULL)
-    {
-        return;
-    }
-
-    for (i = 0; i < bytes; ++i)
-    {
-        void *buffer = (void *)virtio_bits + i;
-
-        if (virtio_input_dev->virtio_dev.mmio_config->version == 1)
-        {
-            HWREG8(config_base + offset + i) = *((rt_uint8_t *)buffer);
-        }
-        else
-        {
-            rt_memcpy(config_base + offset + i, buffer, sizeof(rt_uint8_t));
-        }
-    }
-
-    for (bit = 0; bit < bitcount; ++bit)
-    {
-        if (virtio_bits[bit / 8] & (1 << (bit % 8)))
-        {
-            _set_bit(bit, bits);
-        }
-    }
-
-    rt_free(virtio_bits);
-
-    if (select == VIRTIO_INPUT_CFG_EV_BITS)
-    {
-        _set_bit(subsel, virtio_input_dev->ev_bit);
-    }
-}
-
-static rt_err_t virtio_input_init(rt_device_t dev)
-{
-    int i;
-    rt_uint16_t idx[VIRTIO_INPUT_QUEUE_MAX_SIZE];
-    struct virtio_input_device *virtio_input_dev = (struct virtio_input_device *)dev;
-    struct virtio_device *virtio_dev = &virtio_input_dev->virtio_dev;
-    struct virtq *queue_event, *queue_status;
-
-    virtio_input_cfg_bits(virtio_input_dev, VIRTIO_INPUT_CFG_EV_BITS, EV_KEY, virtio_input_dev->key_bit, KEY_CNT);
-    virtio_input_cfg_bits(virtio_input_dev, VIRTIO_INPUT_CFG_EV_BITS, EV_REL, virtio_input_dev->rel_bit, REL_CNT);
-    virtio_input_cfg_bits(virtio_input_dev, VIRTIO_INPUT_CFG_EV_BITS, EV_ABS, virtio_input_dev->abs_bit, ABS_CNT);
-
-    queue_event = &virtio_dev->queues[VIRTIO_INPUT_QUEUE_EVENT];
-    queue_status = &virtio_dev->queues[VIRTIO_INPUT_QUEUE_STATUS];
-
-    virtio_alloc_desc_chain(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT, queue_event->num, idx);
-    virtio_alloc_desc_chain(virtio_dev, VIRTIO_INPUT_QUEUE_STATUS, queue_status->num, idx);
-
-    for (i = 0; i < queue_event->num; ++i)
-    {
-        rt_uint16_t id = i;
-        void *addr = &virtio_input_dev->recv_events[i];
-
-        virtio_fill_desc(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT, id,
-                VIRTIO_VA2PA(addr), sizeof(struct virtio_input_event), VIRTQ_DESC_F_WRITE, 0);
-
-        virtio_submit_chain(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT, id);
-    }
-    rt_hw_dsb();
-
-    queue_event->avail->flags = 0;
-    queue_status->avail->flags = VIRTQ_AVAIL_F_NO_INTERRUPT;
-
-    virtio_queue_notify(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT);
-
-    return RT_EOK;
-}
-
-static rt_size_t virtio_input_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
-{
-    struct virtio_input_device *virtio_input_dev = (struct virtio_input_device *)dev;
-
-    if (buffer == RT_NULL || pos + size >= virtio_input_dev->virtio_dev.queues[VIRTIO_INPUT_QUEUE_EVENT].num)
-    {
-        return 0;
-    }
-
-    rt_mutex_take(&virtio_input_dev->rw_mutex, RT_WAITING_FOREVER);
-
-    rt_memcpy(buffer, &virtio_input_dev->bcst_events[pos], size);
-
-    rt_mutex_release(&virtio_input_dev->rw_mutex);
-
-    return size;
-}
-
-static rt_size_t virtio_input_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
-{
-    struct virtio_input_device *virtio_input_dev = (struct virtio_input_device *)dev;
-
-    if (buffer == RT_NULL || pos + size >= virtio_input_dev->virtio_dev.queues[VIRTIO_INPUT_QUEUE_EVENT].num)
-    {
-        return 0;
-    }
-
-    rt_mutex_take(&virtio_input_dev->rw_mutex, RT_WAITING_FOREVER);
-
-    rt_memcpy(&virtio_input_dev->bcst_events[pos], buffer, size);
-
-    rt_mutex_release(&virtio_input_dev->rw_mutex);
-
-    return size;
-}
-
-static rt_err_t virtio_input_control(rt_device_t dev, int cmd, void *args)
-{
-    rt_err_t status = RT_EOK;
-    struct virtio_input_device *virtio_input_dev = (struct virtio_input_device *)dev;
-    struct virtio_device *virtio_dev = &virtio_input_dev->virtio_dev;
-    struct virtio_input_config *config = virtio_input_dev->config;
-
-    if (args == RT_NULL)
-    {
-        return -RT_ERROR;
-    }
-
-    switch (cmd)
-    {
-    case VIRTIO_DEVICE_CTRL_INPUT_GET_TYPE:
-
-        *(enum virtio_input_type *)args = virtio_input_dev->type;
-
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_BIND_BSCT_HANDLER:
-
-        virtio_input_dev->bsct_handler = args;
-
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_X_INFO:
-
-        virtio_input_cfg_select(virtio_input_dev, VIRTIO_INPUT_CFG_ABS_INFO, VIRTIO_INPUT_ABS_AXIS_X);
-        rt_memcpy(args, config, sizeof(struct virtio_input_config));
-
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_Y_INFO:
-
-        virtio_input_cfg_select(virtio_input_dev, VIRTIO_INPUT_CFG_ABS_INFO, VIRTIO_INPUT_ABS_AXIS_Y);
-        rt_memcpy(args, config, sizeof(struct virtio_input_config));
-
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_SET_STATUS:
-        {
-            rt_uint16_t id;
-            void *addr;
-            struct virtq *queue_status = &virtio_dev->queues[VIRTIO_INPUT_QUEUE_STATUS];
-
-#ifdef RT_USING_SMP
-            rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-            id = queue_status->avail->idx % queue_status->num;
-            addr = &virtio_input_dev->xmit_events[id];
-
-            rt_memcpy(addr, args, sizeof(struct virtio_input_event));
-
-            virtio_free_desc(virtio_dev, VIRTIO_INPUT_QUEUE_STATUS, id);
-
-            virtio_fill_desc(virtio_dev, VIRTIO_INPUT_QUEUE_STATUS, id,
-                    VIRTIO_VA2PA(addr), sizeof(struct virtio_input_event), 0, 0);
-
-            virtio_submit_chain(virtio_dev, VIRTIO_INPUT_QUEUE_STATUS, id);
-
-            virtio_queue_notify(virtio_dev, VIRTIO_INPUT_QUEUE_STATUS);
-
-            virtio_alloc_desc(virtio_dev, VIRTIO_INPUT_QUEUE_STATUS);
-
-#ifdef RT_USING_SMP
-            rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-        }
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_GET_EV_BIT:
-
-        rt_memcpy(args, virtio_input_dev->ev_bit, sizeof(virtio_input_dev->ev_bit));
-
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_GET_KEY_BIT:
-
-        rt_memcpy(args, virtio_input_dev->key_bit, sizeof(virtio_input_dev->key_bit));
-
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_GET_REL_BIT:
-
-        rt_memcpy(args, virtio_input_dev->rel_bit, sizeof(virtio_input_dev->rel_bit));
-
-        break;
-    case VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_BIT:
-
-        rt_memcpy(args, virtio_input_dev->abs_bit, sizeof(virtio_input_dev->abs_bit));
-
-        break;
-    default:
-        status = -RT_EINVAL;
-        break;
-    }
-
-    return status;
-}
-
-const static struct rt_device_ops virtio_input_ops =
-{
-    virtio_input_init,
-    RT_NULL,
-    RT_NULL,
-    virtio_input_read,
-    virtio_input_write,
-    virtio_input_control
-};
-
-static void virtio_input_isr(int irqno, void *param)
-{
-    struct virtio_input_device *virtio_input_dev = (struct virtio_input_device *)param;
-    struct virtio_device *virtio_dev = &virtio_input_dev->virtio_dev;
-    struct virtq *event_queue = &virtio_dev->queues[VIRTIO_INPUT_QUEUE_EVENT];
-    const char *dev_name = virtio_input_dev->parent.parent.name;
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    virtio_interrupt_ack(virtio_dev);
-    rt_hw_dsb();
-
-    while (event_queue->used_idx != event_queue->used->idx)
-    {
-        rt_uint16_t id = event_queue->used->ring[event_queue->used_idx % event_queue->num].id;
-        rt_uint32_t len = event_queue->used->ring[event_queue->used_idx % event_queue->num].len;
-
-        if (len == sizeof(struct virtio_input_event))
-        {
-            struct virtio_input_event *recv_events = &virtio_input_dev->recv_events[id];
-            struct virtio_input_event *bcst_events = &virtio_input_dev->bcst_events[id];
-
-            if (recv_events->type >= EV_SYN && recv_events->type <= EV_ABS)
-            {
-                bcst_events->type = recv_events->type;
-                bcst_events->code = recv_events->code;
-                bcst_events->value = recv_events->value;
-
-                if (virtio_input_dev->bsct_handler != RT_NULL)
-                {
-                    virtio_input_dev->bsct_handler(*bcst_events);
-                }
-            }
-            else
-            {
-                rt_kprintf("%s: Unsupport event[type: %02x, code: %02x, value: %08x]!\n",
-                        dev_name, recv_events->type, recv_events->code, recv_events->value);
-            }
-        }
-        else
-        {
-            rt_kprintf("%s: Invalid event!\n", dev_name);
-        }
-
-        event_queue->used_idx++;
-
-        virtio_submit_chain(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT, id);
-
-        virtio_queue_notify(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT);
-    }
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-}
-
-rt_err_t rt_virtio_input_init(rt_ubase_t *mmio_base, rt_uint32_t irq)
-{
-    rt_uint32_t flag;
-    static int dev_no = 0;
-    char dev_name[RT_NAME_MAX];
-    struct virtio_device *virtio_dev;
-    struct virtio_input_device *virtio_input_dev;
-
-    virtio_input_dev = rt_malloc(sizeof(struct virtio_input_device));
-
-    if (virtio_input_dev == RT_NULL)
-    {
-        goto _alloc_fail;
-    }
-
-    virtio_dev = &virtio_input_dev->virtio_dev;
-    virtio_dev->irq = irq;
-    virtio_dev->mmio_base = mmio_base;
-
-    virtio_input_dev->config = (struct virtio_input_config *)virtio_dev->mmio_config->config;
-    virtio_input_dev->bsct_handler = RT_NULL;
-
-#ifdef RT_USING_SMP
-    rt_spin_lock_init(&virtio_dev->spinlock);
-#endif
-
-    virtio_reset_device(virtio_dev);
-    virtio_status_acknowledge_driver(virtio_dev);
-
-    virtio_dev->mmio_config->driver_features = virtio_dev->mmio_config->device_features & ~(
-            (1 << VIRTIO_F_RING_EVENT_IDX) |
-            (1 << VIRTIO_F_RING_INDIRECT_DESC));
-
-    virtio_status_driver_ok(virtio_dev);
-
-    if (virtio_queues_alloc(virtio_dev, 2) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    if (virtio_queue_init(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT, VIRTIO_INPUT_EVENT_QUEUE_SIZE) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    if (virtio_queue_init(virtio_dev, VIRTIO_INPUT_QUEUE_STATUS, VIRTIO_INPUT_STATUS_QUEUE_SIZE) != RT_EOK)
-    {
-        virtio_queue_destroy(virtio_dev, VIRTIO_INPUT_QUEUE_EVENT);
-
-        goto _alloc_fail;
-    }
-
-    virtio_input_cfg_select(virtio_input_dev, VIRTIO_INPUT_CFG_ID_DEVIDS, 0);
-
-    if (virtio_input_dev->config->ids.product == EV_ABS)
-    {
-        virtio_input_dev->type = VIRTIO_INPUT_TYPE_TABLET;
-
-        virtio_input_dev->parent.type = RT_Device_Class_Touch;
-
-        flag = RT_DEVICE_FLAG_STANDALONE | RT_DEVICE_FLAG_INT_RX;
-    }
-    else
-    {
-        if (virtio_input_dev->config->ids.product == EV_KEY)
-        {
-            virtio_input_dev->type = VIRTIO_INPUT_TYPE_KEYBOARD;
-        }
-        else
-        {
-            virtio_input_dev->type = VIRTIO_INPUT_TYPE_MOUSE;
-        }
-
-        /* Replace it to "KeyBoard" or "Mouse" if support in the future */
-        virtio_input_dev->parent.type = RT_Device_Class_Miscellaneous;
-
-        flag = RT_DEVICE_FLAG_RDWR;
-    }
-    virtio_input_dev->parent.ops  = &virtio_input_ops;
-
-    rt_snprintf(dev_name, RT_NAME_MAX, "virtio-input%d", dev_no++);
-
-    rt_mutex_init(&virtio_input_dev->rw_mutex, dev_name, RT_IPC_FLAG_PRIO);
-
-    rt_hw_interrupt_install(irq, virtio_input_isr, virtio_input_dev, dev_name);
-    rt_hw_interrupt_umask(irq);
-
-    return rt_device_register((rt_device_t)virtio_input_dev, dev_name, flag);
-
-_alloc_fail:
-
-    if (virtio_input_dev != RT_NULL)
-    {
-        virtio_queues_free(virtio_dev);
-        rt_free(virtio_input_dev);
-    }
-    return -RT_ENOMEM;
-}
-#endif /* BSP_USING_VIRTIO_INPUT */

+ 0 - 145
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input.h

@@ -1,145 +0,0 @@
-/*
- * 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_INPUT_H__
-#define __VIRTIO_INPUT_H__
-
-#include <rtdef.h>
-
-#include <virtio.h>
-#include <virtio_input_event_codes.h>
-
-#define VIRTIO_INPUT_QUEUE_EVENT        0
-#define VIRTIO_INPUT_QUEUE_STATUS       1
-#define VIRTIO_INPUT_EVENT_QUEUE_SIZE   64
-#define VIRTIO_INPUT_STATUS_QUEUE_SIZE  8
-#define VIRTIO_INPUT_QUEUE_MAX_SIZE     (VIRTIO_INPUT_EVENT_QUEUE_SIZE > VIRTIO_INPUT_STATUS_QUEUE_SIZE ? \
-        VIRTIO_INPUT_EVENT_QUEUE_SIZE : VIRTIO_INPUT_STATUS_QUEUE_SIZE)
-
-#define VIRTIO_INPUT_ABS_AXIS_X         0
-#define VIRTIO_INPUT_ABS_AXIS_Y         1
-
-enum virtio_input_type
-{
-    VIRTIO_INPUT_TYPE_KEYBOARD,
-    VIRTIO_INPUT_TYPE_MOUSE,
-    VIRTIO_INPUT_TYPE_TABLET,
-
-    VIRTIO_INPUT_TYPE_SIZE,
-};
-
-enum virtio_input_config_select
-{
-    VIRTIO_INPUT_CFG_UNSET      = 0x00,
-    VIRTIO_INPUT_CFG_ID_NAME    = 0x01,
-    VIRTIO_INPUT_CFG_ID_SERIAL  = 0x02,
-    VIRTIO_INPUT_CFG_ID_DEVIDS  = 0x03,
-    VIRTIO_INPUT_CFG_PROP_BITS  = 0x10,
-    VIRTIO_INPUT_CFG_EV_BITS    = 0x11,
-    VIRTIO_INPUT_CFG_ABS_INFO   = 0x12,
-};
-
-struct virtio_input_absinfo
-{
-    rt_uint32_t min;    /* Minimum value for the axis */
-    rt_uint32_t max;    /* Maximum value for the axis */
-    rt_uint32_t fuzz;   /* Fuzz value that is used to filter noise from the event stream */
-    rt_uint32_t flat;   /* Within this value will be discarded by joydev interface and reported as 0 instead */
-    rt_uint32_t res;    /* Resolution for the values reported for the axis */
-};
-
-struct virtio_input_devids
-{
-    rt_uint16_t bustype;
-    rt_uint16_t vendor;
-    rt_uint16_t product;
-    rt_uint16_t version;
-};
-
-struct virtio_input_config
-{
-    rt_uint8_t select;
-    rt_uint8_t subsel;
-    rt_uint8_t size;
-    rt_uint8_t reserved[5];
-
-    union
-    {
-        char string[128];
-        rt_uint8_t bitmap[128];
-        struct virtio_input_absinfo abs;
-        struct virtio_input_devids ids;
-    };
-} __attribute__((packed));
-
-struct virtio_input_event
-{
-    rt_uint16_t type;
-    rt_uint16_t code;
-    rt_uint32_t value;
-};
-
-#ifdef ARCH_CPU_64BIT
-#define BITS_PER_LONG 64
-#else
-#define BITS_PER_LONG 32
-#endif
-#define BIT_MASK(nr)        (1UL << ((nr) % BITS_PER_LONG))
-#define BIT_WORD(nr)        ((nr) / BITS_PER_LONG)
-#define DIV_ROUND_UP(n, d)  (((n) + (d) - 1) / (d))
-
-#define BITS_PER_BYTE       8
-#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
-#define BITS_TO_BYTES(nr)   DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
-#define BITS_TO_LONGS(nr)   DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
-
-struct virtio_input_device
-{
-    struct rt_device parent;
-
-    struct virtio_device virtio_dev;
-
-    rt_ubase_t ev_bit[BITS_TO_LONGS(EV_CNT)];
-    rt_ubase_t key_bit[BITS_TO_LONGS(KEY_CNT)];
-    rt_ubase_t rel_bit[BITS_TO_LONGS(REL_CNT)];
-    rt_ubase_t abs_bit[BITS_TO_LONGS(ABS_CNT)];
-
-    enum virtio_input_type type;
-    struct virtio_input_config *config;
-
-    /* Broadcast events */
-    struct rt_mutex rw_mutex;
-    void (*bsct_handler)(struct virtio_input_event event);
-    struct virtio_input_event bcst_events[VIRTIO_INPUT_EVENT_QUEUE_SIZE];
-
-    /* Receive events */
-    struct virtio_input_event recv_events[VIRTIO_INPUT_EVENT_QUEUE_SIZE];
-
-    /* Transmit status */
-    struct virtio_input_event xmit_events[VIRTIO_INPUT_STATUS_QUEUE_SIZE];
-};
-
-enum
-{
-    VIRTIO_DEVICE_CTRL_INPUT_GET_TYPE           = 0x20,
-    VIRTIO_DEVICE_CTRL_INPUT_BIND_BSCT_HANDLER,
-    VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_X_INFO,
-    VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_Y_INFO,
-    VIRTIO_DEVICE_CTRL_INPUT_SET_STATUS,
-
-    VIRTIO_DEVICE_CTRL_INPUT_GET_EV_BIT,
-    VIRTIO_DEVICE_CTRL_INPUT_GET_KEY_BIT,
-    VIRTIO_DEVICE_CTRL_INPUT_GET_REL_BIT,
-    VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_BIT,
-};
-
-rt_err_t rt_virtio_input_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
-
-#endif /* __VIRTIO_INPUT_H__ */

+ 0 - 932
bsp/qemu-virt64-aarch64/driver/virtio/virtio_input_event_codes.h

@@ -1,932 +0,0 @@
-/*
- * 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_INPUT_EVENT_CODES__
-#define __VIRTIO_INPUT_EVENT_CODES__
-
-/* Device properties and quirks */
-#define INPUT_PROP_POINTER          0x00    /* Needs a pointer */
-#define INPUT_PROP_DIRECT           0x01    /* Direct input devices */
-#define INPUT_PROP_BUTTONPAD        0x02    /* Has button(s) under pad */
-#define INPUT_PROP_SEMI_MT          0x03    /* Touch rectangle only */
-#define INPUT_PROP_TOPBUTTONPAD     0x04    /* Softbuttons at top of pad */
-#define INPUT_PROP_POINTING_STICK   0x05    /* Is a pointing stick */
-#define INPUT_PROP_ACCELEROMETER    0x06    /* Has accelerometer */
-
-#define INPUT_PROP_MAX              0x1f
-#define INPUT_PROP_CNT              (INPUT_PROP_MAX + 1)
-
-/* Event types */
-#define EV_SYN                  0x00        /* Synchronization events */
-#define EV_KEY                  0x01        /* Keys and buttons type */
-#define EV_REL                  0x02        /* Relative axes events */
-#define EV_ABS                  0x03        /* Absolute axes events */
-#define EV_MSC                  0x04        /* Misc events */
-#define EV_SW                   0x05        /* Switch events */
-#define EV_LED                  0x11        /* LEDs events */
-#define EV_SND                  0x12        /* Sounds events */
-#define EV_REP                  0x14        /* Repeat events */
-#define EV_FF                   0x15        /* Force feedback events */
-#define EV_PWR                  0x16        /* Power management events */
-#define EV_FF_STATUS            0x17        /* Force feedback state */
-#define EV_MAX                  0x1f        /* Maximum number of events */
-#define EV_CNT                  (EV_MAX + 1)/* Event count */
-
-/* Synchronization events.*/
-#define SYN_REPORT              0
-#define SYN_CONFIG              1
-#define SYN_MT_REPORT           2
-#define SYN_DROPPED             3
-#define SYN_MAX                 0xf
-#define SYN_CNT                 (SYN_MAX + 1)
-
-/*
- * Keys and buttons
- *
- * Most of the keys/buttons are modeled after USB HUT 1.12
- * (see http://www.usb.org/developers/hidpage).
- * Abbreviations in the comments:
- * AC - Application Control
- * AL - Application Launch Button
- * SC - System Control
- */
-#define KEY_RESERVED            0
-#define KEY_ESC                 1
-#define KEY_1                   2
-#define KEY_2                   3
-#define KEY_3                   4
-#define KEY_4                   5
-#define KEY_5                   6
-#define KEY_6                   7
-#define KEY_7                   8
-#define KEY_8                   9
-#define KEY_9                   10
-#define KEY_0                   11
-#define KEY_MINUS               12
-#define KEY_EQUAL               13
-#define KEY_BACKSPACE           14
-#define KEY_TAB                 15
-#define KEY_Q                   16
-#define KEY_W                   17
-#define KEY_E                   18
-#define KEY_R                   19
-#define KEY_T                   20
-#define KEY_Y                   21
-#define KEY_U                   22
-#define KEY_I                   23
-#define KEY_O                   24
-#define KEY_P                   25
-#define KEY_LEFTBRACE           26
-#define KEY_RIGHTBRACE          27
-#define KEY_ENTER               28
-#define KEY_LEFTCTRL            29
-#define KEY_A                   30
-#define KEY_S                   31
-#define KEY_D                   32
-#define KEY_F                   33
-#define KEY_G                   34
-#define KEY_H                   35
-#define KEY_J                   36
-#define KEY_K                   37
-#define KEY_L                   38
-#define KEY_SEMICOLON           39
-#define KEY_APOSTROPHE          40
-#define KEY_GRAVE               41
-#define KEY_LEFTSHIFT           42
-#define KEY_BACKSLASH           43
-#define KEY_Z                   44
-#define KEY_X                   45
-#define KEY_C                   46
-#define KEY_V                   47
-#define KEY_B                   48
-#define KEY_N                   49
-#define KEY_M                   50
-#define KEY_COMMA               51
-#define KEY_DOT                 52
-#define KEY_SLASH               53
-#define KEY_RIGHTSHIFT          54
-#define KEY_KPASTERISK          55
-#define KEY_LEFTALT             56
-#define KEY_SPACE               57
-#define KEY_CAPSLOCK            58
-#define KEY_F1                  59
-#define KEY_F2                  60
-#define KEY_F3                  61
-#define KEY_F4                  62
-#define KEY_F5                  63
-#define KEY_F6                  64
-#define KEY_F7                  65
-#define KEY_F8                  66
-#define KEY_F9                  67
-#define KEY_F10                 68
-#define KEY_NUMLOCK             69
-#define KEY_SCROLLLOCK          70
-#define KEY_KP7                 71
-#define KEY_KP8                 72
-#define KEY_KP9                 73
-#define KEY_KPMINUS             74
-#define KEY_KP4                 75
-#define KEY_KP5                 76
-#define KEY_KP6                 77
-#define KEY_KPPLUS              78
-#define KEY_KP1                 79
-#define KEY_KP2                 80
-#define KEY_KP3                 81
-#define KEY_KP0                 82
-#define KEY_KPDOT               83
-
-#define KEY_ZENKAKUHANKAKU      85
-#define KEY_102ND               86
-#define KEY_F11                 87
-#define KEY_F12                 88
-#define KEY_RO                  89
-#define KEY_KATAKANA            90
-#define KEY_HIRAGANA            91
-#define KEY_HENKAN              92
-#define KEY_KATAKANAHIRAGANA    93
-#define KEY_MUHENKAN            94
-#define KEY_KPJPCOMMA           95
-#define KEY_KPENTER             96
-#define KEY_RIGHTCTRL           97
-#define KEY_KPSLASH             98
-#define KEY_SYSRQ               99
-#define KEY_RIGHTALT            100
-#define KEY_LINEFEED            101
-#define KEY_HOME                102
-#define KEY_UP                  103
-#define KEY_PAGEUP              104
-#define KEY_LEFT                105
-#define KEY_RIGHT               106
-#define KEY_END                 107
-#define KEY_DOWN                108
-#define KEY_PAGEDOWN            109
-#define KEY_INSERT              110
-#define KEY_DELETE              111
-#define KEY_MACRO               112
-#define KEY_MUTE                113
-#define KEY_VOLUMEDOWN          114
-#define KEY_VOLUMEUP            115
-#define KEY_POWER               116     /* SC System Power Down */
-#define KEY_KPEQUAL             117
-#define KEY_KPPLUSMINUS         118
-#define KEY_PAUSE               119
-#define KEY_SCALE               120     /* AL Compiz Scale (Expose) */
-
-#define KEY_KPCOMMA             121
-#define KEY_HANGEUL             122
-#define KEY_HANGUEL             KEY_HANGEUL
-#define KEY_HANJA               123
-#define KEY_YEN                 124
-#define KEY_LEFTMETA            125
-#define KEY_RIGHTMETA           126
-#define KEY_COMPOSE             127
-
-#define KEY_STOP                128     /* AC Stop */
-#define KEY_AGAIN               129
-#define KEY_PROPS               130     /* AC Properties */
-#define KEY_UNDO                131     /* AC Undo */
-#define KEY_FRONT               132
-#define KEY_COPY                133     /* AC Copy */
-#define KEY_OPEN                134     /* AC Open */
-#define KEY_PASTE               135     /* AC Paste */
-#define KEY_FIND                136     /* AC Search */
-#define KEY_CUT                 137     /* AC Cut */
-#define KEY_HELP                138     /* AL Integrated Help Center */
-#define KEY_MENU                139     /* Menu (show menu) */
-#define KEY_CALC                140     /* AL Calculator */
-#define KEY_SETUP               141
-#define KEY_SLEEP               142     /* SC System Sleep */
-#define KEY_WAKEUP              143     /* System Wake Up */
-#define KEY_FILE                144     /* AL Local Machine Browser */
-#define KEY_SENDFILE            145
-#define KEY_DELETEFILE          146
-#define KEY_XFER                147
-#define KEY_PROG1               148
-#define KEY_PROG2               149
-#define KEY_WWW                 150     /* AL Internet Browser */
-#define KEY_MSDOS               151
-#define KEY_COFFEE              152     /* AL Terminal Lock/Screensaver */
-#define KEY_SCREENLOCK          KEY_COFFEE
-#define KEY_ROTATE_DISPLAY      153     /* Display orientation for e.g. tablets */
-#define KEY_DIRECTION           KEY_ROTATE_DISPLAY
-#define KEY_CYCLEWINDOWS        154
-#define KEY_MAIL                155
-#define KEY_BOOKMARKS           156     /* AC Bookmarks */
-#define KEY_COMPUTER            157
-#define KEY_BACK                158     /* AC Back */
-#define KEY_FORWARD             159     /* AC Forward */
-#define KEY_CLOSECD             160
-#define KEY_EJECTCD             161
-#define KEY_EJECTCLOSECD        162
-#define KEY_NEXTSONG            163
-#define KEY_PLAYPAUSE           164
-#define KEY_PREVIOUSSONG        165
-#define KEY_STOPCD              166
-#define KEY_RECORD              167
-#define KEY_REWIND              168
-#define KEY_PHONE               169     /* Media Select Telephone */
-#define KEY_ISO                 170
-#define KEY_CONFIG              171     /* AL Consumer Control Configuration */
-#define KEY_HOMEPAGE            172     /* AC Home */
-#define KEY_REFRESH             173     /* AC Refresh */
-#define KEY_EXIT                174     /* AC Exit */
-#define KEY_MOVE                175
-#define KEY_EDIT                176
-#define KEY_SCROLLUP            177
-#define KEY_SCROLLDOWN          178
-#define KEY_KPLEFTPAREN         179
-#define KEY_KPRIGHTPAREN        180
-#define KEY_NEW                 181     /* AC New */
-#define KEY_REDO                182     /* AC Redo/Repeat */
-
-#define KEY_F13                 183
-#define KEY_F14                 184
-#define KEY_F15                 185
-#define KEY_F16                 186
-#define KEY_F17                 187
-#define KEY_F18                 188
-#define KEY_F19                 189
-#define KEY_F20                 190
-#define KEY_F21                 191
-#define KEY_F22                 192
-#define KEY_F23                 193
-#define KEY_F24                 194
-
-#define KEY_PLAYCD              200
-#define KEY_PAUSECD             201
-#define KEY_PROG3               202
-#define KEY_PROG4               203
-#define KEY_ALL_APPLICATIONS    204     /* AC Desktop Show All Applications */
-#define KEY_DASHBOARD           KEY_ALL_APPLICATIONS
-#define KEY_SUSPEND             205
-#define KEY_CLOSE               206     /* AC Close */
-#define KEY_PLAY                207
-#define KEY_FASTFORWARD         208
-#define KEY_BASSBOOST           209
-#define KEY_PRINT               210     /* AC Print */
-#define KEY_HP                  211
-#define KEY_CAMERA              212
-#define KEY_SOUND               213
-#define KEY_QUESTION            214
-#define KEY_EMAIL               215
-#define KEY_CHAT                216
-#define KEY_SEARCH              217
-#define KEY_CONNECT             218
-#define KEY_FINANCE             219     /* AL Checkbook/Finance */
-#define KEY_SPORT               220
-#define KEY_SHOP                221
-#define KEY_ALTERASE            222
-#define KEY_CANCEL              223     /* AC Cancel */
-#define KEY_BRIGHTNESSDOWN      224
-#define KEY_BRIGHTNESSUP        225
-#define KEY_MEDIA               226
-
-#define KEY_SWITCHVIDEOMODE     227     /* Cycle between available video outputs (Monitor/LCD/TV-out/etc) */
-#define KEY_KBDILLUMTOGGLE      228
-#define KEY_KBDILLUMDOWN        229
-#define KEY_KBDILLUMUP          230
-
-#define KEY_SEND                231     /* AC Send */
-#define KEY_REPLY               232     /* AC Reply */
-#define KEY_FORWARDMAIL         233     /* AC Forward Msg */
-#define KEY_SAVE                234     /* AC Save */
-#define KEY_DOCUMENTS           235
-
-#define KEY_BATTERY             236
-
-#define KEY_BLUETOOTH           237
-#define KEY_WLAN                238
-#define KEY_UWB                 239
-
-#define KEY_UNKNOWN             240
-
-#define KEY_VIDEO_NEXT          241     /* Drive next video source */
-#define KEY_VIDEO_PREV          242     /* Drive previous video source */
-#define KEY_BRIGHTNESS_CYCLE    243     /* Brightness up, after max is min */
-#define KEY_BRIGHTNESS_AUTO     244     /* Set Auto Brightness: manual brightness control is off, rely on ambient */
-#define KEY_BRIGHTNESS_ZERO     KEY_BRIGHTNESS_AUTO
-#define KEY_DISPLAY_OFF         245     /* Display device to off state */
-
-#define KEY_WWAN                246     /* Wireless WAN (LTE, UMTS, GSM, etc.) */
-#define KEY_WIMAX               KEY_WWAN
-#define KEY_RFKILL              247     /* Key that controls all radios */
-
-#define KEY_MICMUTE             248     /* Mute / unmute the microphone */
-
-/* Code 255 is reserved for special needs of AT keyboard driver */
-#define BTN_MISC                0x100
-#define BTN_0                   0x100
-#define BTN_1                   0x101
-#define BTN_2                   0x102
-#define BTN_3                   0x103
-#define BTN_4                   0x104
-#define BTN_5                   0x105
-#define BTN_6                   0x106
-#define BTN_7                   0x107
-#define BTN_8                   0x108
-#define BTN_9                   0x109
-
-#define BTN_MOUSE               0x110
-#define BTN_LEFT                0x110
-#define BTN_RIGHT               0x111
-#define BTN_MIDDLE              0x112
-#define BTN_SIDE                0x113
-#define BTN_EXTRA               0x114
-#define BTN_FORWARD             0x115
-#define BTN_BACK                0x116
-#define BTN_TASK                0x117
-
-#define BTN_JOYSTICK            0x120
-#define BTN_TRIGGER             0x120
-#define BTN_THUMB               0x121
-#define BTN_THUMB2              0x122
-#define BTN_TOP                 0x123
-#define BTN_TOP2                0x124
-#define BTN_PINKIE              0x125
-#define BTN_BASE                0x126
-#define BTN_BASE2               0x127
-#define BTN_BASE3               0x128
-#define BTN_BASE4               0x129
-#define BTN_BASE5               0x12a
-#define BTN_BASE6               0x12b
-#define BTN_DEAD                0x12f
-
-#define BTN_GAMEPAD             0x130
-#define BTN_SOUTH               0x130
-#define BTN_A                   BTN_SOUTH
-#define BTN_EAST                0x131
-#define BTN_B                   BTN_EAST
-#define BTN_C                   0x132
-#define BTN_NORTH               0x133
-#define BTN_X                   BTN_NORTH
-#define BTN_WEST                0x134
-#define BTN_Y                   BTN_WEST
-#define BTN_Z                   0x135
-#define BTN_TL                  0x136
-#define BTN_TR                  0x137
-#define BTN_TL2                 0x138
-#define BTN_TR2                 0x139
-#define BTN_SELECT              0x13a
-#define BTN_START               0x13b
-#define BTN_MODE                0x13c
-#define BTN_THUMBL              0x13d
-#define BTN_THUMBR              0x13e
-
-#define BTN_DIGI                0x140
-#define BTN_TOOL_PEN            0x140
-#define BTN_TOOL_RUBBER         0x141
-#define BTN_TOOL_BRUSH          0x142
-#define BTN_TOOL_PENCIL         0x143
-#define BTN_TOOL_AIRBRUSH       0x144
-#define BTN_TOOL_FINGER         0x145
-#define BTN_TOOL_MOUSE          0x146
-#define BTN_TOOL_LENS           0x147
-#define BTN_TOOL_QUINTTAP       0x148   /* Five fingers on trackpad */
-#define BTN_STYLUS3             0x149
-#define BTN_TOUCH               0x14a
-#define BTN_STYLUS              0x14b
-#define BTN_STYLUS2             0x14c
-#define BTN_TOOL_DOUBLETAP      0x14d
-#define BTN_TOOL_TRIPLETAP      0x14e
-#define BTN_TOOL_QUADTAP        0x14f   /* Four fingers on trackpad */
-
-#define BTN_WHEEL               0x150
-#define BTN_GEAR_DOWN           0x150
-#define BTN_GEAR_UP             0x151
-
-#define KEY_OK                  0x160
-#define KEY_SELECT              0x161
-#define KEY_GOTO                0x162
-#define KEY_CLEAR               0x163
-#define KEY_POWER2              0x164
-#define KEY_OPTION              0x165
-#define KEY_INFO                0x166   /* AL OEM Features/Tips/Tutorial */
-#define KEY_TIME                0x167
-#define KEY_VENDOR              0x168
-#define KEY_ARCHIVE             0x169
-#define KEY_PROGRAM             0x16a   /* Media Select Program Guide */
-#define KEY_CHANNEL             0x16b
-#define KEY_FAVORITES           0x16c
-#define KEY_EPG                 0x16d
-#define KEY_PVR                 0x16e   /* Media Select Home */
-#define KEY_MHP                 0x16f
-#define KEY_LANGUAGE            0x170
-#define KEY_TITLE               0x171
-#define KEY_SUBTITLE            0x172
-#define KEY_ANGLE               0x173
-#define KEY_FULL_SCREEN         0x174   /* AC View Toggle */
-#define KEY_ZOOM                KEY_FULL_SCREEN
-#define KEY_MODE                0x175
-#define KEY_KEYBOARD            0x176
-#define KEY_ASPECT_RATIO        0x177   /* HUTRR37: Aspect */
-#define KEY_SCREEN              KEY_ASPECT_RATIO
-#define KEY_PC                  0x178   /* Media Select Computer */
-#define KEY_TV                  0x179   /* Media Select TV */
-#define KEY_TV2                 0x17a   /* Media Select Cable */
-#define KEY_VCR                 0x17b   /* Media Select VCR */
-#define KEY_VCR2                0x17c   /* VCR Plus */
-#define KEY_SAT                 0x17d   /* Media Select Satellite */
-#define KEY_SAT2                0x17e
-#define KEY_CD                  0x17f   /* Media Select CD */
-#define KEY_TAPE                0x180   /* Media Select Tape */
-#define KEY_RADIO               0x181
-#define KEY_TUNER               0x182   /* Media Select Tuner */
-#define KEY_PLAYER              0x183
-#define KEY_TEXT                0x184
-#define KEY_DVD                 0x185   /* Media Select DVD */
-#define KEY_AUX                 0x186
-#define KEY_MP3                 0x187
-#define KEY_AUDIO               0x188   /* AL Audio Browser */
-#define KEY_VIDEO               0x189   /* AL Movie Browser */
-#define KEY_DIRECTORY           0x18a
-#define KEY_LIST                0x18b
-#define KEY_MEMO                0x18c   /* Media Select Messages */
-#define KEY_CALENDAR            0x18d
-#define KEY_RED                 0x18e
-#define KEY_GREEN               0x18f
-#define KEY_YELLOW              0x190
-#define KEY_BLUE                0x191
-#define KEY_CHANNELUP           0x192   /* Channel Increment */
-#define KEY_CHANNELDOWN         0x193   /* Channel Decrement */
-#define KEY_FIRST               0x194
-#define KEY_LAST                0x195   /* Recall Last */
-#define KEY_AB                  0x196
-#define KEY_NEXT                0x197
-#define KEY_RESTART             0x198
-#define KEY_SLOW                0x199
-#define KEY_SHUFFLE             0x19a
-#define KEY_BREAK               0x19b
-#define KEY_PREVIOUS            0x19c
-#define KEY_DIGITS              0x19d
-#define KEY_TEEN                0x19e
-#define KEY_TWEN                0x19f
-#define KEY_VIDEOPHONE          0x1a0   /* Media Select Video Phone */
-#define KEY_GAMES               0x1a1   /* Media Select Games */
-#define KEY_ZOOMIN              0x1a2   /* AC Zoom In */
-#define KEY_ZOOMOUT             0x1a3   /* AC Zoom Out */
-#define KEY_ZOOMRESET           0x1a4   /* AC Zoom */
-#define KEY_WORDPROCESSOR       0x1a5   /* AL Word Processor */
-#define KEY_EDITOR              0x1a6   /* AL Text Editor */
-#define KEY_SPREADSHEET         0x1a7   /* AL Spreadsheet */
-#define KEY_GRAPHICSEDITOR      0x1a8   /* AL Graphics Editor */
-#define KEY_PRESENTATION        0x1a9   /* AL Presentation App */
-#define KEY_DATABASE            0x1aa   /* AL Database App */
-#define KEY_NEWS                0x1ab   /* AL Newsreader */
-#define KEY_VOICEMAIL           0x1ac   /* AL Voicemail */
-#define KEY_ADDRESSBOOK         0x1ad   /* AL Contacts/Address Book */
-#define KEY_MESSENGER           0x1ae   /* AL Instant Messaging */
-#define KEY_DISPLAYTOGGLE       0x1af   /* Turn display (LCD) on and off */
-#define KEY_BRIGHTNESS_TOGGLE   KEY_DISPLAYTOGGLE
-#define KEY_SPELLCHECK          0x1b0   /* AL Spell Check */
-#define KEY_LOGOFF              0x1b1   /* AL Logoff */
-
-#define KEY_DOLLAR              0x1b2
-#define KEY_EURO                0x1b3
-
-#define KEY_FRAMEBACK           0x1b4   /* Consumer - transport controls */
-#define KEY_FRAMEFORWARD        0x1b5
-#define KEY_CONTEXT_MENU        0x1b6   /* GenDesc - system context menu */
-#define KEY_MEDIA_REPEAT        0x1b7   /* Consumer - transport control */
-#define KEY_10CHANNELSUP        0x1b8   /* 10 channels up (10+) */
-#define KEY_10CHANNELSDOWN      0x1b9   /* 10 channels down (10-) */
-#define KEY_IMAGES              0x1ba   /* AL Image Browser */
-#define KEY_NOTIFICATION_CENTER 0x1bc   /* Show/hide the notification center */
-#define KEY_PICKUP_PHONE        0x1bd   /* Answer incoming call */
-#define KEY_HANGUP_PHONE        0x1be   /* Decline incoming call */
-
-#define KEY_DEL_EOL             0x1c0
-#define KEY_DEL_EOS             0x1c1
-#define KEY_INS_LINE            0x1c2
-#define KEY_DEL_LINE            0x1c3
-
-#define KEY_FN                  0x1d0
-#define KEY_FN_ESC              0x1d1
-#define KEY_FN_F1               0x1d2
-#define KEY_FN_F2               0x1d3
-#define KEY_FN_F3               0x1d4
-#define KEY_FN_F4               0x1d5
-#define KEY_FN_F5               0x1d6
-#define KEY_FN_F6               0x1d7
-#define KEY_FN_F7               0x1d8
-#define KEY_FN_F8               0x1d9
-#define KEY_FN_F9               0x1da
-#define KEY_FN_F10              0x1db
-#define KEY_FN_F11              0x1dc
-#define KEY_FN_F12              0x1dd
-#define KEY_FN_1                0x1de
-#define KEY_FN_2                0x1df
-#define KEY_FN_D                0x1e0
-#define KEY_FN_E                0x1e1
-#define KEY_FN_F                0x1e2
-#define KEY_FN_S                0x1e3
-#define KEY_FN_B                0x1e4
-#define KEY_FN_RIGHT_SHIFT      0x1e5
-
-#define KEY_BRL_DOT1            0x1f1
-#define KEY_BRL_DOT2            0x1f2
-#define KEY_BRL_DOT3            0x1f3
-#define KEY_BRL_DOT4            0x1f4
-#define KEY_BRL_DOT5            0x1f5
-#define KEY_BRL_DOT6            0x1f6
-#define KEY_BRL_DOT7            0x1f7
-#define KEY_BRL_DOT8            0x1f8
-#define KEY_BRL_DOT9            0x1f9
-#define KEY_BRL_DOT10           0x1fa
-
-#define KEY_NUMERIC_0           0x200   /* Used by phones, remote controls, and other keypads */
-#define KEY_NUMERIC_1           0x201
-#define KEY_NUMERIC_2           0x202
-#define KEY_NUMERIC_3           0x203
-#define KEY_NUMERIC_4           0x204
-#define KEY_NUMERIC_5           0x205
-#define KEY_NUMERIC_6           0x206
-#define KEY_NUMERIC_7           0x207
-#define KEY_NUMERIC_8           0x208
-#define KEY_NUMERIC_9           0x209
-#define KEY_NUMERIC_STAR        0x20a
-#define KEY_NUMERIC_POUND       0x20b
-#define KEY_NUMERIC_A           0x20c   /* Phone key A - HUT Telephony 0xb9 */
-#define KEY_NUMERIC_B           0x20d
-#define KEY_NUMERIC_C           0x20e
-#define KEY_NUMERIC_D           0x20f
-
-#define KEY_CAMERA_FOCUS        0x210
-#define KEY_WPS_BUTTON          0x211   /* WiFi Protected Setup key */
-
-#define KEY_TOUCHPAD_TOGGLE     0x212   /* Request switch touchpad on or off */
-#define KEY_TOUCHPAD_ON         0x213
-#define KEY_TOUCHPAD_OFF        0x214
-
-#define KEY_CAMERA_ZOOMIN       0x215
-#define KEY_CAMERA_ZOOMOUT      0x216
-#define KEY_CAMERA_UP           0x217
-#define KEY_CAMERA_DOWN         0x218
-#define KEY_CAMERA_LEFT         0x219
-#define KEY_CAMERA_RIGHT        0x21a
-
-#define KEY_ATTENDANT_ON        0x21b
-#define KEY_ATTENDANT_OFF       0x21c
-#define KEY_ATTENDANT_TOGGLE    0x21d   /* Attendant call on or off */
-#define KEY_LIGHTS_TOGGLE       0x21e   /* Reading light on or off */
-
-#define BTN_DPAD_UP             0x220
-#define BTN_DPAD_DOWN           0x221
-#define BTN_DPAD_LEFT           0x222
-#define BTN_DPAD_RIGHT          0x223
-
-#define KEY_ALS_TOGGLE          0x230   /* Ambient light sensor */
-#define KEY_ROTATE_LOCK_TOGGLE  0x231   /* Display rotation lock */
-
-#define KEY_BUTTONCONFIG        0x240   /* AL Button Configuration */
-#define KEY_TASKMANAGER         0x241   /* AL Task/Project Manager */
-#define KEY_JOURNAL             0x242   /* AL Log/Journal/Timecard */
-#define KEY_CONTROLPANEL        0x243   /* AL Control Panel */
-#define KEY_APPSELECT           0x244   /* AL Select Task/Application */
-#define KEY_SCREENSAVER         0x245   /* AL Screen Saver */
-#define KEY_VOICECOMMAND        0x246   /* Listening Voice Command */
-#define KEY_ASSISTANT           0x247   /* AL Context-aware desktop assistant */
-#define KEY_KBD_LAYOUT_NEXT     0x248   /* AC Next Keyboard Layout Select */
-#define KEY_EMOJI_PICKER        0x249   /* Show/hide emoji picker (HUTRR101) */
-#define KEY_DICTATE             0x24a   /* Start or Stop Voice Dictation Session (HUTRR99) */
-
-#define KEY_BRIGHTNESS_MIN      0x250   /* Set Brightness to Minimum */
-#define KEY_BRIGHTNESS_MAX      0x251   /* Set Brightness to Maximum */
-
-#define KEY_KBDINPUTASSIST_PREV         0x260
-#define KEY_KBDINPUTASSIST_NEXT         0x261
-#define KEY_KBDINPUTASSIST_PREVGROUP    0x262
-#define KEY_KBDINPUTASSIST_NEXTGROUP    0x263
-#define KEY_KBDINPUTASSIST_ACCEPT       0x264
-#define KEY_KBDINPUTASSIST_CANCEL       0x265
-
-/* Diagonal movement keys */
-#define KEY_RIGHT_UP                    0x266
-#define KEY_RIGHT_DOWN                  0x267
-#define KEY_LEFT_UP                     0x268
-#define KEY_LEFT_DOWN                   0x269
-
-#define KEY_ROOT_MENU                   0x26a /* Show Device's Root Menu */
-/* Show Top Menu of the Media (e.g. DVD) */
-#define KEY_MEDIA_TOP_MENU              0x26b
-#define KEY_NUMERIC_11                  0x26c
-#define KEY_NUMERIC_12                  0x26d
-/*
- * Toggle Audio Description: refers to an audio service that helps blind and
- * visually impaired consumers understand the action in a program. Note: in
- * some countries this is referred to as "Video Description".
- */
-#define KEY_AUDIO_DESC                  0x26e
-#define KEY_3D_MODE                     0x26f
-#define KEY_NEXT_FAVORITE               0x270
-#define KEY_STOP_RECORD                 0x271
-#define KEY_PAUSE_RECORD                0x272
-#define KEY_VOD                         0x273 /* Video on Demand */
-#define KEY_UNMUTE                      0x274
-#define KEY_FASTREVERSE                 0x275
-#define KEY_SLOWREVERSE                 0x276
-/*
- * Control a data application associated with the currently viewed channel,
- * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
- */
-#define KEY_DATA                        0x277
-#define KEY_ONSCREEN_KEYBOARD           0x278
-/* Electronic privacy screen control */
-#define KEY_PRIVACY_SCREEN_TOGGLE       0x279
-
-/* Select an area of screen to be copied */
-#define KEY_SELECTIVE_SCREENSHOT        0x27a
-
-/* Move the focus to the next or previous user controllable element within a UI container */
-#define KEY_NEXT_ELEMENT                0x27b
-#define KEY_PREVIOUS_ELEMENT            0x27c
-
-/* Toggle Autopilot engagement */
-#define KEY_AUTOPILOT_ENGAGE_TOGGLE     0x27d
-
-/* Shortcut Keys */
-#define KEY_MARK_WAYPOINT               0x27e
-#define KEY_SOS                         0x27f
-#define KEY_NAV_CHART                   0x280
-#define KEY_FISHING_CHART               0x281
-#define KEY_SINGLE_RANGE_RADAR          0x282
-#define KEY_DUAL_RANGE_RADAR            0x283
-#define KEY_RADAR_OVERLAY               0x284
-#define KEY_TRADITIONAL_SONAR           0x285
-#define KEY_CLEARVU_SONAR               0x286
-#define KEY_SIDEVU_SONAR                0x287
-#define KEY_NAV_INFO                    0x288
-#define KEY_BRIGHTNESS_MENU             0x289
-
-/*
- * Some keyboards have keys which do not have a defined meaning, these keys
- * are intended to be programmed / bound to macros by the user. For most
- * keyboards with these macro-keys the key-sequence to inject, or action to
- * take, is all handled by software on the host side. So from the kernel's
- * point of view these are just normal keys.
- *
- * The KEY_MACRO# codes below are intended for such keys, which may be labeled
- * e.g. G1-G18, or S1 - S30. The KEY_MACRO# codes MUST NOT be used for keys
- * where the marking on the key does indicate a defined meaning / purpose.
- *
- * The KEY_MACRO# codes MUST also NOT be used as fallback for when no existing
- * KEY_FOO define matches the marking / purpose. In this case a new KEY_FOO
- * define MUST be added.
- */
-#define KEY_MACRO1              0x290
-#define KEY_MACRO2              0x291
-#define KEY_MACRO3              0x292
-#define KEY_MACRO4              0x293
-#define KEY_MACRO5              0x294
-#define KEY_MACRO6              0x295
-#define KEY_MACRO7              0x296
-#define KEY_MACRO8              0x297
-#define KEY_MACRO9              0x298
-#define KEY_MACRO10             0x299
-#define KEY_MACRO11             0x29a
-#define KEY_MACRO12             0x29b
-#define KEY_MACRO13             0x29c
-#define KEY_MACRO14             0x29d
-#define KEY_MACRO15             0x29e
-#define KEY_MACRO16             0x29f
-#define KEY_MACRO17             0x2a0
-#define KEY_MACRO18             0x2a1
-#define KEY_MACRO19             0x2a2
-#define KEY_MACRO20             0x2a3
-#define KEY_MACRO21             0x2a4
-#define KEY_MACRO22             0x2a5
-#define KEY_MACRO23             0x2a6
-#define KEY_MACRO24             0x2a7
-#define KEY_MACRO25             0x2a8
-#define KEY_MACRO26             0x2a9
-#define KEY_MACRO27             0x2aa
-#define KEY_MACRO28             0x2ab
-#define KEY_MACRO29             0x2ac
-#define KEY_MACRO30             0x2ad
-
-/*
- * Some keyboards with the macro-keys described above have some extra keys
- * for controlling the host-side software responsible for the macro handling:
- * -A macro recording start/stop key. Note that not all keyboards which emit
- *  KEY_MACRO_RECORD_START will also emit KEY_MACRO_RECORD_STOP if
- *  KEY_MACRO_RECORD_STOP is not advertised, then KEY_MACRO_RECORD_START
- *  should be interpreted as a recording start/stop toggle;
- * -Keys for switching between different macro (pre)sets, either a key for
- *  cycling through the configured presets or keys to directly select a preset.
- */
-#define KEY_MACRO_RECORD_START  0x2b0
-#define KEY_MACRO_RECORD_STOP   0x2b1
-#define KEY_MACRO_PRESET_CYCLE  0x2b2
-#define KEY_MACRO_PRESET1       0x2b3
-#define KEY_MACRO_PRESET2       0x2b4
-#define KEY_MACRO_PRESET3       0x2b5
-
-/*
- * Some keyboards have a buildin LCD panel where the contents are controlled
- * by the host. Often these have a number of keys directly below the LCD
- * intended for controlling a menu shown on the LCD. These keys often don't
- * have any labeling so we just name them KEY_KBD_LCD_MENU#
- */
-#define KEY_KBD_LCD_MENU1       0x2b8
-#define KEY_KBD_LCD_MENU2       0x2b9
-#define KEY_KBD_LCD_MENU3       0x2ba
-#define KEY_KBD_LCD_MENU4       0x2bb
-#define KEY_KBD_LCD_MENU5       0x2bc
-
-#define BTN_TRIGGER_HAPPY       0x2c0
-#define BTN_TRIGGER_HAPPY1      0x2c0
-#define BTN_TRIGGER_HAPPY2      0x2c1
-#define BTN_TRIGGER_HAPPY3      0x2c2
-#define BTN_TRIGGER_HAPPY4      0x2c3
-#define BTN_TRIGGER_HAPPY5      0x2c4
-#define BTN_TRIGGER_HAPPY6      0x2c5
-#define BTN_TRIGGER_HAPPY7      0x2c6
-#define BTN_TRIGGER_HAPPY8      0x2c7
-#define BTN_TRIGGER_HAPPY9      0x2c8
-#define BTN_TRIGGER_HAPPY10     0x2c9
-#define BTN_TRIGGER_HAPPY11     0x2ca
-#define BTN_TRIGGER_HAPPY12     0x2cb
-#define BTN_TRIGGER_HAPPY13     0x2cc
-#define BTN_TRIGGER_HAPPY14     0x2cd
-#define BTN_TRIGGER_HAPPY15     0x2ce
-#define BTN_TRIGGER_HAPPY16     0x2cf
-#define BTN_TRIGGER_HAPPY17     0x2d0
-#define BTN_TRIGGER_HAPPY18     0x2d1
-#define BTN_TRIGGER_HAPPY19     0x2d2
-#define BTN_TRIGGER_HAPPY20     0x2d3
-#define BTN_TRIGGER_HAPPY21     0x2d4
-#define BTN_TRIGGER_HAPPY22     0x2d5
-#define BTN_TRIGGER_HAPPY23     0x2d6
-#define BTN_TRIGGER_HAPPY24     0x2d7
-#define BTN_TRIGGER_HAPPY25     0x2d8
-#define BTN_TRIGGER_HAPPY26     0x2d9
-#define BTN_TRIGGER_HAPPY27     0x2da
-#define BTN_TRIGGER_HAPPY28     0x2db
-#define BTN_TRIGGER_HAPPY29     0x2dc
-#define BTN_TRIGGER_HAPPY30     0x2dd
-#define BTN_TRIGGER_HAPPY31     0x2de
-#define BTN_TRIGGER_HAPPY32     0x2df
-#define BTN_TRIGGER_HAPPY33     0x2e0
-#define BTN_TRIGGER_HAPPY34     0x2e1
-#define BTN_TRIGGER_HAPPY35     0x2e2
-#define BTN_TRIGGER_HAPPY36     0x2e3
-#define BTN_TRIGGER_HAPPY37     0x2e4
-#define BTN_TRIGGER_HAPPY38     0x2e5
-#define BTN_TRIGGER_HAPPY39     0x2e6
-#define BTN_TRIGGER_HAPPY40     0x2e7
-
-/* We avoid low common keys in module aliases so they don't get huge. */
-#define KEY_MIN_INTERESTING     KEY_MUTE
-#define KEY_MAX                 0x2ff
-#define KEY_CNT                 (KEY_MAX + 1)
-
-/* Relative axes */
-#define REL_X                   0x00
-#define REL_Y                   0x01
-#define REL_Z                   0x02
-#define REL_RX                  0x03
-#define REL_RY                  0x04
-#define REL_RZ                  0x05
-#define REL_HWHEEL              0x06
-#define REL_DIAL                0x07
-#define REL_WHEEL               0x08
-#define REL_MISC                0x09
-/*
- * 0x0a is reserved and should not be used in input drivers.
- * It was used by HID as REL_MISC + 1 and userspace needs to detect if
- * the next REL_* event is correct or is just REL_MISC + n.
- * We define here REL_RESERVED so userspace can rely on it and detect
- * the situation described above.
- */
-#define REL_RESERVED            0x0a
-#define REL_WHEEL_HI_RES        0x0b
-#define REL_HWHEEL_HI_RES       0x0c
-#define REL_MAX                 0x0f
-#define REL_CNT                 (REL_MAX + 1)
-
-/* Absolute axes */
-#define ABS_X                   0x00
-#define ABS_Y                   0x01
-#define ABS_Z                   0x02
-#define ABS_RX                  0x03
-#define ABS_RY                  0x04
-#define ABS_RZ                  0x05
-#define ABS_THROTTLE            0x06
-#define ABS_RUDDER              0x07
-#define ABS_WHEEL               0x08
-#define ABS_GAS                 0x09
-#define ABS_BRAKE               0x0a
-#define ABS_HAT0X               0x10
-#define ABS_HAT0Y               0x11
-#define ABS_HAT1X               0x12
-#define ABS_HAT1Y               0x13
-#define ABS_HAT2X               0x14
-#define ABS_HAT2Y               0x15
-#define ABS_HAT3X               0x16
-#define ABS_HAT3Y               0x17
-#define ABS_PRESSURE            0x18
-#define ABS_DISTANCE            0x19
-#define ABS_TILT_X              0x1a
-#define ABS_TILT_Y              0x1b
-#define ABS_TOOL_WIDTH          0x1c
-
-#define ABS_VOLUME              0x20
-
-#define ABS_MISC                0x28
-
-/*
- * 0x2e is reserved and should not be used in input drivers.
- * It was used by HID as ABS_MISC + 6 and userspace needs to detect if
- * the next ABS_* event is correct or is just ABS_MISC + n.
- * We define here ABS_RESERVED so userspace can rely on it and detect
- * the situation described above.
- */
-#define ABS_RESERVED            0x2e
-
-#define ABS_MT_SLOT             0x2f    /* MT slot being modified */
-#define ABS_MT_TOUCH_MAJOR      0x30    /* Major axis of touching ellipse */
-#define ABS_MT_TOUCH_MINOR      0x31    /* Minor axis (omit if circular) */
-#define ABS_MT_WIDTH_MAJOR      0x32    /* Major axis of approaching ellipse */
-#define ABS_MT_WIDTH_MINOR      0x33    /* Minor axis (omit if circular) */
-#define ABS_MT_ORIENTATION      0x34    /* Ellipse orientation */
-#define ABS_MT_POSITION_X       0x35    /* Center X touch position */
-#define ABS_MT_POSITION_Y       0x36    /* Center Y touch position */
-#define ABS_MT_TOOL_TYPE        0x37    /* Type of touching device */
-#define ABS_MT_BLOB_ID          0x38    /* Group a set of packets as a blob */
-#define ABS_MT_TRACKING_ID      0x39    /* Unique ID of initiated contact */
-#define ABS_MT_PRESSURE         0x3a    /* Pressure on contact area */
-#define ABS_MT_DISTANCE         0x3b    /* Contact hover distance */
-#define ABS_MT_TOOL_X           0x3c    /* Center X tool position */
-#define ABS_MT_TOOL_Y           0x3d    /* Center Y tool position */
-
-
-#define ABS_MAX                 0x3f
-#define ABS_CNT                 (ABS_MAX + 1)
-
-/* Switch events */
-#define SW_LID                  0x00  /* Set = lid shut */
-#define SW_TABLET_MODE          0x01  /* Set = tablet mode */
-#define SW_HEADPHONE_INSERT     0x02  /* Set = inserted */
-#define SW_RFKILL_ALL           0x03  /* rfkill master switch, type "any" set = radio enabled */
-#define SW_RADIO                SW_RFKILL_ALL   /* deprecated */
-#define SW_MICROPHONE_INSERT    0x04  /* Set = inserted */
-#define SW_DOCK                 0x05  /* Set = plugged into dock */
-#define SW_LINEOUT_INSERT       0x06  /* Set = inserted */
-#define SW_JACK_PHYSICAL_INSERT 0x07  /* Set = mechanical switch set */
-#define SW_VIDEOOUT_INSERT      0x08  /* Set = inserted */
-#define SW_CAMERA_LENS_COVER    0x09  /* Set = lens covered */
-#define SW_KEYPAD_SLIDE         0x0a  /* Set = keypad slide out */
-#define SW_FRONT_PROXIMITY      0x0b  /* Set = front proximity sensor active */
-#define SW_ROTATE_LOCK          0x0c  /* Set = rotate locked/disabled */
-#define SW_LINEIN_INSERT        0x0d  /* Set = inserted */
-#define SW_MUTE_DEVICE          0x0e  /* Set = device disabled */
-#define SW_PEN_INSERTED         0x0f  /* Set = pen inserted */
-#define SW_MACHINE_COVER        0x10  /* Set = cover closed */
-#define SW_MAX                  0x10
-#define SW_CNT                  (SW_MAX + 1)
-
-/* Misc events */
-#define MSC_SERIAL              0x00
-#define MSC_PULSELED            0x01
-#define MSC_GESTURE             0x02
-#define MSC_RAW                 0x03
-#define MSC_SCAN                0x04
-#define MSC_TIMESTAMP           0x05
-#define MSC_MAX                 0x07
-#define MSC_CNT                 (MSC_MAX + 1)
-
-/* LEDs */
-#define LED_NUML                0x00
-#define LED_CAPSL               0x01
-#define LED_SCROLLL             0x02
-#define LED_COMPOSE             0x03
-#define LED_KANA                0x04
-#define LED_SLEEP               0x05
-#define LED_SUSPEND             0x06
-#define LED_MUTE                0x07
-#define LED_MISC                0x08
-#define LED_MAIL                0x09
-#define LED_CHARGING            0x0a
-#define LED_MAX                 0x0f
-#define LED_CNT                 (LED_MAX + 1)
-
-/* Autorepeat values */
-#define REP_DELAY               0x00
-#define REP_PERIOD              0x01
-#define REP_MAX                 0x01
-#define REP_CNT                 (REP_MAX + 1)
-
-/* Sounds */
-#define SND_CLICK               0x00
-#define SND_BELL                0x01
-#define SND_TONE                0x02
-#define SND_MAX                 0x07
-#define SND_CNT                 (SND_MAX + 1)
-
-#endif /* __VIRTIO_INPUT_EVENT_CODES__ */

+ 0 - 57
bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h

@@ -1,57 +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
- * 2021-11-11     GuEe-GUI     modify to virtio common interface
- */
-
-#ifndef __VIRTIO_MMIO_H__
-#define __VIRTIO_MMIO_H__
-
-#include <rtdef.h>
-
-struct virtio_mmio_config
-{
-    rt_uint32_t magic;                  /* [0x00]<RO> Magic value */
-    rt_uint32_t version;                /* [0x04]<RO> Device version number */
-    rt_uint32_t device_id;              /* [0x08]<RO> Virtio Subsystem Device ID */
-    rt_uint32_t vendor_id;              /* [0x0c]<RO> Virtio Subsystem Vendor ID */
-    rt_uint32_t device_features;        /* [0x10]<RO> Flags representing features the device supports */
-    rt_uint32_t device_features_sel;    /* [0x14]<WO> Device (host) features word selection. */
-    rt_uint32_t res0[2];                /* [0x18] */
-    rt_uint32_t driver_features;        /* [0x20]<WO> Device features understood and activated by the driver */
-    rt_uint32_t driver_features_sel;    /* [0x24]<WO> Activated (guest) features word selection */
-    rt_uint32_t guest_page_size;        /* [0x28]<WO> Guest page size, this value should be a power of 2 */
-    rt_uint32_t res1[1];                /* [0x2c] */
-    rt_uint32_t queue_sel;              /* [0x30]<WO> Virtual queue index */
-    rt_uint32_t queue_num_max;          /* [0x34]<RO> Maximum virtual queue size */
-    rt_uint32_t queue_num;              /* [0x38]<WO> Virtual queue size */
-    rt_uint32_t queue_align;            /* [0x3c]<WO> Used Ring alignment in the virtual queue */
-    rt_uint32_t queue_pfn;              /* [0x40]<RW> Guest physical page number of the virtual queue */
-    rt_uint32_t queue_ready;            /* [0x44]<RW> Virtual queue ready bit */
-    rt_uint32_t res2[2];                /* [0x48] */
-    rt_uint32_t queue_notify;           /* [0x50]<WO> Queue notifier */
-    rt_uint32_t res3[3];                /* [0x54] */
-    rt_uint32_t interrupt_status;       /* [0x60]<RO> Interrupt status */
-    rt_uint32_t interrupt_ack;          /* [0x64]<WO> Interrupt acknowledge */
-    rt_uint32_t res4[2];                /* [0x68] */
-    rt_uint32_t status;                 /* [0x70]<RW> Device status */
-    rt_uint32_t res5[3];                /* [0x74] */
-    rt_uint32_t queue_desc_low;         /* [0x80]<WO> Virtual queue’s Descriptor Area 64 bit long physical address */
-    rt_uint32_t queue_desc_high;        /* [0x84]<WO> */
-    rt_uint32_t res6[2];                /* [0x88] */
-    rt_uint32_t queue_driver_low;       /* [0x90]<WO> Virtual queue’s Driver Area 64 bit long physical address */
-    rt_uint32_t queue_driver_high;      /* [0x94]<WO> */
-    rt_uint32_t res7[2];                /* [0x98] */
-    rt_uint32_t queue_device_low;       /* [0xa0]<WO> Virtual queue’s Device Area 64 bit long physical address */
-    rt_uint32_t queue_device_high;      /* [0xa4]<WO> */
-    rt_uint32_t res8[21];               /* [0xa8] */
-    rt_uint32_t config_generation;      /* [0xfc]<RO> Configuration atomicity value */
-    rt_uint32_t config[];               /* [0x100+]<RO> Configuration space */
-} __attribute__((packed));
-
-#endif /* __VIRTIO_MMIO_H__ */

+ 0 - 303
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.c

@@ -1,303 +0,0 @@
-/*
- * 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 <rthw.h>
-#include <rtthread.h>
-#include <cpuport.h>
-
-#ifdef BSP_USING_VIRTIO_NET
-
-#include <virtio_net.h>
-
-static rt_err_t virtio_net_tx(rt_device_t dev, struct pbuf *p)
-{
-    rt_uint16_t id;
-    struct virtio_net_device *virtio_net_dev = (struct virtio_net_device *)dev;
-    struct virtio_device *virtio_dev = &virtio_net_dev->virtio_dev;
-    struct virtq *queue_tx = &virtio_dev->queues[VIRTIO_NET_QUEUE_TX];
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    id = (queue_tx->avail->idx * 2) % queue_tx->num;
-
-    virtio_net_dev->info[id].hdr.flags = 0;
-    virtio_net_dev->info[id].hdr.gso_type = 0;
-    virtio_net_dev->info[id].hdr.hdr_len = 0;
-    virtio_net_dev->info[id].hdr.gso_size = 0;
-    virtio_net_dev->info[id].hdr.csum_start = 0;
-    virtio_net_dev->info[id].hdr.csum_offset = 0;
-    virtio_net_dev->info[id].hdr.num_buffers = 0;
-
-    pbuf_copy_partial(p, virtio_net_dev->info[id].rx_buffer, p->tot_len, 0);
-
-    virtio_free_desc(virtio_dev, VIRTIO_NET_QUEUE_TX, id);
-    virtio_free_desc(virtio_dev, VIRTIO_NET_QUEUE_TX, id + 1);
-
-    virtio_fill_desc(virtio_dev, VIRTIO_NET_QUEUE_TX, id,
-            VIRTIO_VA2PA(&virtio_net_dev->info[id].hdr), VIRTIO_NET_HDR_SIZE, VIRTQ_DESC_F_NEXT, id + 1);
-
-    virtio_fill_desc(virtio_dev, VIRTIO_NET_QUEUE_TX, id + 1,
-            VIRTIO_VA2PA(virtio_net_dev->info[id].rx_buffer), p->tot_len, 0, 0);
-
-    virtio_submit_chain(virtio_dev, VIRTIO_NET_QUEUE_TX, id);
-
-    virtio_queue_notify(virtio_dev, VIRTIO_NET_QUEUE_TX);
-
-    virtio_alloc_desc(virtio_dev, VIRTIO_NET_QUEUE_TX);
-    virtio_alloc_desc(virtio_dev, VIRTIO_NET_QUEUE_TX);
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-
-    return RT_EOK;
-}
-
-static struct pbuf *virtio_net_rx(rt_device_t dev)
-{
-    rt_uint16_t id;
-    rt_uint32_t len;
-    struct pbuf *p = RT_NULL, *new, *ret = RT_NULL;
-    struct virtio_net_device *virtio_net_dev = (struct virtio_net_device *)dev;
-    struct virtio_device *virtio_dev = &virtio_net_dev->virtio_dev;
-    struct virtq *queue_rx = &virtio_dev->queues[VIRTIO_NET_QUEUE_RX];
-
-    while (queue_rx->used_idx != queue_rx->used->idx)
-    {
-#ifdef RT_USING_SMP
-        rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-        id = (queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].id + 1) % queue_rx->num;
-        len = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].len - VIRTIO_NET_HDR_SIZE;
-
-#ifdef RT_USING_SMP
-        rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-        if (len > VIRTIO_NET_PAYLOAD_MAX_SIZE)
-        {
-            rt_kprintf("%s: Receive buffer's size = %u is too big!\n", virtio_net_dev->parent.parent.parent.name, len);
-            len = VIRTIO_NET_PAYLOAD_MAX_SIZE;
-        }
-
-        new = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
-
-        if (p != RT_NULL)
-        {
-            p->next = new;
-            p = p->next;
-        }
-        else
-        {
-            p = new;
-            ret = p;
-        }
-
-        if (p != RT_NULL)
-        {
-#ifdef RT_USING_SMP
-            level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-            rt_memcpy(p->payload, (void *)VIRTIO_PA2VA(queue_rx->desc[id].addr), len);
-
-            queue_rx->used_idx++;
-
-            virtio_submit_chain(virtio_dev, VIRTIO_NET_QUEUE_RX, id - 1);
-
-            virtio_queue_notify(virtio_dev, VIRTIO_NET_QUEUE_RX);
-
-#ifdef RT_USING_SMP
-            rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-        }
-        else
-        {
-            break;
-        }
-    }
-
-    return ret;
-}
-
-static rt_err_t virtio_net_init(rt_device_t dev)
-{
-    int i;
-    rt_uint16_t idx[VIRTIO_NET_RTX_QUEUE_SIZE];
-    struct virtio_net_device *virtio_net_dev = (struct virtio_net_device *)dev;
-    struct virtio_device *virtio_dev = &virtio_net_dev->virtio_dev;
-    struct virtq *queue_rx, *queue_tx;
-
-    queue_rx = &virtio_dev->queues[VIRTIO_NET_QUEUE_RX];
-    queue_tx = &virtio_dev->queues[VIRTIO_NET_QUEUE_TX];
-
-    virtio_alloc_desc_chain(virtio_dev, VIRTIO_NET_QUEUE_RX, queue_rx->num, idx);
-    virtio_alloc_desc_chain(virtio_dev, VIRTIO_NET_QUEUE_TX, queue_tx->num, idx);
-
-    for (i = 0; i < queue_rx->num; ++i)
-    {
-        rt_uint16_t id = (i * 2) % queue_rx->num;
-        void *addr = virtio_net_dev->info[i].tx_buffer;
-
-        /* Descriptor for net_hdr */
-        virtio_fill_desc(virtio_dev, VIRTIO_NET_QUEUE_RX, id,
-                VIRTIO_VA2PA(addr), VIRTIO_NET_HDR_SIZE, VIRTQ_DESC_F_NEXT | VIRTQ_DESC_F_WRITE, id + 1);
-
-        /* Descriptor for data */
-        virtio_fill_desc(virtio_dev, VIRTIO_NET_QUEUE_RX, id + 1,
-                VIRTIO_VA2PA(addr) + VIRTIO_NET_HDR_SIZE, VIRTIO_NET_MSS, VIRTQ_DESC_F_WRITE, 0);
-
-        queue_rx->avail->ring[i] = id;
-    }
-    rt_hw_dsb();
-
-    queue_rx->avail->flags = 0;
-    queue_rx->avail->idx = queue_rx->num;
-
-    queue_rx->used_idx = queue_rx->used->idx;
-
-    queue_tx->avail->flags = VIRTQ_AVAIL_F_NO_INTERRUPT;
-    queue_tx->avail->idx = 0;
-
-    virtio_queue_notify(virtio_dev, VIRTIO_NET_QUEUE_RX);
-
-    return eth_device_linkchange(&virtio_net_dev->parent, RT_TRUE);
-}
-
-static rt_err_t virtio_net_control(rt_device_t dev, int cmd, void *args)
-{
-    rt_err_t status = RT_EOK;
-    struct virtio_net_device *virtio_net_dev = (struct virtio_net_device *)dev;
-
-    switch (cmd)
-    {
-    case NIOCTL_GADDR:
-        if (args == RT_NULL)
-        {
-            status = -RT_ERROR;
-            break;
-        }
-
-        rt_memcpy(args, virtio_net_dev->config->mac, sizeof(virtio_net_dev->config->mac));
-        break;
-    default:
-        status = -RT_EINVAL;
-        break;
-    }
-
-    return status;
-}
-
-const static struct rt_device_ops virtio_net_ops =
-{
-    virtio_net_init,
-    RT_NULL,
-    RT_NULL,
-    RT_NULL,
-    RT_NULL,
-    virtio_net_control
-};
-
-static void virtio_net_isr(int irqno, void *param)
-{
-    struct virtio_net_device *virtio_net_dev = (struct virtio_net_device *)param;
-    struct virtio_device *virtio_dev = &virtio_net_dev->virtio_dev;
-    struct virtq *queue_rx = &virtio_dev->queues[VIRTIO_NET_QUEUE_RX];
-
-#ifdef RT_USING_SMP
-    rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock);
-#endif
-
-    virtio_interrupt_ack(virtio_dev);
-    rt_hw_dsb();
-
-    if (queue_rx->used_idx != queue_rx->used->idx)
-    {
-        rt_hw_dsb();
-
-        eth_device_ready(&virtio_net_dev->parent);
-    }
-
-#ifdef RT_USING_SMP
-    rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level);
-#endif
-}
-
-rt_err_t rt_virtio_net_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_net_device *virtio_net_dev;
-
-    virtio_net_dev = rt_malloc(sizeof(struct virtio_net_device));
-
-    if (virtio_net_dev == RT_NULL)
-    {
-        goto _alloc_fail;
-    }
-
-    virtio_dev = &virtio_net_dev->virtio_dev;
-    virtio_dev->irq = irq;
-    virtio_dev->mmio_base = mmio_base;
-
-    virtio_net_dev->config = (struct virtio_net_config *)virtio_dev->mmio_config->config;
-
-#ifdef RT_USING_SMP
-    rt_spin_lock_init(&virtio_dev->spinlock);
-#endif
-
-    virtio_reset_device(virtio_dev);
-    virtio_status_acknowledge_driver(virtio_dev);
-
-    virtio_dev->mmio_config->driver_features = virtio_dev->mmio_config->device_features & ~(
-            (1 << VIRTIO_NET_F_CTRL_VQ) |
-            (1 << VIRTIO_F_RING_EVENT_IDX));
-
-    virtio_status_driver_ok(virtio_dev);
-
-    if (virtio_queues_alloc(virtio_dev, 2) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    if (virtio_queue_init(virtio_dev, VIRTIO_NET_QUEUE_RX, VIRTIO_NET_RTX_QUEUE_SIZE) != RT_EOK)
-    {
-        goto _alloc_fail;
-    }
-
-    if (virtio_queue_init(virtio_dev, VIRTIO_NET_QUEUE_TX, VIRTIO_NET_RTX_QUEUE_SIZE) != RT_EOK)
-    {
-        virtio_queue_destroy(virtio_dev, VIRTIO_NET_QUEUE_RX);
-        goto _alloc_fail;
-    }
-
-    virtio_net_dev->parent.parent.type = RT_Device_Class_NetIf;
-    virtio_net_dev->parent.parent.ops  = &virtio_net_ops;
-    virtio_net_dev->parent.eth_tx = virtio_net_tx;
-    virtio_net_dev->parent.eth_rx = virtio_net_rx;
-
-    rt_snprintf(dev_name, RT_NAME_MAX, "virtio-net%d", dev_no++);
-
-    rt_hw_interrupt_install(irq, virtio_net_isr, virtio_net_dev, dev_name);
-    rt_hw_interrupt_umask(irq);
-
-    return eth_device_init(&virtio_net_dev->parent, dev_name);
-
-_alloc_fail:
-
-    if (virtio_net_dev != RT_NULL)
-    {
-        virtio_queues_free(virtio_dev);
-        rt_free(virtio_net_dev);
-    }
-    return -RT_ENOMEM;
-}
-#endif /* BSP_USING_VIRTIO_NET */

+ 0 - 115
bsp/qemu-virt64-aarch64/driver/virtio/virtio_net.h

@@ -1,115 +0,0 @@
-/*
- * 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_NET_H__
-#define __VIRTIO_NET_H__
-
-#include <rtdef.h>
-#include <netif/ethernetif.h>
-
-#include <virtio.h>
-
-#define VIRTIO_NET_QUEUE_RX         0
-#define VIRTIO_NET_QUEUE_TX         1
-#define VIRTIO_NET_RTX_QUEUE_SIZE   16
-#define VIRTIO_NET_RTX_BUF_SIZE     2048
-
-#define VIRTIO_NET_F_CSUM                   0   /* Host handles pkts w/ partial csum */
-#define VIRTIO_NET_F_GUEST_CSUM             1   /* Guest handles pkts w/ partial csum */
-#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS    2   /* Dynamic offload configuration */
-#define VIRTIO_NET_F_MTU                    3   /* Initial MTU advice */
-#define VIRTIO_NET_F_MAC                    5   /* Host has given MAC address */
-#define VIRTIO_NET_F_GUEST_TSO4             7   /* Guest can handle TSOv4 in */
-#define VIRTIO_NET_F_GUEST_TSO6             8   /* Guest can handle TSOv6 in */
-#define VIRTIO_NET_F_GUEST_ECN              9   /* Guest can handle TSO[6] w/ ECN in */
-#define VIRTIO_NET_F_GUEST_UFO              10  /* Guest can handle UFO in */
-#define VIRTIO_NET_F_HOST_TSO4              11  /* Host can handle TSOv4 in */
-#define VIRTIO_NET_F_HOST_TSO6              12  /* Host can handle TSOv6 in */
-#define VIRTIO_NET_F_HOST_ECN               13  /* Host can handle TSO[6] w/ ECN in */
-#define VIRTIO_NET_F_HOST_UFO               14  /* Host can handle UFO in */
-#define VIRTIO_NET_F_MRG_RXBUF              15  /* Host can merge receive buffers. */
-#define VIRTIO_NET_F_STATUS                 16  /* virtio_net_config.status available */
-#define VIRTIO_NET_F_CTRL_VQ                17  /* Control channel available */
-#define VIRTIO_NET_F_CTRL_RX                18  /* Control channel RX mode support */
-#define VIRTIO_NET_F_CTRL_VLAN              19  /* Control channel VLAN filtering */
-#define VIRTIO_NET_F_CTRL_RX_EXTRA          20  /* Extra RX mode control support */
-#define VIRTIO_NET_F_GUEST_ANNOUNCE         21  /* Guest can announce device on the network */
-#define VIRTIO_NET_F_MQ                     22  /* Device supports Receive Flow Steering */
-#define VIRTIO_NET_F_CTRL_MAC_ADDR          23  /* Set MAC address */
-
-#define VIRTIO_NET_F_HASH_REPORT            57  /* Supports hash report */
-#define VIRTIO_NET_F_RSS                    60  /* Supports RSS RX steering */
-#define VIRTIO_NET_F_RSC_EXT                61  /* Extended coalescing info */
-#define VIRTIO_NET_F_STANDBY                62  /* Act as standby for another device with the same MAC */
-#define VIRTIO_NET_F_SPEED_DUPLEX           63  /* Device set linkspeed and duplex */
-
-#define VIRTIO_NET_S_LINK_UP        (1 << 0)
-#define VIRTIO_NET_S_ANNOUNCE       (1 << 1)
-
-#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1
-#define VIRTIO_NET_HDR_F_DATA_VALID 2
-#define VIRTIO_NET_HDR_F_RSC_INFO   4
-
-#define VIRTIO_NET_HDR_GSO_NONE     0
-#define VIRTIO_NET_HDR_GSO_TCPV4    1
-#define VIRTIO_NET_HDR_GSO_UDP      3
-#define VIRTIO_NET_HDR_GSO_TCPV6    4
-#define VIRTIO_NET_HDR_GSO_ECN      0x80
-
-struct virtio_net_hdr
-{
-    rt_uint8_t flags;
-    rt_uint8_t gso_type;
-    rt_uint16_t hdr_len;
-    rt_uint16_t gso_size;
-    rt_uint16_t csum_start;
-    rt_uint16_t csum_offset;
-    rt_uint16_t num_buffers;
-} __attribute__ ((packed));
-
-#define VIRTIO_NET_MSS              1514
-#define VIRTIO_NET_HDR_SIZE         (sizeof(struct virtio_net_hdr))
-#define VIRTIO_NET_PAYLOAD_MAX_SIZE (VIRTIO_NET_HDR_SIZE + VIRTIO_NET_MSS)
-
-struct virtio_net_config
-{
-    rt_uint8_t mac[6];
-    rt_uint16_t status;
-    rt_uint16_t max_virtqueue_pairs;
-    rt_uint16_t mtu;
-    rt_uint32_t speed;
-    rt_uint8_t duplex;
-    rt_uint8_t rss_max_key_size;
-    rt_uint16_t rss_max_indirection_table_length;
-    rt_uint32_t supported_hash_types;
-} __attribute__((packed));
-
-struct virtio_net_device
-{
-    struct eth_device parent;
-
-    struct virtio_device virtio_dev;
-
-    struct virtio_net_config *config;
-
-    struct
-    {
-        /* Transmit hdr */
-        struct virtio_net_hdr hdr;
-        /* Transmit buffer */
-        rt_uint8_t tx_buffer[VIRTIO_NET_PAYLOAD_MAX_SIZE];
-        /* Receive buffer */
-        rt_uint8_t rx_buffer[VIRTIO_NET_PAYLOAD_MAX_SIZE];
-    } info[VIRTIO_NET_RTX_QUEUE_SIZE];
-};
-
-rt_err_t rt_virtio_net_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
-
-#endif /* __VIRTIO_NET_H__ */

+ 0 - 97
bsp/qemu-virt64-aarch64/driver/virtio/virtio_queue.h

@@ -1,97 +0,0 @@
-/*
- * 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 <rtdef.h>
-
-#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;
-    rt_size_t free_count;
-};
-
-#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 */
-
-#define VIRTQ_INVALID_DESC_ID   RT_UINT16_MAX
-
-#endif /* __VIRTIO_QUEUE_H__ */

+ 14 - 1
bsp/qemu-virt64-aarch64/driver/Kconfig → bsp/qemu-virt64-aarch64/drivers/Kconfig

@@ -1,4 +1,8 @@
+
 menu "AARCH64 qemu virt64 configs"
+    menuconfig BSP_SUPPORT_FPU
+        bool "Using Float"
+        default y
 
     menuconfig BSP_USING_UART
         bool "Using UART"
@@ -11,7 +15,6 @@ menu "AARCH64 qemu virt64 configs"
             default y
         endif
 
-
     menuconfig BSP_USING_RTC
             bool "Using RTC"
             select RT_USING_RTC
@@ -31,22 +34,32 @@ menu "AARCH64 qemu virt64 configs"
 
     config BSP_USING_VIRTIO_BLK
         bool "Using VirtIO BLK"
+        select RT_USING_VIRTIO
+        select RT_USING_VIRTIO_BLK
         default y
 
     config BSP_USING_VIRTIO_NET
         bool "Using VirtIO NET"
+        select RT_USING_VIRTIO
+        select RT_USING_VIRTIO_NET
         default y
 
     config BSP_USING_VIRTIO_CONSOLE
         bool "Using VirtIO Console"
+        select RT_USING_VIRTIO
+        select RT_USING_VIRTIO_CONSOLE
         default y
 
     config BSP_USING_VIRTIO_GPU
         bool "Using VirtIO GPU"
+        select RT_USING_VIRTIO
+        select RT_USING_VIRTIO_GPU
         default y
 
     config BSP_USING_VIRTIO_INPUT
         bool "Using VirtIO Input"
+        select RT_USING_VIRTIO
+        select RT_USING_VIRTIO_INPUT
         default y
 
     config BSP_USING_GIC

+ 1 - 1
bsp/qemu-virt64-aarch64/driver/virtio/SConscript → bsp/qemu-virt64-aarch64/drivers/SConscript

@@ -3,7 +3,7 @@
 from building import *
 
 cwd     = GetCurrentDir()
-src  	= Glob('*.c')
+src     = Glob('*.c')
 CPPPATH = [cwd]
 
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)

+ 120 - 0
bsp/qemu-virt64-aarch64/drivers/board.c

@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-11-20     Bernard    the first version
+ * 2018-11-22     Jesven     add rt_hw_spin_lock
+ *                           add rt_hw_spin_unlock
+ *                           add smp ipi init
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <mmu.h>
+#ifdef RT_USING_SMART
+#include <page.h>
+#include <lwp_arch.h>
+#endif
+#include "board.h"
+
+#ifdef RT_USING_FDT
+#include "interrupt.h"
+#include "dtb_node.h"
+#include <psci_api.h>
+#include <cpu.h>
+#endif
+
+#ifdef RT_USING_SMART
+struct mem_desc platform_mem_desc[] = {
+    {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM}
+};
+#else
+struct mem_desc platform_mem_desc[] =
+{
+    {0x40000000, 0x80000000 - 1, 0x40000000, NORMAL_MEM},
+    // {PL031_RTC_BASE, PL031_RTC_BASE + 0x1000 - 1, PL031_RTC_BASE, DEVICE_MEM},
+    // {PL061_GPIO_BASE, PL061_GPIO_BASE + 0x1000 - 1, PL061_GPIO_BASE, DEVICE_MEM},
+    {PL011_UART0_BASE, PL011_UART0_BASE + ARCH_SECTION_SIZE - 1, PL011_UART0_BASE, DEVICE_MEM},
+    {VIRTIO_MMIO_BASE, RT_ALIGN(VIRTIO_MMIO_BASE + VIRTIO_MAX_NR * VIRTIO_MMIO_SIZE, ARCH_SECTION_SIZE) - 1, VIRTIO_MMIO_BASE, DEVICE_MEM},
+#ifdef BSP_USING_GICV2
+    {GIC_PL390_DISTRIBUTOR_PPTR, GIC_PL390_DISTRIBUTOR_PPTR + ARCH_SECTION_SIZE - 1, GIC_PL390_DISTRIBUTOR_PPTR, DEVICE_MEM},
+#endif
+#ifdef BSP_USING_GICV3
+    {GIC_PL500_DISTRIBUTOR_PPTR, GIC_PL500_DISTRIBUTOR_PPTR + 0x1000 - 1, GIC_PL500_DISTRIBUTOR_PPTR, DEVICE_MEM},
+    {GIC_PL500_REDISTRIBUTOR_PPTR, GIC_PL500_REDISTRIBUTOR_PPTR + 0xf60000 - 1, GIC_PL500_REDISTRIBUTOR_PPTR, DEVICE_MEM},
+#endif
+};
+#endif
+
+const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
+
+void idle_wfi(void)
+{
+    asm volatile ("wfi");
+}
+
+/**
+ * This function will initialize board
+ */
+
+rt_mmu_info mmu_info;
+
+extern size_t MMUTable[];
+
+#ifdef RT_USING_SMART
+rt_region_t init_page_region = {
+    PAGE_START,
+    PAGE_END,
+};
+#endif
+
+void rt_hw_board_init(void)
+{
+#ifdef RT_USING_SMART
+    rt_page_init(init_page_region);
+
+    rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
+
+    rt_hw_mmu_map_init(&mmu_info, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
+
+    arch_kuser_init(&mmu_info, (void*)0xffffffffffff0000);
+#else
+    rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size);
+    rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0);
+    rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000);
+#endif
+
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init();
+
+    /* initialize system heap */
+    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
+
+    /* support debug feature before components init */
+    rt_hw_uart_init();
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+
+#ifdef RT_USING_FDT
+    // TODO 0x44000000 should be replace by a variable
+    void * fdt_start = (void *)0x44000000 - PV_OFFSET;
+    device_tree_setup(fdt_start);
+
+#ifdef RT_USING_SMP
+    rt_hw_cpu_init();
+#else
+    psci_init();
+#endif /* RT_USING_SMP */
+#endif
+
+    rt_components_board_init();
+
+    rt_thread_idle_sethook(idle_wfi);
+
+#ifdef RT_USING_SMP
+    /* install IPI handle */
+    rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
+#endif
+}

+ 36 - 0
bsp/qemu-virt64-aarch64/drivers/board.h

@@ -0,0 +1,36 @@
+/*
+ * File      : board.h
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-06     Bernard    the first version
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <virt.h>
+
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+
+#define HEAP_BEGIN  (void *)&__bss_end
+
+#ifdef RT_USING_SMART
+#define HEAP_END    (rt_size_t)(KERNEL_VADDR_START + 64 * 1024 * 1024)
+#define PAGE_START  HEAP_END + 1 * 1024 * 1024
+#define PAGE_END    ((rt_size_t)KERNEL_VADDR_START + 128 * 1024 * 1024)
+#else
+#define HEAP_END    ((void *)HEAP_BEGIN + 64 * 1024 * 1024)
+#define KERNEL_VADDR_START 0x40000000
+#define PV_OFFSET 0
+#endif
+
+void rt_hw_board_init(void);
+
+int rt_hw_uart_init(void);
+
+#endif

+ 8 - 2
bsp/qemu-virt64-aarch64/driver/drv_gpio.c → bsp/qemu-virt64-aarch64/drivers/drv_gpio.c

@@ -39,14 +39,16 @@ static struct pl061
     void *args[PL061_GPIO_NR];
 } _pl061;
 
+static rt_ubase_t pl061_gpio_base = PL061_GPIO_BASE;
+
 rt_inline rt_uint8_t pl061_read8(rt_ubase_t offset)
 {
-    return HWREG8(PL061_GPIO_BASE + offset);
+    return HWREG8(pl061_gpio_base + offset);
 }
 
 rt_inline void pl061_write8(rt_ubase_t offset, rt_uint8_t value)
 {
-    HWREG8(PL061_GPIO_BASE + offset) = value;
+    HWREG8(pl061_gpio_base + offset) = value;
 }
 
 static void pl061_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
@@ -303,6 +305,10 @@ int rt_hw_gpio_init(void)
     rt_spin_lock_init(&_pl061.spinlock);
 #endif
 
+#ifdef RT_USING_LWP
+    pl061_gpio_base = (rt_size_t)rt_ioremap((void *)pl061_gpio_base, PL061_GPIO_SIZE);
+#endif
+
     rt_device_pin_register("gpio", &ops, RT_NULL);
     rt_hw_interrupt_install(PL061_GPIO_IRQNUM, rt_hw_gpio_isr, RT_NULL, "gpio");
     rt_hw_interrupt_umask(PL061_GPIO_IRQNUM);

+ 0 - 0
bsp/qemu-virt64-aarch64/driver/drv_gpio.h → bsp/qemu-virt64-aarch64/drivers/drv_gpio.h


+ 123 - 0
bsp/qemu-virt64-aarch64/drivers/drv_rtc.c

@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2021-11-4      GuEe-GUI       first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <sys/time.h>
+#include <board.h>
+
+#include "drv_rtc.h"
+
+#ifdef BSP_USING_RTC
+
+#define RTC_DR      0x00    /* data read register */
+#define RTC_MR      0x04    /* match register */
+#define RTC_LR      0x08    /* data load register */
+#define RTC_CR      0x0c    /* control register */
+#define RTC_IMSC    0x10    /* interrupt mask and set register */
+#define RTC_RIS     0x14    /* raw interrupt status register */
+#define RTC_MIS     0x18    /* masked interrupt status register */
+#define RTC_ICR     0x1c    /* interrupt clear register */
+
+#define RTC_CR_OPEN     1
+#define RTC_CR_CLOSE    0
+
+static struct hw_rtc_device rtc_device;
+static rt_ubase_t pl031_rtc_base = PL031_RTC_BASE;
+
+rt_inline rt_uint32_t pl031_read32(rt_ubase_t offset)
+{
+    return (*((volatile unsigned int *)(pl031_rtc_base + offset)));
+}
+
+rt_inline void pl031_write32(rt_ubase_t offset, rt_uint32_t value)
+{
+    (*((volatile unsigned int *)(pl031_rtc_base + offset))) = value;
+}
+
+static rt_err_t pl031_rtc_init(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t pl031_rtc_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    pl031_write32(RTC_CR, RTC_CR_OPEN);
+    return RT_EOK;
+}
+
+static rt_err_t pl031_rtc_close(rt_device_t dev)
+{
+    pl031_write32(RTC_CR, RTC_CR_CLOSE);
+    return RT_EOK;
+}
+
+static rt_err_t pl031_rtc_control(rt_device_t dev, int cmd, void *args)
+{
+
+    RT_ASSERT(dev != RT_NULL);
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_RTC_GET_TIME:
+        *(rt_uint32_t *)args = pl031_read32(RTC_DR);
+        break;
+    case RT_DEVICE_CTRL_RTC_SET_TIME:
+        pl031_write32(RTC_LR, *(time_t *)args);
+        break;
+    default:
+        return RT_EINVAL;
+    }
+    return RT_EOK;
+}
+
+static rt_size_t pl031_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
+    return size;
+}
+
+static rt_size_t pl031_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    pl031_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
+    return size;
+}
+
+const static struct rt_device_ops pl031_rtc_ops =
+{
+    .init = pl031_rtc_init,
+    .open = pl031_rtc_open,
+    .close = pl031_rtc_close,
+    .read = pl031_rtc_read,
+    .write = pl031_rtc_write,
+    .control = pl031_rtc_control
+};
+
+int rt_hw_rtc_init(void)
+{
+#ifdef RT_USING_LWP
+    pl031_rtc_base = (rt_size_t)rt_ioremap((void *)pl031_rtc_base, PL031_RTC_SIZE);
+#endif
+
+    rt_memset(&rtc_device, 0, sizeof(rtc_device));
+
+    rtc_device.device.type        = RT_Device_Class_RTC;
+    rtc_device.device.rx_indicate = RT_NULL;
+    rtc_device.device.tx_complete = RT_NULL;
+    rtc_device.device.ops         = &pl031_rtc_ops;
+    rtc_device.device.user_data   = RT_NULL;
+
+    /* register a rtc device */
+    rt_device_register(&rtc_device.device, "rtc", RT_DEVICE_FLAG_RDWR);
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_rtc_init);
+#endif /* BSP_USING_RTC */

+ 0 - 0
bsp/qemu-virt64-aarch64/driver/drv_rtc.h → bsp/qemu-virt64-aarch64/drivers/drv_rtc.h


+ 46 - 0
bsp/qemu-virt64-aarch64/drivers/drv_timer.c

@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-22     Jesven       first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <stdint.h>
+#include "cp15.h"
+#include "board.h"
+#include "gtimer.h"
+
+#define TIMER_IRQ   30
+
+static rt_uint64_t timerStep = 0;
+
+static void rt_hw_timer_isr(int vector, void *param)
+{
+    rt_hw_set_gtimer_val(timerStep);
+    rt_tick_increase();
+}
+
+void rt_hw_timer_enable(void)
+{
+    rt_hw_set_gtimer_val(timerStep);
+    rt_hw_interrupt_umask(TIMER_IRQ);
+    rt_hw_gtimer_enable();
+}
+
+int rt_hw_timer_init(void)
+{
+    rt_hw_interrupt_install(TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
+    __ISB();
+    timerStep = rt_hw_get_gtimer_frq();
+    __DSB();
+    timerStep /= RT_TICK_PER_SECOND;
+    rt_hw_timer_enable();
+
+    return 0;
+}
+INIT_BOARD_EXPORT(rt_hw_timer_init);

+ 16 - 0
bsp/qemu-virt64-aarch64/drivers/drv_timer.h

@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-22     Jesven       first version
+ */
+
+#ifndef DRV_TIMER_H__
+#define DRV_TIMER_H__
+
+void timer_init(int timer, unsigned int preload);
+
+#endif

+ 45 - 49
bsp/qemu-virt64-aarch64/driver/drv_uart.c → bsp/qemu-virt64-aarch64/drivers/drv_uart.c

@@ -1,38 +1,45 @@
 /*
+ * serial.c UART driver
  * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
- * 2018/5/5       Bernard      The first version
+ * 2013-03-30     Bernard      the first verion
  */
 
 #include <rthw.h>
-#include <rtthread.h>
 #include <rtdevice.h>
 
 #include "board.h"
+#include "mmu.h"
 
-#define PL011_UARTDR            0x000
-#define PL011_UARTFR            0x018
-#define PL011_UARTFR_TXFF_BIT   5
-
-unsigned int readl(volatile void *addr)
+struct hw_uart_device
 {
-    return *(volatile unsigned int *)addr;
-}
+    rt_size_t hw_base;
+    rt_size_t irqno;
+};
 
-void writel(unsigned int v, volatile void *addr)
-{
-    *(volatile unsigned int *)addr = v;
-}
+#define UART_DR(base)   __REG32(base + 0x00)
+#define UART_FR(base)   __REG32(base + 0x18)
+#define UART_CR(base)   __REG32(base + 0x30)
+#define UART_IMSC(base) __REG32(base + 0x38)
+#define UART_ICR(base)  __REG32(base + 0x44)
 
-struct hw_uart_device
+#define UARTFR_RXFE     0x10
+#define UARTFR_TXFF     0x20
+#define UARTIMSC_RXIM   0x10
+#define UARTIMSC_TXIM   0x20
+#define UARTICR_RXIC    0x10
+#define UARTICR_TXIC    0x20
+
+static void rt_hw_uart_isr(int irqno, void *param)
 {
-    rt_ubase_t hw_base;
-    rt_uint32_t irqno;
-};
+    struct rt_serial_device *serial = (struct rt_serial_device *)param;
+
+    rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+}
 
 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
 {
@@ -42,28 +49,22 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
 {
     struct hw_uart_device *uart;
-    uint32_t val;
 
     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 */
-            val = readl((volatile void *)(uart->hw_base + 0x38));
-            val &= ~0x10;
-            writel(val, (volatile void *)(uart->hw_base + 0x38));
-            rt_hw_interrupt_mask(uart->irqno);
-            break;
-
-        case RT_DEVICE_CTRL_SET_INT:
-            /* enable rx irq */
-            val = readl((volatile void *)(uart->hw_base + 0x38));
-            val |= 0x10;
-            writel(val, (volatile void *)(uart->hw_base + 0x38));
-            rt_hw_interrupt_umask(uart->irqno);
-            break;
+    case RT_DEVICE_CTRL_CLR_INT:
+        /* disable rx irq */
+        UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM;
+        break;
+
+    case RT_DEVICE_CTRL_SET_INT:
+        /* enable rx irq */
+        UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM;
+        rt_hw_interrupt_umask(uart->irqno);
+        break;
     }
 
     return RT_EOK;
@@ -76,26 +77,24 @@ static int uart_putc(struct rt_serial_device *serial, char c)
     RT_ASSERT(serial != RT_NULL);
     uart = (struct hw_uart_device *)serial->parent.user_data;
 
-    while (readl((volatile void *)(uart->hw_base + PL011_UARTFR)) & (1 << PL011_UARTFR_TXFF_BIT))
-    {
-    }
-
-    writel(c, (volatile void *)( uart->hw_base + PL011_UARTDR));
+    while (UART_FR(uart->hw_base) & UARTFR_TXFF);
+    UART_DR(uart->hw_base) = c;
 
     return 1;
 }
 
 static int uart_getc(struct rt_serial_device *serial)
 {
-    int ch = -1;
+    int ch;
     struct hw_uart_device *uart;
 
     RT_ASSERT(serial != RT_NULL);
     uart = (struct hw_uart_device *)serial->parent.user_data;
 
-    if (!(readl((volatile void *)(uart->hw_base + 0x18)) & (1 << 4)))
+    ch = -1;
+    if (!(UART_FR(uart->hw_base) & UARTFR_RXFE))
     {
-        ch = readl((volatile void *)(uart->hw_base));
+        ch = UART_DR(uart->hw_base) & 0xff;
     }
 
     return ch;
@@ -109,12 +108,6 @@ static const struct rt_uart_ops _uart_ops =
     uart_getc,
 };
 
-static void rt_hw_uart_isr(int irqno, void *param)
-{
-    struct rt_serial_device *serial = (struct rt_serial_device*)param;
-    rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
-}
-
 #ifdef RT_USING_UART0
 /* UART device driver structure */
 static struct hw_uart_device _uart0_device =
@@ -131,6 +124,7 @@ int rt_hw_uart_init(void)
     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
 
 #ifdef RT_USING_UART0
+    _uart0_device.hw_base = (rt_size_t)rt_ioremap((void*)_uart0_device.hw_base, PL011_UART0_SIZE);
     uart = &_uart0_device;
 
     _serial0.ops    = &_uart_ops;
@@ -138,9 +132,11 @@ int rt_hw_uart_init(void)
 
     /* register UART1 device */
     rt_hw_serial_register(&_serial0, "uart0",
-            RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
-            uart);
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
     rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0");
+    /* enable Rx and Tx of UART */
+    UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9);
 #endif
 
     return 0;

+ 4 - 4
bsp/qemu-virt64-aarch64/driver/drv_uart.h → bsp/qemu-virt64-aarch64/drivers/drv_uart.h

@@ -5,12 +5,12 @@
  *
  * Change Logs:
  * Date           Author       Notes
- * 2017-5-30      Bernard      the first version
+ * 2013-03-30     Bernard      the first verion
  */
 
-#ifndef DRV_UART_H__
-#define DRV_UART_H__
+#ifndef __DRV_UART_H__
+#define __DRV_UART_H__
 
 int rt_hw_uart_init(void);
 
-#endif /* DRV_UART_H__ */
+#endif /* __DRV_UART_H__ */

+ 9 - 0
bsp/qemu-virt64-aarch64/driver/drv_virtio.c → bsp/qemu-virt64-aarch64/drivers/drv_virtio.c

@@ -62,6 +62,15 @@ int rt_virtio_devices_init(void)
         return 0;
     }
 
+#ifdef RT_USING_LWP
+    mmio_base = (rt_ubase_t)rt_ioremap((void *)mmio_base, VIRTIO_MMIO_SIZE * VIRTIO_MAX_NR);
+
+    if (mmio_base == RT_NULL)
+    {
+        return -RT_ERROR;
+    }
+#endif
+
     for (i = 0; i < VIRTIO_MAX_NR; ++i, ++irq, mmio_base += VIRTIO_MMIO_SIZE)
     {
         mmio_config = (struct virtio_mmio_config *)mmio_base;

+ 0 - 0
bsp/qemu-virt64-aarch64/driver/drv_virtio.h → bsp/qemu-virt64-aarch64/drivers/drv_virtio.h


+ 36 - 0
bsp/qemu-virt64-aarch64/drivers/secondary_cpu.c

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rthw.h>
+#include <rtthread.h>
+#include <cpu.h>
+#include "gic.h"
+#include "interrupt.h"
+#include "mmu.h"
+
+#ifdef RT_USING_SMP
+
+extern unsigned long MMUTable[];
+
+void rt_hw_secondary_cpu_bsp_start(void)
+{
+    rt_hw_spin_lock(&_cpus_lock);
+
+    rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
+
+    // interrupt init
+    rt_hw_vector_init();
+
+    arm_gic_cpu_init(0, 0);
+
+    // local timer init
+
+    rt_system_scheduler_start();
+}
+
+#endif // SMP

+ 18 - 4
bsp/qemu-virt64-aarch64/driver/virt.h → bsp/qemu-virt64-aarch64/drivers/virt.h

@@ -13,6 +13,18 @@
 
 #include <rtdef.h>
 
+#ifdef RT_USING_SMART
+#include <mmu.h>
+#include <ioremap.h>
+
+extern rt_mmu_info mmu_info;
+#else
+#define rt_ioremap(x, ...) (x)
+#endif
+
+#define __REG32(x)          (*((volatile unsigned int *)(x)))
+#define __REG16(x)          (*((volatile unsigned short *)(x)))
+
 /* UART */
 #define PL011_UART0_BASE    0x09000000
 #define PL011_UART0_SIZE    0x00001000
@@ -47,6 +59,8 @@
 /* GICv2 */
 #define GIC_PL390_DISTRIBUTOR_PPTR      0x08000000
 #define GIC_PL390_CONTROLLER_PPTR       0x08010000
+#define GIC_PL390_HYPERVISOR_BASE       0x08030000
+#define GIC_PL390_VIRTUAL_CPU_BASE      0x08040000
 
 /* GICv3 */
 #define GIC_PL500_DISTRIBUTOR_PPTR      GIC_PL390_DISTRIBUTOR_PPTR
@@ -55,7 +69,7 @@
 #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)
+rt_inline rt_ubase_t platform_get_gic_dist_base(void)
 {
 #ifdef BSP_USING_GICV2
     return GIC_PL390_DISTRIBUTOR_PPTR;
@@ -64,12 +78,12 @@ rt_inline rt_uint32_t platform_get_gic_dist_base(void)
 #endif
 }
 
-rt_inline rt_uint32_t platform_get_gic_redist_base(void)
+rt_inline rt_ubase_t platform_get_gic_redist_base(void)
 {
     return GIC_PL500_REDISTRIBUTOR_PPTR;
 }
 
-rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
+rt_inline rt_ubase_t platform_get_gic_cpu_base(void)
 {
 #ifdef BSP_USING_GICV2
     return GIC_PL390_CONTROLLER_PPTR;
@@ -78,7 +92,7 @@ rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
 #endif
 }
 
-rt_inline rt_uint32_t platform_get_gic_its_base(void)
+rt_inline rt_ubase_t platform_get_gic_its_base(void)
 {
     return GIC_PL500_ITS_PPTR;
 }

+ 68 - 110
bsp/qemu-virt64-aarch64/link.lds

@@ -1,94 +1,65 @@
-/*
- * File      : link.lds
- * COPYRIGHT (C) 2017, RT-Thread Development Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * 2017-5-30     bernard       first version
- */
-
-/* _EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 0x20000; */
-
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
 SECTIONS
 {
-    . = 0x40008000;
-    . = ALIGN(4096);
+    /*. = 0x60080000; */
+    . = 0x40080000;
+    /* . = 0xffff000000080000; */
+
+    __text_start = .;
     .text :
     {
-        KEEP(*(.text.entrypoint))       /* The entry point */
-        *(.vectors)
-        *(.text)                        /* remaining code */
-        *(.text.*)                      /* remaining code */
+        KEEP(*(.text.entrypoint))
+        KEEP(*(.vectors))
+        *(.text)
+        *(.text.*)
 
-        *(.rodata)                      /* read-only data (constants) */
-        *(.rodata*)
-        *(.glue_7)
-        *(.glue_7t)
-        *(.gnu.linkonce.t*)
+        /* section information for utest */
+        . = ALIGN(8);
+        __rt_utest_tc_tab_start = .;
+        KEEP(*(UtestTcTab))
+        __rt_utest_tc_tab_end = .;
 
         /* section information for finsh shell */
-        . = ALIGN(16);
+        . = ALIGN(8);
         __fsymtab_start = .;
         KEEP(*(FSymTab))
         __fsymtab_end = .;
-        . = ALIGN(16);
+        . = ALIGN(8);
         __vsymtab_start = .;
         KEEP(*(VSymTab))
         __vsymtab_end = .;
-        . = ALIGN(16);
+        . = ALIGN(8);
 
-        /* section information for initial. */
-        . = ALIGN(16);
+        /* section information for modules */
+        . = ALIGN(8);
+        __rtmsymtab_start = .;
+        KEEP(*(RTMSymTab))
+        __rtmsymtab_end = .;
+
+        /* section information for initialization */
+        . = ALIGN(8);
         __rt_init_start = .;
         KEEP(*(SORT(.rti_fn*)))
         __rt_init_end = .;
-        . = ALIGN(16);
-
-        . = ALIGN(16);
-        _etext = .;
-    }
+    } =0
+    __text_end = .;
 
-    .eh_frame_hdr :
+    .ARM.exidx   :
     {
-         *(.eh_frame_hdr)
-         *(.eh_frame_entry)
+        __exidx_start = .;
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+        __exidx_end = .;
     }
-    .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
 
-    . = ALIGN(16);
-    .data :
-    {
-     *(.data)
-     *(.data.*)
-
-     *(.data1)
-     *(.data1.*)
+    __rodata_start = .;
+    .rodata   : { *(.rodata) *(.rodata.*) }
+    __rodata_end = .;
 
-     . = ALIGN(16);
-     _gp = ABSOLUTE(.);     /* Base of small data */
-
-     *(.sdata)
-     *(.sdata.*)
-    }
-
-    . = ALIGN(16);
+    . = ALIGN(8);
     .ctors :
     {
         PROVIDE(__ctors_start__ = .);
-        /* new GCC version uses .init_array */
         KEEP(*(SORT(.init_array.*)))
         KEEP(*(.init_array))
         PROVIDE(__ctors_end__ = .);
@@ -97,56 +68,43 @@ SECTIONS
     .dtors :
     {
         PROVIDE(__dtors_start__ = .);
-        KEEP(*(SORT(.dtors.*)))
-        KEEP(*(.dtors))
+        KEEP(*(SORT(.fini_array.*)))
+        KEEP(*(.fini_array))
         PROVIDE(__dtors_end__ = .);
     }
 
-    . = ALIGN(16);
-    .bss :
+    . = ALIGN(8);
+    __data_start = .;
+    .data :
     {
-        PROVIDE(__bss_start = .);
-        *(.bss)
-        *(.bss.*)
-        *(.dynbss)
-        *(COMMON)
-        PROVIDE(__bss_end = .);
+        *(.data)
+        *(.data.*)
     }
-    _end = .;
+    __data_end = .;
+
+    . = ALIGN(8);
+    __bss_start = .;
+    .bss       :
+    {
+    *(.bss)
+    *(.bss.*)
+    *(COMMON)
+    . = ALIGN(8);
+    }
+    . = ALIGN(8);
+    __bss_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 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) }
-}
+    .comment 0 : { *(.comment) }
+
+    __data_size = SIZEOF(.data);
+    __bss_size = SIZEOF(.bss);
 
-__bss_size = SIZEOF(.bss);
+    _end = .;
+}

+ 9 - 0
bsp/qemu-virt64-aarch64/qemu-debug.bat

@@ -0,0 +1,9 @@
+@echo off
+if exist sd.bin goto run
+qemu-img create -f raw sd.bin 64M
+
+:run
+qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -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 -s -S ^
+-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0

+ 7 - 0
bsp/qemu-virt64-aarch64/qemu-debug.sh

@@ -0,0 +1,7 @@
+if [ ! -f "sd.bin" ]; then
+dd if=/dev/zero of=sd.bin bs=1024 count=65536
+fi
+qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -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 -s -S \
+-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0

+ 1 - 1
bsp/qemu-virt64-aarch64/qemu-graphic.bat

@@ -3,7 +3,7 @@ if exist sd.bin goto run
 qemu-img create -f raw sd.bin 64M
 
 :run
-qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.elf -serial stdio ^
+qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -serial stdio ^
 -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 ^
 -device virtio-gpu-device,xres=800,yres=600,bus=virtio-mmio-bus.2 ^

+ 1 - 1
bsp/qemu-virt64-aarch64/qemu-graphic.sh

@@ -1,7 +1,7 @@
 if [ ! -f "sd.bin" ]; then
 dd if=/dev/zero of=sd.bin bs=1024 count=65536
 fi
-qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.elf -serial stdio \
+qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -serial stdio \
 -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 \
 -device virtio-gpu-device,xres=800,yres=600,bus=virtio-mmio-bus.2 \

+ 1 - 1
bsp/qemu-virt64-aarch64/qemu.sh

@@ -1,7 +1,7 @@
 if [ ! -f "sd.bin" ]; then
 dd if=/dev/zero of=sd.bin bs=1024 count=65536
 fi
-qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic \
+qemu-system-aarch64 -M virt,gic-version=2 -cpu cortex-a53 -smp 4 -kernel rtthread.bin -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 \
 -device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0

+ 43 - 88
bsp/qemu-virt64-aarch64/rtconfig.h

@@ -9,7 +9,7 @@
 #define RT_NAME_MAX 16
 #define RT_USING_SMP
 #define RT_CPUS_NR 4
-#define RT_ALIGN_SIZE 4
+#define RT_ALIGN_SIZE 8
 #define RT_THREAD_PRIORITY_32
 #define RT_THREAD_PRIORITY_MAX 32
 #define RT_TICK_PER_SECOND 100
@@ -18,14 +18,15 @@
 #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 SYSTEM_THREAD_STACK_SIZE 4096
+#define IDLE_THREAD_STACK_SIZE 8192
+#define SYSTEM_THREAD_STACK_SIZE 8192
 #define RT_USING_TIMER_SOFT
 #define RT_TIMER_THREAD_PRIO 4
-#define RT_TIMER_THREAD_STACK_SIZE 4096
+#define RT_TIMER_THREAD_STACK_SIZE 8192
 
 /* kservice optimization */
 
+#define RT_KSERVICE_USING_STDLIB
 #define RT_KPRINTF_USING_LONGLONG
 #define RT_DEBUG
 #define RT_DEBUG_COLOR
@@ -44,7 +45,8 @@
 #define RT_USING_SMALL_MEM
 #define RT_USING_MEMHEAP
 #define RT_MEMHEAP_FAST_MODE
-#define RT_USING_SMALL_MEM_AS_HEAP
+#define RT_USING_MEMHEAP_AS_HEAP
+#define RT_USING_MEMHEAP_AUTO_BINDING
 #define RT_USING_MEMTRACE
 #define RT_USING_HEAP
 
@@ -52,13 +54,16 @@
 
 #define RT_USING_DEVICE
 #define RT_USING_DEVICE_OPS
+#define RT_USING_INTERRUPT_INFO
 #define RT_USING_CONSOLE
-#define RT_CONSOLEBUF_SIZE 128
+#define RT_CONSOLEBUF_SIZE 256
 #define RT_CONSOLE_DEVICE_NAME "uart0"
 #define RT_VER_NUM 0x50000
 #define ARCH_CPU_64BIT
 #define RT_USING_CACHE
+#define ARCH_MM_MMU
 #define ARCH_ARM
+#define ARCH_ARM_MMU
 #define ARCH_ARMV8
 
 /* RT-Thread Components */
@@ -74,18 +79,18 @@
 #define FINSH_THREAD_PRIORITY 20
 #define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_USING_HISTORY
-#define FINSH_HISTORY_LINES 5
+#define FINSH_HISTORY_LINES 10
 #define FINSH_USING_SYMTAB
-#define FINSH_CMD_SIZE 80
+#define FINSH_CMD_SIZE 256
 #define MSH_USING_BUILT_IN_COMMANDS
 #define FINSH_USING_DESCRIPTION
 #define FINSH_ARG_MAX 10
 #define RT_USING_DFS
 #define DFS_USING_POSIX
 #define DFS_USING_WORKDIR
-#define DFS_FILESYSTEMS_MAX 2
-#define DFS_FILESYSTEM_TYPES_MAX 2
-#define DFS_FD_MAX 16
+#define DFS_FILESYSTEMS_MAX 4
+#define DFS_FILESYSTEM_TYPES_MAX 8
+#define DFS_FD_MAX 32
 #define RT_USING_DFS_ELMFAT
 
 /* elm-chan's FatFs, Generic FAT Filesystem Module */
@@ -102,20 +107,33 @@
 #define RT_DFS_ELM_REENTRANT
 #define RT_DFS_ELM_MUTEX_TIMEOUT 3000
 #define RT_USING_DFS_DEVFS
+#define RT_USING_DFS_ROMFS
 
 /* Device Drivers */
 
 #define RT_USING_DEVICE_IPC
 #define RT_UNAMED_PIPE_NUMBER 64
 #define RT_USING_SYSTEM_WORKQUEUE
-#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096
+#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192
 #define RT_SYSTEM_WORKQUEUE_PRIORITY 23
 #define RT_USING_SERIAL
 #define RT_USING_SERIAL_V1
-#define RT_SERIAL_RB_BUFSZ 64
+#define RT_SERIAL_USING_DMA
+#define RT_SERIAL_RB_BUFSZ 256
 #define RT_USING_PIN
+#define RT_USING_NULL
+#define RT_USING_ZERO
+#define RT_USING_RANDOM
 #define RT_USING_RTC
-#define RT_USING_ALARM
+#define RT_USING_DEV_BUS
+#define RT_USING_VIRTIO
+#define RT_USING_VIRTIO10
+#define RT_USING_VIRTIO_MMIO_ALIGN
+#define RT_USING_VIRTIO_BLK
+#define RT_USING_VIRTIO_CONSOLE
+#define RT_USING_VIRTIO_CONSOLE_PORT_MAX_NR 4
+#define RT_USING_VIRTIO_GPU
+#define RT_USING_VIRTIO_INPUT
 
 /* Using USB */
 
@@ -126,71 +144,25 @@
 
 /* POSIX (Portable Operating System Interface) layer */
 
+#define RT_USING_POSIX_FS
+#define RT_USING_POSIX_DEVIO
+#define RT_USING_POSIX_STDIO
+#define RT_USING_POSIX_POLL
+#define RT_USING_POSIX_SELECT
+#define RT_USING_POSIX_TERMIOS
+#define RT_USING_POSIX_DELAY
+#define RT_USING_POSIX_CLOCK
 
 /* Interprocess Communication (IPC) */
 
+#define RT_USING_POSIX_PIPE
+#define RT_USING_POSIX_PIPE_SIZE 512
 
 /* Socket is in the 'Network' category */
 
 
 /* Network */
 
-#define RT_USING_SAL
-#define SAL_INTERNET_CHECK
-
-/* Docking with protocol stacks */
-
-#define SAL_USING_LWIP
-#define SAL_USING_POSIX
-#define RT_USING_NETDEV
-#define NETDEV_USING_IFCONFIG
-#define NETDEV_USING_PING
-#define NETDEV_USING_NETSTAT
-#define NETDEV_USING_AUTO_DEFAULT
-#define NETDEV_IPV4 1
-#define NETDEV_IPV6 0
-#define RT_USING_LWIP
-#define RT_USING_LWIP203
-#define RT_USING_LWIP_VER_NUM 0x20003
-#define RT_LWIP_MEM_ALIGNMENT 4
-#define RT_LWIP_ICMP
-#define RT_LWIP_DNS
-#define RT_LWIP_DHCP
-#define IP_SOF_BROADCAST 1
-#define IP_SOF_BROADCAST_RECV 1
-
-/* Static IPv4 Address */
-
-#define RT_LWIP_IPADDR "192.168.1.30"
-#define RT_LWIP_GWADDR "192.168.1.1"
-#define RT_LWIP_MSKADDR "255.255.255.0"
-#define RT_LWIP_UDP
-#define RT_LWIP_TCP
-#define RT_LWIP_RAW
-#define RT_MEMP_NUM_NETCONN 8
-#define RT_LWIP_PBUF_NUM 16
-#define RT_LWIP_RAW_PCB_NUM 4
-#define RT_LWIP_UDP_PCB_NUM 4
-#define RT_LWIP_TCP_PCB_NUM 4
-#define RT_LWIP_TCP_SEG_NUM 40
-#define RT_LWIP_TCP_SND_BUF 8196
-#define RT_LWIP_TCP_WND 8196
-#define RT_LWIP_TCPTHREAD_PRIORITY 10
-#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
-#define RT_LWIP_TCPTHREAD_STACKSIZE 4096
-#define RT_LWIP_ETHTHREAD_PRIORITY 12
-#define RT_LWIP_ETHTHREAD_STACKSIZE 4096
-#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
-#define RT_LWIP_REASSEMBLY_FRAG
-#define LWIP_NETIF_STATUS_CALLBACK 1
-#define LWIP_NETIF_LINK_CALLBACK 1
-#define SO_REUSE 1
-#define LWIP_SO_RCVTIMEO 1
-#define LWIP_SO_SNDTIMEO 1
-#define LWIP_SO_RCVBUF 1
-#define LWIP_SO_LINGER 0
-#define LWIP_NETIF_LOOPBACK 0
-#define RT_LWIP_USING_PING
 
 /* Utilities */
 
@@ -255,11 +227,6 @@
 
 /* peripheral libraries and drivers */
 
-/* sensors drivers */
-
-
-/* touch drivers */
-
 
 /* Kendryte SDK */
 
@@ -267,9 +234,6 @@
 /* AI packages */
 
 
-/* Signal Processing and Control Algorithm Packages */
-
-
 /* miscellaneous packages */
 
 /* project laboratory */
@@ -313,25 +277,16 @@
 
 /* Uncategorized */
 
-/* Privated Packages of RealThread */
-
-
-/* Network Utilities */
-
-
-/* RT-Thread Smart */
-
 #define SOC_VIRT64_AARCH64
 
 /* AARCH64 qemu virt64 configs */
 
+#define BSP_SUPPORT_FPU
 #define BSP_USING_UART
 #define RT_USING_UART0
 #define BSP_USING_RTC
-#define BSP_USING_ALARM
 #define BSP_USING_PIN
 #define BSP_USING_VIRTIO_BLK
-#define BSP_USING_VIRTIO_NET
 #define BSP_USING_VIRTIO_CONSOLE
 #define BSP_USING_VIRTIO_GPU
 #define BSP_USING_VIRTIO_INPUT

+ 20 - 32
bsp/qemu-virt64-aarch64/rtconfig.py

@@ -3,31 +3,14 @@ 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')
-
-# cross_tool provides the cross compiler
-# EXEC_PATH is the compiler execute path, for example, CodeSourcery,
-
-if  CROSS_TOOL == 'gcc':
-    PLATFORM    = 'gcc'
-    EXEC_PATH   = r'C:/Program Files/gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf/bin'
-
-if os.getenv('RTT_EXEC_PATH'):
-    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
-
-BUILD = 'debug'
+CROSS_TOOL  = 'gcc'
+PLATFORM    = 'gcc'
+EXEC_PATH   = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
+BUILD       = 'debug'
 
 if PLATFORM == 'gcc':
     # toolchains
-    PREFIX = 'aarch64-none-elf-'
+    PREFIX  = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'
@@ -37,21 +20,26 @@ if PLATFORM == 'gcc':
     SIZE    = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY  = PREFIX + 'objcopy'
-
-    DEVICE = ' -g -march=armv8-a -mtune=cortex-a53'
-    CFLAGS = DEVICE + ' -Wall -fdiagnostics-color=always'
-    AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__'
-    LFLAGS  = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
+    STRIP   = PREFIX + 'strip'
+    CFPFLAGS = ' '
+    AFPFLAGS = ' '
+    DEVICE   = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
+
+    CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall'
+    CFLAGS  = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99'
+    AFLAGS  = ' -c' + AFPFLAGS + ' -x assembler-with-cpp'
+    LFLAGS  = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc -static'
     CPATH   = ''
     LPATH   = ''
 
     if BUILD == 'debug':
-        CFLAGS += ' -O0 -gdwarf-2'
-        AFLAGS += ' -gdwarf-2'
+        CFLAGS   += ' -O0 -gdwarf-2'
+        CXXFLAGS += ' -O0 -gdwarf-2'
+        AFLAGS   += ' -gdwarf-2'
     else:
-        CFLAGS += ' -O2'
-
-    CXXFLAGS = CFLAGS
+        CFLAGS   += ' -Os'
+        CXXFLAGS += ' -Os'
+    CXXFLAGS += ' -Woverloaded-virtual -fno-exceptions -fno-rtti'
 
 DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
 POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'

+ 15 - 176
bsp/raspberry-pi/raspi3-64/.config

@@ -90,7 +90,9 @@ CONFIG_RT_USING_CACHE=y
 # CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
 # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 # CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_MM_MMU=y
 CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_MMU=y
 CONFIG_ARCH_ARMV8=y
 
 #
@@ -360,7 +362,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_SMALL_MODBUS is not set
 # CONFIG_PKG_USING_NET_SERVER is not set
 # CONFIG_PKG_USING_ZFTP is not set
-# CONFIG_PKG_USING_WOL is not set
 
 #
 # security packages
@@ -451,6 +452,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # 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
@@ -484,6 +486,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_CBOX is not set
 # CONFIG_PKG_USING_SNOWFLAKE is not set
 # CONFIG_PKG_USING_HASH_MATCH is not set
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
 # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
 # CONFIG_PKG_USING_VOFA_PLUS is not set
 
@@ -560,83 +563,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # peripheral libraries and drivers
 #
-
-#
-# sensors drivers
-#
-# CONFIG_PKG_USING_FINGERPRINT is not set
-# CONFIG_PKG_USING_LSM6DSM is not set
-# CONFIG_PKG_USING_LSM6DSL is not set
-# CONFIG_PKG_USING_LPS22HB is not set
-# CONFIG_PKG_USING_HTS221 is not set
-# CONFIG_PKG_USING_LSM303AGR is not set
-# CONFIG_PKG_USING_BME280 is not set
-# CONFIG_PKG_USING_BME680 is not set
-# CONFIG_PKG_USING_BMA400 is not set
-# CONFIG_PKG_USING_BMI160_BMX160 is not set
-# CONFIG_PKG_USING_SPL0601 is not set
-# CONFIG_PKG_USING_MS5805 is not set
-# CONFIG_PKG_USING_DA270 is not set
-# CONFIG_PKG_USING_DF220 is not set
-# CONFIG_PKG_USING_HSHCAL001 is not set
-# CONFIG_PKG_USING_BH1750 is not set
-# CONFIG_PKG_USING_MPU6XXX is not set
-# CONFIG_PKG_USING_AHT10 is not set
-# CONFIG_PKG_USING_AP3216C is not set
-# CONFIG_PKG_USING_TSL4531 is not set
-# CONFIG_PKG_USING_DS18B20 is not set
-# CONFIG_PKG_USING_DHT11 is not set
-# CONFIG_PKG_USING_DHTXX is not set
-# CONFIG_PKG_USING_GY271 is not set
-# CONFIG_PKG_USING_GP2Y10 is not set
-# CONFIG_PKG_USING_SGP30 is not set
-# CONFIG_PKG_USING_HDC1000 is not set
-# CONFIG_PKG_USING_BMP180 is not set
-# CONFIG_PKG_USING_BMP280 is not set
-# CONFIG_PKG_USING_SHTC1 is not set
-# CONFIG_PKG_USING_BMI088 is not set
-# CONFIG_PKG_USING_HMC5883 is not set
-# CONFIG_PKG_USING_MAX6675 is not set
-# CONFIG_PKG_USING_TMP1075 is not set
-# CONFIG_PKG_USING_SR04 is not set
-# CONFIG_PKG_USING_CCS811 is not set
-# CONFIG_PKG_USING_PMSXX is not set
-# CONFIG_PKG_USING_RT3020 is not set
-# CONFIG_PKG_USING_MLX90632 is not set
-# CONFIG_PKG_USING_MLX90393 is not set
-# CONFIG_PKG_USING_MLX90392 is not set
-# CONFIG_PKG_USING_MLX90397 is not set
-# CONFIG_PKG_USING_MS5611 is not set
-# CONFIG_PKG_USING_MAX31865 is not set
-# CONFIG_PKG_USING_VL53L0X is not set
-# CONFIG_PKG_USING_INA260 is not set
-# CONFIG_PKG_USING_MAX30102 is not set
-# CONFIG_PKG_USING_INA226 is not set
-# CONFIG_PKG_USING_LIS2DH12 is not set
-# CONFIG_PKG_USING_HS300X is not set
-# CONFIG_PKG_USING_ZMOD4410 is not set
-# CONFIG_PKG_USING_ISL29035 is not set
-# CONFIG_PKG_USING_MMC3680KJ is not set
-# CONFIG_PKG_USING_QMP6989 is not set
-# CONFIG_PKG_USING_BALANCE is not set
+# 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_AD7746 is not set
 # CONFIG_PKG_USING_ADT74XX is not set
-# CONFIG_PKG_USING_MAX17048 is not set
-
-#
-# touch drivers
-#
-# CONFIG_PKG_USING_GT9147 is not set
-# CONFIG_PKG_USING_GT1151 is not set
-# CONFIG_PKG_USING_GT917S is not set
-# CONFIG_PKG_USING_GT911 is not set
-# CONFIG_PKG_USING_FT6206 is not set
-# CONFIG_PKG_USING_FT5426 is not set
-# CONFIG_PKG_USING_FT6236 is not set
-# CONFIG_PKG_USING_XPT2046_TOUCH is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
 # CONFIG_PKG_USING_AS7341 is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
 # CONFIG_PKG_USING_ESP_IDF is not set
@@ -663,9 +594,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # 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
@@ -715,7 +649,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_RFM300 is not set
 # CONFIG_PKG_USING_IO_INPUT_FILTER is not set
 # CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
-# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
 
 #
 # AI packages
@@ -730,12 +663,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_QUEST is not set
 # CONFIG_PKG_USING_NAXOS is not set
 
-#
-# Signal Processing and Control Algorithm Packages
-#
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
-# CONFIG_PKG_USING_UKAL is not set
-
 #
 # miscellaneous packages
 #
@@ -787,6 +714,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # 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
@@ -813,10 +741,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # Sensors
 #
-# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
-# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
 # CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
@@ -901,7 +831,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
@@ -913,44 +842,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
-# CONFIG_PKG_USING_SEEED_ITG3200 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
-# CONFIG_PKG_USING_SEEED_MP503 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
 
 #
 # Display
 #
 # CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-# CONFIG_PKG_USING_SEEED_TM1637 is not set
 
 #
 # Timing
@@ -978,7 +874,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
-# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
 
 #
 # Other
@@ -999,64 +894,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # Uncategorized
 #
-
-#
-# Privated Packages of RealThread
-#
-# CONFIG_PKG_USING_CODEC is not set
-# CONFIG_PKG_USING_PLAYER is not set
-# CONFIG_PKG_USING_MPLAYER is not set
-# CONFIG_PKG_USING_PERSIMMON_SRC is not set
-# CONFIG_PKG_USING_JS_PERSIMMON is not set
-# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
-
-#
-# Network Utilities
-#
-# CONFIG_PKG_USING_WICED is not set
-# CONFIG_PKG_USING_CLOUDSDK is not set
-# CONFIG_PKG_USING_POWER_MANAGER is not set
-# CONFIG_PKG_USING_RT_OTA is not set
-# CONFIG_PKG_USING_RTINSIGHT is not set
-# CONFIG_PKG_USING_SMARTCONFIG is not set
-# CONFIG_PKG_USING_RTX is not set
-# CONFIG_RT_USING_TESTCASE is not set
-# CONFIG_PKG_USING_NGHTTP2 is not set
-# CONFIG_PKG_USING_AVS is not set
-# CONFIG_PKG_USING_ALI_LINKKIT is not set
-# CONFIG_PKG_USING_STS is not set
-# CONFIG_PKG_USING_DLMS is not set
-# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
-# CONFIG_PKG_USING_ZBAR is not set
-# CONFIG_PKG_USING_MCF is not set
-# CONFIG_PKG_USING_URPC is not set
-# CONFIG_PKG_USING_DCM is not set
-# CONFIG_PKG_USING_EMQ is not set
-# CONFIG_PKG_USING_CFGM is not set
-# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
-# CONFIG_PKG_USING_SMODULE is not set
-# CONFIG_PKG_USING_SNFD is not set
-# CONFIG_PKG_USING_UDBD is not set
-# CONFIG_PKG_USING_BENCHMARK is not set
-# CONFIG_PKG_USING_UBJSON is not set
-# CONFIG_PKG_USING_DATATYPE is not set
-# CONFIG_PKG_USING_FASTFS is not set
-# CONFIG_PKG_USING_RIL is not set
-# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
-# CONFIG_PKG_USING_WATCH_APP_FWK is not set
-# CONFIG_PKG_USING_GUI_TEST is not set
-# CONFIG_PKG_USING_PMEM is not set
-# CONFIG_PKG_USING_LWRDP is not set
-# CONFIG_PKG_USING_MASAN is not set
-# CONFIG_PKG_USING_BSDIFF_LIB is not set
-# CONFIG_PKG_USING_PRC_DIFF is not set
-
-#
-# RT-Thread Smart
-#
-# CONFIG_PKG_USING_UKERNEL is not set
-# CONFIG_PKG_USING_TRACE_AGENT is not set
 CONFIG_BCM2836_SOC=y
+CONFIG_SOC_BCM283x=y
 
 #
 # Hardware Drivers Config

+ 5 - 0
bsp/raspberry-pi/raspi3-64/Kconfig

@@ -25,6 +25,11 @@ config BCM2836_SOC
     select RT_USING_USER_MAIN
     select ARCH_CPU_64BIT
     select RT_USING_CACHE
+    select SOC_BCM283x
+    default y
+
+config SOC_BCM283x
+    bool
     default y
 
 source "driver/Kconfig"

+ 4 - 2
bsp/raspberry-pi/raspi3-64/driver/board.c

@@ -51,14 +51,16 @@ void rt_hw_timer_isr(int vector, void *parameter)
     rt_tick_increase();
 }
 
+rt_uint8_t core_timer_flag;
+
 void rt_hw_timer_init(void)
 {
     rt_hw_interrupt_install(IRQ_ARM_TIMER, rt_hw_timer_isr, RT_NULL, "tick");
     rt_hw_interrupt_umask(IRQ_ARM_TIMER);
 #ifdef BSP_USING_CORETIMER
-    __ISB();
+    rt_hw_isb();
     timer_step = rt_hw_get_gtimer_frq();
-    __DSB();
+    rt_hw_dsb();
     timer_step /= RT_TICK_PER_SECOND;
 
     rt_hw_gtimer_enable();

+ 5 - 0
bsp/raspberry-pi/raspi3-64/driver/board.h

@@ -20,6 +20,11 @@ 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)
 
+#ifndef RT_USING_SMART
+#define PV_OFFSET 0
+#define KERNEL_VADDR_START 0
+#endif
+
 void rt_hw_board_init(void);
 
 #endif

+ 3 - 2
bsp/raspberry-pi/raspi3-64/driver/drv_fb.c

@@ -14,6 +14,7 @@
 #include "mbox.h"
 #include "drv_fb.h"
 #include "mmu.h"
+#include "cache.h"
 
 #define LCD_WIDTH     (800)
 #define LCD_HEIGHT    (480)
@@ -299,9 +300,9 @@ int hdmi_fb_init(void)
     _hdmi.pitch = 0;
     _hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
 
-    rt_hw_mmu_map((unsigned long)_hdmi.fb, 0x200000, DEVICE_MEM);
+    // rt_hw_mmu_map(&mmu_info, (unsigned long)_hdmi.fb, (void *)0x200000, DEVICE_MEM);
 
-    rt_hw_dcache_invalidate_range((unsigned long)_hdmi.fb,LCD_WIDTH * LCD_HEIGHT * 3);
+    rt_hw_cpu_dcache_invalidate((unsigned long)_hdmi.fb,LCD_WIDTH * LCD_HEIGHT * 3);
 
     //rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
     rt_hdmi_fb_device_init(&_hdmi, "lcd");

+ 3 - 16
bsp/raspberry-pi/raspi3-64/rtconfig.h

@@ -55,7 +55,9 @@
 #define RT_VER_NUM 0x50000
 #define ARCH_CPU_64BIT
 #define RT_USING_CACHE
+#define ARCH_MM_MMU
 #define ARCH_ARM
+#define ARCH_ARM_MMU
 #define ARCH_ARMV8
 
 /* RT-Thread Components */
@@ -204,11 +206,6 @@
 
 /* peripheral libraries and drivers */
 
-/* sensors drivers */
-
-
-/* touch drivers */
-
 
 /* Kendryte SDK */
 
@@ -216,9 +213,6 @@
 /* AI packages */
 
 
-/* Signal Processing and Control Algorithm Packages */
-
-
 /* miscellaneous packages */
 
 /* project laboratory */
@@ -262,15 +256,8 @@
 
 /* Uncategorized */
 
-/* Privated Packages of RealThread */
-
-
-/* Network Utilities */
-
-
-/* RT-Thread Smart */
-
 #define BCM2836_SOC
+#define SOC_BCM283x
 
 /* Hardware Drivers Config */
 

+ 2 - 2
bsp/raspberry-pi/raspi3-64/rtconfig.py

@@ -23,7 +23,7 @@ BUILD = 'debug'
 
 if PLATFORM == 'gcc':
     # toolchains
-    PREFIX = 'aarch64-none-elf-'
+    PREFIX  = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'
@@ -35,7 +35,7 @@ if PLATFORM == 'gcc':
     OBJCPY  = PREFIX + 'objcopy'
 
     DEVICE = ' -march=armv8-a -mtune=cortex-a53'
-    CFLAGS = DEVICE + ' -Wall'
+    CFLAGS = DEVICE + ' -Wall -Wno-cpp'
     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   = ''

+ 2 - 2
bsp/raspberry-pi/raspi4-32/rtconfig.py

@@ -24,7 +24,7 @@ if os.getenv('RTT_EXEC_PATH'):
 if PLATFORM == 'gcc':
     # toolchains
     # PREFIX = 'arm-none-eabi-'
-    PREFIX = 'arm-none-eabi-'
+    PREFIX  = os.getenv('RTT_CC_PREFIX') or 'arm-none-eabi-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'
@@ -36,7 +36,7 @@ if PLATFORM == 'gcc':
     OBJCPY  = PREFIX + 'objcopy'
 
     DEVICE = ' -march=armv8-a -mtune=cortex-a72'
-    CFLAGS = DEVICE + ' -Wall'
+    CFLAGS = DEVICE + ' -Wall -Wno-cpp'
     AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__'
     LFLAGS  = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
     CPATH   = ''

+ 5 - 0
bsp/raspberry-pi/raspi4-64/driver/board.h

@@ -20,6 +20,11 @@ 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)
 
+#ifndef RT_USING_SMART
+#define PV_OFFSET 0
+#define KERNEL_VADDR_START 0
+#endif
+
 void rt_hw_board_init(void);
 
 #endif

+ 2 - 2
bsp/raspberry-pi/raspi4-64/rtconfig.py

@@ -23,7 +23,7 @@ BUILD = 'debug'
 
 if PLATFORM == 'gcc':
     # toolchains
-    PREFIX = 'aarch64-none-elf-'
+    PREFIX  = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'
@@ -35,7 +35,7 @@ if PLATFORM == 'gcc':
     OBJCPY  = PREFIX + 'objcopy'
 
     DEVICE = ' -march=armv8-a -mtune=cortex-a72'
-    CFLAGS = DEVICE + ' -Wall'
+    CFLAGS = DEVICE + ' -Wall -Wno-cpp'
     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   = ''

+ 2 - 2
bsp/rockchip/rk3568/driver/board.c

@@ -51,7 +51,7 @@ void rt_hw_board_init(void)
 
     rt_thread_idle_sethook(idle_wfi);
 
-    arm_psci_init(PSCI_METHOD_SMC, RT_NULL, RT_NULL);
+    // TODO porting to FDT-driven PSCI: arm_psci_init(PSCI_METHOD_SMC, RT_NULL, RT_NULL);
 
 #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
     /* set console device */
@@ -77,7 +77,7 @@ void rt_hw_board_init(void)
 
 void reboot(void)
 {
-    arm_psci_system_reboot();
+    // TODO poring to FDT to use new PSCI: arm_psci_system_reboot();
 }
 MSH_CMD_EXPORT(reboot, reboot...);
 

+ 5 - 0
bsp/rockchip/rk3568/driver/board.h

@@ -19,6 +19,11 @@ 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)
 
+#ifndef RT_USING_SMART
+#define PV_OFFSET 0
+#define KERNEL_VADDR_START 0
+#endif
+
 void rt_hw_board_init(void);
 
 #endif /* __BOARD_H__ */

+ 2 - 0
bsp/rockchip/rk3568/driver/rk3568.h

@@ -11,6 +11,8 @@
 #ifndef __RK3568_H__
 #define __RK3568_H__
 
+#include <rtthread.h>
+
 /* UART */
 #define UART_MMIO_BASE  0xfe650000
 #define UART0_MMIO_BASE 0xfdd50000

+ 3 - 3
bsp/rockchip/rk3568/rtconfig.py

@@ -23,7 +23,7 @@ BUILD = 'debug'
 
 if PLATFORM == 'gcc':
     # toolchains
-    PREFIX = 'aarch64-none-elf-'
+    PREFIX  = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'
@@ -34,8 +34,8 @@ if PLATFORM == 'gcc':
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY  = PREFIX + 'objcopy'
 
-    DEVICE = ' -g -march=armv8-a -mtune=cortex-a55'
-    CFLAGS = DEVICE + ' -Wall'
+    DEVICE = ' -g -march=armv8-a -mtune=cortex-a53'
+    CFLAGS = DEVICE + ' -Wall -Wno-cpp'
     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   = ''

+ 486 - 486
bsp/wch/risc-v/Libraries/ch32_drivers/drv_hwtimer.c

@@ -1,486 +1,486 @@
-/*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2022-09-10     MXH          the first version
- */
-
-#include <rtthread.h>
-#include <rtdevice.h>
-
-#ifdef BSP_USING_HWTIMER
-#define DBG_TAG               "TIM"
-#define DBG_LVL               DBG_LOG
-#include <rtdbg.h>
-
-#include "drv_hwtimer.h"
-#include "board.h"
-
-#ifdef RT_USING_HWTIMER
-
-enum
-{
-#ifdef BSP_USING_TIM1
-    TIM1_INDEX,
-#endif
-#ifdef BSP_USING_TIM2
-    TIM2_INDEX,
-#endif
-#ifdef BSP_USING_TIM3
-    TIM3_INDEX,
-#endif
-#ifdef BSP_USING_TIM4
-    TIM4_INDEX,
-#endif
-#ifdef BSP_USING_TIM5
-    TIM5_INDEX,
-#endif
-#ifdef BSP_USING_TIM6
-    TIM6_INDEX,
-#endif
-#ifdef BSP_USING_TIM7
-    TIM7_INDEX,
-#endif
-#ifdef BSP_USING_TIM8
-    TIM8_INDEX,
-#endif
-#ifdef BSP_USING_TIM9
-    TIM9_INDEX,
-#endif
-#ifdef BSP_USING_TIM10
-    TIM10_INDEX,
-#endif
-};
-
-static struct ch32_hwtimer ch32_hwtimer_obj[] =
-{
-#ifdef BSP_USING_TIM1
-    TIM1_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM2
-    TIM2_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM3
-    TIM3_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM4
-    TIM4_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM5
-    TIM5_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM6
-    TIM6_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM7
-    TIM7_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM8
-    TIM8_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM9
-    TIM9_CONFIG,
-#endif
-
-#ifdef BSP_USING_TIM10
-    TIM10_CONFIG,
-#endif
-};
-
-/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
-void ch32_get_pclk_doubler(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler)
-{
-    RT_ASSERT(pclk1_doubler != RT_NULL);
-    RT_ASSERT(pclk2_doubler != RT_NULL);
-
-    *pclk1_doubler = 1;
-    *pclk2_doubler = 1;
-
-    if((RCC->CFGR0 & RCC_PPRE1) == RCC_PPRE1_DIV1)
-    {
-        *pclk1_doubler = 1;
-    }
-    else
-    {
-        *pclk1_doubler = 2;
-    }
-
-    if((RCC->CFGR0 & RCC_PPRE2) == RCC_PPRE2_DIV1)
-    {
-        *pclk2_doubler = 1;
-    }
-    else
-    {
-        *pclk2_doubler = 2;
-    }
-}
-
-static void ch32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
-{
-    RT_ASSERT(timer != RT_NULL);
-    TIM_HandleTypeDef *tim = RT_NULL;
-    RCC_ClocksTypeDef RCC_ClockStruct;
-    NVIC_InitTypeDef NVIC_InitStruct;
-    struct ch32_hwtimer *tim_device = RT_NULL;
-    rt_uint32_t prescaler_value = 0;
-    rt_uint32_t pclk1_doubler, pclk2_doubler;
-
-    RCC_GetClocksFreq(&RCC_ClockStruct);
-    ch32_get_pclk_doubler(&pclk1_doubler, &pclk2_doubler);
-
-    if(state)
-    {
-        tim = (TIM_HandleTypeDef *)timer->parent.user_data;
-        tim_device = (struct ch32_hwtimer *)timer;
-
-        if(tim->instance == TIM1 || tim->instance == TIM8 ||
-                tim->instance == TIM9 || tim->instance == TIM10)
-        {
-            RCC_APB2PeriphClockCmd(tim->rcc, ENABLE);
-            prescaler_value = (RCC_ClockStruct.PCLK2_Frequency * pclk2_doubler / 10000) - 1;
-        }
-        else
-        {
-            RCC_APB1PeriphClockCmd(tim->rcc, ENABLE);
-            prescaler_value = (RCC_ClockStruct.PCLK1_Frequency * pclk1_doubler / 10000) - 1;
-        }
-        tim->init.TIM_Prescaler = prescaler_value;
-        tim->init.TIM_ClockDivision = TIM_CKD_DIV1;
-        tim->init.TIM_Period = 10000 - 1;
-        tim->init.TIM_RepetitionCounter = 0;
-
-        if(timer->info->cntmode == HWTIMER_CNTMODE_UP)
-        {
-            tim->init.TIM_CounterMode = TIM_CounterMode_Up;
-        }
-        else
-        {
-            tim->init.TIM_CounterMode   = TIM_CounterMode_Down;
-        }
-
-        /* TIM6 and TIM7 only support counter up mode */
-        if(tim->instance == TIM6 || tim->instance == TIM7)
-        {
-            tim->init.TIM_CounterMode = TIM_CounterMode_Up;
-        }
-
-        TIM_TimeBaseInit(tim->instance, &tim->init);
-
-        NVIC_InitStruct.NVIC_IRQChannel = tim_device->irqn;
-        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
-        NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
-        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
-        NVIC_Init(&NVIC_InitStruct);
-
-        TIM_ClearITPendingBit(tim->instance, TIM_IT_Update);
-        TIM_ITConfig(tim->instance, TIM_IT_Update, ENABLE);
-    }
-}
-
-static rt_err_t ch32_hwtimer_start(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
-{
-    RT_ASSERT(timer != RT_NULL);
-    TIM_HandleTypeDef *tim = RT_NULL;
-    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
-
-    /* set tim cnt */
-    tim->instance->CNT = 0;
-    /* set tim arr */
-    tim->instance->ATRLR = cnt - 1;
-    tim->init.TIM_Period = cnt - 1;
-
-    if (mode == HWTIMER_MODE_ONESHOT)
-    {
-        /* set timer to single mode */
-        tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
-        tim->instance->CTLR1 |= TIM_OPMode_Single;
-    }
-    else
-    {
-        tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
-        tim->instance->CTLR1 |= TIM_OPMode_Repetitive;
-    }
-
-    /* start timer */
-    TIM_Cmd(tim->instance, ENABLE);
-
-    return RT_EOK;
-}
-
-static void ch32_hwtimer_stop(struct rt_hwtimer_device *timer)
-{
-    RT_ASSERT(timer != RT_NULL);
-    TIM_HandleTypeDef *tim = RT_NULL;
-
-    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
-
-    /* stop timer */
-    TIM_Cmd(tim->instance, DISABLE);
-
-    /* set tim cnt */
-    tim->instance->CNT = 0;
-}
-
-static rt_uint32_t ch32_hwtimer_count_get(struct rt_hwtimer_device *timer)
-{
-    RT_ASSERT(timer != RT_NULL);
-    TIM_HandleTypeDef *tim = RT_NULL;
-    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
-
-    return tim->instance->CNT;
-}
-
-static rt_err_t ch32_hwtimer_control(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args)
-{
-    RT_ASSERT(timer != RT_NULL);
-    RT_ASSERT(args != RT_NULL);
-
-    TIM_HandleTypeDef *tim = RT_NULL;
-    rt_err_t result = RT_EOK;
-    rt_uint32_t pclk1_doubler, pclk2_doubler;
-
-    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
-
-    switch (cmd)
-    {
-    case HWTIMER_CTRL_FREQ_SET:
-    {
-        rt_uint32_t freq;
-        rt_uint16_t val;
-        RCC_ClocksTypeDef RCC_ClockStruct;
-
-        /* set timer frequence */
-        freq = *((rt_uint32_t *)args);
-
-        ch32_get_pclk_doubler(&pclk1_doubler, &pclk2_doubler);
-        RCC_GetClocksFreq(&RCC_ClockStruct);
-
-        if(tim->instance == TIM1 || tim->instance == TIM8 ||
-                tim->instance == TIM9 || tim->instance == TIM10)
-        {
-            val = RCC_ClockStruct.PCLK2_Frequency * pclk2_doubler / freq;
-        }
-        else
-        {
-            val = RCC_ClockStruct.PCLK1_Frequency * pclk1_doubler / freq;
-        }
-
-        /* Update frequency value */
-        TIM_PrescalerConfig(tim->instance, val - 1, TIM_PSCReloadMode_Immediate);
-
-        result = RT_EOK;
-        break;
-    }
-
-    case HWTIMER_CTRL_MODE_SET:
-    {
-        if (*(rt_hwtimer_mode_t *)args == HWTIMER_MODE_ONESHOT)
-        {
-            /* set timer to single mode */
-            tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
-            tim->instance->CTLR1 |= TIM_OPMode_Single;
-        }
-        else
-        {
-            tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
-            tim->instance->CTLR1 |= TIM_OPMode_Repetitive;
-        }
-        break;
-    }
-
-    case HWTIMER_CTRL_INFO_GET:
-    {
-        *(rt_hwtimer_mode_t *)args = tim->instance->CNT;
-        break;
-    }
-
-    case HWTIMER_CTRL_STOP:
-    {
-        ch32_hwtimer_stop(timer);
-        break;
-    }
-
-    default:
-    {
-        result = -RT_EINVAL;
-        break;
-    }
-    }
-
-    return result;
-}
-
-static const struct rt_hwtimer_info ch32_hwtimer_info = TIM_DEV_INFO_CONFIG;
-static const struct rt_hwtimer_ops ch32_hwtimer_ops =
-{
-    ch32_hwtimer_init,
-    ch32_hwtimer_start,
-    ch32_hwtimer_stop,
-    ch32_hwtimer_count_get,
-    ch32_hwtimer_control
-};
-
-static void ch32_hwtimer_isr(struct rt_hwtimer_device *device)
-{
-    RT_ASSERT(device != RT_NULL);
-    struct ch32_hwtimer *hwtimer = RT_NULL;
-    hwtimer = rt_container_of(device, struct ch32_hwtimer, device);
-
-    if(TIM_GetITStatus(hwtimer->handle.instance, TIM_IT_Update) != RESET)
-    {
-        rt_device_hwtimer_isr(device);
-        TIM_ClearITPendingBit(hwtimer->handle.instance, TIM_IT_Update);
-    }
-}
-
-#ifdef BSP_USING_TIM1
-void TIM1_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM1_UP_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM1_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM1 */
-
-#ifdef BSP_USING_TIM2
-void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM2_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM2_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM2 */
-
-#ifdef BSP_USING_TIM3
-void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM3_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM3_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM3 */
-
-#ifdef BSP_USING_TIM4
-void TIM4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM4_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM4_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM4 */
-
-#ifdef BSP_USING_TIM5
-void TIM5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM5_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM5_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM5 */
-
-#ifdef BSP_USING_TIM6
-void TIM6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM6_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM6_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM6 */
-
-#ifdef BSP_USING_TIM7
-void TIM7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM7_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM7_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM7 */
-
-#ifdef BSP_USING_TIM8
-void TIM8_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM8_UP_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM8_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM8 */
-
-#ifdef BSP_USING_TIM9
-void TIM9_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM9_UP_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM9_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM9 */
-
-#ifdef BSP_USING_TIM10
-void TIM10_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-void TIM10_UP_IRQHandler(void)
-{
-    GET_INT_SP();
-    rt_interrupt_enter();
-    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM10_INDEX].device));
-    rt_interrupt_leave();
-    FREE_INT_SP();
-}
-#endif /* BSP_USING_TIM10 */
-
-static int rt_hw_timer_init(void)
-{
-    int i = 0;
-    int result = RT_EOK;
-
-    for (i = 0; i < sizeof(ch32_hwtimer_obj) / sizeof(ch32_hwtimer_obj[0]); i++)
-    {
-        ch32_hwtimer_obj[i].device.info = &ch32_hwtimer_info;
-        ch32_hwtimer_obj[i].device.ops  = &ch32_hwtimer_ops;
-        result = rt_device_hwtimer_register(&ch32_hwtimer_obj[i].device,
-                    ch32_hwtimer_obj[i].name, (void *)&ch32_hwtimer_obj[i].handle);
-        RT_ASSERT(result == RT_EOK);
-    }
-
-    return result;
-}
-INIT_BOARD_EXPORT(rt_hw_timer_init);
-
-#endif /* RT_USING_HWTIMER */
-#endif /* BSP_USING_HWTIMER */
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-09-10     MXH          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef BSP_USING_HWTIMER
+#define DBG_TAG               "TIM"
+#define DBG_LVL               DBG_LOG
+#include <rtdbg.h>
+
+#include "drv_hwtimer.h"
+#include "board.h"
+
+#ifdef RT_USING_HWTIMER
+
+enum
+{
+#ifdef BSP_USING_TIM1
+    TIM1_INDEX,
+#endif
+#ifdef BSP_USING_TIM2
+    TIM2_INDEX,
+#endif
+#ifdef BSP_USING_TIM3
+    TIM3_INDEX,
+#endif
+#ifdef BSP_USING_TIM4
+    TIM4_INDEX,
+#endif
+#ifdef BSP_USING_TIM5
+    TIM5_INDEX,
+#endif
+#ifdef BSP_USING_TIM6
+    TIM6_INDEX,
+#endif
+#ifdef BSP_USING_TIM7
+    TIM7_INDEX,
+#endif
+#ifdef BSP_USING_TIM8
+    TIM8_INDEX,
+#endif
+#ifdef BSP_USING_TIM9
+    TIM9_INDEX,
+#endif
+#ifdef BSP_USING_TIM10
+    TIM10_INDEX,
+#endif
+};
+
+static struct ch32_hwtimer ch32_hwtimer_obj[] =
+{
+#ifdef BSP_USING_TIM1
+    TIM1_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM2
+    TIM2_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM3
+    TIM3_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM4
+    TIM4_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM5
+    TIM5_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM6
+    TIM6_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM7
+    TIM7_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM8
+    TIM8_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM9
+    TIM9_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM10
+    TIM10_CONFIG,
+#endif
+};
+
+/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
+void ch32_get_pclk_doubler(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler)
+{
+    RT_ASSERT(pclk1_doubler != RT_NULL);
+    RT_ASSERT(pclk2_doubler != RT_NULL);
+
+    *pclk1_doubler = 1;
+    *pclk2_doubler = 1;
+
+    if((RCC->CFGR0 & RCC_PPRE1) == RCC_PPRE1_DIV1)
+    {
+        *pclk1_doubler = 1;
+    }
+    else
+    {
+        *pclk1_doubler = 2;
+    }
+
+    if((RCC->CFGR0 & RCC_PPRE2) == RCC_PPRE2_DIV1)
+    {
+        *pclk2_doubler = 1;
+    }
+    else
+    {
+        *pclk2_doubler = 2;
+    }
+}
+
+static void ch32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
+{
+    RT_ASSERT(timer != RT_NULL);
+    TIM_HandleTypeDef *tim = RT_NULL;
+    RCC_ClocksTypeDef RCC_ClockStruct;
+    NVIC_InitTypeDef NVIC_InitStruct;
+    struct ch32_hwtimer *tim_device = RT_NULL;
+    rt_uint32_t prescaler_value = 0;
+    rt_uint32_t pclk1_doubler, pclk2_doubler;
+
+    RCC_GetClocksFreq(&RCC_ClockStruct);
+    ch32_get_pclk_doubler(&pclk1_doubler, &pclk2_doubler);
+
+    if(state)
+    {
+        tim = (TIM_HandleTypeDef *)timer->parent.user_data;
+        tim_device = (struct ch32_hwtimer *)timer;
+
+        if(tim->instance == TIM1 || tim->instance == TIM8 ||
+                tim->instance == TIM9 || tim->instance == TIM10)
+        {
+            RCC_APB2PeriphClockCmd(tim->rcc, ENABLE);
+            prescaler_value = (RCC_ClockStruct.PCLK2_Frequency * pclk2_doubler / 10000) - 1;
+        }
+        else
+        {
+            RCC_APB1PeriphClockCmd(tim->rcc, ENABLE);
+            prescaler_value = (RCC_ClockStruct.PCLK1_Frequency * pclk1_doubler / 10000) - 1;
+        }
+        tim->init.TIM_Prescaler = prescaler_value;
+        tim->init.TIM_ClockDivision = TIM_CKD_DIV1;
+        tim->init.TIM_Period = 10000 - 1;
+        tim->init.TIM_RepetitionCounter = 0;
+
+        if(timer->info->cntmode == HWTIMER_CNTMODE_UP)
+        {
+            tim->init.TIM_CounterMode = TIM_CounterMode_Up;
+        }
+        else
+        {
+            tim->init.TIM_CounterMode   = TIM_CounterMode_Down;
+        }
+
+        /* TIM6 and TIM7 only support counter up mode */
+        if(tim->instance == TIM6 || tim->instance == TIM7)
+        {
+            tim->init.TIM_CounterMode = TIM_CounterMode_Up;
+        }
+
+        TIM_TimeBaseInit(tim->instance, &tim->init);
+
+        NVIC_InitStruct.NVIC_IRQChannel = tim_device->irqn;
+        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
+        NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
+        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
+        NVIC_Init(&NVIC_InitStruct);
+
+        TIM_ClearITPendingBit(tim->instance, TIM_IT_Update);
+        TIM_ITConfig(tim->instance, TIM_IT_Update, ENABLE);
+    }
+}
+
+static rt_err_t ch32_hwtimer_start(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
+{
+    RT_ASSERT(timer != RT_NULL);
+    TIM_HandleTypeDef *tim = RT_NULL;
+    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
+
+    /* set tim cnt */
+    tim->instance->CNT = 0;
+    /* set tim arr */
+    tim->instance->ATRLR = cnt - 1;
+    tim->init.TIM_Period = cnt - 1;
+
+    if (mode == HWTIMER_MODE_ONESHOT)
+    {
+        /* set timer to single mode */
+        tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
+        tim->instance->CTLR1 |= TIM_OPMode_Single;
+    }
+    else
+    {
+        tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
+        tim->instance->CTLR1 |= TIM_OPMode_Repetitive;
+    }
+
+    /* start timer */
+    TIM_Cmd(tim->instance, ENABLE);
+
+    return RT_EOK;
+}
+
+static void ch32_hwtimer_stop(struct rt_hwtimer_device *timer)
+{
+    RT_ASSERT(timer != RT_NULL);
+    TIM_HandleTypeDef *tim = RT_NULL;
+
+    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
+
+    /* stop timer */
+    TIM_Cmd(tim->instance, DISABLE);
+
+    /* set tim cnt */
+    tim->instance->CNT = 0;
+}
+
+static rt_uint32_t ch32_hwtimer_count_get(struct rt_hwtimer_device *timer)
+{
+    RT_ASSERT(timer != RT_NULL);
+    TIM_HandleTypeDef *tim = RT_NULL;
+    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
+
+    return tim->instance->CNT;
+}
+
+static rt_err_t ch32_hwtimer_control(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args)
+{
+    RT_ASSERT(timer != RT_NULL);
+    RT_ASSERT(args != RT_NULL);
+
+    TIM_HandleTypeDef *tim = RT_NULL;
+    rt_err_t result = RT_EOK;
+    rt_uint32_t pclk1_doubler, pclk2_doubler;
+
+    tim = (TIM_HandleTypeDef *)timer->parent.user_data;
+
+    switch (cmd)
+    {
+    case HWTIMER_CTRL_FREQ_SET:
+    {
+        rt_uint32_t freq;
+        rt_uint16_t val;
+        RCC_ClocksTypeDef RCC_ClockStruct;
+
+        /* set timer frequence */
+        freq = *((rt_uint32_t *)args);
+
+        ch32_get_pclk_doubler(&pclk1_doubler, &pclk2_doubler);
+        RCC_GetClocksFreq(&RCC_ClockStruct);
+
+        if(tim->instance == TIM1 || tim->instance == TIM8 ||
+                tim->instance == TIM9 || tim->instance == TIM10)
+        {
+            val = RCC_ClockStruct.PCLK2_Frequency * pclk2_doubler / freq;
+        }
+        else
+        {
+            val = RCC_ClockStruct.PCLK1_Frequency * pclk1_doubler / freq;
+        }
+
+        /* Update frequency value */
+        TIM_PrescalerConfig(tim->instance, val - 1, TIM_PSCReloadMode_Immediate);
+
+        result = RT_EOK;
+        break;
+    }
+
+    case HWTIMER_CTRL_MODE_SET:
+    {
+        if (*(rt_hwtimer_mode_t *)args == HWTIMER_MODE_ONESHOT)
+        {
+            /* set timer to single mode */
+            tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
+            tim->instance->CTLR1 |= TIM_OPMode_Single;
+        }
+        else
+        {
+            tim->instance->CTLR1 &= (uint16_t) ~((uint16_t)TIM_OPM);
+            tim->instance->CTLR1 |= TIM_OPMode_Repetitive;
+        }
+        break;
+    }
+
+    case HWTIMER_CTRL_INFO_GET:
+    {
+        *(rt_hwtimer_mode_t *)args = tim->instance->CNT;
+        break;
+    }
+
+    case HWTIMER_CTRL_STOP:
+    {
+        ch32_hwtimer_stop(timer);
+        break;
+    }
+
+    default:
+    {
+        result = -RT_EINVAL;
+        break;
+    }
+    }
+
+    return result;
+}
+
+static const struct rt_hwtimer_info ch32_hwtimer_info = TIM_DEV_INFO_CONFIG;
+static const struct rt_hwtimer_ops ch32_hwtimer_ops =
+{
+    ch32_hwtimer_init,
+    ch32_hwtimer_start,
+    ch32_hwtimer_stop,
+    ch32_hwtimer_count_get,
+    ch32_hwtimer_control
+};
+
+static void ch32_hwtimer_isr(struct rt_hwtimer_device *device)
+{
+    RT_ASSERT(device != RT_NULL);
+    struct ch32_hwtimer *hwtimer = RT_NULL;
+    hwtimer = rt_container_of(device, struct ch32_hwtimer, device);
+
+    if(TIM_GetITStatus(hwtimer->handle.instance, TIM_IT_Update) != RESET)
+    {
+        rt_device_hwtimer_isr(device);
+        TIM_ClearITPendingBit(hwtimer->handle.instance, TIM_IT_Update);
+    }
+}
+
+#ifdef BSP_USING_TIM1
+void TIM1_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM1_UP_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM1_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM1 */
+
+#ifdef BSP_USING_TIM2
+void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM2_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM2_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM2 */
+
+#ifdef BSP_USING_TIM3
+void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM3_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM3_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM3 */
+
+#ifdef BSP_USING_TIM4
+void TIM4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM4_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM4_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM4 */
+
+#ifdef BSP_USING_TIM5
+void TIM5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM5_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM5_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM5 */
+
+#ifdef BSP_USING_TIM6
+void TIM6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM6_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM6_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM6 */
+
+#ifdef BSP_USING_TIM7
+void TIM7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM7_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM7_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM7 */
+
+#ifdef BSP_USING_TIM8
+void TIM8_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM8_UP_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM8_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM8 */
+
+#ifdef BSP_USING_TIM9
+void TIM9_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM9_UP_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM9_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM9 */
+
+#ifdef BSP_USING_TIM10
+void TIM10_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+void TIM10_UP_IRQHandler(void)
+{
+    GET_INT_SP();
+    rt_interrupt_enter();
+    ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM10_INDEX].device));
+    rt_interrupt_leave();
+    FREE_INT_SP();
+}
+#endif /* BSP_USING_TIM10 */
+
+static int rt_hw_timer_init(void)
+{
+    int i = 0;
+    int result = RT_EOK;
+
+    for (i = 0; i < sizeof(ch32_hwtimer_obj) / sizeof(ch32_hwtimer_obj[0]); i++)
+    {
+        ch32_hwtimer_obj[i].device.info = &ch32_hwtimer_info;
+        ch32_hwtimer_obj[i].device.ops  = &ch32_hwtimer_ops;
+        result = rt_device_hwtimer_register(&ch32_hwtimer_obj[i].device,
+                    ch32_hwtimer_obj[i].name, (void *)&ch32_hwtimer_obj[i].handle);
+        RT_ASSERT(result == RT_EOK);
+    }
+
+    return result;
+}
+INIT_BOARD_EXPORT(rt_hw_timer_init);
+
+#endif /* RT_USING_HWTIMER */
+#endif /* BSP_USING_HWTIMER */

+ 148 - 148
bsp/wch/risc-v/Libraries/ch32_drivers/drv_hwtimer.h

@@ -1,148 +1,148 @@
-/*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2022-09-10     MXH          the first version
- */
-
-#ifndef __DRV_HWTIMER_H__
-#define __DRV_HWTIMER_H__
-
-#include <rtthread.h>
-
-#include "ch32v30x_tim.h"
-
-#ifdef BSP_USING_HWTIMER
-
-typedef struct
-{
-    TIM_TypeDef *instance;
-    TIM_TimeBaseInitTypeDef init;
-    rt_uint32_t rcc;
-
-}TIM_HandleTypeDef;
-
-struct ch32_hwtimer
-{
-    rt_hwtimer_t device;
-    TIM_HandleTypeDef handle;
-    IRQn_Type irqn;
-    char *name;
-};
-
-/* TIM CONFIG */
-#ifndef TIM_DEV_INFO_CONFIG
-#define TIM_DEV_INFO_CONFIG                     \
-    {                                           \
-        .maxfreq = 1000000,                     \
-        .minfreq = 3000,                        \
-        .maxcnt  = 0xFFFF,                      \
-        .cntmode = HWTIMER_CNTMODE_UP,          \
-    }
-#endif /* TIM_DEV_INFO_CONFIG */
-
-#ifdef BSP_USING_TIM1
-#define TIM1_CONFIG                         \
-{                                           \
-    .handle.instance = TIM1,                \
-    .handle.rcc = RCC_APB2Periph_TIM1,      \
-    .irqn = TIM1_UP_IRQn,                   \
-    .name = "timer1",                       \
-}
-#endif /* BSP_USING_TIM1 */
-
-#ifdef BSP_USING_TIM2
-#define TIM2_CONFIG                         \
-{                                           \
-    .handle.instance = TIM2,                \
-    .handle.rcc = RCC_APB1Periph_TIM2,      \
-    .irqn = TIM2_IRQn,                      \
-    .name = "timer2",                       \
-}
-#endif /* BSP_USING_TIM2 */
-
-#ifdef BSP_USING_TIM3
-#define TIM3_CONFIG                         \
-{                                           \
-    .handle.instance = TIM3,                \
-    .handle.rcc = RCC_APB1Periph_TIM3,      \
-    .irqn = TIM3_IRQn,                      \
-    .name = "timer3",                       \
-}
-#endif /* BSP_USING_TIM3 */
-
-#ifdef BSP_USING_TIM4
-#define TIM4_CONFIG                         \
-{                                           \
-    .handle.instance = TIM4,                \
-    .handle.rcc = RCC_APB1Periph_TIM4,      \
-    .irqn = TIM4_IRQn,                      \
-    .name = "timer4",                       \
-}
-#endif /* BSP_USING_TIM4 */
-
-#ifdef BSP_USING_TIM5
-#define TIM5_CONFIG                         \
-{                                           \
-    .handle.instance = TIM5,                \
-    .handle.rcc = RCC_APB1Periph_TIM5,      \
-    .irqn = TIM5_IRQn,                      \
-    .name = "timer5",                       \
-}
-#endif /* BSP_USING_TIM5 */
-
-#ifdef BSP_USING_TIM6
-#define TIM6_CONFIG                         \
-{                                           \
-    .handle.instance = TIM6,                \
-    .handle.rcc = RCC_APB1Periph_TIM6,      \
-    .irqn = TIM6_IRQn,                      \
-    .name = "timer6",                       \
-}
-#endif /* BSP_USING_TIM6 */
-
-#ifdef BSP_USING_TIM7
-#define TIM7_CONFIG                         \
-{                                           \
-    .handle.instance = TIM7,                \
-    .handle.rcc = RCC_APB1Periph_TIM7,      \
-    .irqn = TIM7_IRQn,                      \
-    .name = "timer7",                       \
-}
-#endif /* BSP_USING_TIM7 */
-
-#ifdef BSP_USING_TIM8
-#define TIM8_CONFIG                         \
-{                                           \
-    .handle.instance = TIM8,                \
-    .handle.rcc = RCC_APB2Periph_TIM8,      \
-    .irqn = TIM8_UP_IRQn,                   \
-    .name = "timer8",                       \
-}
-#endif /* BSP_USING_TIM8 */
-
-#ifdef BSP_USING_TIM9
-#define TIM9_CONFIG                         \
-{                                           \
-    .handle.instance = TIM9,                \
-    .handle.rcc = RCC_APB2Periph_TIM9,      \
-    .irqn = TIM9_UP_IRQn,                   \
-    .name = "timer9",                       \
-}
-#endif /* BSP_USING_TIM9 */
-
-#ifdef BSP_USING_TIM10
-#define TIM10_CONFIG                        \
-{                                           \
-    .handle.instance = TIM10,               \
-    .handle.rcc = RCC_APB2Periph_TIM10,     \
-    .irqn = TIM10_UP_IRQn,                  \
-    .name = "timer10",                      \
-}
-#endif /* BSP_USING_TIM10 */
-
-#endif /* BSP_USING_HWTIMER */
-#endif /* __DRV_HWTIMER_H__ */
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-09-10     MXH          the first version
+ */
+
+#ifndef __DRV_HWTIMER_H__
+#define __DRV_HWTIMER_H__
+
+#include <rtthread.h>
+
+#include "ch32v30x_tim.h"
+
+#ifdef BSP_USING_HWTIMER
+
+typedef struct
+{
+    TIM_TypeDef *instance;
+    TIM_TimeBaseInitTypeDef init;
+    rt_uint32_t rcc;
+
+}TIM_HandleTypeDef;
+
+struct ch32_hwtimer
+{
+    rt_hwtimer_t device;
+    TIM_HandleTypeDef handle;
+    IRQn_Type irqn;
+    char *name;
+};
+
+/* TIM CONFIG */
+#ifndef TIM_DEV_INFO_CONFIG
+#define TIM_DEV_INFO_CONFIG                     \
+    {                                           \
+        .maxfreq = 1000000,                     \
+        .minfreq = 3000,                        \
+        .maxcnt  = 0xFFFF,                      \
+        .cntmode = HWTIMER_CNTMODE_UP,          \
+    }
+#endif /* TIM_DEV_INFO_CONFIG */
+
+#ifdef BSP_USING_TIM1
+#define TIM1_CONFIG                         \
+{                                           \
+    .handle.instance = TIM1,                \
+    .handle.rcc = RCC_APB2Periph_TIM1,      \
+    .irqn = TIM1_UP_IRQn,                   \
+    .name = "timer1",                       \
+}
+#endif /* BSP_USING_TIM1 */
+
+#ifdef BSP_USING_TIM2
+#define TIM2_CONFIG                         \
+{                                           \
+    .handle.instance = TIM2,                \
+    .handle.rcc = RCC_APB1Periph_TIM2,      \
+    .irqn = TIM2_IRQn,                      \
+    .name = "timer2",                       \
+}
+#endif /* BSP_USING_TIM2 */
+
+#ifdef BSP_USING_TIM3
+#define TIM3_CONFIG                         \
+{                                           \
+    .handle.instance = TIM3,                \
+    .handle.rcc = RCC_APB1Periph_TIM3,      \
+    .irqn = TIM3_IRQn,                      \
+    .name = "timer3",                       \
+}
+#endif /* BSP_USING_TIM3 */
+
+#ifdef BSP_USING_TIM4
+#define TIM4_CONFIG                         \
+{                                           \
+    .handle.instance = TIM4,                \
+    .handle.rcc = RCC_APB1Periph_TIM4,      \
+    .irqn = TIM4_IRQn,                      \
+    .name = "timer4",                       \
+}
+#endif /* BSP_USING_TIM4 */
+
+#ifdef BSP_USING_TIM5
+#define TIM5_CONFIG                         \
+{                                           \
+    .handle.instance = TIM5,                \
+    .handle.rcc = RCC_APB1Periph_TIM5,      \
+    .irqn = TIM5_IRQn,                      \
+    .name = "timer5",                       \
+}
+#endif /* BSP_USING_TIM5 */
+
+#ifdef BSP_USING_TIM6
+#define TIM6_CONFIG                         \
+{                                           \
+    .handle.instance = TIM6,                \
+    .handle.rcc = RCC_APB1Periph_TIM6,      \
+    .irqn = TIM6_IRQn,                      \
+    .name = "timer6",                       \
+}
+#endif /* BSP_USING_TIM6 */
+
+#ifdef BSP_USING_TIM7
+#define TIM7_CONFIG                         \
+{                                           \
+    .handle.instance = TIM7,                \
+    .handle.rcc = RCC_APB1Periph_TIM7,      \
+    .irqn = TIM7_IRQn,                      \
+    .name = "timer7",                       \
+}
+#endif /* BSP_USING_TIM7 */
+
+#ifdef BSP_USING_TIM8
+#define TIM8_CONFIG                         \
+{                                           \
+    .handle.instance = TIM8,                \
+    .handle.rcc = RCC_APB2Periph_TIM8,      \
+    .irqn = TIM8_UP_IRQn,                   \
+    .name = "timer8",                       \
+}
+#endif /* BSP_USING_TIM8 */
+
+#ifdef BSP_USING_TIM9
+#define TIM9_CONFIG                         \
+{                                           \
+    .handle.instance = TIM9,                \
+    .handle.rcc = RCC_APB2Periph_TIM9,      \
+    .irqn = TIM9_UP_IRQn,                   \
+    .name = "timer9",                       \
+}
+#endif /* BSP_USING_TIM9 */
+
+#ifdef BSP_USING_TIM10
+#define TIM10_CONFIG                        \
+{                                           \
+    .handle.instance = TIM10,               \
+    .handle.rcc = RCC_APB2Periph_TIM10,     \
+    .irqn = TIM10_UP_IRQn,                  \
+    .name = "timer10",                      \
+}
+#endif /* BSP_USING_TIM10 */
+
+#endif /* BSP_USING_HWTIMER */
+#endif /* __DRV_HWTIMER_H__ */

+ 963 - 963
bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.c

@@ -1,963 +1,963 @@
-/*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author            Notes
- * 2021-09-23     charlown          first version
- * 2022-10-14     hg0720            the first version which add from wch
- * 2022-10-20     MXH               add the remaining timers
- */
-
-#include "drv_pwm.h"
-
-#ifdef BSP_USING_PWM
-
-#define LOG_TAG "drv.pwm"
-#include <drv_log.h>
-
-void ch32_tim_clock_init(TIM_TypeDef* timx)
-{
-#ifdef BSP_USING_TIM1_PWM
-    if (timx == TIM1)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
-    }
-#endif/* BSP_USING_TIM1_PWM */
-
-#ifdef BSP_USING_TIM2_PWM
-    if (timx == TIM2)
-    {
-        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-    }
-#endif/* BSP_USING_TIM2_PWM */
-
-#ifdef BSP_USING_TIM3_PWM
-    if (timx == TIM3)
-    {
-        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
-    }
-#endif/* BSP_USING_TIM3_PWM */
-
-#ifdef BSP_USING_TIM4_PWM
-    if (timx == TIM4)
-    {
-        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
-    }
-#endif/* BSP_USING_TIM4_PWM */
-
-#ifdef BSP_USING_TIM5_PWM
-    if (timx == TIM5)
-    {
-        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
-    }
-#endif/* BSP_USING_TIM5_PWM */
-
-    /* TIM6 and TIM7 don't support PWM Mode. */
-
-#ifdef BSP_USING_TIM8_PWM
-    if (timx == TIM8)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
-    }
-#endif/* BSP_USING_TIM8_PWM */
-
-#ifdef BSP_USING_TIM9_PWM
-    if (timx == TIM9)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
-    }
-#endif/* BSP_USING_TIM9_PWM */
-
-#ifdef BSP_USING_TIM10_PWM
-    if (timx == TIM10)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
-    }
-#endif/* BSP_USING_TIM10_PWM */
-}
-
-rt_uint32_t ch32_tim_clock_get(TIM_TypeDef* timx)
-{
-    RCC_ClocksTypeDef RCC_Clocks;
-    RCC_GetClocksFreq(&RCC_Clocks);
-
-    /*tim1~10 all in HCLK*/
-    return RCC_Clocks.HCLK_Frequency;
-}
-
-/*
- * NOTE:  some pwm pins of some timers are reused,
- *          please keep caution when using pwm
- */
-
-void ch32_pwm_io_init(TIM_TypeDef* timx, rt_uint8_t channel)
-{
-    GPIO_InitTypeDef GPIO_InitStructure;
-
-#ifdef BSP_USING_TIM1_PWM
-    if (timx == TIM1)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
-#ifdef BSP_USING_TIM1_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM1_PWM_CH1 */
-
-#ifdef BSP_USING_TIM1_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM1_PWM_CH2 */
-
-#ifdef BSP_USING_TIM1_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM1_PWM_CH3 */
-
-#ifdef BSP_USING_TIM1_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM1_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM1_PWM */
-
-#ifdef BSP_USING_TIM2_PWM
-    if (timx == TIM2)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
-#ifdef BSP_USING_TIM2_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM2_PWM_CH1 */
-
-#ifdef BSP_USING_TIM2_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM2_PWM_CH2 */
-
-#ifdef BSP_USING_TIM2_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM2_PWM_CH3 */
-
-#ifdef BSP_USING_TIM2_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM2_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM2_PWM */
-
-#ifdef BSP_USING_TIM3_PWM
-    if (timx == TIM3)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
-#ifdef BSP_USING_TIM3_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM3_PWM_CH1 */
-
-#ifdef BSP_USING_TIM3_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM3_PWM_CH2 */
-
-#ifdef BSP_USING_TIM3_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM3_PWM_CH3 */
-
-#ifdef BSP_USING_TIM3_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM3_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM3_PWM */
-
-#ifdef BSP_USING_TIM4_PWM
-    if (timx == TIM4)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
-#ifdef BSP_USING_TIM4_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM4_PWM_CH1 */
-
-#ifdef BSP_USING_TIM4_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM4_PWM_CH2 */
-
-#ifdef BSP_USING_TIM4_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM4_PWM_CH3 */
-
-#ifdef BSP_USING_TIM4_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM4_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM4_PWM */
-
-#ifdef BSP_USING_TIM5_PWM
-    if (timx == TIM5)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
-#ifdef BSP_USING_TIM5_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM5_PWM_CH1 */
-
-#ifdef BSP_USING_TIM5_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM5_PWM_CH2 */
-
-#ifdef BSP_USING_TIM5_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM5_PWM_CH3 */
-
-#ifdef BSP_USING_TIM5_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM5_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM5_PWM */
-
-    /* TIM6 and TIM7 don't support PWM Mode. */
-
-#ifdef BSP_USING_TIM8_PWM
-    if (timx == TIM8)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
-
-/* I don't test it, because there is a 10M-PHY ETH port on my board,
- * which uses the following four pins.
- * You can try it on a board without a 10M-PHY ETH port. */
-#ifdef BSP_USING_TIM8_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOC, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM8_PWM_CH1 */
-
-#ifdef BSP_USING_TIM8_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOC, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM8_PWM_CH2 */
-
-#ifdef BSP_USING_TIM8_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOC, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM8_PWM_CH3 */
-
-#ifdef BSP_USING_TIM8_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOC, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM8_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM8_PWM */
-
-#ifdef BSP_USING_TIM9_PWM
-    if (timx == TIM9)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
-
-#ifdef BSP_USING_TIM9_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM9_PWM_CH1 */
-
-#ifdef BSP_USING_TIM9_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM9_PWM_CH2 */
-
-#ifdef BSP_USING_TIM9_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOA, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM9_PWM_CH3 */
-
-#ifdef BSP_USING_TIM9_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOC, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM9_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM9_PWM */
-
-#ifdef BSP_USING_TIM10_PWM
-    if (timx == TIM10)
-    {
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
-
-#ifdef BSP_USING_TIM10_PWM_CH1
-        if (channel == TIM_Channel_1)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM10_PWM_CH1 */
-
-#ifdef BSP_USING_TIM10_PWM_CH2
-        if (channel == TIM_Channel_2)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOB, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM10_PWM_CH2 */
-
-#ifdef BSP_USING_TIM10_PWM_CH3
-        if (channel == TIM_Channel_3)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOC, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM10_PWM_CH3 */
-
-#ifdef BSP_USING_TIM10_PWM_CH4
-        if (channel == TIM_Channel_4)
-        {
-            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
-            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-            GPIO_Init(GPIOC, &GPIO_InitStructure);
-        }
-#endif/* BSP_USING_TIM10_PWM_CH4 */
-    }
-#endif/* BSP_USING_TIM10_PWM */
-}
-
-/*
- * channel = FLAG_NOT_INIT: the channel is not use.
- */
-struct rtdevice_pwm_device pwm_device_list[] =
-{
-#ifdef BSP_USING_TIM1_PWM
-    {
-        .periph = TIM1,
-        .name = "pwm1",
-#ifdef BSP_USING_TIM1_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM1_PWM_CH1 */
-
-#ifdef BSP_USING_TIM1_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM1_PWM_CH2 */
-
-#ifdef BSP_USING_TIM1_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM1_PWM_CH3 */
-
-#ifdef BSP_USING_TIM1_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM1_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM1_PWM */
-
-#ifdef BSP_USING_TIM2_PWM
-    {
-        .periph = TIM2,
-        .name = "pwm2",
-#ifdef BSP_USING_TIM2_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM2_PWM_CH1 */
-
-#ifdef BSP_USING_TIM2_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM2_PWM_CH2 */
-
-#ifdef BSP_USING_TIM2_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM2_PWM_CH3 */
-
-#ifdef BSP_USING_TIM2_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM2_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM2_PWM */
-
-#ifdef BSP_USING_TIM3_PWM
-    {
-        .periph = TIM3,
-        .name = "pwm3",
-#ifdef BSP_USING_TIM3_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM3_PWM_CH1 */
-
-#ifdef BSP_USING_TIM3_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM3_PWM_CH2 */
-
-#ifdef BSP_USING_TIM3_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM3_PWM_CH3 */
-
-#ifdef BSP_USING_TIM3_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM3_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM3_PWM */
-
-#ifdef BSP_USING_TIM4_PWM
-    {
-        .periph = TIM4,
-        .name = "pwm4",
-#ifdef BSP_USING_TIM4_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM4_PWM_CH1 */
-
-#ifdef BSP_USING_TIM4_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM4_PWM_CH2 */
-
-#ifdef BSP_USING_TIM4_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM4_PWM_CH3 */
-
-#ifdef BSP_USING_TIM4_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM4_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM4_PWM */
-
-#ifdef BSP_USING_TIM5_PWM
-    {
-        .periph = TIM5,
-        .name = "pwm5",
-#ifdef BSP_USING_TIM5_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM5_PWM_CH1 */
-
-#ifdef BSP_USING_TIM5_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM5_PWM_CH2 */
-
-#ifdef BSP_USING_TIM5_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM5_PWM_CH3 */
-
-#ifdef BSP_USING_TIM5_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM5_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM5_PWM */
-
-#ifdef BSP_USING_TIM8_PWM
-    {
-        .periph = TIM8,
-        .name = "pwm8",
-#ifdef BSP_USING_TIM8_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM8_PWM_CH1 */
-
-#ifdef BSP_USING_TIM8_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM8_PWM_CH2 */
-
-#ifdef BSP_USING_TIM8_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM8_PWM_CH3 */
-
-#ifdef BSP_USING_TIM8_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM8_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM8_PWM */
-
-#ifdef BSP_USING_TIM9_PWM
-    {
-        .periph = TIM9,
-        .name = "pwm9",
-#ifdef BSP_USING_TIM9_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM9_PWM_CH1 */
-
-#ifdef BSP_USING_TIM9_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM9_PWM_CH2 */
-
-#ifdef BSP_USING_TIM9_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM9_PWM_CH3 */
-
-#ifdef BSP_USING_TIM9_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM9_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM9_PWM */
-
-#ifdef BSP_USING_TIM10_PWM
-    {
-        .periph = TIM10,
-        .name = "pwm10",
-#ifdef BSP_USING_TIM10_PWM_CH1
-        .channel[0] = TIM_Channel_1,
-#else
-        .channel[0] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM10_PWM_CH1 */
-
-#ifdef BSP_USING_TIM10_PWM_CH2
-        .channel[1] = TIM_Channel_2,
-#else
-        .channel[1] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM10_PWM_CH2 */
-
-#ifdef BSP_USING_TIM10_PWM_CH3
-        .channel[2] = TIM_Channel_3,
-#else
-        .channel[2] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM10_PWM_CH3 */
-
-#ifdef BSP_USING_TIM10_PWM_CH4
-        .channel[3] = TIM_Channel_4,
-#else
-        .channel[3] = FLAG_NOT_INIT,
-#endif/* BSP_USING_TIM10_PWM_CH4 */
-    },
-#endif /* BSP_USING_TIM10_PWM */
-};
-
-static rt_err_t ch32_pwm_device_enable(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration, rt_bool_t enable)
-{
-    struct rtdevice_pwm_device* pwm_device;
-    rt_uint32_t channel_index;
-    rt_uint16_t ccx_state;
-
-    pwm_device = (struct rtdevice_pwm_device*)device;
-    channel_index = configuration->channel;
-
-    if (enable == RT_TRUE)
-    {
-        ccx_state = TIM_CCx_Enable;
-    }
-    else
-    {
-        ccx_state = TIM_CCx_Disable;
-    }
-
-    if (channel_index <= 4 && channel_index > 0)
-    {
-        if (pwm_device->channel[channel_index - 1] == FLAG_NOT_INIT)
-        {
-            return -RT_EINVAL;
-        }
-        TIM_CCxCmd(pwm_device->periph, pwm_device->channel[channel_index - 1], ccx_state);
-    }
-    else
-    {
-        return -RT_EINVAL;
-    }
-
-    TIM_Cmd(pwm_device->periph, ENABLE);
-
-    return RT_EOK;
-}
-
-static rt_err_t ch32_pwm_device_get(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
-{
-    struct rtdevice_pwm_device* pwm_device;
-    rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
-    rt_uint32_t channel_index;
-    rt_uint32_t tim_clock;
-
-    pwm_device = (struct rtdevice_pwm_device*)device;
-    tim_clock = ch32_tim_clock_get(pwm_device->periph);
-    channel_index = configuration->channel;
-    arr_counter = pwm_device->periph->ATRLR + 1;
-    prescaler = pwm_device->periph->PSC + 1;
-    sample_freq = (tim_clock / prescaler) / arr_counter;
-
-    /* unit:ns */
-    configuration->period = 1000000000 / sample_freq;
-
-    if (channel_index == 1)
-    {
-        ccr_counter = pwm_device->periph->CH1CVR + 1;
-        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
-    }
-    else if (channel_index == 2)
-    {
-        ccr_counter = pwm_device->periph->CH2CVR + 1;
-        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
-    }
-    else if (channel_index == 3)
-    {
-        ccr_counter = pwm_device->periph->CH3CVR + 1;
-        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
-    }
-    else if (channel_index == 4)
-    {
-        ccr_counter = pwm_device->periph->CH4CVR + 1;
-        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
-    }
-    else
-    {
-        return -RT_EINVAL;
-    }
-
-    return RT_EOK;
-}
-
-static rt_err_t ch32_pwm_device_set(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
-{
-    struct rtdevice_pwm_device* pwm_device;
-    rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
-    rt_uint32_t channel_index;
-    rt_uint32_t tim_clock;
-    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
-    TIM_OCInitTypeDef TIM_OCInitType;
-
-    pwm_device = (struct rtdevice_pwm_device*)device;
-    tim_clock = ch32_tim_clock_get(pwm_device->periph);
-    channel_index = configuration->channel;
-
-    /* change to freq, unit:Hz */
-    sample_freq = 1000000000 / configuration->period;
-
-    /* counter = (tim_clk / prescaler) / sample_freq */
-    /* normally, tim_clk is not need div, if arr_counter over 65536, need div. */
-    prescaler = 1;
-    arr_counter = (tim_clock / prescaler) / sample_freq;
-
-    if (arr_counter > MAX_COUNTER)
-    {
-        /* need div tim_clock
-         * and round up the prescaler value.
-         * (tim_clock >> 16) = tim_clock / 65536
-         */
-        if ((tim_clock >> 16) % sample_freq == 0)
-            prescaler = (tim_clock >> 16) / sample_freq;
-        else
-            prescaler = (tim_clock >> 16) / sample_freq + 1;
-
-        /* counter = (tim_clk / prescaler) / sample_freq */
-        arr_counter = (tim_clock / prescaler) / sample_freq;
-    }
-    /* ccr_counter = duty cycle * arr_counter */
-    ccr_counter = (configuration->pulse * 100 / configuration->period) * arr_counter / 100;
-
-    /* check arr_counter > 1, cxx_counter > 1 */
-    if (arr_counter < MIN_COUNTER)
-    {
-        arr_counter = MIN_COUNTER;
-    }
-    if (ccr_counter < MIN_PULSE)
-    {
-        ccr_counter = MIN_PULSE;
-    }
-
-    /* TMRe base configuration */
-    TIM_TimeBaseStructInit(&TIM_TimeBaseInitType);
-    TIM_TimeBaseInitType.TIM_Period = arr_counter - 1;
-    TIM_TimeBaseInitType.TIM_Prescaler = prescaler - 1;
-    TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
-    TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
-    TIM_TimeBaseInit(pwm_device->periph, &TIM_TimeBaseInitType);
-
-    TIM_OCStructInit(&TIM_OCInitType);
-    TIM_OCInitType.TIM_OCMode = TIM_OCMode_PWM1;
-    TIM_OCInitType.TIM_OutputState = TIM_OutputState_Enable;
-    TIM_OCInitType.TIM_Pulse = ccr_counter - 1;
-    TIM_OCInitType.TIM_OCPolarity = TIM_OCPolarity_High;
-
-    if (channel_index == 1)
-    {
-        TIM_OC1Init(pwm_device->periph, &TIM_OCInitType);
-        TIM_OC1PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
-    }
-    else if (channel_index == 2)
-    {
-        TIM_OC2Init(pwm_device->periph, &TIM_OCInitType);
-        TIM_OC2PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
-    }
-    else if (channel_index == 3)
-    {
-        TIM_OC3Init(pwm_device->periph, &TIM_OCInitType);
-        TIM_OC3PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
-    }
-    else if (channel_index == 4)
-    {
-        TIM_OC4Init(pwm_device->periph, &TIM_OCInitType);
-        TIM_OC4PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
-    }
-    else
-    {
-        return -RT_EINVAL;
-    }
-
-    TIM_ARRPreloadConfig(pwm_device->periph, ENABLE);
-    TIM_CtrlPWMOutputs(pwm_device->periph, ENABLE);
-
-    return RT_EOK;
-}
-
-static rt_err_t drv_pwm_control(struct rt_device_pwm* device, int cmd, void* arg)
-{
-    struct rt_pwm_configuration* configuration;
-
-    configuration = (struct rt_pwm_configuration*)arg;
-
-    switch (cmd)
-    {
-    case PWM_CMD_ENABLE:
-        return ch32_pwm_device_enable(device, configuration, RT_TRUE);
-    case PWM_CMD_DISABLE:
-        return ch32_pwm_device_enable(device, configuration, RT_FALSE);
-    case PWM_CMD_SET:
-        return ch32_pwm_device_set(device, configuration);
-    case PWM_CMD_GET:
-        return ch32_pwm_device_get(device, configuration);
-    default:
-        return -RT_EINVAL;
-    }
-}
-
-static struct rt_pwm_ops pwm_ops =
-{
-    .control = drv_pwm_control
-};
-
-static int rt_hw_pwm_init(void)
-{
-    int result = RT_EOK;
-    int index = 0;
-    int channel_index;
-
-    for (index = 0; index < ITEM_NUM(pwm_device_list); index++)
-    {
-        ch32_tim_clock_init(pwm_device_list[index].periph);
-        for (channel_index = 0; channel_index < sizeof(pwm_device_list[index].channel); channel_index++)
-        {
-            if (pwm_device_list[index].channel[channel_index] != FLAG_NOT_INIT)
-            {
-                ch32_pwm_io_init(pwm_device_list[index].periph, pwm_device_list[index].channel[channel_index]);
-            }
-        }
-
-        if (rt_device_pwm_register(&pwm_device_list[index].parent, pwm_device_list[index].name, &pwm_ops, RT_NULL) == RT_EOK)
-        {
-            LOG_D("%s register success", pwm_device_list[index].name);
-        }
-        else
-        {
-            LOG_D("%s register failed", pwm_device_list[index].name);
-            result = -RT_ERROR;
-        }
-    }
-
-    return result;
-}
-
-INIT_BOARD_EXPORT(rt_hw_pwm_init);
-
-#endif /* BSP_USING_PWM */
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2021-09-23     charlown          first version
+ * 2022-10-14     hg0720            the first version which add from wch
+ * 2022-10-20     MXH               add the remaining timers
+ */
+
+#include "drv_pwm.h"
+
+#ifdef BSP_USING_PWM
+
+#define LOG_TAG "drv.pwm"
+#include <drv_log.h>
+
+void ch32_tim_clock_init(TIM_TypeDef* timx)
+{
+#ifdef BSP_USING_TIM1_PWM
+    if (timx == TIM1)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
+    }
+#endif/* BSP_USING_TIM1_PWM */
+
+#ifdef BSP_USING_TIM2_PWM
+    if (timx == TIM2)
+    {
+        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
+    }
+#endif/* BSP_USING_TIM2_PWM */
+
+#ifdef BSP_USING_TIM3_PWM
+    if (timx == TIM3)
+    {
+        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
+    }
+#endif/* BSP_USING_TIM3_PWM */
+
+#ifdef BSP_USING_TIM4_PWM
+    if (timx == TIM4)
+    {
+        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
+    }
+#endif/* BSP_USING_TIM4_PWM */
+
+#ifdef BSP_USING_TIM5_PWM
+    if (timx == TIM5)
+    {
+        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
+    }
+#endif/* BSP_USING_TIM5_PWM */
+
+    /* TIM6 and TIM7 don't support PWM Mode. */
+
+#ifdef BSP_USING_TIM8_PWM
+    if (timx == TIM8)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
+    }
+#endif/* BSP_USING_TIM8_PWM */
+
+#ifdef BSP_USING_TIM9_PWM
+    if (timx == TIM9)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
+    }
+#endif/* BSP_USING_TIM9_PWM */
+
+#ifdef BSP_USING_TIM10_PWM
+    if (timx == TIM10)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
+    }
+#endif/* BSP_USING_TIM10_PWM */
+}
+
+rt_uint32_t ch32_tim_clock_get(TIM_TypeDef* timx)
+{
+    RCC_ClocksTypeDef RCC_Clocks;
+    RCC_GetClocksFreq(&RCC_Clocks);
+
+    /*tim1~10 all in HCLK*/
+    return RCC_Clocks.HCLK_Frequency;
+}
+
+/*
+ * NOTE:  some pwm pins of some timers are reused,
+ *          please keep caution when using pwm
+ */
+
+void ch32_pwm_io_init(TIM_TypeDef* timx, rt_uint8_t channel)
+{
+    GPIO_InitTypeDef GPIO_InitStructure;
+
+#ifdef BSP_USING_TIM1_PWM
+    if (timx == TIM1)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+
+#ifdef BSP_USING_TIM1_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM1_PWM_CH1 */
+
+#ifdef BSP_USING_TIM1_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM1_PWM_CH2 */
+
+#ifdef BSP_USING_TIM1_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM1_PWM_CH3 */
+
+#ifdef BSP_USING_TIM1_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM1_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM1_PWM */
+
+#ifdef BSP_USING_TIM2_PWM
+    if (timx == TIM2)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+
+#ifdef BSP_USING_TIM2_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM2_PWM_CH1 */
+
+#ifdef BSP_USING_TIM2_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM2_PWM_CH2 */
+
+#ifdef BSP_USING_TIM2_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM2_PWM_CH3 */
+
+#ifdef BSP_USING_TIM2_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM2_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM2_PWM */
+
+#ifdef BSP_USING_TIM3_PWM
+    if (timx == TIM3)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+
+#ifdef BSP_USING_TIM3_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM3_PWM_CH1 */
+
+#ifdef BSP_USING_TIM3_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM3_PWM_CH2 */
+
+#ifdef BSP_USING_TIM3_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM3_PWM_CH3 */
+
+#ifdef BSP_USING_TIM3_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM3_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM3_PWM */
+
+#ifdef BSP_USING_TIM4_PWM
+    if (timx == TIM4)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+
+#ifdef BSP_USING_TIM4_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM4_PWM_CH1 */
+
+#ifdef BSP_USING_TIM4_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM4_PWM_CH2 */
+
+#ifdef BSP_USING_TIM4_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM4_PWM_CH3 */
+
+#ifdef BSP_USING_TIM4_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM4_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM4_PWM */
+
+#ifdef BSP_USING_TIM5_PWM
+    if (timx == TIM5)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+
+#ifdef BSP_USING_TIM5_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM5_PWM_CH1 */
+
+#ifdef BSP_USING_TIM5_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM5_PWM_CH2 */
+
+#ifdef BSP_USING_TIM5_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM5_PWM_CH3 */
+
+#ifdef BSP_USING_TIM5_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM5_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM5_PWM */
+
+    /* TIM6 and TIM7 don't support PWM Mode. */
+
+#ifdef BSP_USING_TIM8_PWM
+    if (timx == TIM8)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
+
+/* I don't test it, because there is a 10M-PHY ETH port on my board,
+ * which uses the following four pins.
+ * You can try it on a board without a 10M-PHY ETH port. */
+#ifdef BSP_USING_TIM8_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOC, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM8_PWM_CH1 */
+
+#ifdef BSP_USING_TIM8_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOC, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM8_PWM_CH2 */
+
+#ifdef BSP_USING_TIM8_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOC, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM8_PWM_CH3 */
+
+#ifdef BSP_USING_TIM8_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOC, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM8_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM8_PWM */
+
+#ifdef BSP_USING_TIM9_PWM
+    if (timx == TIM9)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
+
+#ifdef BSP_USING_TIM9_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM9_PWM_CH1 */
+
+#ifdef BSP_USING_TIM9_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM9_PWM_CH2 */
+
+#ifdef BSP_USING_TIM9_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOA, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM9_PWM_CH3 */
+
+#ifdef BSP_USING_TIM9_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOC, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM9_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM9_PWM */
+
+#ifdef BSP_USING_TIM10_PWM
+    if (timx == TIM10)
+    {
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
+
+#ifdef BSP_USING_TIM10_PWM_CH1
+        if (channel == TIM_Channel_1)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM10_PWM_CH1 */
+
+#ifdef BSP_USING_TIM10_PWM_CH2
+        if (channel == TIM_Channel_2)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOB, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM10_PWM_CH2 */
+
+#ifdef BSP_USING_TIM10_PWM_CH3
+        if (channel == TIM_Channel_3)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOC, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM10_PWM_CH3 */
+
+#ifdef BSP_USING_TIM10_PWM_CH4
+        if (channel == TIM_Channel_4)
+        {
+            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
+            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+            GPIO_Init(GPIOC, &GPIO_InitStructure);
+        }
+#endif/* BSP_USING_TIM10_PWM_CH4 */
+    }
+#endif/* BSP_USING_TIM10_PWM */
+}
+
+/*
+ * channel = FLAG_NOT_INIT: the channel is not use.
+ */
+struct rtdevice_pwm_device pwm_device_list[] =
+{
+#ifdef BSP_USING_TIM1_PWM
+    {
+        .periph = TIM1,
+        .name = "pwm1",
+#ifdef BSP_USING_TIM1_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM1_PWM_CH1 */
+
+#ifdef BSP_USING_TIM1_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM1_PWM_CH2 */
+
+#ifdef BSP_USING_TIM1_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM1_PWM_CH3 */
+
+#ifdef BSP_USING_TIM1_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM1_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM1_PWM */
+
+#ifdef BSP_USING_TIM2_PWM
+    {
+        .periph = TIM2,
+        .name = "pwm2",
+#ifdef BSP_USING_TIM2_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM2_PWM_CH1 */
+
+#ifdef BSP_USING_TIM2_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM2_PWM_CH2 */
+
+#ifdef BSP_USING_TIM2_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM2_PWM_CH3 */
+
+#ifdef BSP_USING_TIM2_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM2_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM2_PWM */
+
+#ifdef BSP_USING_TIM3_PWM
+    {
+        .periph = TIM3,
+        .name = "pwm3",
+#ifdef BSP_USING_TIM3_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM3_PWM_CH1 */
+
+#ifdef BSP_USING_TIM3_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM3_PWM_CH2 */
+
+#ifdef BSP_USING_TIM3_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM3_PWM_CH3 */
+
+#ifdef BSP_USING_TIM3_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM3_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM3_PWM */
+
+#ifdef BSP_USING_TIM4_PWM
+    {
+        .periph = TIM4,
+        .name = "pwm4",
+#ifdef BSP_USING_TIM4_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM4_PWM_CH1 */
+
+#ifdef BSP_USING_TIM4_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM4_PWM_CH2 */
+
+#ifdef BSP_USING_TIM4_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM4_PWM_CH3 */
+
+#ifdef BSP_USING_TIM4_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM4_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM4_PWM */
+
+#ifdef BSP_USING_TIM5_PWM
+    {
+        .periph = TIM5,
+        .name = "pwm5",
+#ifdef BSP_USING_TIM5_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM5_PWM_CH1 */
+
+#ifdef BSP_USING_TIM5_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM5_PWM_CH2 */
+
+#ifdef BSP_USING_TIM5_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM5_PWM_CH3 */
+
+#ifdef BSP_USING_TIM5_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM5_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM5_PWM */
+
+#ifdef BSP_USING_TIM8_PWM
+    {
+        .periph = TIM8,
+        .name = "pwm8",
+#ifdef BSP_USING_TIM8_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM8_PWM_CH1 */
+
+#ifdef BSP_USING_TIM8_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM8_PWM_CH2 */
+
+#ifdef BSP_USING_TIM8_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM8_PWM_CH3 */
+
+#ifdef BSP_USING_TIM8_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM8_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM8_PWM */
+
+#ifdef BSP_USING_TIM9_PWM
+    {
+        .periph = TIM9,
+        .name = "pwm9",
+#ifdef BSP_USING_TIM9_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM9_PWM_CH1 */
+
+#ifdef BSP_USING_TIM9_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM9_PWM_CH2 */
+
+#ifdef BSP_USING_TIM9_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM9_PWM_CH3 */
+
+#ifdef BSP_USING_TIM9_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM9_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM9_PWM */
+
+#ifdef BSP_USING_TIM10_PWM
+    {
+        .periph = TIM10,
+        .name = "pwm10",
+#ifdef BSP_USING_TIM10_PWM_CH1
+        .channel[0] = TIM_Channel_1,
+#else
+        .channel[0] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM10_PWM_CH1 */
+
+#ifdef BSP_USING_TIM10_PWM_CH2
+        .channel[1] = TIM_Channel_2,
+#else
+        .channel[1] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM10_PWM_CH2 */
+
+#ifdef BSP_USING_TIM10_PWM_CH3
+        .channel[2] = TIM_Channel_3,
+#else
+        .channel[2] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM10_PWM_CH3 */
+
+#ifdef BSP_USING_TIM10_PWM_CH4
+        .channel[3] = TIM_Channel_4,
+#else
+        .channel[3] = FLAG_NOT_INIT,
+#endif/* BSP_USING_TIM10_PWM_CH4 */
+    },
+#endif /* BSP_USING_TIM10_PWM */
+};
+
+static rt_err_t ch32_pwm_device_enable(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration, rt_bool_t enable)
+{
+    struct rtdevice_pwm_device* pwm_device;
+    rt_uint32_t channel_index;
+    rt_uint16_t ccx_state;
+
+    pwm_device = (struct rtdevice_pwm_device*)device;
+    channel_index = configuration->channel;
+
+    if (enable == RT_TRUE)
+    {
+        ccx_state = TIM_CCx_Enable;
+    }
+    else
+    {
+        ccx_state = TIM_CCx_Disable;
+    }
+
+    if (channel_index <= 4 && channel_index > 0)
+    {
+        if (pwm_device->channel[channel_index - 1] == FLAG_NOT_INIT)
+        {
+            return -RT_EINVAL;
+        }
+        TIM_CCxCmd(pwm_device->periph, pwm_device->channel[channel_index - 1], ccx_state);
+    }
+    else
+    {
+        return -RT_EINVAL;
+    }
+
+    TIM_Cmd(pwm_device->periph, ENABLE);
+
+    return RT_EOK;
+}
+
+static rt_err_t ch32_pwm_device_get(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
+{
+    struct rtdevice_pwm_device* pwm_device;
+    rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
+    rt_uint32_t channel_index;
+    rt_uint32_t tim_clock;
+
+    pwm_device = (struct rtdevice_pwm_device*)device;
+    tim_clock = ch32_tim_clock_get(pwm_device->periph);
+    channel_index = configuration->channel;
+    arr_counter = pwm_device->periph->ATRLR + 1;
+    prescaler = pwm_device->periph->PSC + 1;
+    sample_freq = (tim_clock / prescaler) / arr_counter;
+
+    /* unit:ns */
+    configuration->period = 1000000000 / sample_freq;
+
+    if (channel_index == 1)
+    {
+        ccr_counter = pwm_device->periph->CH1CVR + 1;
+        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+    }
+    else if (channel_index == 2)
+    {
+        ccr_counter = pwm_device->periph->CH2CVR + 1;
+        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+    }
+    else if (channel_index == 3)
+    {
+        ccr_counter = pwm_device->periph->CH3CVR + 1;
+        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+    }
+    else if (channel_index == 4)
+    {
+        ccr_counter = pwm_device->periph->CH4CVR + 1;
+        configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
+    }
+    else
+    {
+        return -RT_EINVAL;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t ch32_pwm_device_set(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
+{
+    struct rtdevice_pwm_device* pwm_device;
+    rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
+    rt_uint32_t channel_index;
+    rt_uint32_t tim_clock;
+    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
+    TIM_OCInitTypeDef TIM_OCInitType;
+
+    pwm_device = (struct rtdevice_pwm_device*)device;
+    tim_clock = ch32_tim_clock_get(pwm_device->periph);
+    channel_index = configuration->channel;
+
+    /* change to freq, unit:Hz */
+    sample_freq = 1000000000 / configuration->period;
+
+    /* counter = (tim_clk / prescaler) / sample_freq */
+    /* normally, tim_clk is not need div, if arr_counter over 65536, need div. */
+    prescaler = 1;
+    arr_counter = (tim_clock / prescaler) / sample_freq;
+
+    if (arr_counter > MAX_COUNTER)
+    {
+        /* need div tim_clock
+         * and round up the prescaler value.
+         * (tim_clock >> 16) = tim_clock / 65536
+         */
+        if ((tim_clock >> 16) % sample_freq == 0)
+            prescaler = (tim_clock >> 16) / sample_freq;
+        else
+            prescaler = (tim_clock >> 16) / sample_freq + 1;
+
+        /* counter = (tim_clk / prescaler) / sample_freq */
+        arr_counter = (tim_clock / prescaler) / sample_freq;
+    }
+    /* ccr_counter = duty cycle * arr_counter */
+    ccr_counter = (configuration->pulse * 100 / configuration->period) * arr_counter / 100;
+
+    /* check arr_counter > 1, cxx_counter > 1 */
+    if (arr_counter < MIN_COUNTER)
+    {
+        arr_counter = MIN_COUNTER;
+    }
+    if (ccr_counter < MIN_PULSE)
+    {
+        ccr_counter = MIN_PULSE;
+    }
+
+    /* TMRe base configuration */
+    TIM_TimeBaseStructInit(&TIM_TimeBaseInitType);
+    TIM_TimeBaseInitType.TIM_Period = arr_counter - 1;
+    TIM_TimeBaseInitType.TIM_Prescaler = prescaler - 1;
+    TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
+    TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
+    TIM_TimeBaseInit(pwm_device->periph, &TIM_TimeBaseInitType);
+
+    TIM_OCStructInit(&TIM_OCInitType);
+    TIM_OCInitType.TIM_OCMode = TIM_OCMode_PWM1;
+    TIM_OCInitType.TIM_OutputState = TIM_OutputState_Enable;
+    TIM_OCInitType.TIM_Pulse = ccr_counter - 1;
+    TIM_OCInitType.TIM_OCPolarity = TIM_OCPolarity_High;
+
+    if (channel_index == 1)
+    {
+        TIM_OC1Init(pwm_device->periph, &TIM_OCInitType);
+        TIM_OC1PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+    }
+    else if (channel_index == 2)
+    {
+        TIM_OC2Init(pwm_device->periph, &TIM_OCInitType);
+        TIM_OC2PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+    }
+    else if (channel_index == 3)
+    {
+        TIM_OC3Init(pwm_device->periph, &TIM_OCInitType);
+        TIM_OC3PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+    }
+    else if (channel_index == 4)
+    {
+        TIM_OC4Init(pwm_device->periph, &TIM_OCInitType);
+        TIM_OC4PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
+    }
+    else
+    {
+        return -RT_EINVAL;
+    }
+
+    TIM_ARRPreloadConfig(pwm_device->periph, ENABLE);
+    TIM_CtrlPWMOutputs(pwm_device->periph, ENABLE);
+
+    return RT_EOK;
+}
+
+static rt_err_t drv_pwm_control(struct rt_device_pwm* device, int cmd, void* arg)
+{
+    struct rt_pwm_configuration* configuration;
+
+    configuration = (struct rt_pwm_configuration*)arg;
+
+    switch (cmd)
+    {
+    case PWM_CMD_ENABLE:
+        return ch32_pwm_device_enable(device, configuration, RT_TRUE);
+    case PWM_CMD_DISABLE:
+        return ch32_pwm_device_enable(device, configuration, RT_FALSE);
+    case PWM_CMD_SET:
+        return ch32_pwm_device_set(device, configuration);
+    case PWM_CMD_GET:
+        return ch32_pwm_device_get(device, configuration);
+    default:
+        return -RT_EINVAL;
+    }
+}
+
+static struct rt_pwm_ops pwm_ops =
+{
+    .control = drv_pwm_control
+};
+
+static int rt_hw_pwm_init(void)
+{
+    int result = RT_EOK;
+    int index = 0;
+    int channel_index;
+
+    for (index = 0; index < ITEM_NUM(pwm_device_list); index++)
+    {
+        ch32_tim_clock_init(pwm_device_list[index].periph);
+        for (channel_index = 0; channel_index < sizeof(pwm_device_list[index].channel); channel_index++)
+        {
+            if (pwm_device_list[index].channel[channel_index] != FLAG_NOT_INIT)
+            {
+                ch32_pwm_io_init(pwm_device_list[index].periph, pwm_device_list[index].channel[channel_index]);
+            }
+        }
+
+        if (rt_device_pwm_register(&pwm_device_list[index].parent, pwm_device_list[index].name, &pwm_ops, RT_NULL) == RT_EOK)
+        {
+            LOG_D("%s register success", pwm_device_list[index].name);
+        }
+        else
+        {
+            LOG_D("%s register failed", pwm_device_list[index].name);
+            result = -RT_ERROR;
+        }
+    }
+
+    return result;
+}
+
+INIT_BOARD_EXPORT(rt_hw_pwm_init);
+
+#endif /* BSP_USING_PWM */

+ 40 - 40
bsp/wch/risc-v/Libraries/ch32_drivers/drv_pwm.h

@@ -1,40 +1,40 @@
-/*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2022-10-20     MXH          the first version
- */
-
-#ifndef __DRV_PWM_H__
-#define __DRV_PWM_H__
-
-#include <rtthread.h>
-#ifdef BSP_USING_PWM
-#include "ch32v30x_tim.h"
-#include <drivers/rt_drv_pwm.h>
-#include <drivers/hwtimer.h>
-#include <board.h>
-
-#ifndef ITEM_NUM
-#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
-#endif
-
-#define MAX_COUNTER     65535
-#define MIN_COUNTER     2
-#define MIN_PULSE       2
-#define FLAG_NOT_INIT   0xFF
-
-struct rtdevice_pwm_device
-{
-    struct rt_device_pwm parent;
-    TIM_TypeDef* periph;
-    rt_uint8_t channel[4];
-    char* name;
-};
-
-#endif/* BSP_USING_PWM */
-
-#endif/* __DRV_PWM_H__ */
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-10-20     MXH          the first version
+ */
+
+#ifndef __DRV_PWM_H__
+#define __DRV_PWM_H__
+
+#include <rtthread.h>
+#ifdef BSP_USING_PWM
+#include "ch32v30x_tim.h"
+#include <drivers/rt_drv_pwm.h>
+#include <drivers/hwtimer.h>
+#include <board.h>
+
+#ifndef ITEM_NUM
+#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
+#endif
+
+#define MAX_COUNTER     65535
+#define MIN_COUNTER     2
+#define MIN_PULSE       2
+#define FLAG_NOT_INIT   0xFF
+
+struct rtdevice_pwm_device
+{
+    struct rt_device_pwm parent;
+    TIM_TypeDef* periph;
+    rt_uint8_t channel[4];
+    char* name;
+};
+
+#endif/* BSP_USING_PWM */
+
+#endif/* __DRV_PWM_H__ */

+ 2 - 1
components/drivers/fdt/inc/dtb_node.h

@@ -8,6 +8,7 @@
 
 #include "libfdt_env.h"
 #include <rtthread.h>
+#include <stdint.h>
 
 //#define RT_DTB_DEBUG
 #ifdef RT_DTB_DEBUG
@@ -326,7 +327,7 @@ struct dtb_node *dtb_node_first_subnode(const struct dtb_node *node);
 struct dtb_node *dtb_node_next_subnode(const struct dtb_node *node);
 struct dtb_node *dtb_node_get_parent(const struct dtb_node *node);
 const char *dtb_node_get_name(const struct dtb_node *node);
-struct dtb_node *dtb_node_get_by_phandle(uint phandle);
+struct dtb_node *dtb_node_get_by_phandle(uint32_t phandle);
 int dtb_node_read_size(const struct dtb_node *node, const char *propname);
 size_t dtb_node_get_addr_index(const struct dtb_node *node, int index);
 size_t dtb_node_get_addr(const struct dtb_node *node);

+ 49 - 35
components/drivers/fdt/libfdt/fdt.h

@@ -1,3 +1,13 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-12-20     RT-Thread   the first version
+ */
+
 #ifndef _FDT_H
 #define _FDT_H
 /*
@@ -54,58 +64,62 @@
 
 #ifndef __ASSEMBLY__
 
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
 struct fdt_header {
-	fdt32_t magic;			 /* magic word FDT_MAGIC */
-	fdt32_t totalsize;		 /* total size of DT block */
-	fdt32_t off_dt_struct;		 /* offset to structure */
-	fdt32_t off_dt_strings;		 /* offset to strings */
-	fdt32_t off_mem_rsvmap;		 /* offset to memory reserve map */
-	fdt32_t version;		 /* format version */
-	fdt32_t last_comp_version;	 /* last compatible version */
+    fdt32_t magic;                  /* magic word FDT_MAGIC */
+    fdt32_t totalsize;              /* total size of DT block */
+    fdt32_t off_dt_struct;          /* offset to structure */
+    fdt32_t off_dt_strings;         /* offset to strings */
+    fdt32_t off_mem_rsvmap;         /* offset to memory reserve map */
+    fdt32_t version;                /* format version */
+    fdt32_t last_comp_version;      /* last compatible version */
 
-	/* version 2 fields below */
-	fdt32_t boot_cpuid_phys;	 /* Which physical CPU id we're
-					    booting on */
-	/* version 3 fields below */
-	fdt32_t size_dt_strings;	 /* size of the strings block */
+    /* version 2 fields below */
+    fdt32_t boot_cpuid_phys;        /* Which physical CPU id we're
+                                    booting on */
+    /* version 3 fields below */
+    fdt32_t size_dt_strings;        /* size of the strings block */
 
-	/* version 17 fields below */
-	fdt32_t size_dt_struct;		 /* size of the structure block */
+    /* version 17 fields below */
+    fdt32_t size_dt_struct;         /* size of the structure block */
 };
 
 struct fdt_reserve_entry {
-	fdt64_t address;
-	fdt64_t size;
+    fdt64_t address;
+    fdt64_t size;
 };
 
 struct fdt_node_header {
-	fdt32_t tag;
-	char name[0];
+    fdt32_t tag;
+    char name[0];
 };
 
 struct fdt_property {
-	fdt32_t tag;
-	fdt32_t len;
-	fdt32_t nameoff;
-	char data[0];
+    fdt32_t tag;
+    fdt32_t len;
+    fdt32_t nameoff;
+    char data[0];
 };
 
 #endif /* !__ASSEMBLY */
 
-#define FDT_MAGIC	0xd00dfeed	/* 4: version, 4: total size */
-#define FDT_TAGSIZE	sizeof(fdt32_t)
+#define FDT_MAGIC    0xd00dfeed    /* 4: version, 4: total size */
+#define FDT_TAGSIZE    sizeof(fdt32_t)
 
-#define FDT_BEGIN_NODE	0x1		/* Start node: full name */
-#define FDT_END_NODE	0x2		/* End node */
-#define FDT_PROP	0x3		/* Property: name off,
-					   size, content */
-#define FDT_NOP		0x4		/* nop */
-#define FDT_END		0x9
+#define FDT_BEGIN_NODE    0x1        /* Start node: full name */
+#define FDT_END_NODE    0x2        /* End node */
+#define FDT_PROP    0x3        /* Property: name off,
+                       size, content */
+#define FDT_NOP        0x4        /* nop */
+#define FDT_END        0x9
 
-#define FDT_V1_SIZE	(7*sizeof(fdt32_t))
-#define FDT_V2_SIZE	(FDT_V1_SIZE + sizeof(fdt32_t))
-#define FDT_V3_SIZE	(FDT_V2_SIZE + sizeof(fdt32_t))
-#define FDT_V16_SIZE	FDT_V3_SIZE
-#define FDT_V17_SIZE	(FDT_V16_SIZE + sizeof(fdt32_t))
+#define FDT_V1_SIZE    (7*sizeof(fdt32_t))
+#define FDT_V2_SIZE    (FDT_V1_SIZE + sizeof(fdt32_t))
+#define FDT_V3_SIZE    (FDT_V2_SIZE + sizeof(fdt32_t))
+#define FDT_V16_SIZE    FDT_V3_SIZE
+#define FDT_V17_SIZE    (FDT_V16_SIZE + sizeof(fdt32_t))
 
 #endif /* _FDT_H */

+ 1 - 2
components/drivers/tty/pty.c

@@ -308,7 +308,7 @@ static int ptmx_register(void)
 
     level = rt_hw_interrupt_disable();
     RT_ASSERT(ptm_drv->init_flag == TTY_INIT_FLAG_NONE);
-    
+
     device = &(ptm_drv->parent);
 
     device->type = RT_Device_Class_Char;
@@ -348,7 +348,6 @@ static int ptmx_register(void)
     }
     tty_initstack(ptm_drv->head);
 
-    rt_spin_lock_init(&ptm_drv->spinlock);
     ptm_drv->pgrp = -1;
     ptm_drv->session = -1;
     ptm_drv->foreground = RT_NULL;

+ 2 - 0
libcpu/Kconfig

@@ -82,6 +82,7 @@ config ARCH_ARM_MMU
 if RT_USING_SMART
 config KERNEL_VADDR_START
     hex "The virtural address of kernel start"
+    default 0xffff000000000000 if ARCH_ARMV8
     default 0xc0000000 if ARCH_ARM
     default 0x80000000 if ARCH_RISCV
     depends on ARCH_MM_MMU
@@ -159,6 +160,7 @@ config RT_BACKTRACE_FUNCTION_NAME
 config ARCH_ARMV8
     bool
     select ARCH_ARM
+    select ARCH_ARM_MMU
 
 config ARCH_MIPS
     bool

+ 42 - 45
libcpu/aarch64/common/armv8.h

@@ -1,67 +1,64 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2011-09-15     Bernard      first version
- * 2021-12-28     GuEe-GUI     add fpu support
  */
 
 #ifndef __ARMV8_H__
 #define __ARMV8_H__
 
-#include <rtdef.h>
-
 /* the exception stack without VFP registers */
 struct rt_hw_exp_stack
 {
-    unsigned long long pc;
-    unsigned long long spsr;
-    unsigned long long x30;
-    unsigned long long xzr;
-    unsigned long long fpcr;
-    unsigned long long fpsr;
-    unsigned long long x28;
-    unsigned long long x29;
-    unsigned long long x26;
-    unsigned long long x27;
-    unsigned long long x24;
-    unsigned long long x25;
-    unsigned long long x22;
-    unsigned long long x23;
-    unsigned long long x20;
-    unsigned long long x21;
-    unsigned long long x18;
-    unsigned long long x19;
-    unsigned long long x16;
-    unsigned long long x17;
-    unsigned long long x14;
-    unsigned long long x15;
-    unsigned long long x12;
-    unsigned long long x13;
-    unsigned long long x10;
-    unsigned long long x11;
-    unsigned long long x8;
-    unsigned long long x9;
-    unsigned long long x6;
-    unsigned long long x7;
-    unsigned long long x4;
-    unsigned long long x5;
-    unsigned long long x2;
-    unsigned long long x3;
-    unsigned long long x0;
-    unsigned long long x1;
+    unsigned long pc;
+    unsigned long cpsr;
+    unsigned long sp_el0;
+    unsigned long x30;
+    unsigned long fpcr;
+    unsigned long fpsr;
+    unsigned long x28;
+    unsigned long x29;
+    unsigned long x26;
+    unsigned long x27;
+    unsigned long x24;
+    unsigned long x25;
+    unsigned long x22;
+    unsigned long x23;
+    unsigned long x20;
+    unsigned long x21;
+    unsigned long x18;
+    unsigned long x19;
+    unsigned long x16;
+    unsigned long x17;
+    unsigned long x14;
+    unsigned long x15;
+    unsigned long x12;
+    unsigned long x13;
+    unsigned long x10;
+    unsigned long x11;
+    unsigned long x8;
+    unsigned long x9;
+    unsigned long x6;
+    unsigned long x7;
+    unsigned long x4;
+    unsigned long x5;
+    unsigned long x2;
+    unsigned long x3;
+    unsigned long x0;
+    unsigned long x1;
 
     unsigned long long fpu[16];
 };
 
-#define SP_ELx                      ( ( unsigned long long ) 0x01 )
-#define SP_EL0                      ( ( unsigned long long ) 0x00 )
-#define PSTATE_EL1                  ( ( unsigned long long ) 0x04 )
-#define PSTATE_EL2                  ( ( unsigned long long ) 0x08 )
-#define PSTATE_EL3                  ( ( unsigned long long ) 0x0c )
+#define SP_ELx     ((unsigned long)0x01)
+#define SP_EL0     ((unsigned long)0x00)
+#define PSTATE_EL1 ((unsigned long)0x04)
+#define PSTATE_EL2 ((unsigned long)0x08)
+#define PSTATE_EL3 ((unsigned long)0x0c)
 
 rt_ubase_t rt_hw_get_current_el(void);
 void rt_hw_set_elx_env(void);

+ 46 - 0
libcpu/aarch64/common/asm-fpu.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-05-18     Jesven       the first version
+ */
+
+.macro SAVE_FPU, reg
+    STR Q0, [\reg, #-0x10]!
+    STR Q1, [\reg, #-0x10]!
+    STR Q2, [\reg, #-0x10]!
+    STR Q3, [\reg, #-0x10]!
+    STR Q4, [\reg, #-0x10]!
+    STR Q5, [\reg, #-0x10]!
+    STR Q6, [\reg, #-0x10]!
+    STR Q7, [\reg, #-0x10]!
+    STR Q8, [\reg, #-0x10]!
+    STR Q9, [\reg, #-0x10]!
+    STR Q10, [\reg, #-0x10]!
+    STR Q11, [\reg, #-0x10]!
+    STR Q12, [\reg, #-0x10]!
+    STR Q13, [\reg, #-0x10]!
+    STR Q14, [\reg, #-0x10]!
+    STR Q15, [\reg, #-0x10]!
+.endm
+.macro RESTORE_FPU, reg
+    LDR Q15, [\reg], #0x10
+    LDR Q14, [\reg], #0x10
+    LDR Q13, [\reg], #0x10
+    LDR Q12, [\reg], #0x10
+    LDR Q11, [\reg], #0x10
+    LDR Q10, [\reg], #0x10
+    LDR Q9, [\reg], #0x10
+    LDR Q8, [\reg], #0x10
+    LDR Q7, [\reg], #0x10
+    LDR Q6, [\reg], #0x10
+    LDR Q5, [\reg], #0x10
+    LDR Q4, [\reg], #0x10
+    LDR Q3, [\reg], #0x10
+    LDR Q2, [\reg], #0x10
+    LDR Q1, [\reg], #0x10
+    LDR Q0, [\reg], #0x10
+.endm

+ 57 - 0
libcpu/aarch64/common/backtrace.c

@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-06-02     Jesven       the first version
+ */
+
+#include <rtthread.h>
+#include <backtrace.h>
+
+#define BT_NESTING_MAX 100
+
+static int unwind_frame(struct bt_frame *frame)
+{
+    unsigned long fp = frame->fp;
+
+    if ((fp & 0x7)
+#ifdef RT_USING_LWP
+         || fp < KERNEL_VADDR_START
+#endif
+            )
+    {
+        return 1;
+    }
+    frame->fp = *(unsigned long *)fp;
+    frame->pc = *(unsigned long *)(fp + 8);
+    return 0;
+}
+
+static void walk_unwind(unsigned long pc, unsigned long fp)
+{
+    struct bt_frame frame;
+    unsigned long lr = pc;
+    int nesting = 0;
+
+    frame.fp = fp;
+    while (nesting < BT_NESTING_MAX)
+    {
+        rt_kprintf(" %p", (void *)lr);
+        if (unwind_frame(&frame))
+        {
+            break;
+        }
+        lr = frame.pc;
+        nesting++;
+    }
+}
+
+void backtrace(unsigned long pc, unsigned long lr, unsigned long fp)
+{
+    rt_kprintf("please use: addr2line -e rtthread.elf -a -f %p", (void *)pc);
+    walk_unwind(lr, fp);
+    rt_kprintf("\n");
+}

+ 22 - 0
libcpu/aarch64/common/backtrace.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-06-02     Jesven       the first version
+ */
+
+#ifndef  __BACKTRACE_H__
+#define  __BACKTRACE_H__
+
+struct bt_frame
+{
+    unsigned long fp;
+    unsigned long pc;
+};
+
+void backtrace(unsigned long pc, unsigned long lr, unsigned long fp);
+
+#endif  /*__BACKTRACE_H__*/

+ 3 - 2
libcpu/aarch64/common/cache.S

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -127,7 +127,8 @@ __asm_flush_dcache_range:
     /* x2 <- minimal cache line size in cache system */
     sub    x3, x2, #1
     bic    x0, x0, x3
-1:    dc    civac, x0    /* clean & invalidate data or unified cache */
+
+1:  dc    civac, x0    /* clean & invalidate data or unified cache */
     add    x0, x0, x2
     cmp    x0, x1
     b.lo    1b

+ 23 - 0
libcpu/aarch64/common/cache.h

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-12-18     RT-Thread    the first version
+ */
+
+#ifndef __CACHE_H__
+#define __CACHE_H__
+
+void rt_hw_dcache_flush_all(void);
+void rt_hw_dcache_invalidate_all(void);
+void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size);
+void rt_hw_cpu_dcache_clean(void *addr, int size);
+void rt_hw_cpu_dcache_invalidate(unsigned long start_addr,unsigned long size);
+
+void rt_hw_icache_invalidate_all();
+void rt_hw_icache_invalidate_range(unsigned long start_addr, int size);
+
+#endif /* __CACHE_H__ */

+ 53 - 21
libcpu/aarch64/common/cache_ops.c

@@ -1,59 +1,58 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2018, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
- * 2021-12-28     GuEe-GUI     the first version
+ * 2019-03-29 	  quanzhao 	   the first version
  */
-
 #include <rthw.h>
 #include <rtdef.h>
 
+void __asm_invalidate_icache_all(void);
 void __asm_flush_dcache_all(void);
-void __asm_invalidate_dcache_all(void);
 void __asm_flush_dcache_range(unsigned long start, unsigned long end);
 void __asm_invalidate_dcache_range(unsigned long start, unsigned long end);
-
-void __asm_invalidate_icache_all(void);
 void __asm_invalidate_icache_range(unsigned long start, unsigned long end);
+void __asm_invalidate_dcache_all(void);
+void __asm_invalidate_icache_all(void);
 
-void rt_hw_dcache_flush_all(void)
+rt_inline rt_uint32_t rt_cpu_icache_line_size(void)
 {
-    __asm_flush_dcache_all();
+    return 0;
 }
 
-void rt_hw_dcache_invalidate_all(void)
+rt_inline rt_uint32_t rt_cpu_dcache_line_size(void)
 {
-    __asm_invalidate_dcache_all();
+    return 0;
 }
 
-void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size)
+void rt_hw_cpu_icache_invalidate(void *addr, int size)
 {
-    __asm_flush_dcache_range(start_addr, start_addr + size);
+    __asm_invalidate_icache_range((unsigned long)addr, (unsigned long)addr + size);
 }
 
-void rt_hw_dcache_invalidate_range(unsigned long start_addr,unsigned long size)
+void rt_hw_cpu_dcache_invalidate(void *addr, int size)
 {
-    __asm_invalidate_dcache_range(start_addr, start_addr + size);
+    __asm_invalidate_dcache_range((unsigned long)addr, (unsigned long)addr + size);
 }
 
-void rt_hw_icache_invalidate_all()
+void rt_hw_cpu_dcache_clean(void *addr, int size)
 {
-    __asm_invalidate_icache_all();
+    __asm_flush_dcache_range((unsigned long)addr, (unsigned long)addr + size);
 }
 
-void rt_hw_icache_invalidate_range(unsigned long start_addr, int size)
+void rt_hw_cpu_dcache_clean_and_invalidate(void *addr, int size)
 {
-    __asm_invalidate_icache_range(start_addr, start_addr + size);
+    __asm_flush_dcache_range((unsigned long)addr, (unsigned long)addr + size);
 }
 
 void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
 {
     if (ops == RT_HW_CACHE_INVALIDATE)
     {
-        rt_hw_icache_invalidate_range((unsigned long)addr, size);
+        rt_hw_cpu_icache_invalidate(addr, size);
     }
 }
 
@@ -61,10 +60,43 @@ void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
 {
     if (ops == RT_HW_CACHE_FLUSH)
     {
-        rt_hw_dcache_flush_range((unsigned long)addr, size);
+        rt_hw_cpu_dcache_clean(addr, size);
     }
     else if (ops == RT_HW_CACHE_INVALIDATE)
     {
-        rt_hw_dcache_invalidate_range((unsigned long)addr, size);
+        rt_hw_cpu_dcache_invalidate(addr, size);
+    }
+}
+
+rt_base_t rt_hw_cpu_icache_status(void)
+{
+    return 0;
+}
+
+rt_base_t rt_hw_cpu_dcache_status(void)
+{
+    return 0;
+}
+
+#ifdef RT_USING_LWP
+#define ICACHE (1<<0)
+#define DCACHE (1<<1)
+#define BCACHE (ICACHE|DCACHE)
+
+int sys_cacheflush(void *addr, int size, int cache)
+{
+    if ((size_t)addr < KERNEL_VADDR_START && (size_t)addr + size <= KERNEL_VADDR_START)
+    {
+        if ((cache & DCACHE) != 0)
+        {
+            rt_hw_cpu_dcache_clean_and_invalidate(addr, size);
+        }
+        if ((cache & ICACHE) != 0)
+        {
+            rt_hw_cpu_icache_invalidate(addr, size);
+        }
+        return 0;
     }
+    return -1;
 }
+#endif

+ 307 - 182
libcpu/aarch64/common/context_gcc.S

@@ -1,24 +1,44 @@
 /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
- * 2018-10-06     ZhaoXiaowei  the first version
- * 2021-11-04     GuEe-GUI     set sp with SP_ELx
- * 2021-12-28     GuEe-GUI     add fpu and smp support
+ * 2021-05-18     Jesven       the first version
  */
 
 #include "rtconfig.h"
-#include "asm_fpu.h"
 
-#ifdef RT_USING_SMP
-#define rt_hw_interrupt_disable rt_hw_local_irq_disable
-#define rt_hw_interrupt_enable rt_hw_local_irq_enable
-#endif
+#include "asm-fpu.h"
+
+.text
+.weak rt_hw_cpu_id_set
+.type rt_hw_cpu_id_set, @function
+rt_hw_cpu_id_set:
+    mrs x0, mpidr_el1           /* MPIDR_EL1: Multi-Processor Affinity Register */
+    and x0, x0, #15
+    msr tpidr_el1, x0
+    ret
 
 /*
+int rt_hw_cpu_id(void)
+*/
+.global rt_hw_cpu_id
+.type rt_hw_cpu_id, @function
+rt_hw_cpu_id:
+   mrs x0, tpidr_el1           /* MPIDR_EL1: Multi-Processor Affinity Register */
+   ret
+
+/*
+void rt_hw_set_process_id(size_t id)
+*/
+.global rt_hw_set_process_id
+rt_hw_set_process_id:
+    msr CONTEXTIDR_EL1, x0
+    ret
+
+  /*
  *enable gtimer
  */
 .globl rt_hw_gtimer_enable
@@ -27,14 +47,6 @@ rt_hw_gtimer_enable:
     MSR CNTP_CTL_EL0,X0
     RET
 
-/*
- *disable gtimer
- */
-.globl rt_hw_gtimer_disable
-rt_hw_gtimer_disable:
-    MSR CNTP_CTL_EL0,XZR
-    RET
-
 /*
  *set gtimer CNTP_TVAL_EL0 value
  */
@@ -65,19 +77,6 @@ rt_hw_get_gtimer_frq:
     MRS X0,CNTFRQ_EL0
     RET
 
-/*
- *set gtimer frq value (only in EL3)
- */
-.globl rt_hw_set_gtimer_frq
-rt_hw_set_gtimer_frq:
-    MRS X1, CurrentEL
-    CMP X1, 0xc
-    BNE rt_hw_set_gtimer_frq_exit
-    MSR CNTFRQ_EL0, X0
-    MOV X0, XZR
-rt_hw_set_gtimer_frq_exit:
-    RET
-
 .macro SAVE_CONTEXT
     /* Save the entire context. */
     SAVE_FPU SP
@@ -99,39 +98,18 @@ rt_hw_set_gtimer_frq_exit:
     MRS     X28, FPCR
     MRS     X29, FPSR
     STP     X28, X29, [SP, #-0x10]!
-    STP     X30, XZR, [SP, #-0x10]!
-
-    MRS     X0, CurrentEL
-    CMP     X0, 0xc
-    B.EQ    3f
-    CMP     X0, 0x8
-    B.EQ    2f
-    CMP     X0, 0x4
-    B.EQ    1f
-    B       .
-3:
-    MRS     X3, SPSR_EL3
-    /* Save the ELR. */
-    MRS     X2, ELR_EL3
-    B       0f
-2:
-    MRS     X3, SPSR_EL2
-    /* Save the ELR. */
-    MRS     X2, ELR_EL2
-    B       0f
-1:
+    MRS     X29, SP_EL0
+    STP     X29, X30, [SP, #-0x10]!
+
     MRS     X3, SPSR_EL1
     MRS     X2, ELR_EL1
-    B       0f
-0:
 
     STP     X2, X3, [SP, #-0x10]!
 
     MOV     X0, SP   /* Move SP into X0 for saving. */
+.endm
 
-    .endm
-
-.macro SAVE_CONTEXT_T
+.macro SAVE_CONTEXT_FROM_EL1
     /* Save the entire context. */
     SAVE_FPU SP
     STP     X0, X1, [SP, #-0x10]!
@@ -152,66 +130,28 @@ rt_hw_set_gtimer_frq_exit:
     MRS     X28, FPCR
     MRS     X29, FPSR
     STP     X28, X29, [SP, #-0x10]!
-    STP     X30, XZR, [SP, #-0x10]!
-
-    MRS     X0, CurrentEL
-    CMP     X0, 0xc
-    B.EQ    3f
-    CMP     X0, 0x8
-    B.EQ    2f
-    CMP     X0, 0x4
-    B.EQ    1f
-    B       .
-3:
-    MOV     X3, #((3 << 6) | 0x0d)  /* EL3h */
-    MOV     X2, X30
-    B       0f
-2:
-    MOV     X3, #((3 << 6) | 0x09)  /* EL2h */
-    MOV     X2, X30
-    B       0f
-1:
-    MOV     X3, #((3 << 6) | 0x05)  /* EL1h */
-    MOV     X2, X30
-    B       0f
-0:
-
-    STP     X2, X3, [SP, #-0x10]!
+    MRS     X29, SP_EL0
+    STP     X29, X30, [SP, #-0x10]!
 
-    MOV     X0, SP   /* Move SP into X0 for saving. */
+    MOV     X19, #((3 << 6) | 0x4 | 0x1)  /* el1h, disable interrupt */
+    MOV     X18, X30
 
-    .endm
+    STP     X18, X19, [SP, #-0x10]!
+.endm
 
+#ifdef RT_USING_SMP
 .macro RESTORE_CONTEXT
-
     /* Set the SP to point to the stack of the task being restored. */
     MOV     SP, X0
 
     LDP     X2, X3, [SP], #0x10  /* SPSR and ELR. */
 
-    MRS     X0, CurrentEL
-    CMP     X0, 0xc
-    B.EQ    3f
-    CMP     X0, 0x8
-    B.EQ    2f
-    CMP     X0, 0x4
-    B.EQ    1f
-    B       .
-3:
-    MSR     SPSR_EL3, X3
-    MSR     ELR_EL3, X2
-    B       0f
-2:
-    MSR     SPSR_EL2, X3
-    MSR     ELR_EL2, X2
-    B       0f
-1:
+    TST     X3, #0x1f
     MSR     SPSR_EL1, X3
     MSR     ELR_EL1, X2
-    B       0f
-0:
 
-    LDP     X30, XZR, [SP], #0x10
+    LDP     X29, X30, [SP], #0x10
+    MSR     SP_EL0, X29
     LDP     X28, X29, [SP], #0x10
     MSR     FPCR, X28
     MSR     FPSR, X29
@@ -231,10 +171,95 @@ rt_hw_set_gtimer_frq_exit:
     LDP     X2, X3, [SP], #0x10
     LDP     X0, X1, [SP], #0x10
     RESTORE_FPU SP
+#ifdef RT_USING_LWP
+    BEQ     arch_ret_to_user
+#endif
+    ERET
+.endm
+#else
+.macro RESTORE_CONTEXT
+    /* Set the SP to point to the stack of the task being restored. */
+    MOV     SP, X0
+#ifdef RT_USING_LWP
+    BL      rt_thread_self
+    MOV     X19, X0
+    BL      lwp_mmu_switch
+    MOV     X0, X19
+    BL      lwp_user_setting_restore
+#endif
+    LDP     X2, X3, [SP], #0x10  /* SPSR and ELR. */
+
+    TST     X3, #0x1f
+    MSR     SPSR_EL1, X3
+    MSR     ELR_EL1, X2
 
+    LDP     X29, X30, [SP], #0x10
+    MSR     SP_EL0, X29
+    LDP     X28, X29, [SP], #0x10
+    MSR     FPCR, X28
+    MSR     FPSR, X29
+    LDP     X28, X29, [SP], #0x10
+    LDP     X26, X27, [SP], #0x10
+    LDP     X24, X25, [SP], #0x10
+    LDP     X22, X23, [SP], #0x10
+    LDP     X20, X21, [SP], #0x10
+    LDP     X18, X19, [SP], #0x10
+    LDP     X16, X17, [SP], #0x10
+    LDP     X14, X15, [SP], #0x10
+    LDP     X12, X13, [SP], #0x10
+    LDP     X10, X11, [SP], #0x10
+    LDP     X8, X9, [SP], #0x10
+    LDP     X6, X7, [SP], #0x10
+    LDP     X4, X5, [SP], #0x10
+    LDP     X2, X3, [SP], #0x10
+    LDP     X0, X1, [SP], #0x10
+    RESTORE_FPU SP
+#ifdef RT_USING_LWP
+    BEQ     arch_ret_to_user
+#endif
     ERET
+.endm
+#endif
+
+.macro RESTORE_CONTEXT_WITHOUT_MMU_SWITCH
+    /* the SP is already ok */
+    LDP     X2, X3, [SP], #0x10  /* SPSR and ELR. */
 
-    .endm
+    TST     X3, #0x1f
+    MSR     SPSR_EL1, X3
+    MSR     ELR_EL1, X2
+
+    LDP     X29, X30, [SP], #0x10
+    MSR     SP_EL0, X29
+    LDP     X28, X29, [SP], #0x10
+    MSR     FPCR, X28
+    MSR     FPSR, X29
+    LDP     X28, X29, [SP], #0x10
+    LDP     X26, X27, [SP], #0x10
+    LDP     X24, X25, [SP], #0x10
+    LDP     X22, X23, [SP], #0x10
+    LDP     X20, X21, [SP], #0x10
+    LDP     X18, X19, [SP], #0x10
+    LDP     X16, X17, [SP], #0x10
+    LDP     X14, X15, [SP], #0x10
+    LDP     X12, X13, [SP], #0x10
+    LDP     X10, X11, [SP], #0x10
+    LDP     X8, X9, [SP], #0x10
+    LDP     X6, X7, [SP], #0x10
+    LDP     X4, X5, [SP], #0x10
+    LDP     X2, X3, [SP], #0x10
+    LDP     X0, X1, [SP], #0x10
+    RESTORE_FPU SP
+#ifdef RT_USING_LWP
+    BEQ     arch_ret_to_user
+#endif
+    ERET
+.endm
+
+#ifdef RT_USING_SMP
+#define rt_hw_interrupt_disable rt_hw_local_irq_disable
+#define rt_hw_interrupt_enable rt_hw_local_irq_enable
+#endif
 
 .text
 /*
@@ -242,9 +267,9 @@ rt_hw_set_gtimer_frq_exit:
  */
 .globl rt_hw_interrupt_disable
 rt_hw_interrupt_disable:
-    MRS      X0, DAIF
-    MSR      DAIFSet, #3
-    DSB      SY
+    MRS     X0, DAIF
+    MSR     DAIFSet, #3
+    DSB     SY
     RET
 
 /*
@@ -253,99 +278,166 @@ rt_hw_interrupt_disable:
 .globl rt_hw_interrupt_enable
 rt_hw_interrupt_enable:
     DSB     SY
-    MOV     X1, #0xC0
-    ANDS    X0, X0, X1
-    B.NE    rt_hw_interrupt_enable_exit
-    MSR     DAIFClr, #3
-rt_hw_interrupt_enable_exit:
+    AND     X0, X0, #0xc0
+    MRS     X1, DAIF
+    BIC     X1, X1, #0xc0
+    ORR     X0, X0, X1
+    MSR     DAIF, X0
     RET
 
+.text
+
+#ifdef RT_USING_SMP
+
 /*
- * #ifdef RT_USING_SMP
- * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread);
- * #else
- * void rt_hw_context_switch_to(rt_ubase_t to);
- * #endif
- * X0 --> to
+ * void rt_hw_context_switch_to(rt_uint3 to, struct rt_thread *to_thread);
+ * X0 --> to (thread stack)
  * X1 --> to_thread
  */
+
 .globl rt_hw_context_switch_to
 rt_hw_context_switch_to:
-#ifdef RT_USING_SMP
-    STR     X0, [SP, #-0x8]!
+    LDR     X0, [X0]
+    MOV     SP, X0
     MOV     X0, X1
     BL      rt_cpus_lock_status_restore
-    LDR     X0, [SP], #0x8
-#endif /*RT_USING_SMP*/
-    LDR     X0, [X0]
-    RESTORE_CONTEXT
+#ifdef RT_USING_LWP
+    BL      rt_thread_self
+    BL      lwp_user_setting_restore
+#endif
+    B       rt_hw_context_switch_exit
 
-.text
 /*
- * #ifdef RT_USING_SMP
- * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
- * #else
- * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
- * #endif
- * X0 --> from
- * X1 --> to
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32
+to, struct rt_thread *to_thread);
+ * X0 --> from (from_thread stack)
+ * X1 --> to (to_thread stack)
  * X2 --> to_thread
  */
 .globl rt_hw_context_switch
 rt_hw_context_switch:
-#ifdef RT_USING_SMP
+    SAVE_CONTEXT_FROM_EL1
+    MOV    X3, SP
+    STR    X3, [X0]            // store sp in preempted tasks TCB
+    LDR    X0, [X1]            // get new task stack pointer
+    MOV    SP, X0
+    MOV    X0, X2
+    BL     rt_cpus_lock_status_restore
+#ifdef RT_USING_LWP
+    BL     rt_thread_self
+    BL     lwp_user_setting_restore
+#endif
+    B      rt_hw_context_switch_exit
+
+/*
+ * void rt_hw_context_switch_interrupt(context, from sp, to sp, tp tcb)
+ * X0 :interrupt context
+ * X1 :addr of from_thread's sp
+ * X2 :addr of to_thread's sp
+ * X3 :to_thread's tcb
+ */
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
     STP     X0, X1, [SP, #-0x10]!
-    STR     X30, [SP, #-0x8]!
-    MOV     X0, X2
+    STP     X2, X3, [SP, #-0x10]!
+    STP     X29, X30, [SP, #-0x10]!
+#ifdef RT_USING_LWP
+    BL      rt_thread_self
+    BL      lwp_user_setting_save
+#endif
+    LDP     X29, X30, [SP], #0x10
+    LDP     X2, X3, [SP], #0x10
+    LDP     X0, X1, [SP], #0x10
+    STR     X0, [X1]
+    LDR     X0, [X2]
+    MOV     SP, X0
+    MOV     X0, X3
+    MOV     X19, X0
     BL      rt_cpus_lock_status_restore
-    LDR     X30, [SP], #0x8
+    MOV     X0, X19
+#ifdef RT_USING_LWP
+    BL      lwp_user_setting_restore
+#endif
+    B       rt_hw_context_switch_exit
+
+.globl vector_fiq
+vector_fiq:
+    B       .
+
+.globl vector_irq
+vector_irq:
+    CLREX
+    SAVE_CONTEXT
+    STP     X0, X1, [SP, #-0x10]!   /* X0 is thread sp */
+
+    BL      rt_interrupt_enter
+    BL      rt_hw_trap_irq
+    BL      rt_interrupt_leave
+
     LDP     X0, X1, [SP], #0x10
-#endif /*RT_USING_SMP*/
+    BL      rt_scheduler_do_irq_switch
+    B       rt_hw_context_switch_exit
 
-    MOV     X8,X0
-    MOV     X9,X1
+.global rt_hw_context_switch_exit
+rt_hw_context_switch_exit:
+    MOV     X0, SP
+    RESTORE_CONTEXT
 
-    SAVE_CONTEXT_T
+#else
 
-    STR     X0, [X8]            // store sp in preempted tasks TCB
-    LDR     X0, [X9]            // get new task stack pointer
+/*
+ * void rt_hw_context_switch_to(rt_ubase_t to);
+ * X0 --> to sp
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+    LDR     X0, [X0]
+    RESTORE_CONTEXT
+
+/*
+ * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
+ * X0 --> from sp
+ * X1 --> to sp
+ * X2 --> to thread
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+
+    SAVE_CONTEXT_FROM_EL1
+
+    MOV    X2, SP
+    STR    X2, [X0]            // store sp in preempted tasks TCB
+    LDR    X0, [X1]            // get new task stack pointer
 
     RESTORE_CONTEXT
 
 /*
- * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to);
+ * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread);
  */
 .globl rt_thread_switch_interrupt_flag
 .globl rt_interrupt_from_thread
 .globl rt_interrupt_to_thread
 .globl rt_hw_context_switch_interrupt
 rt_hw_context_switch_interrupt:
-#ifdef RT_USING_SMP
-    /* x0 = context */
-    /* x1 = &current_thread->sp */
-    /* x2 = &to_thread->sp, */
-    /* x3 = to_thread TCB */
-    STR     X0, [X1]
-    LDR     X0, [x2]
-    MOV     SP, X0
-    MOV     X0, X3
-    BL      rt_cpus_lock_status_restore
-    MOV     X0, SP
-    RESTORE_CONTEXT
-#else
-    LDR     X2, =rt_thread_switch_interrupt_flag
-    LDR     X3, [X2]
-    CMP     X3, #1
-    B.EQ    _reswitch
-    LDR     X4, =rt_interrupt_from_thread  // set rt_interrupt_from_thread
-    MOV     X3, #1              // set rt_thread_switch_interrupt_flag to 1
+    LDR     X6, =rt_thread_switch_interrupt_flag
+    LDR     X7, [X6]
+    CMP     X7, #1
+    B.EQ     _reswitch
+    LDR     X4, =rt_interrupt_from_thread   // set rt_interrupt_from_thread
     STR     X0, [X4]
-    STR     X3, [X2]
+    MOV     X7, #1              // set rt_thread_switch_interrupt_flag to 1
+    STR     X7, [X6]
+    STP     X1, X30, [SP, #-0x10]!
+#ifdef RT_USING_LWP
+    MOV     X0, X2
+    BL      lwp_user_setting_save
+#endif
+    LDP     X1, X30, [SP], #0x10
 _reswitch:
-    LDR     X2, =rt_interrupt_to_thread    // set rt_interrupt_to_thread
-    STR     X1, [X2]
+    LDR     X6, =rt_interrupt_to_thread     // set rt_interrupt_to_thread
+    STR     X1, [X6]
     RET
-#endif
+
 .text
 
 // -- Exception handlers ----------------------------------
@@ -372,45 +464,78 @@ vector_fiq:
 .globl vector_irq
 vector_irq:
     SAVE_CONTEXT
-    STP     X0, X1, [SP, #-0x10]!
+    STP     X0, X1, [SP, #-0x10]!   /* X0 is thread sp */
 
     BL      rt_interrupt_enter
     BL      rt_hw_trap_irq
     BL      rt_interrupt_leave
 
     LDP     X0, X1, [SP], #0x10
-#ifdef RT_USING_SMP
-    /* Never reture If can switch */
-    BL      rt_scheduler_do_irq_switch
-    MOV     X0, SP
-#endif
 
     // if rt_thread_switch_interrupt_flag set, jump to
     // rt_hw_context_switch_interrupt_do and don't return
     LDR     X1, =rt_thread_switch_interrupt_flag
     LDR     X2, [X1]
     CMP     X2, #1
-    B.NE     vector_irq_exit
+    B.NE    vector_irq_exit
 
     MOV     X2,  #0         // clear flag
     STR     X2,  [X1]
 
-    LDR     X3, =rt_interrupt_from_thread
+    LDR     X3,  =rt_interrupt_from_thread
     LDR     X4,  [X3]
     STR     x0,  [X4]       // store sp in preempted tasks's TCB
 
-    LDR     x3, =rt_interrupt_to_thread
+    LDR     x3,  =rt_interrupt_to_thread
     LDR     X4,  [X3]
     LDR     x0,  [X4]       // get new task's stack pointer
 
-vector_irq_exit:
     RESTORE_CONTEXT
 
+vector_irq_exit:
+    MOV     SP, X0
+    RESTORE_CONTEXT_WITHOUT_MMU_SWITCH
+#endif
+
 // -------------------------------------------------
 
-    .align  8
-    .globl  vector_error
-vector_error:
+    .globl  vector_exception
+vector_exception:
     SAVE_CONTEXT
-    BL      rt_hw_trap_error
-    B       .
+    STP     X0, X1, [SP, #-0x10]!
+    BL      rt_hw_trap_exception
+    LDP     X0, X1, [SP], #0x10
+    MOV     SP, X0
+    RESTORE_CONTEXT_WITHOUT_MMU_SWITCH
+
+    .globl  vector_serror
+vector_serror:
+    SAVE_CONTEXT
+    STP     X0, X1, [SP, #-0x10]!
+    BL      rt_hw_trap_serror
+    b .
+
+.global rt_hw_mmu_switch
+rt_hw_mmu_switch:
+    MSR TTBR0_EL1, X0
+    MRS X1, TCR_EL1
+    CMP X0, XZR
+    ORR X1, X1, #(1 << 7)
+    BEQ 1f
+    BIC X1, X1, #(1 << 7)
+1:
+    MSR TCR_EL1, X1
+    DSB SY
+    ISB
+    TLBI VMALLE1
+    DSB SY
+    ISB
+    IC IALLUIS
+    DSB SY
+    ISB
+    RET
+
+.global rt_hw_mmu_tbl_get
+rt_hw_mmu_tbl_get:
+    MRS X0, TTBR0_EL1
+    RET

+ 65 - 0
libcpu/aarch64/common/cp15.h

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-09-15     Bernard      first version
+ */
+
+#ifndef __CP15_H__
+#define __CP15_H__
+
+#ifndef   __STATIC_FORCEINLINE
+#define __STATIC_FORCEINLINE     __attribute__((always_inline)) static inline
+#endif
+
+#define __WFI()    __asm__ volatile ("wfi":::"memory")
+
+#define __WFE()    __asm__ volatile ("wfe":::"memory")
+
+#define __SEV()    __asm__ volatile ("sev")
+
+__STATIC_FORCEINLINE  void __ISB(void)
+{
+    __asm__ volatile ("isb 0xF":::"memory");
+}
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+__STATIC_FORCEINLINE  void __DSB(void)
+{
+    __asm__ volatile ("dsb 0xF":::"memory");
+}
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+
+__STATIC_FORCEINLINE  void __DMB(void)
+{
+    __asm__ volatile ("dmb 0xF":::"memory");
+}
+
+unsigned long rt_cpu_get_smp_id(void);
+
+void rt_cpu_mmu_disable(void);
+void rt_cpu_mmu_enable(void);
+void rt_cpu_tlb_set(volatile unsigned long*);
+
+void rt_cpu_dcache_clean_flush(void);
+void rt_cpu_icache_flush(void);
+
+void rt_cpu_vector_set_base(rt_ubase_t addr);
+void rt_hw_mmu_init(void);
+void rt_hw_vector_init(void);
+
+void set_timer_counter(unsigned int counter);
+void set_timer_control(unsigned int control);
+#endif

+ 292 - 34
libcpu/aarch64/common/cpu.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2019, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -7,15 +7,43 @@
  * Date           Author       Notes
  * 2011-09-15     Bernard      first version
  * 2019-07-28     zdzn         add smp support
- * 2021-12-21     GuEe-GUI     set tpidr_el1 as multiprocessor id instead of mpidr_el1
- * 2021-12-28     GuEe-GUI     add spinlock for aarch64
  */
 
 #include <rthw.h>
 #include <rtthread.h>
-#include <cpuport.h>
+#include <board.h>
+#include "cp15.h"
+
+#define DBG_TAG "libcpu.aarch64.cpu"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+#include <string.h>
+#include "cpu.h"
+#include "psci_api.h"
+
+void (*system_off)(void);
 
 #ifdef RT_USING_SMP
+
+#ifdef RT_USING_FDT
+#include "dtb_node.h"
+struct dtb_node *_cpu_node[RT_CPUS_NR];
+#endif /* RT_USING_FDT */
+
+#define MPIDR_AFF_MASK 0x000000FF00FFFFFFul
+#define REPORT_ERR(retval) LOG_E("got error code %d in %s(), %s:%d", (retval), __func__, __FILE__, __LINE__)
+#define CHECK_RETVAL(retval) if (retval) {REPORT_ERR(retval);}
+
+/**
+ * cpu_ops_tbl contains cpu_ops_t for each cpu kernel observed,
+ * given cpu logical id 'i', its cpu_ops_t is 'cpu_ops_tbl[i]'
+ */
+struct cpu_ops_t *cpu_ops_tbl[RT_CPUS_NR];
+
+#ifdef RT_USING_SMART
+// _id_to_mpidr is a table translate logical id to mpid, which is a 64-bit value
+rt_uint64_t rt_cpu_mpidr_early[RT_CPUS_NR] rt_weak = {[0 ... RT_CPUS_NR - 1] = ID_ERROR};
+#else
 /* The more common mpidr_el1 table, redefine it in BSP if it is in other cases */
 rt_weak rt_uint64_t rt_cpu_mpidr_early[] =
 {
@@ -29,65 +57,290 @@ rt_weak rt_uint64_t rt_cpu_mpidr_early[] =
     [7] = 0x80000007,
     [RT_CPUS_NR] = 0
 };
-#endif
-
-int rt_hw_cpu_id(void)
-{
-    rt_base_t value;
-
-    __asm__ volatile ("mrs %0, tpidr_el1":"=r"(value));
-
-    return value;
-}
+#endif /* RT_USING_SMART */
 
-#ifdef RT_USING_SMP
 void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
 {
     lock->slock = 0;
 }
 
+#define TICKET_SHIFT 16
 void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
 {
-    rt_hw_spinlock_t lock_val, new_lockval;
     unsigned int tmp;
+    struct __arch_tickets lockval, newval;
 
-    __asm__ volatile (
-        /* Increment the next ticket. */
+    asm volatile(
+        /* Atomically increment the next ticket. */
         "   prfm    pstl1strm, %3\n"
         "1: ldaxr   %w0, %3\n"
         "   add %w1, %w0, %w5\n"
         "   stxr    %w2, %w1, %3\n"
         "   cbnz    %w2, 1b\n"
-        /* Check wether we get the lock */
-        "   eor     %w1, %w0, %w0, ror #16\n"
-        "   cbz     %w1, 3f\n"
+        /* Did we get the lock? */
+        "   eor %w1, %w0, %w0, ror #16\n"
+        "   cbz %w1, 3f\n"
         /*
-         * Didn't get lock and spin on the owner.
-         * Should send a local event to avoid missing an
+         * No: spin on the owner. Send a local event to avoid missing an
          * unlock before the exclusive load.
          */
         "   sevl\n"
         "2: wfe\n"
         "   ldaxrh  %w2, %4\n"
-        "   eor     %w1, %w2, %w0, lsr #16\n"
+        "   eor %w1, %w2, %w0, lsr #16\n"
         "   cbnz    %w1, 2b\n"
-        /* got the lock. */
+        /* We got the lock. Critical section starts here. */
         "3:"
-        : "=&r" (lock_val), "=&r" (new_lockval), "=&r" (tmp), "+Q" (*lock)
-        : "Q" (lock->tickets.owner), "I" (1 << 16)
+        : "=&r"(lockval), "=&r"(newval), "=&r"(tmp), "+Q"(*lock)
+        : "Q"(lock->tickets.owner), "I"(1 << TICKET_SHIFT)
         : "memory");
-    __DMB();
+    rt_hw_dmb();
 }
 
 void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
 {
-    __DMB();
-    __asm__ volatile (
-        "stlrh   %w1, %0\n"
-        : "=Q" (lock->tickets.owner)
-        : "r" (lock->tickets.owner + 1)
+    rt_hw_dmb();
+    asm volatile(
+        "   stlrh   %w1, %0\n"
+        : "=Q"(lock->tickets.owner)
+        : "r"(lock->tickets.owner + 1)
         : "memory");
 }
+
+static int _cpus_init_data_hardcoded(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[])
+{
+    // load in cpu_hw_ids in cpuid_to_hwid,
+    // cpu_ops to cpu_ops_tbl
+    if (num_cpus > RT_CPUS_NR)
+    {
+        LOG_W("num_cpus (%d) greater than RT_CPUS_NR (%d)\n", num_cpus, RT_CPUS_NR);
+        num_cpus = RT_CPUS_NR;
+    }
+
+    for (int i = 0; i < num_cpus; i++)
+    {
+        set_hwid(i, cpu_hw_ids[i]);
+        cpu_ops_tbl[i] = cpu_ops[i];
+    }
+    return 0;
+}
+
+#ifdef RT_USING_FDT
+
+/** read ('size' * 4) bytes number from start, big-endian format */
+static rt_uint64_t _read_be_number(void *start, int size)
+{
+    rt_uint64_t buf = 0;
+    for (; size > 0; size--)
+        buf = (buf << 32) | fdt32_to_cpu(*(uint32_t *)start++);
+    return buf;
+}
+
+/** check device-type of the node, */
+static bool _node_is_cpu(struct dtb_node *node)
+{
+    char *device_type = dtb_node_get_dtb_node_property_value(node, "device_type", NULL);
+    if (device_type)
+    {
+        return !strcmp(device_type, "cpu");
+    }
+    return false;
+}
+
+static int _read_and_set_hwid(struct dtb_node *cpu, int *id_pool, int *pcpuid)
+{
+    // size/address_cells is number of elements in reg array
+    int size;
+    static int address_cells, size_cells;
+    if (!address_cells && !size_cells)
+        dtb_node_get_dtb_node_cells(cpu, &address_cells, &size_cells);
+
+    void *id_start = dtb_node_get_dtb_node_property_value(cpu, "reg", &size);
+    rt_uint64_t mpid = _read_be_number(id_start, address_cells);
+
+    *pcpuid = *id_pool;
+    *id_pool = *id_pool + 1;
+    set_hwid(*pcpuid, mpid);
+
+    LOG_I("Using MPID 0x%lx as cpu %d", mpid, *pcpuid);
+
+    // setting _cpu_node for cpu_init use
+    _cpu_node[*pcpuid] = cpu;
+
+    return 0;
+}
+
+static int _read_and_set_cpuops(struct dtb_node *cpu, int cpuid)
+{
+    char *method = dtb_node_get_dtb_node_property_value(cpu, "enable-method", NULL);
+    if (!method)
+    {
+        LOG_E("Cannot read method from cpu node");
+        return -1;
+    }
+
+    struct cpu_ops_t *cpu_ops;
+    if (!strcmp(method, cpu_ops_psci.method))
+    {
+        cpu_ops = &cpu_ops_psci;
+    }
+    else if (!strcmp(method, cpu_ops_spin_tbl.method))
+    {
+        cpu_ops = &cpu_ops_spin_tbl;
+    }
+    else
+    {
+        cpu_ops = RT_NULL;
+        LOG_E("Not supported cpu_ops: %s", method);
+    }
+    cpu_ops_tbl[cpuid] = cpu_ops;
+
+    LOG_D("Using boot method [%s] for cpu %d", cpu_ops->method, cpuid);
+    return 0;
+}
+
+static int _cpus_init_data_fdt()
+{
+    // cpuid_to_hwid and cpu_ops_tbl with fdt
+    void *root = get_dtb_node_head();
+    int id_pool = 0;
+    int cpuid;
+    struct dtb_node *cpus = dtb_node_get_dtb_node_by_path(root, "/cpus");
+
+    // for each cpu node (device-type is cpu), read its mpid and set its cpuid_to_hwid
+    for_each_node_child(cpus)
+    {
+        if (!_node_is_cpu(cpus))
+        {
+            continue;
+        }
+
+        if (id_pool > RT_CPUS_NR)
+        {
+            LOG_W("Reading more cpus from FDT than RT_CPUS_NR"
+                "\n  Parsing will not continue and only %d cpus will be used.", RT_CPUS_NR);
+            break;
+        }
+
+        _read_and_set_hwid(cpus, &id_pool, &cpuid);
+
+        _read_and_set_cpuops(cpus, cpuid);
+    }
+    return 0;
+}
+
+#endif /* RT_USING_FDT */
+
+/** init cpu with hardcoded infomation or parsing from FDT */
+static int _cpus_init(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[])
+{
+    int retval;
+
+    // first setup cpu_ops_tbl and cpuid_to_hwid
+    if (num_cpus > 0)
+        retval = _cpus_init_data_hardcoded(num_cpus, cpu_hw_ids, cpu_ops);
+    else
+    {
+        retval = -1;
+#ifdef RT_USING_FDT
+        retval = _cpus_init_data_fdt();
+#endif
+    }
+
+    if (retval)
+        return retval;
+
+    // using cpuid_to_hwid and cpu_ops_tbl to call method_init and cpu_init
+    // assuming that cpuid 0 has already init
+    for (int i = 1; i < RT_CPUS_NR; i++)
+    {
+        if (cpuid_to_hwid(i) == ID_ERROR)
+        {
+            LOG_E("Failed to find hardware id of CPU %d", i);
+            continue;
+        }
+
+        if (cpu_ops_tbl[i] && cpu_ops_tbl[i]->cpu_init)
+        {
+            retval = cpu_ops_tbl[i]->cpu_init(i);
+            CHECK_RETVAL(retval);
+        }
+        else
+        {
+            LOG_E("Failed to find cpu_init for cpu %d with cpu_ops[%p], cpu_ops->cpu_init[%p]"
+                , cpuid_to_hwid(i), cpu_ops_tbl[i], cpu_ops_tbl[i] ? cpu_ops_tbl[i]->cpu_init : NULL);
+        }
+    }
+    return 0;
+}
+
+static void _boot_secondary(void)
+{
+    for (int i = 1; i < RT_CPUS_NR; i++)
+    {
+        int retval = -0xbad0; // mark no support operation
+        if (cpu_ops_tbl[i] && cpu_ops_tbl[i]->cpu_boot)
+            retval = cpu_ops_tbl[i]->cpu_boot(i);
+        if (retval)
+        {
+            if (retval == -0xbad0)
+                LOG_E("No cpu_ops was probed for CPU %d. Try to configure it or use fdt", i);
+            else
+                LOG_E("Failed to boot secondary CPU %d, error code %d", i, retval);
+        } else {
+            LOG_I("Secondary CPU %d booted", i);
+        }
+    }
+}
+
+rt_weak void rt_hw_secondary_cpu_up(void)
+{
+    _boot_secondary();
+}
+
+/**
+ * @brief boot cpu with hardcoded data
+ *
+ * @param num_cpus number of cpus
+ * @param cpu_hw_ids each element represents a hwid of cpu[i]
+ * @param cpu_ops each element represents a pointer to cpu_ops of cpu[i]
+ * @return int 0 on success,
+ */
+int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[])
+{
+    int retval = 0;
+    if (num_cpus < 1 || !cpu_hw_ids || !cpu_ops)
+        return -1;
+
+    retval = _cpus_init(num_cpus, cpu_hw_ids, cpu_ops);
+    CHECK_RETVAL(retval);
+
+    return retval;
+}
+
+#define CPU_INIT_USING_FDT 0,0,0
+
+/**
+ * @brief Initialize cpu infomation from fdt
+ *
+ * @return int
+ */
+int rt_hw_cpu_init()
+{
+#ifdef RT_USING_FDT
+    return _cpus_init(CPU_INIT_USING_FDT);
+#else
+    LOG_E("CPU init failed since RT_USING_FDT was not defined");
+    return -0xa; /* no fdt support */
+#endif /* RT_USING_FDT */
+}
+
+rt_weak void rt_hw_secondary_cpu_idle_exec(void)
+{
+    asm volatile("wfe" ::
+                     : "memory", "cc");
+}
+
 #endif /*RT_USING_SMP*/
 
 /**
@@ -98,14 +351,19 @@ void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
 /** shutdown CPU */
 rt_weak void rt_hw_cpu_shutdown()
 {
-    register rt_int32_t level;
+    rt_uint32_t level;
     rt_kprintf("shutdown...\n");
 
+    if (system_off)
+        system_off();
+    LOG_E("system shutdown failed");
+
     level = rt_hw_interrupt_disable();
     while (level)
     {
         RT_ASSERT(0);
     }
 }
+MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_shutdown, shutdown, shutdown machine);
 
 /*@}*/

+ 63 - 0
libcpu/aarch64/common/cpu.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#ifndef __RT_HW_CPU_H__
+#define __RT_HW_CPU_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <stdbool.h>
+
+#ifndef RT_CPUS_NR
+#define RT_CPUS_NR 1
+#endif /* RT_CPUS_NR */
+
+#ifdef RT_USING_SMP
+struct cpu_ops_t
+{
+    const char *method;
+    int     (*cpu_init)(rt_uint32_t id);
+    int     (*cpu_boot)(rt_uint32_t id);
+    void    (*cpu_shutdown)(void);
+};
+
+/**
+ * Identifier to mark a wrong CPU MPID.
+ * All elements in rt_cpu_mpidr_early[] should be initialized with this value
+ */
+#define ID_ERROR __INT64_MAX__
+
+extern rt_uint64_t rt_cpu_mpidr_early[];
+extern struct dtb_node *_cpu_node[];
+
+#define cpuid_to_hwid(cpuid) \
+    ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? rt_cpu_mpidr_early[cpuid] : ID_ERROR)
+#define set_hwid(cpuid, hwid) \
+    ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? (rt_cpu_mpidr_early[cpuid] = (hwid)) : ID_ERROR)
+#define get_cpu_node(cpuid) \
+    ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? _cpu_node[cpuid] : NULL)
+#define set_cpu_node(cpuid, node) \
+    ((((cpuid) >= 0) && ((cpuid) < RT_CPUS_NR)) ? (_cpu_node[cpuid] = node) : NULL)
+
+extern int rt_hw_cpu_init();
+
+extern int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_ops_t *cpu_ops[]);
+
+extern void rt_hw_secondary_cpu_idle_exec(void);
+
+extern struct cpu_ops_t cpu_ops_psci;
+
+extern struct cpu_ops_t cpu_ops_spin_tbl;
+
+#endif /* RT_USING_SMP */
+
+extern void rt_hw_cpu_shutdown(void);
+
+extern void (*system_off)(void);
+
+#endif /* __RT_HW_CPU_H__ */

+ 73 - 52
libcpu/aarch64/common/cpu_gcc.S

@@ -1,82 +1,103 @@
 /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Date           Author       Notes
  * 2018-10-06     ZhaoXiaowei    the first version
  */
-
+ 
 .text
 .globl rt_hw_get_current_el
 rt_hw_get_current_el:
-    MRS     X0, CurrentEL
-    CMP     X0, 0xc
-    B.EQ    3f
-    CMP     X0, 0x8
-    B.EQ    2f
-    CMP     X0, 0x4
-    B.EQ    1f
-
-    LDR     X0, =0
-    B       0f
+	MRS		X0, CurrentEL
+	CMP		X0, 0xc
+	B.EQ	3f
+	CMP		X0, 0x8
+	B.EQ	2f
+	CMP		X0, 0x4
+	B.EQ	1f
+	
+	LDR		X0, =0
+	B		0f
 3:
-    LDR     X0, =3
-    B       0f
+	LDR		X0, =3
+	B		0f
 2:
-    LDR     X0, =2
-    B       0f
+	LDR		X0, =2
+	B		0f
 1:
-    LDR     X0, =1
-    B       0f
+	LDR		X0, =1
+	B		0f
 0:
-    RET
+	RET
 
 
 .globl rt_hw_set_current_vbar
 rt_hw_set_current_vbar:
-    MRS     X1, CurrentEL
-    CMP     X1, 0xc
-    B.EQ    3f
-    CMP     X1, 0x8
-    B.EQ    2f
-    CMP     X1, 0x4
-    B.EQ    1f
-    B       0f
+	MRS		X1, CurrentEL
+	CMP		X1, 0xc
+	B.EQ	3f
+	CMP		X1, 0x8
+	B.EQ	2f
+	CMP		X1, 0x4
+	B.EQ	1f
+	B		0f
 3:
-    MSR     VBAR_EL3,X0
-    B       0f
+	MSR		VBAR_EL3,X0
+	B		0f
 2:
-    MSR     VBAR_EL2,X0
-    B       0f
+	MSR		VBAR_EL2,X0
+	B		0f
 1:
-    MSR     VBAR_EL1,X0
-    B       0f
+	MSR		VBAR_EL1,X0
+	B		0f
 0:
-    RET
-
+	RET
 
 .globl rt_hw_set_elx_env
 rt_hw_set_elx_env:
-    MRS     X1, CurrentEL
-    CMP     X1, 0xc
-    B.EQ    3f
-    CMP     X1, 0x8
-    B.EQ    2f
-    CMP     X1, 0x4
-    B.EQ    1f
-    B       0f
+	MRS		X1, CurrentEL
+	CMP		X1, 0xc
+	B.EQ	3f
+	CMP		X1, 0x8
+	B.EQ	2f
+	CMP		X1, 0x4
+	B.EQ	1f
+	B		0f
 3:
-    MRS     X0, SCR_EL3
-    ORR     X0, X0, #0xF            /* SCR_EL3.NS|IRQ|FIQ|EA */
-    MSR     SCR_EL3, X0
-    B       0f
+	MRS		X0, SCR_EL3
+	ORR		X0, X0, #0xF			/* SCR_EL3.NS|IRQ|FIQ|EA */
+	MSR		SCR_EL3, X0
+	B		0f
 2:
-    MRS X0, HCR_EL2
-    ORR X0, X0, #0x38
-    MSR HCR_EL2, X0
-    B       0f
+	MRS	X0, HCR_EL2
+	ORR	X0, X0, #0x38
+	MSR	HCR_EL2, X0
+	B		0f
 1:
-    B       0f
+	B		0f
 0:
+	RET
+
+.global rt_cpu_vector_set_base
+rt_cpu_vector_set_base:
+	MSR		VBAR_EL1,X0
     RET
+
+
+/**
+ * unsigned long rt_hw_ffz(unsigned long x)
+ */
+.global rt_hw_ffz
+rt_hw_ffz:
+    mvn x1, x0
+    clz x0, x1
+    mov x1, #0x3f
+    sub x0, x1, x0
+    ret
+
+.global rt_hw_clz
+rt_hw_clz:
+    clz x0, x0
+    ret

+ 21 - 0
libcpu/aarch64/common/cpu_ops_common.h

@@ -0,0 +1,21 @@
+#ifndef __CPU_OPS_COMMON_H__
+#define __CPU_OPS_COMMON_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <mmu.h>
+#include "entry_point.h"
+
+static inline rt_uint64_t get_secondary_entry_pa(void)
+{
+    rt_uint64_t secondary_entry_pa = (rt_uint64_t)rt_hw_mmu_v2p(&mmu_info, _secondary_cpu_entry);
+
+    if (!secondary_entry_pa)
+    {
+        LOG_E("Failed to translate 'secondary_entry_pa' to physical address");
+        return 0;
+    }
+    return secondary_entry_pa;
+}
+
+#endif /* __CPU_OPS_COMMON_H__ */

+ 70 - 0
libcpu/aarch64/common/cpu_psci.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rthw.h>
+#include <rtthread.h>
+#include <stdint.h>
+
+#ifdef RT_USING_SMP
+
+#define DBG_TAG "libcpu.aarch64.cpu_psci"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+#include "cpu_ops_common.h"
+
+#include "cpu.h"
+#include "errno.h"
+#include "psci.h"
+#include "psci_api.h"
+
+static int (*_psci_init)(void) = psci_init;
+
+static int __call_method_init()
+{
+    int (*init)(void) = _psci_init;
+    _psci_init = RT_NULL;
+
+    return init();
+}
+
+/** return 0 on success, otherwise failed */
+#define _call_method_init() ((_psci_init) ? __call_method_init() : 0);
+
+static int cpu_psci_cpu_init(rt_uint32_t cpuid)
+{
+    // init psci only once
+    return _call_method_init();
+}
+
+static int cpu_psci_cpu_boot(rt_uint32_t cpuid)
+{
+    rt_uint64_t secondary_entry_pa = get_secondary_entry_pa();
+
+    if (!secondary_entry_pa)
+        return -1;
+
+    if (!psci_ops.cpu_on) {
+        LOG_E("Uninitialized psci operation");
+        return -1;
+    }
+    return psci_ops.cpu_on(cpuid_to_hwid(cpuid), secondary_entry_pa);
+}
+
+static void cpu_psci_cpu_shutdown()
+{
+    psci_ops.cpu_off(cpuid_to_hwid(rt_hw_cpu_id()));
+}
+
+struct cpu_ops_t cpu_ops_psci = {
+    .method = "psci",
+    .cpu_boot = cpu_psci_cpu_boot,
+    .cpu_init = cpu_psci_cpu_init,
+    .cpu_shutdown = cpu_psci_cpu_shutdown,
+};
+
+#endif /* RT_USING_SMP */

+ 80 - 0
libcpu/aarch64/common/cpu_spin_table.c

@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "cpu.h"
+
+#ifdef RT_USING_SMART
+#include <ioremap.h>
+#else
+#define rt_ioremap(x, ...) (x)
+#define rt_iounmap(x)
+#endif
+
+#define DBG_TAG "libcpu.aarch64.cpu_spin_table"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+#include "cpu_ops_common.h"
+
+#ifdef RT_USING_SMP
+#ifdef RT_USING_FDT
+#include <dtb_node.h>
+
+static rt_uint64_t cpu_release_addr[RT_CPUS_NR];
+
+static int spin_table_cpu_init(rt_uint32_t cpuid)
+{
+    struct dtb_node *cpu = get_cpu_node(cpuid);
+    if (!cpu)
+        return -1; /* uninitialized cpu node in fdt */
+
+    int size;
+    rt_uint64_t *phead = (rt_uint64_t*)dtb_node_get_dtb_node_property_value(cpu, "cpu-release-addr", &size);
+    cpu_release_addr[cpuid] = fdt64_to_cpu(*phead);
+
+    LOG_D("Using release address 0x%p for CPU %d", cpu_release_addr[cpuid], cpuid);
+    return 0;
+}
+
+static int spin_table_cpu_boot(rt_uint32_t cpuid)
+{
+    rt_uint64_t secondary_entry_pa = get_secondary_entry_pa();
+    if (!secondary_entry_pa)
+        return -1;
+
+    // map release_addr to addressable place
+    void *rel_va = (void *)cpu_release_addr[cpuid];
+
+#ifdef RT_USING_SMART
+    rel_va = rt_ioremap(rel_va, sizeof(cpu_release_addr[0]));
+#endif
+    if (!rel_va)
+    {
+        LOG_E("IO remap failing");
+        return -1;
+    }
+
+    __asm__ volatile("str %0, [%1]" ::"rZ"(secondary_entry_pa), "r"(rel_va));
+    __asm__ volatile("dsb sy");
+    __asm__ volatile("sev");
+    rt_iounmap(rel_va);
+    return 0;
+}
+#endif /* RT_USING_FDT */
+
+struct cpu_ops_t cpu_ops_spin_tbl = {
+    .method = "spin-table",
+#ifdef RT_USING_FDT
+    .cpu_init = spin_table_cpu_init,
+    .cpu_boot = spin_table_cpu_boot,
+#endif
+};
+
+#endif /* RT_USING_SMP */

+ 7 - 15
libcpu/aarch64/common/cpuport.h

@@ -5,20 +5,12 @@
  *
  * Change Logs:
  * Date           Author       Notes
- * 2021-09-10     GuEe-GUI     first version
  */
 
-#ifndef __CPUPORT_H__
-#define __CPUPORT_H__
+#ifndef  CPUPORT_H__
+#define  CPUPORT_H__
 
-#include <rtdef.h>
-
-#define __WFI() __asm__ volatile ("wfi":::"memory")
-#define __WFE() __asm__ volatile ("wfe":::"memory")
-#define __SEV() __asm__ volatile ("sev")
-#define __ISB() __asm__ volatile ("isb 0xf":::"memory")
-#define __DSB() __asm__ volatile ("dsb 0xf":::"memory")
-#define __DMB() __asm__ volatile ("dmb 0xf":::"memory")
+#include <armv8.h>
 
 #ifdef RT_USING_SMP
 typedef union {
@@ -32,17 +24,17 @@ typedef union {
 
 rt_inline void rt_hw_isb(void)
 {
-    __asm__ volatile ("isb":::"memory");
+    asm volatile ("isb":::"memory");
 }
 
 rt_inline void rt_hw_dmb(void)
 {
-    __asm__ volatile ("dmb sy":::"memory");
+    asm volatile ("dmb sy":::"memory");
 }
 
 rt_inline void rt_hw_dsb(void)
 {
-    __asm__ volatile ("dsb sy":::"memory");
+    asm volatile ("dsb sy":::"memory");
 }
 
-#endif /* __CPUPORT_H__ */
+#endif  /*CPUPORT_H__*/

+ 13 - 0
libcpu/aarch64/common/entry_point.h

@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#ifndef __ENTRY_POINT_H__
+#define __ENTRY_POINT_H__
+
+extern void _secondary_cpu_entry(void);
+#endif /* __ENTRY_POINT_H__ */

+ 232 - 0
libcpu/aarch64/common/exception.c

@@ -0,0 +1,232 @@
+#include "rtthread.h"
+
+static void data_abort(unsigned long far, unsigned long iss)
+{
+    rt_kprintf("fault addr = 0x%016lx\n", far);
+    if (iss & 0x40)
+    {
+        rt_kprintf("abort caused by write instruction\n");
+    }
+    else
+    {
+        rt_kprintf("abort caused by read instruction\n");
+    }
+    switch (iss & 0x3f)
+    {
+    case 0b000000:
+        rt_kprintf("Address size fault, zeroth level of translation or translation table base register\n");
+        break;
+
+    case 0b000001:
+        rt_kprintf("Address size fault, first level\n");
+        break;
+
+    case 0b000010:
+        rt_kprintf("Address size fault, second level\n");
+        break;
+
+    case 0b000011:
+        rt_kprintf("Address size fault, third level\n");
+        break;
+
+    case 0b000100:
+        rt_kprintf("Translation fault, zeroth level\n");
+        break;
+
+    case 0b000101:
+        rt_kprintf("Translation fault, first level\n");
+        break;
+
+    case 0b000110:
+        rt_kprintf("Translation fault, second level\n");
+        break;
+
+    case 0b000111:
+        rt_kprintf("Translation fault, third level\n");
+        break;
+
+    case 0b001001:
+        rt_kprintf("Access flag fault, first level\n");
+        break;
+
+    case 0b001010:
+        rt_kprintf("Access flag fault, second level\n");
+        break;
+
+    case 0b001011:
+        rt_kprintf("Access flag fault, third level\n");
+        break;
+
+    case 0b001101:
+        rt_kprintf("Permission fault, first level\n");
+        break;
+
+    case 0b001110:
+        rt_kprintf("Permission fault, second level\n");
+        break;
+
+    case 0b001111:
+        rt_kprintf("Permission fault, third level\n");
+        break;
+
+    case 0b010000:
+        rt_kprintf("Synchronous external abort, not on translation table walk\n");
+        break;
+
+    case 0b011000:
+        rt_kprintf("Synchronous parity or ECC error on memory access, not on translation table walk\n");
+        break;
+
+    case 0b010100:
+        rt_kprintf("Synchronous external abort on translation table walk, zeroth level\n");
+        break;
+
+    case 0b010101:
+        rt_kprintf("Synchronous external abort on translation table walk, first level\n");
+        break;
+
+    case 0b010110:
+        rt_kprintf("Synchronous external abort on translation table walk, second level\n");
+        break;
+
+    case 0b010111:
+        rt_kprintf("Synchronous external abort on translation table walk, third level\n");
+        break;
+
+    case 0b011100:
+        rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, zeroth level\n");
+        break;
+
+    case 0b011101:
+        rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, first level\n");
+        break;
+
+    case 0b011110:
+        rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, second level\n");
+        break;
+
+    case 0b011111:
+        rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, third level\n");
+        break;
+
+    case 0b100001:
+        rt_kprintf("Alignment fault\n");
+        break;
+
+    case 0b110000:
+        rt_kprintf("TLB conflict abort\n");
+        break;
+
+    case 0b110100:
+        rt_kprintf("IMPLEMENTATION DEFINED fault (Lockdown fault)\n");
+        break;
+
+    case 0b110101:
+        rt_kprintf("IMPLEMENTATION DEFINED fault (Unsupported Exclusive access fault)\n");
+        break;
+
+    case 0b111101:
+        rt_kprintf("Section Domain Fault, used only for faults reported in the PAR_EL1\n");
+        break;
+
+    case 0b111110:
+        rt_kprintf("Page Domain Fault, used only for faults reported in the PAR_EL1\n");
+        break;
+
+    default:
+        rt_kprintf("unknow abort\n");
+        break;
+    }
+}
+
+void process_exception(unsigned long esr, unsigned long epc)
+{
+    rt_uint8_t ec;
+    rt_uint32_t iss;
+    unsigned long fault_addr;
+    rt_kprintf("\nexception info:\n");
+    ec = (unsigned char)((esr >> 26) & 0x3fU);
+    iss = (unsigned int)(esr & 0x00ffffffU);
+    rt_kprintf("esr.EC :0x%02x\n", ec);
+    rt_kprintf("esr.IL :0x%02x\n", (unsigned char)((esr >> 25) & 0x01U));
+    rt_kprintf("esr.ISS:0x%08x\n", iss);
+    rt_kprintf("epc    :0x%016p\n", (void *)epc);
+    switch (ec)
+    {
+    case 0x00:
+        rt_kprintf("Exceptions with an unknow reason\n");
+        break;
+
+    case 0x01:
+        rt_kprintf("Exceptions from an WFI or WFE instruction\n");
+        break;
+
+    case 0x03:
+        rt_kprintf("Exceptions from an MCR or MRC access to CP15 from AArch32\n");
+        break;
+
+    case 0x04:
+        rt_kprintf("Exceptions from an MCRR or MRRC access to CP15 from AArch32\n");
+        break;
+
+    case 0x05:
+        rt_kprintf("Exceptions from an MCR or MRC access to CP14 from AArch32\n");
+        break;
+
+    case 0x06:
+        rt_kprintf("Exceptions from an LDC or STC access to CP14 from AArch32\n");
+        break;
+
+    case 0x07:
+        rt_kprintf("Exceptions from Access to Advanced SIMD or floating-point registers\n");
+        break;
+
+    case 0x08:
+        rt_kprintf("Exceptions from an MRC (or VMRS) access to CP10 from AArch32\n");
+        break;
+
+    case 0x0c:
+        rt_kprintf("Exceptions from an MCRR or MRRC access to CP14 from AArch32\n");
+        break;
+
+    case 0x0e:
+        rt_kprintf("Exceptions that occur because ther value of PSTATE.IL is 1\n");
+        break;
+
+    case 0x11:
+        rt_kprintf("SVC call from AArch32 state\n");
+        break;
+
+    case 0x15:
+        rt_kprintf("SVC call from AArch64 state\n");
+        break;
+
+    case 0x20:
+        rt_kprintf("Instruction abort from lower exception level\n");
+        break;
+
+    case 0x21:
+        rt_kprintf("Instruction abort from current exception level\n");
+        break;
+
+    case 0x22:
+        rt_kprintf("PC alignment fault\n");
+        break;
+
+    case 0x24:
+        rt_kprintf("Data abort from a lower Exception level\n");
+        __asm__ volatile("mrs %0, far_el1":"=r"(fault_addr));
+        data_abort(fault_addr, iss);
+        break;
+
+    case 0x25:
+        rt_kprintf("Data abort\n");
+        __asm__ volatile("mrs %0, far_el1":"=r"(fault_addr));
+        data_abort(fault_addr, iss);
+        break;
+
+    default:
+        rt_kprintf("Other error\n");
+        break;
+    }
+}

+ 45 - 42
libcpu/aarch64/common/gic.c

@@ -9,7 +9,6 @@
  * 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 <rthw.h>
@@ -17,17 +16,15 @@
 
 #if defined(BSP_USING_GIC) && defined(BSP_USING_GICV2)
 
-#include <gic.h>
-#include <cpuport.h>
-
-#include <board.h>
+#include "gic.h"
+#include "cp15.h"
 
 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 address of the gic cpu interface */
+    rt_uint64_t cpu_hw_base;    /* the base addrees of the gic cpu interface */
 };
 
 /* 'ARM_GIC_MAX_NR' is the number of cores */
@@ -35,33 +32,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)               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)
+#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)
 
 /** 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_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)
 
 static unsigned int _gic_max_irq;
 
@@ -184,7 +181,7 @@ 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)
+void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config)
 {
     rt_uint64_t icfgr;
     rt_uint64_t shift;
@@ -328,8 +325,6 @@ 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)
@@ -348,8 +343,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)
 {
-    rt_uint32_t igroupr;
-    rt_uint32_t shift;
+    uint32_t igroupr;
+    uint32_t shift;
 
     RT_ASSERT(index < ARM_GIC_MAX_NR);
     RT_ASSERT(group <= 1U);
@@ -380,10 +375,6 @@ 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;
@@ -438,6 +429,12 @@ int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start)
     }
 
     /* All interrupts defaults to IGROUP1(IRQ). */
+    /*
+    for (i = 0; i < _gic_max_irq; i += 32)
+    {
+        GIC_DIST_IGROUP(dist_base, i) = 0xffffffffU;
+    }
+    */
     for (i = 0U; i < _gic_max_irq; i += 32U)
     {
         GIC_DIST_IGROUP(dist_base, i) = 0U;
@@ -489,17 +486,23 @@ void arm_gic_dump(rt_uint64_t index)
     rt_kprintf("--- hw mask ---\n");
     for (i = 0U; i < _gic_max_irq / 32U; i++)
     {
-        rt_kprintf("0x%08x, ", GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, i * 32U));
+        rt_kprintf("0x%08x, ",
+                   GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base,
+                                       i * 32U));
     }
     rt_kprintf("\n--- hw pending ---\n");
     for (i = 0U; i < _gic_max_irq / 32U; i++)
     {
-        rt_kprintf("0x%08x, ", GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, i * 32U));
+        rt_kprintf("0x%08x, ",
+                   GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base,
+                                        i * 32U));
     }
     rt_kprintf("\n--- hw active ---\n");
     for (i = 0U; i < _gic_max_irq / 32U; i++)
     {
-        rt_kprintf("0x%08x, ", GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, i * 32U));
+        rt_kprintf("0x%08x, ",
+                   GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base,
+                                       i * 32U));
     }
     rt_kprintf("\n");
 }

+ 3 - 6
libcpu/aarch64/common/gic.h

@@ -11,9 +11,8 @@
 #ifndef __GIC_H__
 #define __GIC_H__
 
-#include <rtdef.h>
-
-#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV2)
+#include <rthw.h>
+#include <board.h>
 
 int arm_gic_get_active_irq(rt_uint64_t index);
 void arm_gic_ack(rt_uint64_t index, int irq);
@@ -25,7 +24,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, rt_uint32_t config);
+void arm_gic_set_configuration(rt_uint64_t index, int irq, 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,7 +58,5 @@ 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
 

+ 15 - 2
libcpu/aarch64/common/gicv3.c

@@ -27,7 +27,7 @@
 #if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3)
 
 #include <gicv3.h>
-#include <cpuport.h>
+#include <cp15.h>
 
 #include <board.h>
 
@@ -479,7 +479,7 @@ 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)
+void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint32_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;
@@ -731,9 +731,22 @@ int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base)
 {
     int i;
     int cpu_id = rt_hw_cpu_id();
+    static int master_cpu_id = -1;
 
     RT_ASSERT(index < ARM_GIC_MAX_NR);
 
+    if (master_cpu_id < 0)
+    {
+        master_cpu_id = cpu_id;
+        rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, &master_cpu_id, sizeof(master_cpu_id));
+    }
+
+    if (!_gic_table[index].redist_hw_base[master_cpu_id])
+    {
+        _gic_table[index].redist_hw_base[master_cpu_id] = redist_base;
+    }
+    redist_base = _gic_table[index].redist_hw_base[master_cpu_id];
+
     redist_base += cpu_id * (2 << 16);
     _gic_table[index].redist_hw_base[cpu_id] = redist_base;
 

+ 1 - 1
libcpu/aarch64/common/gicv3.h

@@ -51,7 +51,7 @@ 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);
+void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint32_t cpu_masks[], rt_uint64_t routing_mode);
 #endif
 
 rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index);

+ 2 - 2
libcpu/aarch64/common/gtimer.c

@@ -26,9 +26,9 @@ static void rt_hw_timer_isr(int vector, void *parameter)
 void rt_hw_gtimer_init(void)
 {
     rt_hw_interrupt_install(EL1_PHY_TIMER_IRQ_NUM, rt_hw_timer_isr, RT_NULL, "tick");
-    __ISB();
+    rt_hw_isb();
     timer_step = rt_hw_get_gtimer_frq();
-    __DSB();
+    rt_hw_dsb();
     timer_step /= RT_TICK_PER_SECOND;
     rt_hw_gtimer_local_enable();
 }

+ 6 - 1
libcpu/aarch64/common/gtimer.h

@@ -18,7 +18,12 @@ void rt_hw_gtimer_local_enable(void);
 void rt_hw_gtimer_local_disable(void);
 
 void rt_hw_gtimer_enable();
-void rt_hw_gtimer_disable();
+
+rt_inline void rt_hw_gtimer_disable(void)
+{
+    __asm__ volatile ("msr CNTP_CTL_EL0, xzr":::"memory");
+}
+
 void rt_hw_set_gtimer_val(rt_uint64_t value);
 rt_uint64_t rt_hw_get_gtimer_val();
 rt_uint64_t rt_hw_get_cntpct_val();

+ 16 - 0
libcpu/aarch64/common/hypercall.c

@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-02-24     GuEe-GUI     first version
+ */
+
+#include <hypercall.h>
+
+rt_err_t rt_hv_stage2_map(unsigned long paddr, unsigned long size)
+{
+    return rt_hw_hypercall(120, paddr & (~4095), (paddr & (~4095)) + size, (1 << 0) | (1 << 1) | (1 << 4), 0, 0, 0, 0);
+}

+ 27 - 0
libcpu/aarch64/common/hypercall.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-02-24     GuEe-GUI     first version
+ */
+
+#ifndef __HYPERCALL_H__
+#define __HYPERCALL_H__
+
+#include <rtdef.h>
+
+rt_inline rt_uint32_t rt_hw_hypercall(rt_uint32_t w0, rt_uint64_t x1, rt_uint64_t x2,
+        rt_uint64_t x3, rt_uint64_t x4, rt_uint64_t x5, rt_uint64_t x6, rt_uint32_t w7)
+{
+    register rt_uint64_t ret __asm__ ("x0");
+    __asm__ volatile ("hvc #0");
+
+    return (rt_uint32_t)ret;
+}
+
+rt_err_t rt_hv_stage2_map(unsigned long paddr, unsigned long size);
+
+#endif

+ 87 - 74
libcpu/aarch64/common/interrupt.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -14,23 +14,45 @@
 #include "interrupt.h"
 #include "gic.h"
 #include "gicv3.h"
-#include "armv8.h"
-#include "mmu.h"
-#include "cpuport.h"
 
 /* exception and interrupt handler table */
 struct rt_irq_desc isr_table[MAX_HANDLERS];
 
+#ifndef RT_USING_SMP
 /* Those variables will be accessed in ISR, so we need to share them. */
 rt_ubase_t rt_interrupt_from_thread        = 0;
 rt_ubase_t rt_interrupt_to_thread          = 0;
 rt_ubase_t rt_thread_switch_interrupt_flag = 0;
+#endif
+
+#ifndef RT_CPUS_NR
+#define RT_CPUS_NR 1
+#endif
 
-extern int system_vectors;
+const unsigned int VECTOR_BASE = 0x00;
+extern void rt_cpu_vector_set_base(void *addr);
+extern void *system_vectors;
+
+#ifdef RT_USING_SMP
+#define rt_interrupt_nest rt_cpu_self()->irq_nest
+#else
+extern volatile rt_uint8_t rt_interrupt_nest;
+#endif
+
+#ifdef SOC_BCM283x
+static void default_isr_handler(int vector, void *param)
+{
+#ifdef RT_USING_SMP
+    rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector);
+#else
+    rt_kprintf("unhandled irq: %d\n",vector);
+#endif
+}
+#endif
 
 void rt_hw_vector_init(void)
 {
-    rt_hw_set_current_vbar((rt_ubase_t)&system_vectors);
+    rt_cpu_vector_set_base(&system_vectors);
 }
 
 /**
@@ -38,23 +60,69 @@ void rt_hw_vector_init(void)
  */
 void rt_hw_interrupt_init(void)
 {
+#ifdef SOC_BCM283x
+    rt_uint32_t index;
     /* initialize vector table */
     rt_hw_vector_init();
 
     /* initialize exceptions table */
     rt_memset(isr_table, 0x00, sizeof(isr_table));
 
-#ifndef BSP_USING_GIC
     /* mask all of interrupts */
     IRQ_DISABLE_BASIC = 0x000000ff;
     IRQ_DISABLE1      = 0xffffffff;
     IRQ_DISABLE2      = 0xffffffff;
+    for (index = 0; index < MAX_HANDLERS; index ++)
+    {
+        isr_table[index].handler = default_isr_handler;
+        isr_table[index].param = RT_NULL;
+#ifdef RT_USING_INTERRUPT_INFO
+        rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX);
+        isr_table[index].counter = 0;
+#endif
+    }
+
+    /* init interrupt nest, and context in thread sp */
+    rt_interrupt_nest = 0;
+    rt_interrupt_from_thread = 0;
+    rt_interrupt_to_thread = 0;
+    rt_thread_switch_interrupt_flag = 0;
 #else
+    rt_uint64_t gic_cpu_base;
+    rt_uint64_t gic_dist_base;
+#ifdef BSP_USING_GICV3
+    rt_uint64_t gic_rdist_base;
+#endif
+    rt_uint64_t gic_irq_start;
+
+    /* initialize vector table */
+    rt_hw_vector_init();
+
+    /* initialize exceptions table */
+    rt_memset(isr_table, 0x00, sizeof(isr_table));
+
     /* 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 RT_USING_SMART
+    gic_dist_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_dist_base(), 0x2000, MMU_MAP_K_DEVICE);
+    gic_cpu_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_cpu_base(), 0x1000, MMU_MAP_K_DEVICE);
+#ifdef BSP_USING_GICV3
+    gic_rdist_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_redist_base(),
+            RT_CPUS_NR * (2 << 16), MMU_MAP_K_DEVICE);
+#endif
+#else
+    gic_dist_base = platform_get_gic_dist_base();
+    gic_cpu_base = platform_get_gic_cpu_base();
+#ifdef BSP_USING_GICV3
+    gic_rdist_base = platform_get_gic_redist_base();
+#endif
+#endif
+
+    gic_irq_start = GIC_IRQ_START;
+
+    arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
+    arm_gic_cpu_init(0, gic_cpu_base);
 #ifdef BSP_USING_GICV3
-    arm_gic_redist_init(0, platform_get_gic_redist_base());
+    arm_gic_redist_init(0, gic_rdist_base);
 #endif
 #endif
 }
@@ -65,7 +133,7 @@ void rt_hw_interrupt_init(void)
  */
 void rt_hw_interrupt_mask(int vector)
 {
-#ifndef BSP_USING_GIC
+#ifdef SOC_BCM283x
     if (vector < 32)
     {
         IRQ_DISABLE1 = (1 << vector);
@@ -91,8 +159,8 @@ void rt_hw_interrupt_mask(int vector)
  */
 void rt_hw_interrupt_umask(int vector)
 {
-#ifndef BSP_USING_GIC
-    if (vector < 32)
+#ifdef SOC_BCM283x
+if (vector < 32)
     {
         IRQ_ENABLE1 = (1 << vector);
     }
@@ -117,7 +185,7 @@ void rt_hw_interrupt_umask(int vector)
  */
 int rt_hw_interrupt_get_irq(void)
 {
-#ifdef BSP_USING_GIC
+#ifndef SOC_BCM283x
     return arm_gic_get_active_irq(0);
 #else
     return 0;
@@ -130,11 +198,12 @@ int rt_hw_interrupt_get_irq(void)
  */
 void rt_hw_interrupt_ack(int vector)
 {
-#ifdef BSP_USING_GIC
+#ifndef SOC_BCM283x
     arm_gic_ack(0, vector);
 #endif
 }
 
+#ifndef SOC_BCM283x
 /**
  * This function set interrupt CPU targets.
  * @param vector:   the interrupt number
@@ -142,9 +211,7 @@ void rt_hw_interrupt_ack(int vector)
  */
 void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask)
 {
-#ifdef BSP_USING_GIC
     arm_gic_set_cpu(0, vector, cpu_mask);
-#endif
 }
 
 /**
@@ -154,11 +221,7 @@ void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask)
  */
 unsigned int rt_hw_interrupt_get_target_cpus(int vector)
 {
-#ifdef BSP_USING_GIC
     return arm_gic_get_target_cpu(0, vector);
-#else
-    return -RT_ERROR;
-#endif
 }
 
 /**
@@ -168,9 +231,7 @@ unsigned int rt_hw_interrupt_get_target_cpus(int vector)
  */
 void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode)
 {
-#ifdef BSP_USING_GIC
     arm_gic_set_configuration(0, vector, mode);
-#endif
 }
 
 /**
@@ -180,11 +241,7 @@ void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode)
  */
 unsigned int rt_hw_interrupt_get_triger_mode(int vector)
 {
-#ifdef BSP_USING_GIC
     return arm_gic_get_configuration(0, vector);
-#else
-    return -RT_ERROR;
-#endif
 }
 
 /**
@@ -193,9 +250,7 @@ unsigned int rt_hw_interrupt_get_triger_mode(int vector)
  */
 void rt_hw_interrupt_set_pending(int vector)
 {
-#ifdef BSP_USING_GIC
     arm_gic_set_pending_irq(0, vector);
-#endif
 }
 
 /**
@@ -205,11 +260,7 @@ void rt_hw_interrupt_set_pending(int vector)
  */
 unsigned int rt_hw_interrupt_get_pending(int vector)
 {
-#ifdef BSP_USING_GIC
     return arm_gic_get_pending_irq(0, vector);
-#else
-    return -RT_ERROR;
-#endif
 }
 
 /**
@@ -218,9 +269,7 @@ unsigned int rt_hw_interrupt_get_pending(int vector)
  */
 void rt_hw_interrupt_clear_pending(int vector)
 {
-#ifdef BSP_USING_GIC
     arm_gic_clear_pending_irq(0, vector);
-#endif
 }
 
 /**
@@ -230,9 +279,7 @@ void rt_hw_interrupt_clear_pending(int vector)
  */
 void rt_hw_interrupt_set_priority(int vector, unsigned int priority)
 {
-#ifdef BSP_USING_GIC
     arm_gic_set_priority(0, vector, priority);
-#endif
 }
 
 /**
@@ -242,11 +289,7 @@ void rt_hw_interrupt_set_priority(int vector, unsigned int priority)
  */
 unsigned int rt_hw_interrupt_get_priority(int vector)
 {
-#ifdef BSP_USING_GIC
     return arm_gic_get_priority(0, vector);
-#else
-    return -RT_ERROR;
-#endif
 }
 
 /**
@@ -255,9 +298,7 @@ unsigned int rt_hw_interrupt_get_priority(int vector)
  */
 void rt_hw_interrupt_set_priority_mask(unsigned int priority)
 {
-#ifdef BSP_USING_GIC
     arm_gic_set_interface_prior_mask(0, priority);
-#endif
 }
 
 /**
@@ -267,11 +308,7 @@ void rt_hw_interrupt_set_priority_mask(unsigned int priority)
  */
 unsigned int rt_hw_interrupt_get_priority_mask(void)
 {
-#ifdef BSP_USING_GIC
     return arm_gic_get_interface_prior_mask(0);
-#else
-    return -RT_ERROR;
-#endif
 }
 
 /**
@@ -281,7 +318,6 @@ unsigned int rt_hw_interrupt_get_priority_mask(void)
  */
 int rt_hw_interrupt_set_prior_group_bits(unsigned int bits)
 {
-#ifdef BSP_USING_GIC
     int status;
 
     if (bits < 8)
@@ -295,9 +331,6 @@ int rt_hw_interrupt_set_prior_group_bits(unsigned int bits)
     }
 
     return (status);
-#else
-    return -RT_ERROR;
-#endif
 }
 
 /**
@@ -307,16 +340,13 @@ int rt_hw_interrupt_set_prior_group_bits(unsigned int bits)
  */
 unsigned int rt_hw_interrupt_get_prior_group_bits(void)
 {
-#ifdef BSP_USING_GIC
     unsigned int bp;
 
     bp = arm_gic_get_binary_point(0) & 0x07;
 
     return (7 - bp);
-#else
-    return -RT_ERROR;
-#endif
 }
+#endif /* SOC_BCM283x */
 
 /**
  * This function will install a interrupt service routine to a interrupt.
@@ -349,26 +379,10 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
 #ifdef RT_USING_SMP
 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;
-
-    __DSB();
-
-    for (i = 0; i < RT_CPUS_NR; ++i)
-    {
-        if (cpu_mask & (1 << i))
-        {
-            IPI_MAILBOX_SET(i) = 1 << ipi_vector;
-        }
-    }
-
-    __DSB();
+#elif defined(BSP_USING_GICV3)
+    arm_gic_send_affinity_sgi(0, ipi_vector, (unsigned int *)&cpu_mask, GICV3_ROUTED_TO_SPEC);
 #endif
 }
 
@@ -378,4 +392,3 @@ void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)
     rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER");
 }
 #endif
-

Некоторые файлы не были показаны из-за большого количества измененных файлов