Kaynağa Gözat

[libcpu/aarch64] add smp support

GuEe-GUI 3 yıl önce
ebeveyn
işleme
353f717037
56 değiştirilmiş dosya ile 1891 ekleme ve 983 silme
  1. 13 0
      .github/workflows/action.yml
  2. 32 74
      bsp/qemu-virt64-aarch64/.config
  3. 1 0
      bsp/qemu-virt64-aarch64/README.md
  4. 1 0
      bsp/qemu-virt64-aarch64/README_zh.md
  5. 16 3
      bsp/qemu-virt64-aarch64/driver/Kconfig
  6. 75 51
      bsp/qemu-virt64-aarch64/driver/board.c
  7. 9 0
      bsp/qemu-virt64-aarch64/driver/board.h
  8. 118 0
      bsp/qemu-virt64-aarch64/driver/drv_rtc.c
  9. 25 0
      bsp/qemu-virt64-aarch64/driver/drv_rtc.h
  10. 2 1
      bsp/qemu-virt64-aarch64/qemu.bat
  11. 2 1
      bsp/qemu-virt64-aarch64/qemu.sh
  12. 14 56
      bsp/qemu-virt64-aarch64/rtconfig.h
  13. 2 1
      bsp/qemu-virt64-aarch64/rtconfig.py
  14. 34 0
      bsp/raspberry-pi/raspi3-32/cpu/trap.c
  15. 1 0
      bsp/raspberry-pi/raspi3-32/driver/drv_fb.c
  16. 1 1
      bsp/raspberry-pi/raspi3-32/driver/drv_fb.h
  17. 3 7
      bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c
  18. 35 21
      bsp/raspberry-pi/raspi3-64/.config
  19. 61 77
      bsp/raspberry-pi/raspi3-64/driver/board.c
  20. 1 1
      bsp/raspberry-pi/raspi3-64/driver/drv_fb.c
  21. 3 3
      bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c
  22. 2 0
      bsp/raspberry-pi/raspi3-64/driver/mbox.c
  23. 8 0
      bsp/raspberry-pi/raspi3-64/driver/raspi.h
  24. 12 6
      bsp/raspberry-pi/raspi3-64/rtconfig.h
  25. 4 2
      bsp/raspberry-pi/raspi3-64/rtconfig.py
  26. 43 31
      bsp/raspberry-pi/raspi4-64/.config
  27. 7 16
      bsp/raspberry-pi/raspi4-64/driver/Kconfig
  28. 87 45
      bsp/raspberry-pi/raspi4-64/driver/board.c
  29. 6 1
      bsp/raspberry-pi/raspi4-64/driver/drv_eth.c
  30. 4 0
      bsp/raspberry-pi/raspi4-64/driver/drv_sdio.c
  31. 141 0
      bsp/raspberry-pi/raspi4-64/driver/drv_wdt.c
  32. 26 0
      bsp/raspberry-pi/raspi4-64/driver/drv_wdt.h
  33. 24 2
      bsp/raspberry-pi/raspi4-64/driver/raspi4.h
  34. 19 13
      bsp/raspberry-pi/raspi4-64/rtconfig.h
  35. 4 2
      bsp/raspberry-pi/raspi4-64/rtconfig.py
  36. 8 1
      libcpu/aarch64/common/armv8.h
  37. 47 0
      libcpu/aarch64/common/asm_fpu.h
  38. 52 1
      libcpu/aarch64/common/cache.S
  39. 70 0
      libcpu/aarch64/common/cache_ops.c
  40. 74 11
      libcpu/aarch64/common/context_gcc.S
  41. 0 166
      libcpu/aarch64/common/cp15.h
  42. 55 35
      libcpu/aarch64/common/cpu.c
  43. 7 0
      libcpu/aarch64/common/cpuport.h
  44. 1 1
      libcpu/aarch64/common/gic.c
  45. 48 0
      libcpu/aarch64/common/gtimer.c
  46. 27 0
      libcpu/aarch64/common/gtimer.h
  47. 17 5
      libcpu/aarch64/common/interrupt.c
  48. 158 274
      libcpu/aarch64/common/mmu.c
  49. 52 56
      libcpu/aarch64/common/mmu.h
  50. 95 0
      libcpu/aarch64/common/psci.c
  51. 130 0
      libcpu/aarch64/common/psci.h
  52. 37 0
      libcpu/aarch64/common/smccc.S
  53. 33 0
      libcpu/aarch64/common/smccc.h
  54. 36 2
      libcpu/aarch64/common/stack.c
  55. 32 5
      libcpu/aarch64/common/trap.c
  56. 76 11
      libcpu/aarch64/cortex-a/entry_point.S

+ 13 - 0
.github/workflows/action.yml

@@ -145,11 +145,15 @@ jobs:
          - {RTT_BSP: "at32/at32f407-start", RTT_TOOL_CHAIN: "sourcery-arm"}
          - {RTT_BSP: "smartfusion2", RTT_TOOL_CHAIN: "sourcery-arm"}
          - {RTT_BSP: "raspberry-pico", RTT_TOOL_CHAIN: "sourcery-arm"}
+         - {RTT_BSP: "raspberry-pi/raspi3-32", RTT_TOOL_CHAIN: "sourcery-arm"}
          - {RTT_BSP: "raspberry-pi/raspi4-32", RTT_TOOL_CHAIN: "sourcery-arm"}
          - {RTT_BSP: "hc32l196", RTT_TOOL_CHAIN: "sourcery-arm"}
          - {RTT_BSP: "tae32f5300", RTT_TOOL_CHAIN: "sourcery-arm"}
          - {RTT_BSP: "bluetrum/ab32vg1-ab-prougen", RTT_TOOL_CHAIN: "sourcery-riscv64-unknown-elf"}
          - {RTT_BSP: "k210", RTT_TOOL_CHAIN: "sourcery-riscv-none-embed"}
+         - {RTT_BSP: "qemu-virt64-aarch64", RTT_TOOL_CHAIN: "sourcery-aarch64"}
+         - {RTT_BSP: "raspberry-pi/raspi3-64", RTT_TOOL_CHAIN: "sourcery-aarch64"}
+         - {RTT_BSP: "raspberry-pi/raspi4-64", RTT_TOOL_CHAIN: "sourcery-aarch64"}
     steps:
       - uses: actions/checkout@v2
       - name: Set up Python
@@ -178,6 +182,15 @@ jobs:
           /opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc --version
           echo "RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-10-2020-q4-major/bin" >> $GITHUB_ENV
 
+      - name: Install AArch64 ToolChains
+        if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-aarch64' && success() }}
+        shell: bash
+        run: |
+          wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.6/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf.tar.xz
+          sudo tar -xf gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf.tar.xz -C /opt
+          /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gcc --version
+          echo "RTT_EXEC_PATH=/opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf/bin" >> $GITHUB_ENV
+
       - name: Install Mips ToolChains
         if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-mips' && success() }}
         shell: bash

+ 32 - 74
bsp/qemu-virt64-aarch64/.config

@@ -1,9 +1,13 @@
-# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Project Configuration
+#
 
 #
 # RT-Thread Kernel
 #
-CONFIG_RT_NAME_MAX=8
+CONFIG_RT_NAME_MAX=16
+# CONFIG_RT_USING_BIG_ENDIAN is not set
 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set
 # CONFIG_RT_USING_SMP is not set
 CONFIG_RT_ALIGN_SIZE=4
@@ -14,12 +18,13 @@ CONFIG_RT_THREAD_PRIORITY_MAX=32
 CONFIG_RT_TICK_PER_SECOND=100
 CONFIG_RT_USING_OVERFLOW_CHECK=y
 CONFIG_RT_USING_HOOK=y
+CONFIG_RT_HOOK_USING_FUNC_PTR=y
 CONFIG_RT_USING_IDLE_HOOK=y
 CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
-CONFIG_IDLE_THREAD_STACK_SIZE=2048
+CONFIG_IDLE_THREAD_STACK_SIZE=4096
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
-CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096
 
 #
 # kservice optimization
@@ -28,8 +33,6 @@ CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
 # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
 # CONFIG_RT_USING_TINY_FFS is not set
 # CONFIG_RT_PRINTF_LONGLONG is not set
-# end of kservice optimization
-
 CONFIG_RT_DEBUG=y
 CONFIG_RT_DEBUG_COLOR=y
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -52,7 +55,6 @@ CONFIG_RT_USING_EVENT=y
 CONFIG_RT_USING_MAILBOX=y
 CONFIG_RT_USING_MESSAGEQUEUE=y
 # CONFIG_RT_USING_SIGNALS is not set
-# end of Inter-Thread communication
 
 #
 # Memory Management
@@ -71,7 +73,6 @@ CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y
 CONFIG_RT_USING_MEMTRACE=y
 # CONFIG_RT_USING_HEAP_ISR is not set
 CONFIG_RT_USING_HEAP=y
-# end of Memory Management
 
 #
 # Kernel Device Object
@@ -82,19 +83,17 @@ CONFIG_RT_USING_DEVICE_OPS=y
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=128
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
-# end of Kernel Device Object
-
 CONFIG_RT_VER_NUM=0x40100
-# end of RT-Thread Kernel
-
 CONFIG_ARCH_CPU_64BIT=y
+# CONFIG_RT_USING_CPU_FFS is not set
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 
 #
 # RT-Thread Components
 #
 CONFIG_RT_USING_COMPONENTS_INIT=y
 CONFIG_RT_USING_USER_MAIN=y
-CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192
 CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # CONFIG_RT_USING_LEGACY is not set
 
@@ -102,7 +101,6 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # C++ features
 #
 # CONFIG_RT_USING_CPLUSPLUS is not set
-# end of C++ features
 
 #
 # Command shell
@@ -122,7 +120,6 @@ CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
 # CONFIG_FINSH_USING_AUTH is not set
 CONFIG_FINSH_ARG_MAX=10
-# end of Command shell
 
 #
 # Device virtual file system
@@ -157,12 +154,9 @@ CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
 # CONFIG_RT_DFS_ELM_USE_ERASE is not set
 CONFIG_RT_DFS_ELM_REENTRANT=y
 CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000
-# end of elm-chan's FatFs, Generic FAT Filesystem Module
-
 CONFIG_RT_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
-# end of Device virtual file system
 
 #
 # Device Drivers
@@ -187,7 +181,7 @@ CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_MTD_NAND is not set
 # CONFIG_RT_USING_PM is not set
 CONFIG_RT_USING_RTC=y
-# CONFIG_RT_USING_ALARM is not set
+CONFIG_RT_USING_ALARM=y
 # CONFIG_RT_USING_SOFT_RTC is not set
 # CONFIG_RT_USING_SDIO is not set
 # CONFIG_RT_USING_SPI is not set
@@ -203,17 +197,13 @@ CONFIG_RT_USING_RTC=y
 #
 # Using USB
 #
+# CONFIG_RT_USING_USB is not set
 # CONFIG_RT_USING_USB_HOST is not set
 # CONFIG_RT_USING_USB_DEVICE is not set
-# end of Using USB
-# end of Device Drivers
 
 #
 # POSIX layer and C standard library
 #
-CONFIG_RT_USING_LIBC=y
-CONFIG_RT_LIBC_USING_TIME=y
-# CONFIG_RT_LIBC_USING_FILEIO is not set
 # CONFIG_RT_USING_MODULE is not set
 CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 
@@ -223,7 +213,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # 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_GETLINE is not set
 # CONFIG_RT_USING_PTHREADS is not set
 
 #
@@ -236,9 +225,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # Socket is in the 'Network' category
 #
-# end of Interprocess Communication (IPC)
-# end of POSIX (Portable Operating System Interface) layer
-# end of POSIX layer and C standard library
 
 #
 # Network
@@ -248,32 +234,26 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # Socket abstraction layer
 #
 # CONFIG_RT_USING_SAL is not set
-# end of Socket abstraction layer
 
 #
 # Network interface device
 #
 # CONFIG_RT_USING_NETDEV is not set
-# end of Network interface device
 
 #
 # light weight TCP/IP stack
 #
 # CONFIG_RT_USING_LWIP is not set
-# end of light weight TCP/IP stack
 
 #
 # AT commands
 #
 # CONFIG_RT_USING_AT is not set
-# end of AT commands
-# end of Network
 
 #
 # VBUS(Virtual Software BUS)
 #
 # CONFIG_RT_USING_VBUS is not set
-# end of VBUS(Virtual Software BUS)
 
 #
 # Utilities
@@ -283,14 +263,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_RT_USING_UTEST is not set
 # CONFIG_RT_USING_VAR_EXPORT is not set
 # CONFIG_RT_USING_RT_LINK is not set
-# end of Utilities
-# end of RT-Thread Components
 
 #
 # RT-Thread Utestcases
 #
 # CONFIG_RT_USING_UTESTCASES is not set
-# end of RT-Thread Utestcases
 
 #
 # RT-Thread online packages
@@ -325,17 +302,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # Marvell WiFi
 #
 # CONFIG_PKG_USING_WLANMARVELL is not set
-# end of Marvell WiFi
 
 #
 # Wiced WiFi
 #
 # CONFIG_PKG_USING_WLAN_WICED is not set
-# end of Wiced WiFi
-
 # CONFIG_PKG_USING_RW007 is not set
-# end of Wi-Fi
-
 # CONFIG_PKG_USING_COAP is not set
 # CONFIG_PKG_USING_NOPOLL is not set
 # CONFIG_PKG_USING_NETUTILS is not set
@@ -357,8 +329,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_JIOT-C-SDK is not set
 # CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
 # CONFIG_PKG_USING_JOYLINK is not set
-# end of IoT Cloud
-
+# CONFIG_PKG_USING_EZ_IOT_OS is not set
 # CONFIG_PKG_USING_NIMBLE is not set
 # CONFIG_PKG_USING_OTA_DOWNLOADER is not set
 # CONFIG_PKG_USING_IPMSG is not set
@@ -393,7 +364,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
 # CONFIG_PKG_USING_HM is not set
 # CONFIG_PKG_USING_SMALL_MODBUS is not set
-# end of IoT - internet of things
+# CONFIG_PKG_USING_NET_SERVER is not set
 
 #
 # security packages
@@ -403,7 +374,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_TINYCRYPT is not set
 # CONFIG_PKG_USING_TFM is not set
 # CONFIG_PKG_USING_YD_CRYPTO is not set
-# end of security packages
 
 #
 # language packages
@@ -412,7 +382,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_JERRYSCRIPT is not set
 # CONFIG_PKG_USING_MICROPYTHON is not set
 # CONFIG_PKG_USING_PIKASCRIPT is not set
-# end of language packages
 
 #
 # multimedia packages
@@ -424,15 +393,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_LVGL is not set
 # CONFIG_PKG_USING_LITTLEVGL2RTT is not set
 # CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
-# end of LVGL: powerful and easy-to-use embedded GUI library
 
 #
 # u8g2: a monochrome graphic library
 #
 # CONFIG_PKG_USING_U8G2_OFFICIAL is not set
 # CONFIG_PKG_USING_U8G2 is not set
-# end of u8g2: a monochrome graphic library
-
 # CONFIG_PKG_USING_OPENMV is not set
 # CONFIG_PKG_USING_MUPDF is not set
 # CONFIG_PKG_USING_STEMWIN is not set
@@ -452,8 +418,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # CONFIG_PKG_USING_PAINTERENGINE is not set
 # CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
-# end of PainterEngine: A cross-platform graphics application framework written in C language
-# end of multimedia packages
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_VT100 is not set
 
 #
 # tools packages
@@ -497,7 +464,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_SOLAR_TERMS is not set
 # CONFIG_PKG_USING_GAN_ZHI is not set
 # CONFIG_PKG_USING_FDT is not set
-# end of tools packages
 
 #
 # system packages
@@ -509,7 +475,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_RT_MEMCPY_CM is not set
 # CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
 # CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
-# end of enhanced kernel services
+
+#
+# POSIX extension functions
+#
+# CONFIG_PKG_USING_POSIX_GETLINE is not set
+# CONFIG_PKG_USING_POSIX_WCWIDTH is not set
 
 #
 # acceleration: Assembly language or algorithmic acceleration packages
@@ -517,14 +488,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
 # CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
 # CONFIG_PKG_USING_QFPLIB_M3 is not set
-# end of acceleration: Assembly language or algorithmic acceleration packages
 
 #
 # CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
 #
 # CONFIG_PKG_USING_CMSIS_5 is not set
 # CONFIG_PKG_USING_CMSIS_RTOS2 is not set
-# end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
 
 #
 # Micrium: Micrium software products porting for RT-Thread
@@ -535,8 +504,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_UC_CLK is not set
 # CONFIG_PKG_USING_UC_COMMON is not set
 # CONFIG_PKG_USING_UC_MODBUS is not set
-# end of Micrium: Micrium software products porting for RT-Thread
-
 # CONFIG_RT_USING_ARDUINO is not set
 # CONFIG_PKG_USING_GUIENGINE is not set
 # CONFIG_PKG_USING_CAIRO is not set
@@ -566,11 +533,10 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_TLSF is not set
 # CONFIG_PKG_USING_EVENT_RECORDER is not set
 # CONFIG_PKG_USING_ARM_2D is not set
-# CONFIG_PKG_USING_WCWIDTH is not set
 # CONFIG_PKG_USING_MCUBOOT is not set
 # CONFIG_PKG_USING_TINYUSB is not set
 # CONFIG_PKG_USING_USB_STACK is not set
-# end of system packages
+# CONFIG_PKG_USING_LUATOS_SOC is not set
 
 #
 # peripheral libraries and drivers
@@ -644,10 +610,10 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_BLUETRUM_SDK is not set
 # CONFIG_PKG_USING_MISAKA_AT24CXX is not set
 # CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
+# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
 # CONFIG_PKG_USING_BL_MCU_SDK is not set
 # CONFIG_PKG_USING_SOFT_SERIAL is not set
 # CONFIG_PKG_USING_MB85RS16 is not set
-# end of peripheral libraries and drivers
 
 #
 # AI packages
@@ -661,7 +627,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_ULAPACK is not set
 # CONFIG_PKG_USING_QUEST is not set
 # CONFIG_PKG_USING_NAXOS is not set
-# end of AI packages
 
 #
 # miscellaneous packages
@@ -674,7 +639,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
 # CONFIG_PKG_USING_NETWORK_SAMPLES is not set
 # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
-# end of samples: kernel and components samples
 
 #
 # entertainment: terminal games and other interesting software packages
@@ -688,8 +652,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_SNAKE is not set
 # CONFIG_PKG_USING_TETRIS is not set
 # CONFIG_PKG_USING_DONUT is not set
-# end of entertainment: terminal games and other interesting software packages
-
+# CONFIG_PKG_USING_COWSAY is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
@@ -711,26 +674,21 @@ 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_VT100 is not set
 # CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_CRCLIB is not set
 # CONFIG_PKG_USING_LWGPS is not set
 # CONFIG_PKG_USING_STATE_MACHINE is not set
-# CONFIG_PKG_USING_MCURSES is not set
-# CONFIG_PKG_USING_COWSAY is not set
-# CONFIG_PKG_USING_TERMBOX is not set
-# end of miscellaneous packages
-# end of RT-Thread online packages
-
+# CONFIG_PKG_USING_DESIGN_PATTERN is not set
 CONFIG_SOC_VIRT64_AARCH64=y
+CONFIG_BSP_SUPPORT_FPU=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_VIRTIO_BLK=y
 CONFIG_RT_USING_VIRTIO_BLK0=y
 CONFIG_BSP_USING_GIC=y
-# end of AARCH64 qemu virt64 configs

+ 1 - 0
bsp/qemu-virt64-aarch64/README.md

@@ -50,4 +50,5 @@ msh />
 | Driver | Condition | Remark |
 | ------ | --------- | ------ |
 | UART   | Support   | UART0  |
+| RTC    | Support   | - |
 | VIRTIO BLK | Support | VIRTIO BLK0 |

+ 1 - 0
bsp/qemu-virt64-aarch64/README_zh.md

@@ -51,4 +51,5 @@ msh />
 | 驱动 | 支持情况  |  备注  |
 | ------ | ----  | :------:  |
 | UART | 支持 | UART0 |
+| RTC  | 支持 | - |
 | VIRTIO BLK | 支持 | VIRTIO BLK0 |

+ 16 - 3
bsp/qemu-virt64-aarch64/driver/Kconfig

@@ -1,8 +1,8 @@
+menuconfig BSP_SUPPORT_FPU
+    bool "Using Float"
+    default y
 
 menu "AARCH64 qemu virt64 configs"
-    menuconfig BSP_SUPPORT_FPU
-        bool "Using Float"
-        default y
 
     menuconfig BSP_USING_UART
         bool "Using UART"
@@ -15,6 +15,19 @@ menu "AARCH64 qemu virt64 configs"
             default y
         endif
 
+
+    menuconfig BSP_USING_RTC
+            bool "Using RTC"
+            select RT_USING_RTC
+            default y
+
+        if BSP_USING_RTC
+            config BSP_USING_ALARM
+                bool "Enable Alarm"
+                select RT_USING_ALARM
+                default n
+        endif
+
     menuconfig BSP_USING_VIRTIO_BLK
         bool "Using VirtIO BLK"
         default y

+ 75 - 51
bsp/qemu-virt64-aarch64/driver/board.c

@@ -8,6 +8,7 @@
  * 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>
@@ -15,40 +16,24 @@
 
 #include "board.h"
 #include <mmu.h>
-#include "drv_uart.h"
-
-void rt_hw_vector_init(void);
-
-static uint64_t timer_val;
-static uint64_t timer_step;
-
-void rt_hw_timer_isr(int vector, void *parameter)
-{
-    timer_val += timer_step;
-    __asm__ volatile ("msr CNTV_CVAL_EL0, %0"::"r"(timer_val));
-    __asm__ volatile ("isb":::"memory");
+#include <gic.h>
+#include <psci.h>
+#include <gtimer.h>
+#include <cpuport.h>
+#include <interrupt.h>
 
-    rt_tick_increase();
-}
+#include "drv_uart.h"
 
-int rt_hw_timer_init(void)
+struct mem_desc platform_mem_desc[] =
 {
-    rt_hw_interrupt_install(27, rt_hw_timer_isr, RT_NULL, "tick");
-    rt_hw_interrupt_umask(27);
-
-    __asm__ volatile ("msr CNTV_CTL_EL0, %0"::"r"(0));
-
-    __asm__ volatile ("isb 0xf":::"memory");
-    __asm__ volatile ("mrs %0, CNTFRQ_EL0" : "=r" (timer_step));
-    timer_step /= RT_TICK_PER_SECOND;
-    timer_val = timer_step;
-    __asm__ volatile ("dsb 0xf":::"memory");
+    {0x40000000, 0x80000000, 0x40000000, NORMAL_MEM},
+    {PL031_RTC_BASE, PL031_RTC_BASE + 0x1000, PL031_RTC_BASE, DEVICE_MEM},
+    {PL011_UART0_BASE, PL011_UART0_BASE + 0x1000, PL011_UART0_BASE, DEVICE_MEM},
+    {VIRTIO_MMIO_BLK0_BASE, VIRTIO_MMIO_BLK0_BASE + 0x1000, VIRTIO_MMIO_BLK0_BASE, DEVICE_MEM},
+    {GIC_PL390_DISTRIBUTOR_PPTR, GIC_PL390_DISTRIBUTOR_PPTR + 0x1000, GIC_PL390_DISTRIBUTOR_PPTR, DEVICE_MEM},
+};
 
-    __asm__ volatile ("msr CNTV_CVAL_EL0, %0"::"r"(timer_val));
-    __asm__ volatile ("msr CNTV_CTL_EL0, %0"::"r"(1));
-
-    return 0;
-}
+const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
 
 void idle_wfi(void)
 {
@@ -61,37 +46,24 @@ void idle_wfi(void)
  */
 void rt_hw_board_init(void)
 {
-    uint64_t cont;
-
-    mmu_init();
-    cont = (uint64_t)RT_HW_HEAP_END + 0x1fffff;
-    cont &= ~0x1fffff;
-    cont -= 0x40000000;
-    cont >>= 21;
-    /* memory location */
-    armv8_map_2M(0x40000000, 0x40000000, cont, MEM_ATTR_MEMORY);
-    /* virtio blk0 */
-    armv8_map_2M(VIRTIO_MMIO_BLK0_BASE, VIRTIO_MMIO_BLK0_BASE, 0x1, MEM_ATTR_IO);
-    /* uart location*/
-    armv8_map_2M(PL011_UART0_BASE, PL011_UART0_BASE, 0x1, MEM_ATTR_IO);
-    /* gic location*/
-    armv8_map_2M(GIC_PL390_DISTRIBUTOR_PPTR, GIC_PL390_DISTRIBUTOR_PPTR, 0x1, MEM_ATTR_IO);
-    mmu_enable();
+    rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size);
+    rt_hw_mmu_init();
 
     /* initialize hardware interrupt */
-    rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
-    rt_hw_vector_init();    // in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors);
+    rt_hw_interrupt_init();
 
     /* initialize uart */
-    rt_hw_uart_init();      // driver/drv_uart.c
+    rt_hw_uart_init();
     /* initialize timer for os tick */
-    rt_hw_timer_init();
+    rt_hw_gtimer_init();
     rt_thread_idle_sethook(idle_wfi);
 
+    arm_psci_init(RT_NULL, RT_NULL);
+
 #ifdef RT_USING_CONSOLE
     /* set console device */
     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
-#endif /* RT_USING_CONSOLE */
+#endif
 
 #ifdef RT_USING_HEAP
     /* initialize memory system */
@@ -102,4 +74,56 @@ void rt_hw_board_init(void)
 #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 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());
+    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

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

@@ -40,6 +40,11 @@ extern unsigned char __bss_end;
 #define PL011_UART0_SIZE            0x00001000
 #define PL011_UART0_IRQNUM          (VIRTIO_SPI_IRQ_BASE + 1)
 
+/* RTC */
+#define PL031_RTC_BASE              0x9010000
+#define PL031_RTC_SIZE              0x00001000
+#define PL031_RTC_IRQNUM            (VIRTIO_SPI_IRQ_BASE + 2)
+
 /* DIST and CPU */
 #define GIC_PL390_DISTRIBUTOR_PPTR  0x08000000
 #define GIC_PL390_CONTROLLER_PPTR   0x08010000
@@ -51,6 +56,10 @@ extern unsigned char __bss_end;
 /* only one GIC available */
 #define ARM_GIC_MAX_NR              1
 
+/* ipi interrupt number */
+#define IRQ_ARM_IPI_KICK            0
+#define IRQ_ARM_IPI_CALL            1
+
 #define IRQ_ARM_VTIMER              27
 
 /* the basic constants and interfaces needed by gic */

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

@@ -0,0 +1,118 @@
+/*
+ * 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;
+
+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)
+{
+    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 */

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

@@ -0,0 +1,25 @@
+/*
+ * 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
+ */
+
+#ifndef DRV_RTC_H__
+#define DRV_RTC_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <time.h>
+
+struct hw_rtc_device
+{
+    struct rt_device device;
+};
+
+int rt_hw_rtc_init(void);
+
+#endif

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

@@ -3,4 +3,5 @@ if exist sd.bin goto run
 qemu-img create -f raw sd.bin 64M
 
 :run
-qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -kernel rtthread.elf -drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 -nographic
+qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic ^
+-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0

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

@@ -1,4 +1,5 @@
 if [ ! -f "sd.bin" ]; then
 dd if=/dev/zero of=sd.bin bs=1024 count=65536
 fi
-qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic -drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 -monitor pty
+qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 4 -kernel rtthread.elf -nographic \
+-drive if=none,file=sd.bin,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0

+ 14 - 56
bsp/qemu-virt64-aarch64/rtconfig.h

@@ -1,27 +1,28 @@
 #ifndef RT_CONFIG_H__
 #define RT_CONFIG_H__
 
-/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Project Configuration */
 
 /* RT-Thread Kernel */
 
-#define RT_NAME_MAX 8
+#define RT_NAME_MAX 16
 #define RT_ALIGN_SIZE 4
 #define RT_THREAD_PRIORITY_32
 #define RT_THREAD_PRIORITY_MAX 32
 #define RT_TICK_PER_SECOND 100
 #define RT_USING_OVERFLOW_CHECK
 #define RT_USING_HOOK
+#define RT_HOOK_USING_FUNC_PTR
 #define RT_USING_IDLE_HOOK
 #define RT_IDLE_HOOK_LIST_SIZE 4
-#define IDLE_THREAD_STACK_SIZE 2048
+#define IDLE_THREAD_STACK_SIZE 4096
 #define RT_USING_TIMER_SOFT
 #define RT_TIMER_THREAD_PRIO 4
-#define RT_TIMER_THREAD_STACK_SIZE 2048
+#define RT_TIMER_THREAD_STACK_SIZE 4096
 
 /* kservice optimization */
 
-/* end of kservice optimization */
 #define RT_DEBUG
 #define RT_DEBUG_COLOR
 
@@ -32,7 +33,6 @@
 #define RT_USING_EVENT
 #define RT_USING_MAILBOX
 #define RT_USING_MESSAGEQUEUE
-/* end of Inter-Thread communication */
 
 /* Memory Management */
 
@@ -43,7 +43,6 @@
 #define RT_USING_SMALL_MEM_AS_HEAP
 #define RT_USING_MEMTRACE
 #define RT_USING_HEAP
-/* end of Memory Management */
 
 /* Kernel Device Object */
 
@@ -52,21 +51,18 @@
 #define RT_USING_CONSOLE
 #define RT_CONSOLEBUF_SIZE 128
 #define RT_CONSOLE_DEVICE_NAME "uart0"
-/* end of Kernel Device Object */
 #define RT_VER_NUM 0x40100
-/* end of RT-Thread Kernel */
 #define ARCH_CPU_64BIT
 
 /* RT-Thread Components */
 
 #define RT_USING_COMPONENTS_INIT
 #define RT_USING_USER_MAIN
-#define RT_MAIN_THREAD_STACK_SIZE 2048
+#define RT_MAIN_THREAD_STACK_SIZE 8192
 #define RT_MAIN_THREAD_PRIORITY 10
 
 /* C++ features */
 
-/* end of C++ features */
 
 /* Command shell */
 
@@ -83,7 +79,6 @@
 #define MSH_USING_BUILT_IN_COMMANDS
 #define FINSH_USING_DESCRIPTION
 #define FINSH_ARG_MAX 10
-/* end of Command shell */
 
 /* Device virtual file system */
 
@@ -108,9 +103,7 @@
 #define RT_DFS_ELM_MAX_SECTOR_SIZE 512
 #define RT_DFS_ELM_REENTRANT
 #define RT_DFS_ELM_MUTEX_TIMEOUT 3000
-/* end of elm-chan's FatFs, Generic FAT Filesystem Module */
 #define RT_USING_DFS_DEVFS
-/* end of Device virtual file system */
 
 /* Device Drivers */
 
@@ -120,16 +113,13 @@
 #define RT_SERIAL_RB_BUFSZ 64
 #define RT_USING_PIN
 #define RT_USING_RTC
+#define RT_USING_ALARM
 
 /* Using USB */
 
-/* end of Using USB */
-/* end of Device Drivers */
 
 /* POSIX layer and C standard library */
 
-#define RT_USING_LIBC
-#define RT_LIBC_USING_TIME
 #define RT_LIBC_DEFAULT_TIMEZONE 8
 
 /* POSIX (Portable Operating System Interface) layer */
@@ -140,41 +130,28 @@
 
 /* Socket is in the 'Network' category */
 
-/* end of Interprocess Communication (IPC) */
-/* end of POSIX (Portable Operating System Interface) layer */
-/* end of POSIX layer and C standard library */
-
 /* Network */
 
 /* Socket abstraction layer */
 
-/* end of Socket abstraction layer */
 
 /* Network interface device */
 
-/* end of Network interface device */
 
 /* light weight TCP/IP stack */
 
-/* end of light weight TCP/IP stack */
 
 /* AT commands */
 
-/* end of AT commands */
-/* end of Network */
 
 /* VBUS(Virtual Software BUS) */
 
-/* end of VBUS(Virtual Software BUS) */
 
 /* Utilities */
 
-/* end of Utilities */
-/* end of RT-Thread Components */
 
 /* RT-Thread Utestcases */
 
-/* end of RT-Thread Utestcases */
 
 /* RT-Thread online packages */
 
@@ -185,93 +162,74 @@
 
 /* Marvell WiFi */
 
-/* end of Marvell WiFi */
 
 /* Wiced WiFi */
 
-/* end of Wiced WiFi */
-/* end of Wi-Fi */
 
 /* IoT Cloud */
 
-/* end of IoT Cloud */
-/* end of IoT - internet of things */
 
 /* security packages */
 
-/* end of security packages */
 
 /* language packages */
 
-/* end of language packages */
 
 /* multimedia packages */
 
 /* LVGL: powerful and easy-to-use embedded GUI library */
 
-/* end of LVGL: powerful and easy-to-use embedded GUI library */
 
 /* u8g2: a monochrome graphic library */
 
-/* end of u8g2: a monochrome graphic library */
 
 /* PainterEngine: A cross-platform graphics application framework written in C language */
 
-/* end of PainterEngine: A cross-platform graphics application framework written in C language */
-/* end of multimedia packages */
 
 /* tools packages */
 
-/* end of tools packages */
 
 /* system packages */
 
 /* enhanced kernel services */
 
-/* end of enhanced kernel services */
+
+/* POSIX extension functions */
+
 
 /* acceleration: Assembly language or algorithmic acceleration packages */
 
-/* end of acceleration: Assembly language or algorithmic acceleration packages */
 
 /* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
 
-/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
 
 /* Micrium: Micrium software products porting for RT-Thread */
 
-/* end of Micrium: Micrium software products porting for RT-Thread */
-/* end of system packages */
 
 /* peripheral libraries and drivers */
 
-/* end of peripheral libraries and drivers */
 
 /* AI packages */
 
-/* end of AI packages */
 
 /* miscellaneous packages */
 
 /* samples: kernel and components samples */
 
-/* end of samples: kernel and components samples */
 
 /* entertainment: terminal games and other interesting software packages */
 
-/* end of entertainment: terminal games and other interesting software packages */
-/* end of miscellaneous packages */
-/* end of RT-Thread online packages */
 #define SOC_VIRT64_AARCH64
+#define BSP_SUPPORT_FPU
 
 /* 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_VIRTIO_BLK
 #define RT_USING_VIRTIO_BLK0
 #define BSP_USING_GIC
-/* end of AARCH64 qemu virt64 configs */
 
 #endif

+ 2 - 1
bsp/qemu-virt64-aarch64/rtconfig.py

@@ -1,4 +1,5 @@
 import os
+import platform
 
 # toolchains options
 ARCH        ='aarch64'
@@ -27,7 +28,7 @@ BUILD = 'debug'
 
 if PLATFORM == 'gcc':
     # toolchains
-    PREFIX = 'aarch64-elf-'
+    PREFIX = 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'

+ 34 - 0
bsp/raspberry-pi/raspi3-32/cpu/trap.c

@@ -130,6 +130,40 @@ void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
     rt_hw_cpu_shutdown();
 }
 
+#ifdef RT_USING_CPU_FFS
+int __rt_ffs(int value)
+{
+    int num = 0;
+
+    if ((value & 0xffff) == 0)
+    {
+        num += 16;
+        value >>= 16;
+    }
+    if ((value & 0xff) == 0)
+    {
+        num += 8;
+        value >>= 8;
+    }
+    if ((value & 0xf) == 0)
+    {
+        num += 4;
+        value >>= 4;
+    }
+    if ((value & 0x3) == 0)
+    {
+        num += 2;
+        value >>= 2;
+    }
+    if ((value & 0x1) == 0)
+    {
+        num += 1;
+    }
+
+    return num;
+}
+#endif
+
 void rt_hw_trap_irq(void)
 {
     void *param;

+ 1 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_fb.c

@@ -19,6 +19,7 @@
 
 #define COLOR_DELTA     0.05
 static struct rt_hdmi_fb_device _hdmi;
+fb_t fb_info;
 
 // https://github.com/xinu-os/xinu/blob/1789b7a50b5b73c2ea76ebd764c54a034097d04d/device/framebuffer_rpi/font.c
 unsigned char FONT[] = {

+ 1 - 1
bsp/raspberry-pi/raspi3-32/driver/drv_fb.h

@@ -53,7 +53,7 @@ struct rt_hdmi_fb_device
     fb_t fb;
 };
 
-fb_t fb_info;
+extern fb_t fb_info;
 void print_fb_info();
 
 #endif/* __DRV_FB_H__ */

+ 3 - 7
bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c

@@ -10,10 +10,6 @@
 
 #include "drv_i2c.h"
 
-//Maybe redefined
-typedef unsigned long                   rt_ubase_t;
-typedef rt_ubase_t                      rt_size_t;
-
 rt_uint8_t i2c_read_or_write(volatile rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len, rt_uint8_t flag)
 {
     rt_uint32_t status;
@@ -128,7 +124,7 @@ static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
 
     volatile rt_uint32_t base = (volatile rt_uint32_t)(bus->parent.user_data);
 
-    if (bus->addr == 0)
+    if (bus->parent.user_data == 0)
         base = BCM283X_BSC0_BASE;
     else
         base = BCM283X_BSC1_BASE;
@@ -198,7 +194,6 @@ static struct raspi_i2c_hw_config hw_device0 =
 struct rt_i2c_bus_device device0 =
 {
     .ops = &raspi_i2c_ops,
-    .addr = 0,
 };
 
 #endif
@@ -216,7 +211,6 @@ static struct raspi_i2c_hw_config hw_device1 =
 struct rt_i2c_bus_device device1 =
 {
     .ops = &raspi_i2c_ops,
-    .addr = 1,
 };
 
 #endif
@@ -224,11 +218,13 @@ struct rt_i2c_bus_device device1 =
 int rt_hw_i2c_init(void)
 {
 #if defined(BSP_USING_I2C0)
+    device0.parent.user_data = (void *)0;
     raspi_i2c_configure(&hw_device0);
     rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME);
 #endif
 
 #if defined(BSP_USING_I2C1)
+    device1.parent.user_data = (void *)1;
     raspi_i2c_configure(&hw_device1);
     rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME);
 #endif

+ 35 - 21
bsp/raspberry-pi/raspi3-64/.config

@@ -18,20 +18,19 @@ CONFIG_RT_THREAD_PRIORITY_MAX=32
 CONFIG_RT_TICK_PER_SECOND=100
 CONFIG_RT_USING_OVERFLOW_CHECK=y
 CONFIG_RT_USING_HOOK=y
+CONFIG_RT_HOOK_USING_FUNC_PTR=y
 CONFIG_RT_USING_IDLE_HOOK=y
 CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
-CONFIG_IDLE_THREAD_STACK_SIZE=2048
+CONFIG_IDLE_THREAD_STACK_SIZE=8192
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
-CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096
 
 #
 # kservice optimization
 #
 # CONFIG_RT_KSERVICE_USING_STDLIB is not set
 # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
-# CONFIG_RT_USING_ASM_MEMCPY is not set
-# CONFIG_RT_USING_ASM_MEMSET is not set
 # CONFIG_RT_USING_TINY_FFS is not set
 # CONFIG_RT_PRINTF_LONGLONG is not set
 CONFIG_RT_DEBUG=y
@@ -164,7 +163,6 @@ CONFIG_RT_USING_DFS_DEVFS=y
 # Device Drivers
 #
 CONFIG_RT_USING_DEVICE_IPC=y
-CONFIG_RT_PIPE_BUFSZ=512
 # CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
 CONFIG_RT_USING_SERIAL=y
 CONFIG_RT_USING_SERIAL_V1=y
@@ -219,9 +217,6 @@ CONFIG_RT_USING_WDT=y
 #
 # POSIX layer and C standard library
 #
-CONFIG_RT_USING_LIBC=y
-CONFIG_RT_LIBC_USING_TIME=y
-# CONFIG_RT_LIBC_USING_FILEIO is not set
 # CONFIG_RT_USING_MODULE is not set
 CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 
@@ -230,12 +225,20 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # CONFIG_RT_USING_POSIX_FS is not set
 # CONFIG_RT_USING_POSIX_DELAY is not set
-# CONFIG_RT_USING_POSIX_GETLINE is not set
-# CONFIG_RT_USING_POSIX_MMAP is not set
-# CONFIG_RT_USING_POSIX_TERMIOS is not set
-# CONFIG_RT_USING_POSIX_AIO is not set
+# CONFIG_RT_USING_POSIX_CLOCK is not set
 # CONFIG_RT_USING_PTHREADS is not set
 
+#
+# Interprocess Communication (IPC)
+#
+# CONFIG_RT_USING_POSIX_PIPE is not set
+# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set
+# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
+
+#
+# Socket is in the 'Network' category
+#
+
 #
 # Network
 #
@@ -339,6 +342,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_JIOT-C-SDK is not set
 # CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
 # CONFIG_PKG_USING_JOYLINK is not set
+# CONFIG_PKG_USING_EZ_IOT_OS is not set
 # CONFIG_PKG_USING_NIMBLE is not set
 # CONFIG_PKG_USING_OTA_DOWNLOADER is not set
 # CONFIG_PKG_USING_IPMSG is not set
@@ -373,12 +377,13 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
 # CONFIG_PKG_USING_HM is not set
 # CONFIG_PKG_USING_SMALL_MODBUS is not set
+# CONFIG_PKG_USING_NET_SERVER is not set
 
 #
 # security packages
 #
 # CONFIG_PKG_USING_MBEDTLS is not set
-# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_LIBSODIUM is not set
 # CONFIG_PKG_USING_TINYCRYPT is not set
 # CONFIG_PKG_USING_TFM is not set
 # CONFIG_PKG_USING_YD_CRYPTO is not set
@@ -400,6 +405,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # CONFIG_PKG_USING_LVGL is not set
 # CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
 
 #
 # u8g2: a monochrome graphic library
@@ -425,6 +431,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # CONFIG_PKG_USING_PAINTERENGINE is not set
 # CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_VT100 is not set
 
 #
 # tools packages
@@ -474,15 +483,21 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 
 #
-# rt_kprintf: enhanced rt_kprintf packages
+# enhanced kernel services
 #
+# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
 # CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
 # CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
 
+#
+# POSIX extension functions
+#
+# CONFIG_PKG_USING_POSIX_GETLINE is not set
+# CONFIG_PKG_USING_POSIX_WCWIDTH is not set
+
 #
 # acceleration: Assembly language or algorithmic acceleration packages
 #
-# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
 # CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
 # CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
 # CONFIG_PKG_USING_QFPLIB_M3 is not set
@@ -491,7 +506,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
 #
 # CONFIG_PKG_USING_CMSIS_5 is not set
-# CONFIG_PKG_USING_CMSIS_5_AUX is not set
 # CONFIG_PKG_USING_CMSIS_RTOS2 is not set
 
 #
@@ -503,6 +517,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_UC_CLK is not set
 # CONFIG_PKG_USING_UC_COMMON is not set
 # CONFIG_PKG_USING_UC_MODBUS is not set
+# CONFIG_RT_USING_ARDUINO is not set
 # CONFIG_PKG_USING_GUIENGINE is not set
 # CONFIG_PKG_USING_CAIRO is not set
 # CONFIG_PKG_USING_PIXMAN is not set
@@ -531,10 +546,10 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_TLSF is not set
 # CONFIG_PKG_USING_EVENT_RECORDER is not set
 # CONFIG_PKG_USING_ARM_2D is not set
-# CONFIG_PKG_USING_WCWIDTH is not set
 # CONFIG_PKG_USING_MCUBOOT is not set
 # CONFIG_PKG_USING_TINYUSB is not set
 # CONFIG_PKG_USING_USB_STACK is not set
+# CONFIG_PKG_USING_LUATOS_SOC is not set
 
 #
 # peripheral libraries and drivers
@@ -608,6 +623,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_BLUETRUM_SDK is not set
 # CONFIG_PKG_USING_MISAKA_AT24CXX is not set
 # CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
+# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
 # CONFIG_PKG_USING_BL_MCU_SDK is not set
 # CONFIG_PKG_USING_SOFT_SERIAL is not set
 # CONFIG_PKG_USING_MB85RS16 is not set
@@ -649,6 +665,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_SNAKE is not set
 # CONFIG_PKG_USING_TETRIS is not set
 # CONFIG_PKG_USING_DONUT is not set
+# CONFIG_PKG_USING_COWSAY is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
@@ -670,14 +687,11 @@ 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_VT100 is not set
 # CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_CRCLIB is not set
 # CONFIG_PKG_USING_LWGPS is not set
 # CONFIG_PKG_USING_STATE_MACHINE is not set
-# CONFIG_PKG_USING_MCURSES is not set
-# CONFIG_PKG_USING_COWSAY is not set
-# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_DESIGN_PATTERN is not set
 CONFIG_BCM2836_SOC=y
 CONFIG_BSP_SUPPORT_FPU=y
 

+ 61 - 77
bsp/raspberry-pi/raspi3-64/driver/board.c

@@ -6,6 +6,7 @@
  * Change Logs:
  * Date           Author         Notes
  * 2019-07-29     zdzn           first version
+ * 2021-12-28     GuEe-GUI       add smp support
  */
 
 #include <rthw.h>
@@ -15,38 +16,35 @@
 #include "drv_uart.h"
 #include "drv_timer.h"
 
-#include "cp15.h"
+#include "gtimer.h"
+#include "cpuport.h"
+#include "interrupt.h"
 #include "mmu.h"
 #include "raspi.h"
 
-#ifdef BSP_USING_CORETIMER
-static rt_uint64_t timerStep;
-#define CORE0_TIMER_IRQ_CTRL    HWREG32(0x40000040)
-
-int rt_hw_get_gtimer_frq(void);
-void rt_hw_set_gtimer_val(rt_uint64_t value);
-int rt_hw_get_gtimer_val(void);
-int rt_hw_get_cntpct_val(void);
-void rt_hw_gtimer_enable(void);
-
-void core0_timer_enable_interrupt_controller()
+struct mem_desc platform_mem_desc[] =
 {
-    CORE0_TIMER_IRQ_CTRL |= NON_SECURE_TIMER_IRQ;
-}
-#endif
-
-#ifdef RT_USING_SMP
-extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
-
-void ipi_handler(){
-    rt_scheduler_ipi_handler(0,RT_NULL);
-}
+    {0, 0x6400000, 0, NORMAL_MEM},
+    {0xc00000, 0xc01000, 0xc00000, DEVICE_MEM}, /* mbox */
+    {0x3f000000, 0x3f200000, 0x3f000000, DEVICE_MEM}, /* timer */
+    {0x3f200000, 0x3f216000, 0x3f200000, DEVICE_MEM}, /* uart */
+    {0x40000000, 0x40200000, 0x40000000, DEVICE_MEM}, /* core timer */
+    {0x3F300000, 0x3F301000, 0x3F300000, DEVICE_MEM}, /* sdio */
+    {0x3f804000, 0x3f805000, 0x3f804000, DEVICE_MEM}, /* i2c0 */
+    {0x3f205000, 0x3f206000, 0x3f205000, DEVICE_MEM}, /* i2c1 */
+};
+
+const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
+
+#if defined(BSP_USING_CORETIMER) || defined(RT_USING_SMP)
+static volatile rt_uint64_t timer_step;
+#define BSP_USING_CORETIMER
 #endif
 
 void rt_hw_timer_isr(int vector, void *parameter)
 {
 #ifdef BSP_USING_CORETIMER
-    rt_hw_set_gtimer_val(timerStep);
+    rt_hw_set_gtimer_val(timer_step);
 #else
     ARM_TIMER_IRQCLR = 0;
 #endif
@@ -59,13 +57,17 @@ void rt_hw_timer_init(void)
     rt_hw_interrupt_umask(IRQ_ARM_TIMER);
 #ifdef BSP_USING_CORETIMER
     __ISB();
-    timerStep = rt_hw_get_gtimer_frq();
+    timer_step = rt_hw_get_gtimer_frq();
     __DSB();
-    timerStep /= RT_TICK_PER_SECOND;
+    timer_step /= RT_TICK_PER_SECOND;
 
     rt_hw_gtimer_enable();
-    rt_hw_set_gtimer_val(timerStep);
-    core0_timer_enable_interrupt_controller();
+    rt_hw_set_gtimer_val(timer_step);
+#ifdef RT_USING_SMP
+    core_timer_enable(rt_hw_cpu_id());
+#else
+    core_timer_enable(0);
+#endif
 #else
     __DSB();
     /* timer_clock = apb_clock/(pre_divider + 1) */
@@ -95,20 +97,11 @@ void idle_wfi(void)
  */
 void rt_hw_board_init(void)
 {
-    mmu_init();
-    armv8_map(0, 0, 0x6400000, MEM_ATTR_MEMORY);
-    armv8_map(0x3f000000, 0x3f000000, 0x200000, MEM_ATTR_IO);//timer
-    armv8_map(0x3f200000, 0x3f200000, 0x16000, MEM_ATTR_IO);//uart
-    armv8_map(0x40000000, 0x40000000, 0x1000, MEM_ATTR_IO);//core timer
-    armv8_map(0x3F300000, 0x3F300000, 0x1000, MEM_ATTR_IO);//sdio
-    armv8_map(0xc00000, 0xc00000, 0x1000, MEM_ATTR_IO);//mbox
-    armv8_map(0x3f804000, 0x3f804000, 0x1000, MEM_ATTR_IO);//i2c0
-    armv8_map(0x3f205000, 0x3f205000, 0x1000, MEM_ATTR_IO);//i2c1
-    mmu_enable();
+    rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size);
+    rt_hw_mmu_init();
 
     /* initialize hardware interrupt */
     rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
-    rt_hw_vector_init();    // in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors);
 
     /* initialize uart */
     rt_hw_uart_init();      // driver/drv_uart.c
@@ -116,7 +109,7 @@ void rt_hw_board_init(void)
     rt_hw_timer_init();
     rt_thread_idle_sethook(idle_wfi);
 
-    #ifdef RT_USING_CONSOLE
+#ifdef RT_USING_CONSOLE
     /* set console device */
     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
 #endif /* RT_USING_CONSOLE */
@@ -131,60 +124,51 @@ void rt_hw_board_init(void)
     rt_components_board_init();
 #endif
 
+#ifdef RT_USING_SMP
+    /* install IPI handle */
+    rt_hw_ipi_handler_install(IRQ_ARM_MAILBOX, rt_scheduler_ipi_handler);
+    rt_hw_interrupt_umask(IRQ_ARM_MAILBOX);
+    enable_cpu_ipi_intr(0);
+#endif
 }
 
 #ifdef RT_USING_SMP
-void _reset(void);
-void secondary_cpu_start(void);
+static unsigned long cpu_release_paddr[] =
+{
+    [0] = 0xd8,
+    [1] = 0xe0,
+    [2] = 0xe8,
+    [3] = 0xf0,
+    [4] = 0
+};
 
 void rt_hw_secondary_cpu_up(void)
 {
     int i;
-    int retry,val;
-    rt_cpu_dcache_clean_flush();
-    rt_cpu_icache_flush();
-    /*TODO maybe, there is some bug */
-    for(i=RT_CPUS_NR-1; i>0; i-- )
+    extern void secondary_cpu_start(void);
+
+    for (i = 1; i < RT_CPUS_NR && cpu_release_paddr[i]; ++i)
     {
-        rt_kprintf("boot cpu:%d\n", i);
-        setup_bootstrap_addr(i, (int)_reset);
-        __SEV();
+        __asm__ volatile ("str %0, [%1]"::"rZ"((unsigned long)secondary_cpu_start), "r"(cpu_release_paddr[i]));
+        rt_hw_dcache_flush_range(cpu_release_paddr[i], sizeof(cpu_release_paddr[i]));
         __DSB();
-        __ISB();
-        retry = 10;
-        rt_thread_delay(RT_TICK_PER_SECOND/1000);
-        do
-        {
-            val = CORE_MAILBOX3_CLEAR(i);
-            if (val == 0)
-            {
-                rt_kprintf("start OK: CPU %d \n",i);
-                break;
-            }
-            rt_thread_delay(RT_TICK_PER_SECOND);
-
-            retry --;
-            if (retry <= 0)
-            {
-                rt_kprintf("can't start for CPU %d \n",i);
-                break;
-            }
-        }while (1);
+        __SEV();
     }
-    __DSB();
-    __SEV();
 }
 
 void secondary_cpu_c_start(void)
 {
-    uint32_t id;
-    id = rt_hw_cpu_id();
-    rt_kprintf("cpu = 0x%08x\n",id);
-    rt_hw_timer_init();
-    rt_kprintf("cpu %d startup.\n",id);
+    int id = rt_hw_cpu_id();
+
+    rt_hw_mmu_init();
+    rt_hw_spin_lock(&_cpus_lock);
+
     rt_hw_vector_init();
+    rt_hw_timer_init();
     enable_cpu_ipi_intr(id);
-    rt_hw_spin_lock(&_cpus_lock);
+
+    rt_kprintf("\rcall cpu %d on success\n", id);
+
     rt_system_scheduler_start();
 }
 

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

@@ -299,7 +299,7 @@ int hdmi_fb_init(void)
     _hdmi.pitch = 0;
     _hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
 
-    armv8_map((unsigned long)_hdmi.fb, (unsigned long)_hdmi.fb, 0x200000, MEM_ATTR_IO);
+    rt_hw_mmu_map((unsigned long)_hdmi.fb, 0x200000, DEVICE_MEM);
 
     rt_hw_dcache_invalidate_range((unsigned long)_hdmi.fb,LCD_WIDTH * LCD_HEIGHT * 3);
 

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

@@ -129,7 +129,7 @@ static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
 
     volatile rt_base_t base = (volatile rt_base_t)(bus->parent.user_data);
 
-    if (bus->addr == 0)
+    if (bus->parent.user_data == 0)
         base = BCM283X_BSC0_BASE;
     else
         base = BCM283X_BSC1_BASE;
@@ -198,7 +198,6 @@ static struct raspi_i2c_hw_config hw_device0 =
 struct rt_i2c_bus_device device0 =
 {
     .ops = &raspi_i2c_ops,
-    .addr = 0,
 };
 
 #endif
@@ -216,7 +215,6 @@ static struct raspi_i2c_hw_config hw_device1 =
 struct rt_i2c_bus_device device1 =
 {
     .ops = &raspi_i2c_ops,
-    .addr = 1,
 };
 
 #endif
@@ -224,11 +222,13 @@ struct rt_i2c_bus_device device1 =
 int rt_hw_i2c_init(void)
 {
 #if defined(BSP_USING_I2C0)
+    device0.parent.user_data = (void *)0;
     raspi_i2c_configure(&hw_device0);
     rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME);
 #endif
 
 #if defined(BSP_USING_I2C1)
+    device1.parent.user_data = (void *)1;
     raspi_i2c_configure(&hw_device1);
     rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME);
 #endif

+ 2 - 0
bsp/raspberry-pi/raspi3-64/driver/mbox.c

@@ -14,6 +14,8 @@
 #include "mmu.h"
 //volatile unsigned int  __attribute__((aligned(16))) mbox[36];
 volatile unsigned int *mbox = (volatile unsigned int *) MBOX_ADDR;
+#define BUS_ADDRESS(phys)   (((phys) & ~0xC0000000)  |  0xC0000000)
+
 /**
  * Make a mailbox call. Returns 0 on failure, non-zero on success
  */

+ 8 - 0
bsp/raspberry-pi/raspi3-64/driver/raspi.h

@@ -304,6 +304,10 @@ typedef enum
 #define SYSTEM_TIMER_IRQ_3    (1 << 3)
 
 #define NON_SECURE_TIMER_IRQ    (1 << 1)
+rt_inline void core_timer_enable(int cpu_id)
+{
+    CORETIMER_INTCTL(cpu_id) |= NON_SECURE_TIMER_IRQ;
+}
 
 /* ARM Core Mailbox interrupt */
 #define C0MB_INTCTL      __REG32(PER_BASE_40000000 + 0x50)  /* Core0 Mailboxes Interrupt control */
@@ -337,6 +341,10 @@ typedef enum
 #define IPI_MAILBOX_SET  CORE_MAILBOX0_SET
 #define IPI_MAILBOX_CLEAR     CORE_MAILBOX0_CLEAR
 #define IPI_MAILBOX_INT_MASK (0x01)
+rt_inline void enable_cpu_ipi_intr(int cpu_id)
+{
+    COREMB_INTCTL(cpu_id) = IPI_MAILBOX_INT_MASK;
+}
 
 enum spi_bit_order
 {

+ 12 - 6
bsp/raspberry-pi/raspi3-64/rtconfig.h

@@ -13,12 +13,13 @@
 #define RT_TICK_PER_SECOND 100
 #define RT_USING_OVERFLOW_CHECK
 #define RT_USING_HOOK
+#define RT_HOOK_USING_FUNC_PTR
 #define RT_USING_IDLE_HOOK
 #define RT_IDLE_HOOK_LIST_SIZE 4
-#define IDLE_THREAD_STACK_SIZE 2048
+#define IDLE_THREAD_STACK_SIZE 8192
 #define RT_USING_TIMER_SOFT
 #define RT_TIMER_THREAD_PRIO 4
-#define RT_TIMER_THREAD_STACK_SIZE 2048
+#define RT_TIMER_THREAD_STACK_SIZE 4096
 
 /* kservice optimization */
 
@@ -108,7 +109,6 @@
 /* Device Drivers */
 
 #define RT_USING_DEVICE_IPC
-#define RT_PIPE_BUFSZ 512
 #define RT_USING_SERIAL
 #define RT_USING_SERIAL_V1
 #define RT_SERIAL_RB_BUFSZ 64
@@ -132,13 +132,16 @@
 
 /* POSIX layer and C standard library */
 
-#define RT_USING_LIBC
-#define RT_LIBC_USING_TIME
 #define RT_LIBC_DEFAULT_TIMEZONE 8
 
 /* POSIX (Portable Operating System Interface) layer */
 
 
+/* Interprocess Communication (IPC) */
+
+
+/* Socket is in the 'Network' category */
+
 /* Network */
 
 /* Socket abstraction layer */
@@ -200,7 +203,10 @@
 
 /* system packages */
 
-/* rt_kprintf: enhanced rt_kprintf packages */
+/* enhanced kernel services */
+
+
+/* POSIX extension functions */
 
 
 /* acceleration: Assembly language or algorithmic acceleration packages */

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

@@ -16,12 +16,14 @@ if os.getenv('RTT_CC'):
 PLATFORM    = 'gcc'
 EXEC_PATH   = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/'  
 
+if os.getenv('RTT_EXEC_PATH'):
+    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+
 BUILD = 'debug'
 
 if PLATFORM == 'gcc':
     # toolchains
-    # PREFIX = 'arm-none-eabi-'
-    PREFIX = 'aarch64-elf-'
+    PREFIX = 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'

+ 43 - 31
bsp/raspberry-pi/raspi4-64/.config

@@ -18,20 +18,19 @@ CONFIG_RT_THREAD_PRIORITY_MAX=32
 CONFIG_RT_TICK_PER_SECOND=100
 CONFIG_RT_USING_OVERFLOW_CHECK=y
 CONFIG_RT_USING_HOOK=y
+CONFIG_RT_HOOK_USING_FUNC_PTR=y
 CONFIG_RT_USING_IDLE_HOOK=y
 CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
-CONFIG_IDLE_THREAD_STACK_SIZE=2048
+CONFIG_IDLE_THREAD_STACK_SIZE=4096
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
-CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096
 
 #
 # kservice optimization
 #
 # CONFIG_RT_KSERVICE_USING_STDLIB is not set
 # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
-# CONFIG_RT_USING_ASM_MEMCPY is not set
-# CONFIG_RT_USING_ASM_MEMSET is not set
 # CONFIG_RT_USING_TINY_FFS is not set
 # CONFIG_RT_PRINTF_LONGLONG is not set
 CONFIG_RT_DEBUG=y
@@ -93,7 +92,7 @@ CONFIG_ARCH_ARMV8=y
 #
 CONFIG_RT_USING_COMPONENTS_INIT=y
 CONFIG_RT_USING_USER_MAIN=y
-CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=4096
 CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # CONFIG_RT_USING_LEGACY is not set
 
@@ -163,9 +162,8 @@ CONFIG_RT_USING_DFS_DEVFS=y
 # Device Drivers
 #
 CONFIG_RT_USING_DEVICE_IPC=y
-CONFIG_RT_PIPE_BUFSZ=512
 CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
-CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
+CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192
 CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
 CONFIG_RT_USING_SERIAL=y
 CONFIG_RT_USING_SERIAL_V1=y
@@ -190,12 +188,12 @@ CONFIG_RT_USING_ALARM=y
 CONFIG_RT_USING_SDIO=y
 CONFIG_RT_SDIO_STACK_SIZE=512
 CONFIG_RT_SDIO_THREAD_PRIORITY=15
-CONFIG_RT_MMCSD_STACK_SIZE=2048
+CONFIG_RT_MMCSD_STACK_SIZE=8192
 CONFIG_RT_MMCSD_THREAD_PREORITY=22
 CONFIG_RT_MMCSD_MAX_PARTITION=16
 # CONFIG_RT_SDIO_DEBUG is not set
 # CONFIG_RT_USING_SPI is not set
-# CONFIG_RT_USING_WDT is not set
+CONFIG_RT_USING_WDT=y
 # CONFIG_RT_USING_AUDIO is not set
 # CONFIG_RT_USING_SENSOR is not set
 # CONFIG_RT_USING_TOUCH is not set
@@ -214,9 +212,6 @@ CONFIG_RT_MMCSD_MAX_PARTITION=16
 #
 # POSIX layer and C standard library
 #
-CONFIG_RT_USING_LIBC=y
-CONFIG_RT_LIBC_USING_TIME=y
-# CONFIG_RT_LIBC_USING_FILEIO is not set
 # CONFIG_RT_USING_MODULE is not set
 CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 
@@ -225,12 +220,20 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 #
 # CONFIG_RT_USING_POSIX_FS is not set
 # CONFIG_RT_USING_POSIX_DELAY is not set
-# CONFIG_RT_USING_POSIX_GETLINE is not set
-# CONFIG_RT_USING_POSIX_MMAP is not set
-# CONFIG_RT_USING_POSIX_TERMIOS is not set
-# CONFIG_RT_USING_POSIX_AIO is not set
+# CONFIG_RT_USING_POSIX_CLOCK is not set
 # CONFIG_RT_USING_PTHREADS is not set
 
+#
+# Interprocess Communication (IPC)
+#
+# CONFIG_RT_USING_POSIX_PIPE is not set
+# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set
+# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
+
+#
+# Socket is in the 'Network' category
+#
+
 #
 # Network
 #
@@ -299,11 +302,11 @@ 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=2048
+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=2048
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=4096
 CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8
 # CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
 CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
@@ -407,6 +410,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CONFIG_PKG_USING_JIOT-C-SDK is not set
 # CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
 # CONFIG_PKG_USING_JOYLINK is not set
+# CONFIG_PKG_USING_EZ_IOT_OS is not set
 # CONFIG_PKG_USING_NIMBLE is not set
 # CONFIG_PKG_USING_OTA_DOWNLOADER is not set
 # CONFIG_PKG_USING_IPMSG is not set
@@ -441,12 +445,13 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
 # CONFIG_PKG_USING_HM is not set
 # CONFIG_PKG_USING_SMALL_MODBUS is not set
+# CONFIG_PKG_USING_NET_SERVER is not set
 
 #
 # security packages
 #
 # CONFIG_PKG_USING_MBEDTLS is not set
-# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_LIBSODIUM is not set
 # CONFIG_PKG_USING_TINYCRYPT is not set
 # CONFIG_PKG_USING_TFM is not set
 # CONFIG_PKG_USING_YD_CRYPTO is not set
@@ -468,6 +473,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 #
 # CONFIG_PKG_USING_LVGL is not set
 # CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
 
 #
 # u8g2: a monochrome graphic library
@@ -493,6 +499,9 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 #
 # CONFIG_PKG_USING_PAINTERENGINE is not set
 # CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_VT100 is not set
 
 #
 # tools packages
@@ -542,15 +551,21 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 #
 
 #
-# rt_kprintf: enhanced rt_kprintf packages
+# enhanced kernel services
 #
+# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
 # CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
 # CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
 
+#
+# POSIX extension functions
+#
+# CONFIG_PKG_USING_POSIX_GETLINE is not set
+# CONFIG_PKG_USING_POSIX_WCWIDTH is not set
+
 #
 # acceleration: Assembly language or algorithmic acceleration packages
 #
-# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
 # CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
 # CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
 # CONFIG_PKG_USING_QFPLIB_M3 is not set
@@ -559,7 +574,6 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
 #
 # CONFIG_PKG_USING_CMSIS_5 is not set
-# CONFIG_PKG_USING_CMSIS_5_AUX is not set
 # CONFIG_PKG_USING_CMSIS_RTOS2 is not set
 
 #
@@ -571,6 +585,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CONFIG_PKG_USING_UC_CLK is not set
 # CONFIG_PKG_USING_UC_COMMON is not set
 # CONFIG_PKG_USING_UC_MODBUS is not set
+# CONFIG_RT_USING_ARDUINO is not set
 # CONFIG_PKG_USING_GUIENGINE is not set
 # CONFIG_PKG_USING_CAIRO is not set
 # CONFIG_PKG_USING_PIXMAN is not set
@@ -599,10 +614,10 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CONFIG_PKG_USING_TLSF is not set
 # CONFIG_PKG_USING_EVENT_RECORDER is not set
 # CONFIG_PKG_USING_ARM_2D is not set
-# CONFIG_PKG_USING_WCWIDTH is not set
 # CONFIG_PKG_USING_MCUBOOT is not set
 # CONFIG_PKG_USING_TINYUSB is not set
 # CONFIG_PKG_USING_USB_STACK is not set
+# CONFIG_PKG_USING_LUATOS_SOC is not set
 
 #
 # peripheral libraries and drivers
@@ -676,6 +691,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CONFIG_PKG_USING_BLUETRUM_SDK is not set
 # CONFIG_PKG_USING_MISAKA_AT24CXX is not set
 # CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
+# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
 # CONFIG_PKG_USING_BL_MCU_SDK is not set
 # CONFIG_PKG_USING_SOFT_SERIAL is not set
 # CONFIG_PKG_USING_MB85RS16 is not set
@@ -717,6 +733,7 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CONFIG_PKG_USING_SNAKE is not set
 # CONFIG_PKG_USING_TETRIS is not set
 # CONFIG_PKG_USING_DONUT is not set
+# CONFIG_PKG_USING_COWSAY is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
@@ -738,14 +755,11 @@ CONFIG_YMODEM_USING_FILE_TRANSFER=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_VT100 is not set
 # CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_CRCLIB is not set
 # CONFIG_PKG_USING_LWGPS is not set
 # CONFIG_PKG_USING_STATE_MACHINE is not set
-# CONFIG_PKG_USING_MCURSES is not set
-# CONFIG_PKG_USING_COWSAY is not set
-# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_DESIGN_PATTERN is not set
 CONFIG_BCM2711_SOC=y
 CONFIG_BSP_SUPPORT_FPU=y
 
@@ -763,13 +777,11 @@ CONFIG_RT_USING_UART0=y
 # CONFIG_RT_USING_UART4 is not set
 # CONFIG_RT_USING_UART5 is not set
 CONFIG_BSP_USING_GIC=y
-CONFIG_BSP_USING_GIC400=y
-# CONFIG_BSP_USING_GIC500 is not set
 CONFIG_BSP_USING_PIN=y
 CONFIG_BSP_USING_CORETIMER=y
 # CONFIG_BSP_USING_SYSTIMER is not set
-CONFIG_BSP_USING_ETH=y
-# CONFIG_BSP_USING_WDT is not set
+# CONFIG_BSP_USING_ETH is not set
+CONFIG_BSP_USING_WDT=y
 CONFIG_BSP_USING_RTC=y
 CONFIG_BSP_USING_ALARM=y
 CONFIG_BSP_USING_SDIO=y

+ 7 - 16
bsp/raspberry-pi/raspi4-64/driver/Kconfig

@@ -12,38 +12,29 @@ menu "Hardware Drivers Config"
 
             if BSP_USING_UART
                 config RT_USING_UART0
-                bool "Enabel UART 0"
+                bool "Enable UART 0"
                 default y
 
                 config RT_USING_UART1
-                bool "Enabel UART 1"
+                bool "Enable UART 1"
                 default n
 
                 config RT_USING_UART3
-                bool "Enabel UART 3"
+                bool "Enable UART 3"
                 default n
 
                 config RT_USING_UART4
-                bool "Enabel UART 4"
+                bool "Enable UART 4"
                 default n
 
                 config RT_USING_UART5
-                bool "Enabel UART 5"
+                bool "Enable UART 5"
                 default n
             endif
 
-        menuconfig BSP_USING_GIC
-            bool "Enable GIC"
-            select RT_USING_GIC
+        config BSP_USING_GIC
+            bool
             default y
-        if BSP_USING_GIC
-            config BSP_USING_GIC400
-                bool "Enable GIC400"
-                default y
-            config BSP_USING_GIC500
-                bool "Enable GIC500"
-                default n
-        endif
 
         config BSP_USING_PIN
             bool "Using PIN"

+ 87 - 45
bsp/raspberry-pi/raspi4-64/driver/board.c

@@ -6,6 +6,7 @@
  * Change Logs:
  * Date           Author         Notes
  * 2020-04-16     bigmagic       first version
+ * 2021-12-28     GuEe-GUI       add smp support
  */
 
 #include <rthw.h>
@@ -14,48 +15,43 @@
 #include "board.h"
 #include "drv_uart.h"
 
-#include "cp15.h"
 #include "mmu.h"
+#include "gic.h"
+#include "gtimer.h"
+#include "cpuport.h"
+#include "interrupt.h"
 #include "mbox.h"
 
-#ifdef BSP_USING_CORETIMER
-static rt_uint64_t timerStep;
-
-int rt_hw_get_gtimer_frq(void);
-void rt_hw_set_gtimer_val(rt_uint64_t value);
-int rt_hw_get_gtimer_val(void);
-int rt_hw_get_cntpct_val(void);
-void rt_hw_gtimer_enable(void);
-
-void core0_timer_enable_interrupt_controller(void)
+struct mem_desc platform_mem_desc[] =
 {
-    CORE0_TIMER_IRQ_CTRL |= NON_SECURE_TIMER_IRQ;
-}
-#endif
-
+    {0, 0x6400000, 0, NORMAL_MEM},
+    {0xFE200000, 0xFE400000, 0xFE200000, DEVICE_MEM}, /* uart gpio */
+    {0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM}, /* gic timer */
+    {WDT_BASE, WDT_BASE + 0x1000, WDT_BASE, DEVICE_MEM}, /* wdt */
+    {MBOX_ADDR, MBOX_ADDR + 0x200000, MBOX_ADDR, DEVICE_MEM}, /* mbox msg */
+    {STIMER_BASE, STIMER_BASE + 0x200000, STIMER_BASE, DEVICE_MEM}, /* stimer */
+    {MAC_BASE_ADDR, MAC_BASE_ADDR + 0x80000, MAC_BASE_ADDR, DEVICE_MEM}, /* mac */
+    {MMC2_BASE_ADDR, MMC2_BASE_ADDR + 0x200000, MMC2_BASE_ADDR, DEVICE_MEM}, /* mmc */
+    {ARM_TIMER_BASE, ARM_TIMER_BASE + 0x200000, ARM_TIMER_BASE, DEVICE_MEM}, /* arm timer */
+    {SEND_DATA_NO_CACHE, SEND_DATA_NO_CACHE + 0x200000, SEND_DATA_NO_CACHE, NORMAL_MEM}, /* eth send */
+    {RECV_DATA_NO_CACHE, RECV_DATA_NO_CACHE + 0x200000, RECV_DATA_NO_CACHE, NORMAL_MEM}, /* eth recv */
+};
+
+const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
+
+#if !defined(BSP_USING_CORETIMER) && !defined(RT_USING_SMP)
 void rt_hw_timer_isr(int vector, void *parameter)
 {
-#ifdef BSP_USING_CORETIMER
-    rt_hw_set_gtimer_val(timerStep);
-#else
     ARM_TIMER_IRQCLR = 0;
-#endif
     rt_tick_increase();
 }
+#endif
 
 void rt_hw_timer_init(void)
 {
-#ifdef BSP_USING_CORETIMER
-    rt_hw_interrupt_install(TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
-    rt_hw_interrupt_umask(TIMER_IRQ);
-    __ISB();
-    timerStep = rt_hw_get_gtimer_frq();
-    __DSB();
-    timerStep /= RT_TICK_PER_SECOND;
-
-    rt_hw_gtimer_enable();
-    rt_hw_set_gtimer_val(timerStep);
-    core0_timer_enable_interrupt_controller();
+#if defined(BSP_USING_CORETIMER) || defined(RT_USING_SMP)
+    rt_hw_gtimer_init();
+    core_timer_enable(0);
 #else
     rt_uint32_t apb_clock = 0;
     rt_uint32_t timer_clock = 1000000;
@@ -65,7 +61,7 @@ void rt_hw_timer_init(void)
 
     ARM_TIMER_RELOAD = 0;
     ARM_TIMER_LOAD   = 0;
-    ARM_TIMER_IRQCLR = 0;
+    ARM_TIMER_IRQCLR = 1;
     ARM_TIMER_CTRL   = 0;
 
     ARM_TIMER_RELOAD = 1000000 / RT_TICK_PER_SECOND;
@@ -90,22 +86,11 @@ void idle_wfi(void)
  */
 void rt_hw_board_init(void)
 {
-    mmu_init();
-    armv8_map(0, 0, 0x6400000, MEM_ATTR_MEMORY);
-    armv8_map(0xFE200000, 0xFE200000, 0x200000, MEM_ATTR_IO);//uart gpio
-    armv8_map(0xFF800000, 0xFF800000, 0x200000, MEM_ATTR_IO);//gic timer
-    armv8_map(ARM_TIMER_BASE, ARM_TIMER_BASE, 0x200000, MEM_ATTR_IO);//arm timer
-    armv8_map(STIMER_BASE, STIMER_BASE, 0x200000, MEM_ATTR_IO);//stimer
-    armv8_map(MMC2_BASE_ADDR, MMC2_BASE_ADDR, 0x200000, MEM_ATTR_IO);//mmc
-    armv8_map(MBOX_ADDR, MBOX_ADDR, 0x200000, MEM_ATTR_IO);//mbox msg
-    armv8_map((unsigned long)MAC_REG_BASE_ADDR, (unsigned long)MAC_REG_BASE_ADDR, 0x80000, MEM_ATTR_IO);//mac
-    armv8_map(SEND_DATA_NO_CACHE, SEND_DATA_NO_CACHE, 0x200000, MEM_ATTR_MEMORY);//eth send
-    armv8_map(RECV_DATA_NO_CACHE, RECV_DATA_NO_CACHE, 0x200000, MEM_ATTR_MEMORY);//eth recv
-    mmu_enable();
+    rt_hw_init_mmu_table(platform_mem_desc, platform_mem_desc_size);
+    rt_hw_mmu_init();
 
     /* initialize hardware interrupt */
     rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
-    rt_hw_vector_init();    // in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors);
 
     /* initialize uart */
     rt_hw_uart_init();      // driver/drv_uart.c
@@ -119,11 +104,68 @@ void rt_hw_board_init(void)
     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
-        /* initialize timer for os tick */
+    /* initialize timer for os tick */
     rt_hw_timer_init();
     rt_thread_idle_sethook(idle_wfi);
 
 #ifdef RT_USING_COMPONENTS_INIT
     rt_components_board_init();
 #endif
+
+#ifdef RT_USING_SMP
+    /* install IPI handle */
+    rt_hw_ipi_handler_install(IRQ_ARM_IPI_KICK, rt_scheduler_ipi_handler);
+    arm_gic_umask(0, IRQ_ARM_IPI_KICK);
+#endif
+}
+
+#ifdef RT_USING_SMP
+static unsigned long cpu_release_paddr[] =
+{
+    [0] = 0xd8,
+    [1] = 0xe0,
+    [2] = 0xe8,
+    [3] = 0xf0,
+    [4] = 0
+};
+
+void rt_hw_secondary_cpu_up(void)
+{
+    int i;
+    extern void secondary_cpu_start(void);
+
+    for (i = 1; i < RT_CPUS_NR && cpu_release_paddr[i]; ++i)
+    {
+        __asm__ volatile ("str %0, [%1]"::"rZ"((unsigned long)secondary_cpu_start), "r"(cpu_release_paddr[i]));
+        rt_hw_dcache_flush_range(cpu_release_paddr[i], sizeof(cpu_release_paddr[i]));
+        __DSB();
+        __SEV();
+    }
+}
+
+void secondary_cpu_c_start(void)
+{
+    int id;
+
+    rt_hw_mmu_init();
+
+    id = rt_hw_cpu_id();
+    rt_hw_spin_lock(&_cpus_lock);
+
+    arm_gic_cpu_init(0, platform_get_gic_cpu_base());
+    rt_hw_vector_init();
+    rt_hw_gtimer_local_enable();
+    core_timer_enable(id);
+    arm_gic_umask(0, IRQ_ARM_IPI_KICK);
+
+    rt_kprintf("\rcall cpu %d on success\n", id);
+
+    rt_system_scheduler_start();
 }
+
+void rt_hw_secondary_cpu_idle_exec(void)
+{
+    __WFE();
+}
+#endif
+

+ 6 - 1
bsp/raspberry-pi/raspi4-64/driver/drv_eth.c

@@ -13,6 +13,9 @@
 #include <rthw.h>
 #include <stdint.h>
 #include <rtthread.h>
+
+#ifdef BSP_USING_ETH
+
 #include <lwip/sys.h>
 #include <netif/ethernetif.h>
 #include <mmu.h>
@@ -39,7 +42,7 @@
 
 #define BIT(nr)                 (1UL << (nr))
 
-#define LINK_THREAD_STACK_SIZE  (1024)
+#define LINK_THREAD_STACK_SIZE  (2048)
 #define LINK_THREAD_PRIORITY    (20)
 #define LINK_THREAD_TIMESLICE   (10)
 
@@ -721,3 +724,5 @@ int rt_hw_eth_init(void)
     return 0;
 }
 INIT_COMPONENT_EXPORT(rt_hw_eth_init);
+
+#endif /* BSP_USING_ETH */

+ 4 - 0
bsp/raspberry-pi/raspi4-64/driver/drv_sdio.c

@@ -15,6 +15,8 @@
 
 #include "mmu.h"
 
+#ifdef BSP_USING_SDIO
+
 static rt_uint32_t mmc_base_clock = 0;
 
 static rt_uint32_t sdCommandTable[] =
@@ -718,3 +720,5 @@ err:
 }
 
 INIT_DEVICE_EXPORT(raspi_sdmmc_init);
+
+#endif /* BSP_USING_SDIO */

+ 141 - 0
bsp/raspberry-pi/raspi4-64/driver/drv_wdt.c

@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-10-26     bigmagic       first version
+ */
+
+#include <rthw.h>
+#include "drv_wdt.h"
+#include "raspi4.h"
+
+#ifdef BSP_USING_WDT
+
+#define SECS_TO_WDOG_TICKS(x) ((x) << 16)
+#define WDOG_TICKS_TO_SECS(x) ((x) >> 16)
+
+static struct raspi_wdt_driver bcm_wdt;
+
+void raspi_watchdog_init(rt_uint32_t time_init)
+{
+    bcm_wdt.timeout = time_init;
+}
+
+void raspi_watchdog_start()
+{
+    volatile rt_uint32_t cur;
+    PM_WDOG = PM_PASSWORD | (SECS_TO_WDOG_TICKS(bcm_wdt.timeout) & PM_WDOG_TIME_SET);
+    cur = (PM_RSTC);
+    PM_RSTC = PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET;
+}
+
+void raspi_watchdog_stop()
+{
+    PM_RSTC = PM_PASSWORD | PM_RSTC_RESET;
+}
+
+void raspi_watchdog_clr()
+{
+    bcm_wdt.timeout = 0;
+}
+
+void raspi_watchdog_set_timeout(rt_uint32_t timeout_us)
+{
+    bcm_wdt.timeout = timeout_us;
+}
+
+rt_uint64_t raspi_watchdog_get_timeout()
+{
+    return bcm_wdt.timeout;
+}
+
+rt_uint64_t raspi_watchdog_get_timeleft()
+{
+    rt_uint32_t ret = (PM_WDOG);
+    return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
+}
+
+static rt_err_t raspi_wdg_init(rt_watchdog_t *wdt)
+{
+    /* init for 10S */
+    raspi_watchdog_init(1000000);
+    raspi_watchdog_start();
+    raspi_watchdog_stop();
+
+    return RT_EOK;
+}
+
+static rt_err_t raspi_wdg_control(rt_watchdog_t *wdt, int cmd, void *arg)
+{
+    rt_uint64_t timeout_us = 0;
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
+        timeout_us = *((rt_uint32_t *)arg) * 1000000;
+        if (timeout_us >= 0xFFFFFFFF)
+        {
+            timeout_us = 0xFFFFFFFF;
+        }
+        raspi_watchdog_set_timeout((rt_uint32_t)timeout_us);
+        break;
+    case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
+        timeout_us = raspi_watchdog_get_timeout();
+        *((rt_uint32_t *)arg) = timeout_us / 1000000;
+        break;
+    case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
+        timeout_us = raspi_watchdog_get_timeleft();
+        *((rt_uint32_t *)arg) = timeout_us / 1000000;
+        break;
+    case RT_DEVICE_CTRL_WDT_KEEPALIVE:
+        raspi_watchdog_clr();
+        break;
+    case RT_DEVICE_CTRL_WDT_START:
+        raspi_watchdog_start();
+        break;
+    case RT_DEVICE_CTRL_WDT_STOP:
+        raspi_watchdog_stop();
+        break;
+    default:
+        return RT_EIO;
+    }
+
+    return RT_EOK;
+}
+
+static const struct rt_watchdog_ops raspi_wdg_pos =
+{
+    raspi_wdg_init,
+    raspi_wdg_control,
+};
+
+static rt_watchdog_t raspi_wdg;
+
+int rt_hw_wdt_init(void)
+{
+    raspi_wdg.ops = &raspi_wdg_pos;
+    rt_hw_watchdog_register(&raspi_wdg, "wdg", 0, RT_NULL);
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_wdt_init);
+
+void reboot(void)
+{
+    unsigned int r;
+
+    rt_kprintf("reboot system...\n");
+    rt_thread_mdelay(100);
+    r = PM_RSTS;
+    /* trigger a restart by instructing the GPU to boot from partition 0 */
+    r &= ~0xfffffaaa;
+    PM_RSTS |= (PM_PASSWORD | r);   /* boot from partition 0 */
+    PM_WDOG |= (PM_PASSWORD | 0x0A);
+    PM_RSTC |= (PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET);
+
+    while (1) {};
+}
+MSH_CMD_EXPORT(reboot, reboot system...);
+#endif /*BSP_USING_WDT */

+ 26 - 0
bsp/raspberry-pi/raspi4-64/driver/drv_wdt.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-10-26     bigmagic       first version
+ */
+
+#ifndef __DRV_WDT_H__
+#define __DRV_WDT_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "board.h"
+
+struct raspi_wdt_driver
+{
+    rt_uint32_t timeout;
+};
+
+int rt_hw_wdt_init(void);
+
+#endif

+ 24 - 2
bsp/raspberry-pi/raspi4-64/driver/raspi4.h

@@ -83,9 +83,13 @@ typedef enum
 } PACTL_CS_VAL;
 
 // 0x40, 0x44, 0x48, 0x4c: Core 0~3 Timers interrupt control
-#define CORE0_TIMER_IRQ_CTRL    HWREG32(0xFF800040)
+#define CORE_TIMER_IRQ_CTRL(n)  HWREG32((unsigned long)(0xFF800040 + (n) * 4))
 #define TIMER_IRQ               30
 #define NON_SECURE_TIMER_IRQ    (1 << 1)
+rt_inline void core_timer_enable(int cpu_id)
+{
+    CORE_TIMER_IRQ_CTRL(cpu_id) |= NON_SECURE_TIMER_IRQ;
+}
 
 //core timer
 #define ST_BASE_OFFSET          (0x003000)
@@ -109,11 +113,25 @@ do { \
 #define MMC2_BASE_ADDR          (PER_BASE + 0x340000)
 
 //eth
-#define MAC_REG_BASE_ADDR       (void *)(0xfd580000)
+#define MAC_BASE_ADDR           (0xfd580000)
+#define MAC_REG_BASE_ADDR       (void *)(MAC_BASE_ADDR)
 #define ETH_IRQ                 (160 + 29)
 #define SEND_DATA_NO_CACHE      (0x08200000)
 #define RECV_DATA_NO_CACHE      (0x08400000)
 
+//watchdog
+#define WDT_BASE                    (PER_BASE + 0x00100000)
+#define PM_RSTC                     HWREG32(WDT_BASE + 0x0000001c)
+#define PM_RSTS                     HWREG32(WDT_BASE + 0x00000020)
+#define PM_WDOG                     HWREG32(WDT_BASE + 0x00000024)
+
+#define PM_PASSWORD                 (0x5A000000)
+#define PM_WDOG_TIME_SET            (0x000fffff)
+#define PM_RSTS_HADWRH_SET          (0x00000040)
+#define PM_RSTC_WRCFG_FULL_RESET    (0x00000020)
+#define PM_RSTC_WRCFG_CLR           (0xffffffcf)
+#define PM_RSTC_RESET               (0x00000102)
+
 //gic max
 #define MAX_HANDLERS                (256)
 #define ARM_GIC_NR_IRQS             (512)
@@ -125,6 +143,10 @@ do { \
 #define GIC_V2_HYPERVISOR_BASE      (INTC_BASE + 0x00044000)
 #define GIC_V2_VIRTUAL_CPU_BASE     (INTC_BASE + 0x00046000)
 
+/* ipi interrupt number */
+#define IRQ_ARM_IPI_KICK            0
+#define IRQ_ARM_IPI_CALL            1
+
 #define GIC_IRQ_START               0
 #define GIC_ACK_INTID_MASK          0x000003ff
 

+ 19 - 13
bsp/raspberry-pi/raspi4-64/rtconfig.h

@@ -13,12 +13,13 @@
 #define RT_TICK_PER_SECOND 100
 #define RT_USING_OVERFLOW_CHECK
 #define RT_USING_HOOK
+#define RT_HOOK_USING_FUNC_PTR
 #define RT_USING_IDLE_HOOK
 #define RT_IDLE_HOOK_LIST_SIZE 4
-#define IDLE_THREAD_STACK_SIZE 2048
+#define IDLE_THREAD_STACK_SIZE 4096
 #define RT_USING_TIMER_SOFT
 #define RT_TIMER_THREAD_PRIO 4
-#define RT_TIMER_THREAD_STACK_SIZE 2048
+#define RT_TIMER_THREAD_STACK_SIZE 4096
 
 /* kservice optimization */
 
@@ -53,7 +54,7 @@
 
 #define RT_USING_COMPONENTS_INIT
 #define RT_USING_USER_MAIN
-#define RT_MAIN_THREAD_STACK_SIZE 2048
+#define RT_MAIN_THREAD_STACK_SIZE 4096
 #define RT_MAIN_THREAD_PRIORITY 10
 
 /* C++ features */
@@ -103,9 +104,8 @@
 /* Device Drivers */
 
 #define RT_USING_DEVICE_IPC
-#define RT_PIPE_BUFSZ 512
 #define RT_USING_SYSTEM_WORKQUEUE
-#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
+#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192
 #define RT_SYSTEM_WORKQUEUE_PRIORITY 23
 #define RT_USING_SERIAL
 #define RT_USING_SERIAL_V1
@@ -117,22 +117,26 @@
 #define RT_USING_SDIO
 #define RT_SDIO_STACK_SIZE 512
 #define RT_SDIO_THREAD_PRIORITY 15
-#define RT_MMCSD_STACK_SIZE 2048
+#define RT_MMCSD_STACK_SIZE 8192
 #define RT_MMCSD_THREAD_PREORITY 22
 #define RT_MMCSD_MAX_PARTITION 16
+#define RT_USING_WDT
 
 /* Using USB */
 
 
 /* POSIX layer and C standard library */
 
-#define RT_USING_LIBC
-#define RT_LIBC_USING_TIME
 #define RT_LIBC_DEFAULT_TIMEZONE 8
 
 /* POSIX (Portable Operating System Interface) layer */
 
 
+/* Interprocess Communication (IPC) */
+
+
+/* Socket is in the 'Network' category */
+
 /* Network */
 
 /* Socket abstraction layer */
@@ -185,9 +189,9 @@
 #define RT_LWIP_TCP_WND 8196
 #define RT_LWIP_TCPTHREAD_PRIORITY 10
 #define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
-#define RT_LWIP_TCPTHREAD_STACKSIZE 2048
+#define RT_LWIP_TCPTHREAD_STACKSIZE 4096
 #define RT_LWIP_ETHTHREAD_PRIORITY 12
-#define RT_LWIP_ETHTHREAD_STACKSIZE 2048
+#define RT_LWIP_ETHTHREAD_STACKSIZE 4096
 #define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
 #define LWIP_NETIF_STATUS_CALLBACK 1
 #define LWIP_NETIF_LINK_CALLBACK 1
@@ -251,7 +255,10 @@
 
 /* system packages */
 
-/* rt_kprintf: enhanced rt_kprintf packages */
+/* enhanced kernel services */
+
+
+/* POSIX extension functions */
 
 
 /* acceleration: Assembly language or algorithmic acceleration packages */
@@ -286,10 +293,9 @@
 #define BSP_USING_UART
 #define RT_USING_UART0
 #define BSP_USING_GIC
-#define BSP_USING_GIC400
 #define BSP_USING_PIN
 #define BSP_USING_CORETIMER
-#define BSP_USING_ETH
+#define BSP_USING_WDT
 #define BSP_USING_RTC
 #define BSP_USING_ALARM
 #define BSP_USING_SDIO

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

@@ -16,12 +16,14 @@ if os.getenv('RTT_CC'):
 PLATFORM    = 'gcc'
 EXEC_PATH   = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/'  
 
+if os.getenv('RTT_EXEC_PATH'):
+    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+
 BUILD = 'debug'
 
 if PLATFORM == 'gcc':
     # toolchains
-    # PREFIX = 'arm-none-eabi-'
-    PREFIX = 'aarch64-elf-'
+    PREFIX = 'aarch64-none-elf-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'

+ 8 - 1
libcpu/aarch64/common/armv8.h

@@ -6,18 +6,23 @@
  * 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 xz;
+    unsigned long long xzr;
+    unsigned long long fpcr;
+    unsigned long long fpsr;
     unsigned long long x28;
     unsigned long long x29;
     unsigned long long x26;
@@ -48,6 +53,8 @@ struct rt_hw_exp_stack
     unsigned long long x3;
     unsigned long long x0;
     unsigned long long x1;
+
+    unsigned long long fpu[16];
 };
 
 #define SP_ELx                      ( ( unsigned long long ) 0x01 )

+ 47 - 0
libcpu/aarch64/common/asm_fpu.h

@@ -0,0 +1,47 @@
+/*
+ * 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

+ 52 - 1
libcpu/aarch64/common/cache.S

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -134,6 +134,57 @@ __asm_flush_dcache_range:
     dsb    sy
     ret
 
+/* void __asm_invalidate_dcache_range(start, end)
+ *
+ * invalidate data cache in the range
+ *
+ * x0: start address
+ * x1: end address
+ */
+.globl __asm_invalidate_dcache_range
+__asm_invalidate_dcache_range:
+    mrs    x3, ctr_el0
+    lsr    x3, x3, #16
+    and    x3, x3, #0xf
+    mov    x2, #4
+    lsl    x2, x2, x3        /* cache line size */
+
+    /* x2 <- minimal cache line size in cache system */
+    sub    x3, x2, #1
+    bic    x0, x0, x3
+
+1:  dc   ivac, x0    /* invalidate data or unified cache */
+    add    x0, x0, x2
+    cmp    x0, x1
+    b.lo    1b
+    dsb    sy
+    ret
+
+/* void __asm_invalidate_icache_range(start, end)
+ *
+ * invalidate icache in the range
+ *
+ * x0: start address
+ * x1: end address
+ */
+.globl __asm_invalidate_icache_range
+__asm_invalidate_icache_range:
+    mrs    x3, ctr_el0
+    and    x3, x3, #0xf
+    mov    x2, #4
+    lsl    x2, x2, x3        /* cache line size */
+
+    /* x2 <- minimal cache line size in cache system */
+    sub    x3, x2, #1
+    bic    x0, x0, x3
+
+1:  ic   ivau, x0    /* invalidate instruction or unified cache */
+    add    x0, x0, x2
+    cmp    x0, x1
+    b.lo    1b
+    dsb    sy
+    ret
+
 /*
  * void __asm_invalidate_icache_all(void)
  *

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

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-12-28     GuEe-GUI     the first version
+ */
+
+#include <rthw.h>
+#include <rtdef.h>
+
+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 rt_hw_dcache_flush_all(void)
+{
+    __asm_flush_dcache_all();
+}
+
+void rt_hw_dcache_invalidate_all(void)
+{
+    __asm_invalidate_dcache_all();
+}
+
+void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size)
+{
+    __asm_flush_dcache_range(start_addr, start_addr + size);
+}
+
+void rt_hw_dcache_invalidate_range(unsigned long start_addr,unsigned long size)
+{
+    __asm_invalidate_dcache_range(start_addr, start_addr + size);
+}
+
+void rt_hw_icache_invalidate_all()
+{
+    __asm_invalidate_icache_all();
+}
+
+void rt_hw_icache_invalidate_range(unsigned long start_addr, int size)
+{
+    __asm_invalidate_icache_range(start_addr, start_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);
+    }
+}
+
+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);
+    }
+    else if (ops == RT_HW_CACHE_INVALIDATE)
+    {
+        rt_hw_dcache_invalidate_range((unsigned long)addr, size);
+    }
+}

+ 74 - 11
libcpu/aarch64/common/context_gcc.S

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -7,8 +7,17 @@
  * 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
  */
 
+#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
+
 /*
  *enable gtimer
  */
@@ -58,6 +67,7 @@ rt_hw_get_gtimer_frq:
 
 .macro SAVE_CONTEXT
     /* Save the entire context. */
+    SAVE_FPU SP
     STP 	X0, X1, [SP, #-0x10]!
     STP 	X2, X3, [SP, #-0x10]!
     STP 	X4, X5, [SP, #-0x10]!
@@ -73,6 +83,9 @@ rt_hw_get_gtimer_frq:
     STP 	X24, X25, [SP, #-0x10]!
     STP 	X26, X27, [SP, #-0x10]!
     STP 	X28, X29, [SP, #-0x10]!
+    MRS     X28, FPCR
+    MRS     X29, FPSR
+    STP     X28, X29, [SP, #-0x10]!
     STP 	X30, XZR, [SP, #-0x10]!
 
     MRS		X0, CurrentEL
@@ -107,6 +120,7 @@ rt_hw_get_gtimer_frq:
 
 .macro SAVE_CONTEXT_T
     /* Save the entire context. */
+    SAVE_FPU SP
     STP 	X0, X1, [SP, #-0x10]!
     STP 	X2, X3, [SP, #-0x10]!
     STP 	X4, X5, [SP, #-0x10]!
@@ -122,6 +136,9 @@ rt_hw_get_gtimer_frq:
     STP 	X24, X25, [SP, #-0x10]!
     STP 	X26, X27, [SP, #-0x10]!
     STP 	X28, X29, [SP, #-0x10]!
+    MRS     X28, FPCR
+    MRS     X29, FPSR
+    STP     X28, X29, [SP, #-0x10]!
     STP 	X30, XZR, [SP, #-0x10]!
 
     MRS		X0, CurrentEL
@@ -182,6 +199,9 @@ rt_hw_get_gtimer_frq:
 0:
 
     LDP 	X30, XZR, [SP], #0x10
+    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
@@ -197,6 +217,7 @@ rt_hw_get_gtimer_frq:
     LDP 	X4, X5, [SP], #0x10
     LDP 	X2, X3, [SP], #0x10
     LDP 	X0, X1, [SP], #0x10
+    RESTORE_FPU SP
 
     ERET
 
@@ -227,22 +248,46 @@ rt_hw_interrupt_enable_exit:
     RET
 
 /*
+ * #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);
- * r0 --> to
+ * #endif
+ * X0 --> to
+ * X1 --> to_thread
  */
 .globl rt_hw_context_switch_to
 rt_hw_context_switch_to:
+#ifdef RT_USING_SMP
+    STR     X0, [SP, #-0x8]!
+    MOV     X0, X1
+    BL      rt_cpus_lock_status_restore
+    LDR     X0, [SP], #0x8
+#endif /*RT_USING_SMP*/
     LDR		X0, [X0]
     RESTORE_CONTEXT
 
 .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);
- * r0 --> from
- * r1 --> to
+ * #endif
+ * X0 --> from
+ * X1 --> to
+ * X2 --> to_thread
  */
 .globl rt_hw_context_switch
 rt_hw_context_switch:
+#ifdef RT_USING_SMP
+    STP     X0, X1, [SP, #-0x10]!
+    STR     X30, [SP, #-0x8]!
+    MOV     X0, X2
+    BL      rt_cpus_lock_status_restore
+    LDR     X30, [SP], #0x8
+    LDP     X0, X1, [SP], #0x10
+#endif /*RT_USING_SMP*/
 
     MOV		X8,X0
     MOV		X9,X1
@@ -262,19 +307,32 @@ rt_hw_context_switch:
 .globl rt_interrupt_to_thread
 .globl rt_hw_context_switch_interrupt
 rt_hw_context_switch_interrupt:
-    ADR 	X2, rt_thread_switch_interrupt_flag
+#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
-    ADR 	X4, rt_interrupt_from_thread   // set rt_interrupt_from_thread
+    LDR 	X4, =rt_interrupt_from_thread  // set rt_interrupt_from_thread
     MOV 	X3, #1              // set rt_thread_switch_interrupt_flag to 1
     STR 	X0, [X4]
     STR 	X3, [X2]
 _reswitch:
-    ADR 	X2, rt_interrupt_to_thread     // set rt_interrupt_to_thread
+    LDR 	X2, =rt_interrupt_to_thread    // set rt_interrupt_to_thread
     STR 	X1, [X2]
     RET
-
+#endif
 .text
 
 // -- Exception handlers ----------------------------------
@@ -308,10 +366,15 @@ vector_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
-    ADR 	X1, rt_thread_switch_interrupt_flag
+    LDR 	X1, =rt_thread_switch_interrupt_flag
     LDR     X2, [X1]
     CMP     X2, #1
     B.NE     vector_irq_exit
@@ -319,11 +382,11 @@ vector_irq:
     MOV     X2,  #0         // clear flag
     STR     X2,  [X1]
 
-    ADR     X3,  rt_interrupt_from_thread
+    LDR     X3, =rt_interrupt_from_thread
     LDR     X4,  [X3]
     STR     x0,  [X4]       // store sp in preempted tasks's TCB
 
-    ADR     x3,  rt_interrupt_to_thread
+    LDR     x3, =rt_interrupt_to_thread
     LDR     X4,  [X3]
     LDR     x0,  [X4]       // get new task's stack pointer
     

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

@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2006-2021, 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");
-}
-
-#ifdef RT_USING_SMP
-static inline void send_ipi_msg(int cpu, int ipi_vector)
-{
-    IPI_MAILBOX_SET(cpu) = 1 << ipi_vector;
-}
-
-static inline void setup_bootstrap_addr(int cpu, int addr)
-{
-    CORE_MAILBOX3_SET(cpu) = addr;
-}
-
-static inline void enable_cpu_ipi_intr(int cpu)
-{
-    COREMB_INTCTL(cpu) = IPI_MAILBOX_INT_MASK;
-}
-
-static inline void enable_cpu_timer_intr(int cpu)
-{
-    CORETIMER_INTCTL(cpu) = 0x8;
-}
-
-static inline void enable_cntv(void)
-{
-    rt_uint32_t cntv_ctl;
-    cntv_ctl = 1;
-    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL
-}
-
-static inline void disable_cntv(void)
-{
-    rt_uint32_t cntv_ctl;
-    cntv_ctl = 0;
-    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL
-}
-
-static inline  void mask_cntv(void)
-{
-    rt_uint32_t cntv_ctl;
-    cntv_ctl = 2;
-    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL
-}
-
-static inline void unmask_cntv(void)
-{
-    rt_uint32_t cntv_ctl;
-    cntv_ctl = 1;
-    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL
-}
-
-static inline rt_uint64_t read_cntvct(void)
-{
-    rt_uint32_t val,val1;
-    asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (val),"=r" (val1));
-    return (val);
-}
-
-static inline rt_uint64_t read_cntvoff(void)
-{
-
-    rt_uint64_t val;
-    asm volatile("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val));
-    return (val);
-}
-
-static inline rt_uint32_t read_cntv_tval(void)
-{
-    rt_uint32_t val;
-    asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val) );
-    return val;
-}
-
-
-static inline  void write_cntv_tval(rt_uint32_t val)
-{
-    asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val) );
-    return;
-}
-
-static inline rt_uint32_t read_cntfrq(void)
-{
-    rt_uint32_t val;
-    asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val) );
-    return val;
-}
-
-
-static inline  rt_uint32_t read_cntctrl(void)
-{
-    rt_uint32_t val;
-    asm volatile ("mrc p15, 0, %0, c14, c1, 0" : "=r"(val) );
-    return val;
-}
-
-static inline uint32_t write_cntctrl(uint32_t val)
-{
-
-    asm volatile ("mcr p15, 0, %0, c14, c1, 0" : :"r"(val) );
-    return val;
-}
-#endif
-
-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

+ 55 - 35
libcpu/aarch64/common/cpu.c

@@ -7,25 +7,38 @@
  * Date           Author       Notes
  * 2011-09-15     Bernard      first version
  * 2019-07-28     zdzn         add smp support
+ * 2021-12-21     GuEe-GUI     set tpidr_el2 as multiprocessor id instead of mpidr_el1
+ * 2021-12-28     GuEe-GUI     add spinlock for aarch64
  */
 
 #include <rthw.h>
 #include <rtthread.h>
-#include <board.h>
-#include "cp15.h"
+#include <cpuport.h>
+
+#ifdef RT_USING_SMP
+/* 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[] =
+{
+    [0] = 0x80000000,
+    [1] = 0x80000001,
+    [2] = 0x80000002,
+    [3] = 0x80000003,
+    [4] = 0x80000004,
+    [5] = 0x80000005,
+    [6] = 0x80000006,
+    [7] = 0x80000007,
+    [RT_CPUS_NR] = 0
+};
+#endif
 
 int rt_hw_cpu_id(void)
 {
-    int cpu_id;
     rt_base_t value;
 
-    __asm__ volatile (
-            "mrs %0, mpidr_el1"
-            :"=r"(value)
-            );
-    cpu_id = value & 0xf;
-    return cpu_id;
-};
+    __asm__ volatile ("mrs %0, tpidr_el1":"=r"(value));
+
+    return value;
+}
 
 #ifdef RT_USING_SMP
 void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
@@ -35,38 +48,45 @@ void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
 
 void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
 {
-    unsigned long tmp;
-    unsigned long newval;
-    rt_hw_spinlock_t lockval;
-    __asm__ __volatile__(
-            "pld [%0]"
-            ::"r"(&lock->slock)
-            );
-
-    __asm__ __volatile__(
-            "1: ldrex   %0, [%3]\n"
-            "   add %1, %0, %4\n"
-            "   strex   %2, %1, [%3]\n"
-            "   teq %2, #0\n"
-            "   bne 1b"
-            : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
-            : "r" (&lock->slock), "I" (1 << 16)
-            : "cc");
-
-    while (lockval.tickets.next != lockval.tickets.owner) {
-        __WFE();
-        lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
-    }
+    rt_hw_spinlock_t lock_val, new_lockval;
+    unsigned int tmp;
 
+    __asm__ volatile (
+        /* 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"
+        /*
+         * Didn't get lock and spin on the owner.
+         * Should 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"
+        "   cbnz    %w1, 2b\n"
+        /* got the lock. */
+        "3:"
+        : "=&r" (lock_val), "=&r" (new_lockval), "=&r" (tmp), "+Q" (*lock)
+        : "Q" (lock->tickets.owner), "I" (1 << 16)
+        : "memory");
     __DMB();
 }
 
 void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
 {
     __DMB();
-    lock->tickets.owner++;
-    __DSB();
-    __SEV();
+    __asm__ volatile (
+        "stlrh   %w1, %0\n"
+        : "=Q" (lock->tickets.owner)
+        : "r" (lock->tickets.owner + 1)
+        : "memory");
 }
 #endif /*RT_USING_SMP*/
 

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

@@ -13,6 +13,13 @@
 
 #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")
+
 rt_inline void rt_hw_isb(void)
 {
     __asm__ volatile ("isb":::"memory");

+ 1 - 1
libcpu/aarch64/common/gic.c

@@ -15,7 +15,7 @@
 #include <rtthread.h>
 
 #include <gic.h>
-#include <cp15.h>
+#include <cpuport.h>
 
 struct arm_gic
 {

+ 48 - 0
libcpu/aarch64/common/gtimer.c

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-12-20     GuEe-GUI     first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <gtimer.h>
+#include <cpuport.h>
+
+#define EL1_PHY_TIMER_IRQ_NUM 30
+
+static volatile rt_uint64_t timer_step;
+
+static void rt_hw_timer_isr(int vector, void *parameter)
+{
+    rt_hw_set_gtimer_val(timer_step);
+    rt_tick_increase();
+}
+
+void rt_hw_gtimer_init(void)
+{
+    rt_hw_interrupt_install(EL1_PHY_TIMER_IRQ_NUM, rt_hw_timer_isr, RT_NULL, "tick");
+    __ISB();
+    timer_step = rt_hw_get_gtimer_frq();
+    __DSB();
+    timer_step /= RT_TICK_PER_SECOND;
+    rt_hw_gtimer_local_enable();
+}
+
+void rt_hw_gtimer_local_enable(void)
+{
+    rt_hw_gtimer_disable();
+    rt_hw_set_gtimer_val(timer_step);
+    rt_hw_interrupt_umask(EL1_PHY_TIMER_IRQ_NUM);
+    rt_hw_gtimer_enable();
+}
+
+void rt_hw_gtimer_local_disable(void)
+{
+    rt_hw_gtimer_disable();
+    rt_hw_interrupt_mask(EL1_PHY_TIMER_IRQ_NUM);
+}

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

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-12-20     GuEe-GUI     first version
+ */
+
+#ifndef __GTIMER_H__
+#define __GTIMER_H__
+
+#include <rtdef.h>
+
+void rt_hw_gtimer_init(void);
+void rt_hw_gtimer_local_enable(void);
+void rt_hw_gtimer_local_disable(void);
+
+void rt_hw_gtimer_enable();
+void rt_hw_gtimer_disable();
+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();
+rt_uint64_t rt_hw_get_gtimer_frq();
+
+#endif /* __GTIMER_H__ */

+ 17 - 5
libcpu/aarch64/common/interrupt.c

@@ -15,16 +15,15 @@
 #include "gic.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
 
 const unsigned int VECTOR_BASE = 0x00;
 extern int system_vectors;
@@ -39,9 +38,9 @@ extern volatile rt_uint8_t rt_interrupt_nest;
 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);
+    rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(), vector);
 #else
-    rt_kprintf("unhandled irq: %d\n",vector);
+    rt_kprintf("unhandled irq: %d\n", vector);
 #endif
 }
 #endif
@@ -138,7 +137,7 @@ void rt_hw_interrupt_mask(int vector)
 void rt_hw_interrupt_umask(int vector)
 {
 #ifndef BSP_USING_GIC
-if (vector < 32)
+    if (vector < 32)
     {
         IRQ_ENABLE1 = (1 << vector);
     }
@@ -397,7 +396,20 @@ void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
 {
 #ifdef BSP_USING_GIC
     arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0);
+#else
+    int i;
+
+    __DSB();
+
+    for (i = 0; i < RT_CPUS_NR; ++i)
+    {
+        if (cpu_mask & (1 << i))
+        {
+            IPI_MAILBOX_SET(i) = 1 << ipi_vector;
+        }
+    }
 #endif
+    __DSB();
 }
 
 void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)

+ 158 - 274
libcpu/aarch64/common/mmu.c

@@ -4,364 +4,248 @@
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
- * Date           Author             Notes
- * 2020-02-20     bigmagic           first version
+ * Date           Author       Notes
+ * 2021-11-28     GuEe-GUI     first version
  */
-#include <mmu.h>
-#include <stddef.h>
-#include <rthw.h>
-
-#define TTBR_CNP    1
-
-typedef unsigned long int    uint64_t;
-
-static unsigned long main_tbl[512 * 20] __attribute__((aligned (4096)));
-
-#define IS_ALIGNED(x, a)        (((x) & ((typeof(x))(a) - 1)) == 0)
-
-#define PMD_TYPE_SECT        (1 << 0)
 
-#define PMD_TYPE_TABLE        (3 << 0)
-
-#define PTE_TYPE_PAGE        (3 << 0)
-
-#define BITS_PER_VA          39
-
-/* Granule size of 4KB is being used */
-#define GRANULE_SIZE_SHIFT         12
-#define GRANULE_SIZE               (1 << GRANULE_SIZE_SHIFT)
-#define XLAT_ADDR_MASK             ((1UL << BITS_PER_VA) - GRANULE_SIZE)
-
-#define PMD_TYPE_MASK               (3 << 0)
-
-int free_idx = 1;
+#include <rtthread.h>
+#include <rthw.h>
 
-void __asm_invalidate_icache_all(void);
-void __asm_flush_dcache_all(void);
-int __asm_flush_l3_cache(void);
-void __asm_flush_dcache_range(unsigned long long start, unsigned long long end);
-void __asm_invalidate_dcache_all(void);
-void __asm_invalidate_icache_all(void);
+#include <cpuport.h>
+#include <mmu.h>
 
-void mmu_memset(char *dst, char v,  size_t len)
-{
-    while (len--)
-    {
-        *dst++ = v;
-    }
-}
+#define ARCH_SECTION_SHIFT  21
+#define ARCH_SECTION_SIZE   (1 << ARCH_SECTION_SHIFT)
+#define ARCH_SECTION_MASK   (ARCH_SECTION_SIZE - 1)
+#define ARCH_PAGE_SHIFT     12
+#define ARCH_PAGE_SIZE      (1 << ARCH_PAGE_SHIFT)
+#define ARCH_PAGE_MASK      (ARCH_PAGE_SIZE - 1)
 
-static unsigned long __page_off = 0;
-static unsigned long get_free_page(void)
-{
-    __page_off += 512;
-    return (unsigned long)(main_tbl + __page_off);
-}
+#define MMU_LEVEL_MASK      0x1ffUL
+#define MMU_LEVEL_SHIFT     9
+#define MMU_ADDRESS_BITS    39
+#define MMU_ADDRESS_MASK    0x0000fffffffff000UL
+#define MMU_ATTRIB_MASK     0xfff0000000000ffcUL
 
+#define MMU_TYPE_MASK       3UL
+#define MMU_TYPE_USED       1UL
+#define MMU_TYPE_BLOCK      1UL
+#define MMU_TYPE_TABLE      3UL
+#define MMU_TYPE_PAGE       3UL
 
-static inline unsigned int get_sctlr(void)
-{
-    unsigned int val;
-    asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc");
-    return val;
-}
+#define MMU_TBL_BLOCK_2M_LEVEL  2
+#define MMU_TBL_PAGE_NR_MAX     32
 
-static inline void set_sctlr(unsigned int val)
+/* only map 4G io/memory */
+static volatile unsigned long MMUTable[512] __attribute__((aligned(4096)));
+static volatile struct
 {
-    asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc");
-    asm volatile("isb");
-}
+    unsigned long entry[512];
+} MMUPage[MMU_TBL_PAGE_NR_MAX] __attribute__((aligned(4096)));
 
-void mmu_init(void)
+static unsigned long _kernel_free_page(void)
 {
-    unsigned long val64;
-    unsigned long val32;
-
-    val64 = 0x007f6eUL;
-    __asm__ volatile("msr MAIR_EL1, %0\n dsb sy\n"::"r"(val64));
-    __asm__ volatile("mrs %0, MAIR_EL1\n dsb sy\n":"=r"(val64));
-
-    //TCR_EL1
-    val32 = (16UL << 0)//48bit
-        | (0x0UL << 6)
-        | (0x0UL << 7)
-        | (0x3UL << 8)
-        | (0x3UL << 10)//Inner Shareable
-        | (0x2UL << 12)
-        | (0x0UL << 14)//4K
-        | (0x0UL << 16)
-        | (0x0UL << 22)
-        | (0x1UL << 23)
-        | (0x2UL << 30)
-        | (0x1UL << 32)
-        | (0x0UL << 35)
-        | (0x0UL << 36)
-        | (0x0UL << 37)
-        | (0x0UL << 38);
-    __asm__ volatile("msr TCR_EL1, %0\n"::"r"(val32));
-    __asm__ volatile("mrs %0, TCR_EL1\n":"=r"(val32));
-
-    __asm__ volatile("msr TTBR0_EL1, %0\n dsb sy\n"::"r"(main_tbl));
-    __asm__ volatile("mrs %0, TTBR0_EL1\n dsb sy\n":"=r"(val64));
-
-    mmu_memset((char *)main_tbl, 0, 4096);
-}
+    static unsigned long i = 0;
 
-void mmu_enable(void)
-{
-    unsigned long val64;
-    unsigned long val32;
-
-    __asm__ volatile("mrs %0, SCTLR_EL1\n":"=r"(val64));
-    val64 &= ~0x1000; //disable I
-    __asm__ volatile("dmb sy\n msr SCTLR_EL1, %0\n isb sy\n"::"r"(val64));
-
-    __asm__ volatile("IC IALLUIS\n dsb sy\n isb sy\n");
-    __asm__ volatile("tlbi vmalle1\n dsb sy\n isb sy\n");
+    if (i >= MMU_TBL_PAGE_NR_MAX)
+    {
+        return RT_NULL;
+    }
 
-    //SCTLR_EL1, turn on mmu
-    __asm__ volatile("mrs %0, SCTLR_EL1\n":"=r"(val32));
-    val32 |= 0x1005; //enable mmu, I C M
-    __asm__ volatile("dmb sy\n msr SCTLR_EL1, %0\nisb sy\n"::"r"(val32));
-    rt_hw_icache_enable();
-    rt_hw_dcache_enable();
+    ++i;
 
+    return (unsigned long)&MMUPage[i - 1].entry;
 }
 
-static int map_single_page_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr)
+static int _kenrel_map_2M(unsigned long *tbl, unsigned long va, unsigned long pa, unsigned long attr)
 {
     int level;
-    unsigned long* cur_lv_tbl = lv0_tbl;
+    unsigned long *cur_lv_tbl = tbl;
     unsigned long page;
     unsigned long off;
-    int level_shift = 39;
+    int level_shift = MMU_ADDRESS_BITS;
 
-    if (va & (0x200000UL - 1))
+    if (va & ARCH_SECTION_MASK)
     {
         return MMU_MAP_ERROR_VANOTALIGN;
     }
-    if (pa & (0x200000UL - 1))
+    if (pa & ARCH_SECTION_MASK)
     {
         return MMU_MAP_ERROR_PANOTALIGN;
     }
-    for (level = 0; level < 2; level++)
+
+    for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; ++level)
     {
         off = (va >> level_shift);
         off &= MMU_LEVEL_MASK;
-        if ((cur_lv_tbl[off] & 1) == 0)
+
+        if (!(cur_lv_tbl[off] & MMU_TYPE_USED))
         {
-            page = get_free_page();
+            page = _kernel_free_page();
+
             if (!page)
             {
                 return MMU_MAP_ERROR_NOPAGE;
             }
-            mmu_memset((char *)page, 0, 4096);
-            cur_lv_tbl[off] = page | 0x3UL;
+
+            rt_memset((char *)page, 0, ARCH_PAGE_SIZE);
+            rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)page, ARCH_PAGE_SIZE);
+            cur_lv_tbl[off] = page | MMU_TYPE_TABLE;
+            rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *));
+        }
+        else
+        {
+            page = cur_lv_tbl[off];
+            page &= MMU_ADDRESS_MASK;
         }
+
         page = cur_lv_tbl[off];
-        if (!(page & 0x2))
+        if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK)
         {
-            //is block! error!
+            /* is block! error! */
             return MMU_MAP_ERROR_CONFLICT;
         }
-        cur_lv_tbl = (unsigned long*)(page & 0x0000fffffffff000UL);
-        level_shift -= 9;
+
+        /* next level */
+        cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK);
+        level_shift -= MMU_LEVEL_SHIFT;
     }
-    attr &= 0xfff0000000000ffcUL;
-    pa |= (attr | 0x1UL); //block
-    off = (va >> 21);
+
+    attr &= MMU_ATTRIB_MASK;
+    pa |= (attr | MMU_TYPE_BLOCK);
+    off = (va >> ARCH_SECTION_SHIFT);
     off &= MMU_LEVEL_MASK;
     cur_lv_tbl[off] = pa;
+    rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *));
+
     return 0;
 }
 
-int armv8_map_2M(unsigned long va, unsigned long pa, int count, unsigned long attr)
+int rt_hw_mmu_setmtt(unsigned long vaddr_start, unsigned long vaddr_end,
+        unsigned long paddr_start, unsigned long attr)
 {
+    int ret = -1;
     int i;
-    int ret;
+    unsigned long count;
+    unsigned long map_attr = MMU_MAP_CUSTOM(MMU_AP_KAUN, attr);
 
-    if (va & (0x200000 - 1))
+    if (vaddr_start > vaddr_end)
+    {
+        goto end;
+    }
+    if (vaddr_start % ARCH_SECTION_SIZE)
+    {
+        vaddr_start = (vaddr_start / ARCH_SECTION_SIZE) * ARCH_SECTION_SIZE;
+    }
+    if (paddr_start % ARCH_SECTION_SIZE)
     {
-        return -1;
+        paddr_start = (paddr_start / ARCH_SECTION_SIZE) * ARCH_SECTION_SIZE;
     }
-    if (pa & (0x200000 - 1))
+    if (vaddr_end % ARCH_SECTION_SIZE)
     {
-        return -1;
+        vaddr_end = (vaddr_end / ARCH_SECTION_SIZE + 1) * ARCH_SECTION_SIZE;
     }
+
+    count = (vaddr_end - vaddr_start) >> ARCH_SECTION_SHIFT;
+
     for (i = 0; i < count; i++)
     {
-        ret = map_single_page_2M((unsigned long *)main_tbl, va, pa, attr);
-        va += 0x200000;
-        pa += 0x200000;
+        ret = _kenrel_map_2M((void *)MMUTable, vaddr_start, paddr_start, map_attr);
+        vaddr_start += ARCH_SECTION_SIZE;
+        paddr_start += ARCH_SECTION_SIZE;
+
         if (ret != 0)
         {
-            return ret;
+            goto end;
         }
     }
-    return 0;
-}
 
-static void set_table(uint64_t *pt, uint64_t *table_addr)
-{
-    uint64_t val;
-    val = (0x3UL | (uint64_t)table_addr);
-    *pt = val;
+end:
+    return ret;
 }
 
-void mmu_memset2(unsigned char *dst, char v,  int len)
+void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_size_t desc_nr)
 {
-    while (len--)
+    rt_memset((void *)MMUTable, 0, sizeof(MMUTable));
+    rt_memset((void *)MMUPage, 0, sizeof(MMUPage));
+
+    /* set page table */
+    for (; desc_nr > 0; --desc_nr)
     {
-        *dst++ = v;
+        rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, mdesc->paddr_start, mdesc->attr);
+        ++mdesc;
     }
-}
-
-static uint64_t *create_table(void)
-{
-    uint64_t *new_table = (uint64_t *)((unsigned char *)&main_tbl[0] + free_idx * 4096); //+ free_idx * GRANULE_SIZE;
-    /* Mark all entries as invalid */
-    mmu_memset2((unsigned char *)new_table, 0, 4096);
-    free_idx++;
-    return new_table;
-}
 
-static int pte_type(uint64_t *pte)
-{
-    return *pte & PMD_TYPE_MASK;
+    rt_hw_dcache_flush_range((unsigned long)MMUTable, sizeof(MMUTable));
 }
 
-static int level2shift(int level)
+void rt_hw_mmu_tlb_invalidate(void)
 {
-    /* Page is 12 bits wide, every level translates 9 bits */
-    return (12 + 9 * (3 - level));
+    __asm__ volatile (
+        "tlbi vmalle1\n\r"
+        "dsb sy\n\r"
+        "isb sy\n\r"
+        "ic ialluis\n\r"
+        "dsb sy\n\r"
+        "isb sy");
 }
 
-static uint64_t *get_level_table(uint64_t *pte)
+void rt_hw_mmu_init(void)
 {
-    uint64_t *table = (uint64_t *)(*pte & XLAT_ADDR_MASK);
-
-    if (pte_type(pte) != PMD_TYPE_TABLE)
-    {
-        table = create_table();
-        set_table(pte, table);
-    }
-    return table;
-}
+    unsigned long reg_val;
 
-static void map_region(uint64_t virt, uint64_t phys, uint64_t size, uint64_t attr)
-{
-    uint64_t block_size = 0;
-    uint64_t block_shift = 0;
-    uint64_t *pte;
-    uint64_t idx = 0;
-    uint64_t addr = 0;
-    uint64_t *table = 0;
-    int level = 0;
-
-    addr = virt;
-    while (size)
-    {
-        table = &main_tbl[0];
-        for (level = 0; level < 4; level++)
-        {
-            block_shift = level2shift(level);
-            idx = addr >> block_shift;
-            idx = idx%512;
-            block_size = (uint64_t)(1L << block_shift);
-            pte = table + idx;
+    reg_val = 0x00447fUL;
+    __asm__ volatile("msr mair_el1, %0"::"r"(reg_val));
 
-            if (size >= block_size && IS_ALIGNED(addr, block_size))
-            {
-                attr &= 0xfff0000000000ffcUL;
-                if(level != 3)
-                {
-                    *pte = phys | (attr | 0x1UL);
-                }
-                else
-                {
-                    *pte = phys | (attr | 0x3UL);
-                }
-                addr += block_size;
-                phys += block_size;
-                size -= block_size;
-                break;
-            }
-            table = get_level_table(pte);
-        }
-    }
-}
+    rt_hw_isb();
 
-void armv8_map(unsigned long va, unsigned long pa, unsigned long size, unsigned long attr)
-{
-    map_region(va, pa, size, attr);
-}
+    reg_val = (16UL << 0)   /* t0sz 48bit */
+            | (0UL  << 6)   /* reserved */
+            | (0UL  << 7)   /* epd0 */
+            | (3UL  << 8)   /* t0 wb cacheable */
+            | (3UL  << 10)  /* inner shareable */
+            | (2UL  << 12)  /* t0 outer shareable */
+            | (0UL  << 14)  /* t0 4K */
+            | (16UL << 16)  /* t1sz 48bit */
+            | (0UL  << 22)  /* define asid use ttbr0.asid */
+            | (0UL  << 23)  /* epd1 */
+            | (3UL  << 24)  /* t1 inner wb cacheable */
+            | (3UL  << 26)  /* t1 outer wb cacheable */
+            | (2UL  << 28)  /* t1 outer shareable */
+            | (2UL  << 30)  /* t1 4k */
+            | (1UL  << 32)  /* 001b 64GB PA */
+            | (0UL  << 35)  /* reserved */
+            | (1UL  << 36)  /* as: 0:8bit 1:16bit */
+            | (0UL  << 37)  /* tbi0 */
+            | (0UL  << 38); /* tbi1 */
+    __asm__ volatile("msr tcr_el1, %0"::"r"(reg_val));
 
-void rt_hw_dcache_enable(void)
-{
-    if (!(get_sctlr() & CR_M))
-    {
-        rt_kprintf("please init mmu!\n");
-    }
-    else
-    {
-        set_sctlr(get_sctlr() | CR_C);
-    }
-}
+    rt_hw_isb();
 
-void rt_hw_dcache_flush_all(void)
-{
-    int ret;
+    __asm__ volatile ("mrs %0, sctlr_el1":"=r"(reg_val));
 
-    __asm_flush_dcache_all();
-    ret = __asm_flush_l3_cache();
-    if (ret)
-    {
-        rt_kprintf("flushing dcache returns 0x%x\n", ret);
-    }
-    else
-    {
-        rt_kprintf("flushing dcache successfully.\n");
-    }
-}
+    reg_val |= 1 << 2;  /* enable dcache */
+    reg_val |= 1 << 0;  /* enable mmu */
 
-void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size)
-{
-    __asm_flush_dcache_range(start_addr, start_addr + size);
-}
-void rt_hw_dcache_invalidate_range(unsigned long start_addr,unsigned long size)
-{
-    __asm_flush_dcache_range(start_addr, start_addr + size);
-}
+    __asm__ volatile (
+        "msr ttbr0_el1, %0\n\r"
+        "msr sctlr_el1, %1\n\r"
+        "dsb sy\n\r"
+        "isb sy\n\r"
+        ::"r"(MMUTable), "r"(reg_val) :"memory");
 
-void rt_hw_dcache_invalidate_all(void)
-{
-    __asm_invalidate_dcache_all();
+    rt_hw_mmu_tlb_invalidate();
 }
 
-void rt_hw_dcache_disable(void)
+int rt_hw_mmu_map(unsigned long addr, unsigned long size, unsigned long attr)
 {
-    /* if cache isn't enabled no need to disable */
-    if(!(get_sctlr() & CR_C))
-    {
-        rt_kprintf("need enable cache!\n");
-        return;
-    }
-    set_sctlr(get_sctlr() & ~CR_C);
-}
+    int ret;
+    rt_ubase_t level;
 
-//icache
-void rt_hw_icache_enable(void)
-{
-    __asm_invalidate_icache_all();
-    set_sctlr(get_sctlr() | CR_I);
-}
+    level = rt_hw_interrupt_disable();
+    ret = rt_hw_mmu_setmtt(addr, addr + size, addr, attr);
 
-void rt_hw_icache_invalidate_all(void)
-{
-    __asm_invalidate_icache_all();
-}
+    rt_hw_interrupt_enable(level);
 
-void rt_hw_icache_disable(void)
-{
-    set_sctlr(get_sctlr() & ~CR_I);
+    return ret;
 }

+ 52 - 56
libcpu/aarch64/common/mmu.h

@@ -4,75 +4,71 @@
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
- * Date           Author             Notes
- * 2020-02-20     bigmagic           first version
+ * Date           Author       Notes
+ * 2021-11-28     GuEe-GUI     the first version
  */
 
-#ifndef  __MMU_H__
-#define  __MMU_H__
+#ifndef __MMU_H_
+#define __MMU_H_
 
-/*
- * CR1 bits (CP#15 CR1)
- */
-#define CR_M    (1 << 0)    /* MMU enable                */
-#define CR_A    (1 << 1)    /* Alignment abort enable        */
-#define CR_C    (1 << 2)    /* Dcache enable            */
-#define CR_W    (1 << 3)    /* Write buffer enable            */
-#define CR_P    (1 << 4)    /* 32-bit exception handler        */
-#define CR_D    (1 << 5)    /* 32-bit data address range        */
-#define CR_L    (1 << 6)    /* Implementation defined        */
-#define CR_B    (1 << 7)    /* Big endian                */
-#define CR_S    (1 << 8)    /* System MMU protection        */
-#define CR_R    (1 << 9)    /* ROM MMU protection            */
-#define CR_F    (1 << 10)    /* Implementation defined        */
-#define CR_Z    (1 << 11)    /* Implementation defined        */
-#define CR_I    (1 << 12)    /* Icache enable            */
-#define CR_V    (1 << 13)    /* Vectors relocated to 0xffff0000    */
-#define CR_RR   (1 << 14)    /* Round Robin cache replacement    */
-#define CR_L4   (1 << 15)    /* LDR pc can set T bit            */
-#define CR_DT   (1 << 16)
-#define CR_IT   (1 << 18)
-#define CR_ST   (1 << 19)
-#define CR_FI   (1 << 21)    /* Fast interrupt (lower latency mode)    */
-#define CR_U    (1 << 22)    /* Unaligned access operation        */
-#define CR_XP   (1 << 23)    /* Extended page tables            */
-#define CR_VE   (1 << 24)    /* Vectored interrupts            */
-#define CR_EE   (1 << 25)    /* Exception (Big) Endian        */
-#define CR_TRE  (1 << 28)    /* TEX remap enable            */
-#define CR_AFE  (1 << 29)    /* Access flag enable            */
-#define CR_TE   (1 << 30)    /* Thumb exception enable        */
+#include <rtthread.h>
 
-#define MMU_LEVEL_MASK 0x1ffUL
-#define MMU_MAP_ERROR_VANOTALIGN  -1
-#define MMU_MAP_ERROR_PANOTALIGN  -2
-#define MMU_MAP_ERROR_NOPAGE      -3
-#define MMU_MAP_ERROR_CONFLICT    -4
+/* normal memory wra mapping type */
+#define NORMAL_MEM          0
+/* normal nocache memory mapping type */
+#define NORMAL_NOCACHE_MEM  1
+/* device mapping type */
+#define DEVICE_MEM          2
 
-#define MEM_ATTR_MEMORY ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x1UL << 2))
-#define MEM_ATTR_IO     ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x2UL << 2))
+#define MMU_MAP_ERROR_VANOTALIGN    (-1)
+#define MMU_MAP_ERROR_PANOTALIGN    (-2)
+#define MMU_MAP_ERROR_NOPAGE        (-3)
+#define MMU_MAP_ERROR_CONFLICT      (-4)
 
-#define BUS_ADDRESS(phys)    (((phys) & ~0xC0000000)  |  0xC0000000)
+struct mem_desc
+{
+    unsigned long vaddr_start;
+    unsigned long vaddr_end;
+    unsigned long paddr_start;
+    unsigned long attr;
+};
 
-void mmu_init(void);
+#define MMU_AF_SHIFT        10
+#define MMU_SHARED_SHIFT    8
+#define MMU_AP_SHIFT        6
+#define MMU_MA_SHIFT        2
 
-void mmu_enable(void);
+#define MMU_AP_KAUN         0UL /* kernel r/w, user none */
+#define MMU_AP_KAUA         1UL /* kernel r/w, user r/w */
+#define MMU_AP_KRUN         2UL /* kernel r, user none */
+#define MMU_AP_KRUR         3UL /* kernel r, user r */
 
-int armv8_map_2M(unsigned long va, unsigned long pa, int count, unsigned long attr);
+#define MMU_MAP_CUSTOM(ap, mtype) \
+(\
+    (0x1UL << MMU_AF_SHIFT) |\
+    (0x2UL << MMU_SHARED_SHIFT) |\
+    ((ap) << MMU_AP_SHIFT) |\
+    ((mtype) << MMU_MA_SHIFT)\
+)
+#define MMU_MAP_K_RO        MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM)
+#define MMU_MAP_K_RWCB      MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM)
+#define MMU_MAP_K_RW        MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM)
+#define MMU_MAP_K_DEVICE    MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM)
+#define MMU_MAP_U_RO        MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM)
+#define MMU_MAP_U_RWCB      MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM)
+#define MMU_MAP_U_RW        MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM)
+#define MMU_MAP_U_DEVICE    MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM)
 
-void armv8_map(unsigned long va, unsigned long pa, unsigned long size, unsigned long attr);
+void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_size_t desc_nr);
+void rt_hw_mmu_init(void);
+int rt_hw_mmu_map(unsigned long addr, unsigned long size, unsigned long attr);
 
-//dcache
-void rt_hw_dcache_enable(void);
 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_dcache_invalidate_range(unsigned long start_addr,unsigned long size);
-void rt_hw_dcache_invalidate_all(void);
-void rt_hw_dcache_disable(void);
-
-//icache
-void rt_hw_icache_enable(void);
-void rt_hw_icache_invalidate_all(void);
-void rt_hw_icache_disable(void);
 
+void rt_hw_icache_invalidate_all();
+void rt_hw_icache_invalidate_range(unsigned long start_addr, int size);
 
-#endif  /*__MMU_H__*/
+#endif /* __MMU_H_ */

+ 95 - 0
libcpu/aarch64/common/psci.c

@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-09     GuEe-GUI     The first version
+ */
+
+#include <psci.h>
+#include <smccc.h>
+#include <armv8.h>
+
+typedef uint64_t (*psci_call_handle)(uint32_t fn, uint64_t arg0, uint64_t arg1, uint64_t arg2);
+
+static uint64_t psci_smc_call(uint32_t fn, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+    return arm_smc_call(fn, arg0, arg1, arg2, 0, 0, 0, 0).x0;
+}
+
+static uint64_t psci_hvc_call(uint32_t fn, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+    return arm_hvc_call(fn, arg0, arg1, arg2, 0, 0, 0, 0).x0;
+}
+
+static psci_call_handle psci_call = psci_smc_call;
+
+static uint64_t shutdown_args[3] = {0, 0, 0};
+static uint64_t reboot_args[3] = {0, 0, 0};
+
+void arm_psci_init(uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args)
+{
+    if (rt_hw_get_current_el() < 2)
+    {
+        psci_call = psci_hvc_call;
+    }
+
+    if (platform_shutdown_args != RT_NULL)
+    {
+        shutdown_args[0] = platform_shutdown_args[0];
+        shutdown_args[1] = platform_shutdown_args[1];
+        shutdown_args[2] = platform_shutdown_args[2];
+    }
+
+    if (platform_reboot_args != RT_NULL)
+    {
+        reboot_args[0] = platform_reboot_args[0];
+        reboot_args[1] = platform_reboot_args[1];
+        reboot_args[2] = platform_reboot_args[2];
+    }
+}
+
+uint32_t arm_psci_get_version()
+{
+    return (uint32_t)psci_call(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
+}
+
+uint32_t arm_psci_get_affinity_info(uint64_t target_affinity, uint64_t lowest_affinity_level)
+{
+    return (uint32_t)psci_call(PSCI_0_2_FN_AFFINITY_INFO, target_affinity, lowest_affinity_level, 0);
+}
+
+uint32_t arm_psci_get_feature(uint32_t psci_func_id)
+{
+    return (uint32_t)psci_call(PSCI_1_0_FN_PSCI_FEATURES, psci_func_id, 0, 0);
+}
+
+uint32_t arm_psci_cpu_off(uint64_t state)
+{
+    return (uint32_t)psci_call(PSCI_0_2_FN_CPU_OFF, state, 0, 0);
+}
+
+uint32_t arm_psci_cpu_on(uint64_t mpid, uint64_t entry)
+{
+    /* [40:63] and [24:31] must be zero, other is aff3, aff2, aff1, aff0 */
+    mpid = mpid & 0xff00ffffff;
+
+    return (uint32_t)psci_call(PSCI_0_2_FN_CPU_ON, mpid, entry, 0);
+}
+
+uint32_t arm_psci_cpu_suspend(uint32_t power_state, uint64_t entry)
+{
+    return (uint32_t)psci_call(PSCI_0_2_FN_CPU_SUSPEND, power_state, entry, 0);
+}
+
+void arm_psci_system_off()
+{
+    psci_call(PSCI_0_2_FN_SYSTEM_OFF, shutdown_args[0], shutdown_args[1], shutdown_args[2]);
+}
+
+void arm_psci_system_reboot()
+{
+    psci_call(PSCI_0_2_FN_SYSTEM_RESET, reboot_args[0], reboot_args[1], reboot_args[2]);
+}

+ 130 - 0
libcpu/aarch64/common/psci.h

@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-09     GuEe-GUI     The first version
+ */
+
+#ifndef __PSCI_H__
+#define __PSCI_H__
+
+#include <stdint.h>
+
+/*
+ * Non-Confidential PSCI 1.0 release (30 January 2015), and errata fix for PSCI 0.2, unsupport PSCI 0.1
+ */
+#define PSCI_VER_0_2                        0x00000002
+
+/* PSCI 0.2 interface */
+#define PSCI_0_2_FN_BASE                    0x84000000
+#define PSCI_0_2_FN(n)                      (PSCI_0_2_FN_BASE + (n))
+#define PSCI_0_2_FN_END                     0x8400001F
+
+#define PSCI_0_2_FN64_BASE                  0xC4000000
+#define PSCI_0_2_FN64(n)                    (PSCI_0_2_FN64_BASE + (n))
+#define PSCI_0_2_FN64_END                   0xC400001F
+
+#define PSCI_0_2_FN_PSCI_VERSION            PSCI_0_2_FN(0)
+#define PSCI_0_2_FN_CPU_SUSPEND             PSCI_0_2_FN(1)
+#define PSCI_0_2_FN_CPU_OFF                 PSCI_0_2_FN(2)
+#define PSCI_0_2_FN_CPU_ON                  PSCI_0_2_FN(3)
+#define PSCI_0_2_FN_AFFINITY_INFO           PSCI_0_2_FN(4)
+#define PSCI_0_2_FN_MIGRATE                 PSCI_0_2_FN(5)
+#define PSCI_0_2_FN_MIGRATE_INFO_TYPE       PSCI_0_2_FN(6)
+#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU     PSCI_0_2_FN(7)
+#define PSCI_0_2_FN_SYSTEM_OFF              PSCI_0_2_FN(8)
+#define PSCI_0_2_FN_SYSTEM_RESET            PSCI_0_2_FN(9)
+
+#define PSCI_0_2_FN64_CPU_SUSPEND           PSCI_0_2_FN64(1)
+#define PSCI_0_2_FN64_CPU_ON                PSCI_0_2_FN64(3)
+#define PSCI_0_2_FN64_AFFINITY_INFO         PSCI_0_2_FN64(4)
+#define PSCI_0_2_FN64_MIGRATE               PSCI_0_2_FN64(5)
+#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU   PSCI_0_2_FN64(7)
+
+/* PSCI 1.0 interface */
+#define PSCI_1_0_FN_PSCI_FEATURES           PSCI_0_2_FN(10)
+#define PSCI_1_0_FN_CPU_FREEZE              PSCI_0_2_FN(11)
+#define PSCI_1_0_FN_CPU_DEFAULT_SUSPEND     PSCI_0_2_FN(12)
+#define PSCI_1_0_FN_NODE_HW_STATE           PSCI_0_2_FN(13)
+#define PSCI_1_0_FN_SYSTEM_SUSPEND          PSCI_0_2_FN(14)
+#define PSCI_1_0_FN_SET_SUSPEND_MODE        PSCI_0_2_FN(15)
+#define PSCI_1_0_FN_STAT_RESIDENCY          PSCI_0_2_FN(16)
+#define PSCI_1_0_FN_STAT_COUNT              PSCI_0_2_FN(17)
+
+#define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND   PSCI_0_2_FN64(12)
+#define PSCI_1_0_FN64_NODE_HW_STATE         PSCI_0_2_FN64(13)
+#define PSCI_1_0_FN64_SYSTEM_SUSPEND        PSCI_0_2_FN64(14)
+#define PSCI_1_0_FN64_STAT_RESIDENCY        PSCI_0_2_FN64(16)
+#define PSCI_1_0_FN64_STAT_COUNT            PSCI_0_2_FN64(17)
+
+/* 1KB stack per core */
+#define PSCI_STACK_SHIFT                    10
+#define PSCI_STACK_SIZE                     (1 << PSCI_STACK_SHIFT)
+
+/* PSCI affinity level state returned by AFFINITY_INFO */
+#define PSCI_AFFINITY_LEVEL_ON              0
+#define PSCI_AFFINITY_LEVEL_OFF             1
+#define PSCI_AFFINITY_LEVEL_ON_PENDING      2
+
+/*
+ * PSCI power state
+ *  power_level:
+ *      Level 0: cores
+ *      Level 1: clusters
+ *      Level 2: system
+ *  state_type:
+ *      value 0: standby or retention state
+ *      value 1: powerdown state(entry and context_id is valid)
+ *  state_id:
+ *      StateID
+ */
+#define PSCI_POWER_STATE(power_level, state_type, state_id) \
+( \
+    ((power_level) << 24) | \
+    ((state_type) << 16)  | \
+    ((state_id) << 24) \
+)
+
+/*
+ * For system, cluster, core
+ *  0: run
+ *  1: standby(only core)
+ *  2: retention
+ *  3: powerdown
+ */
+#define PSCI_POWER_STATE_ID(state_id_power_level, system, cluster, core) \
+( \
+    ((state_id_power_level) << 12) | \
+    ((system) << 8)  | \
+    ((cluster) << 4) | \
+    (core) \
+)
+
+#define PSCI_RET_SUCCESS                    0
+#define PSCI_RET_NOT_SUPPORTED              (-1)
+#define PSCI_RET_INVALID_PARAMETERS         (-2)
+#define PSCI_RET_DENIED                     (-3)
+#define PSCI_RET_ALREADY_ON                 (-4)
+#define PSCI_RET_ON_PENDING                 (-5)
+#define PSCI_RET_INTERNAL_FAILURE           (-6)
+#define PSCI_RET_NOT_PRESENT                (-7)
+#define PSCI_RET_DISABLED                   (-8)
+#define PSCI_RET_INVALID_ADDRESS            (-9)
+
+void arm_psci_init(uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args);
+
+uint32_t arm_psci_get_version();
+uint32_t arm_psci_get_affinity_info(uint64_t target_affinity, uint64_t lowest_affinity_level);
+uint32_t arm_psci_get_feature(uint32_t psci_func_id);
+
+uint32_t arm_psci_cpu_off(uint64_t state);
+uint32_t arm_psci_cpu_on(uint64_t mpid, uint64_t entry);
+uint32_t arm_psci_cpu_suspend(uint32_t power_state, uint64_t entry);
+
+void arm_psci_system_off();
+void arm_psci_system_reboot();
+
+#endif  /*__PSCI_H__*/

+ 37 - 0
libcpu/aarch64/common/smccc.S

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-09     GuEe-GUI     The first version
+ */
+
+/*
+ * smc calling convention call
+ */
+.macro SMCCC_CALL INS
+    stp     x8, x29, [sp,#-16]! /* push the frame pointer (x29) for the purposes of AAPCS64 compatibility */
+    \INS    #0
+    ldp     x8, x29, [sp], #16
+
+    stp     x0, x1, [x8]
+    stp     x2, x3, [x8, #16]
+    str     x6, [x8, #32]
+    ret
+.endm
+
+/*
+ * smc call
+ */
+.globl arm_smc_call
+arm_smc_call:
+    SMCCC_CALL smc
+
+/*
+ * hvc call
+ */
+.globl arm_hvc_call
+arm_hvc_call:
+    SMCCC_CALL hvc

+ 33 - 0
libcpu/aarch64/common/smccc.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-09     GuEe-GUI     The first version
+ */
+
+#include <stdint.h>
+
+/*
+ * The ARM SMCCC v1.0 calling convention provides the following guarantees about registers:
+ *  Register     Modified    Return State
+ *  X0...X3      Yes         Result values
+ *  X4...X17     Yes         Unpredictable
+ *  X18...X30    No          Preserved
+ *  SP_EL0       No          Preserved
+ *  SP_ELx       No          Preserved
+ */
+
+struct arm_smccc_ret
+{
+    uint64_t x0;    /* Parameter registers */
+    uint64_t x1;    /* Parameter registers */
+    uint64_t x2;    /* Parameter registers */
+    uint64_t x3;    /* Parameter registers */
+    uint64_t x6;    /* Parameter register: Optional Session ID register */
+};
+
+struct arm_smccc_ret arm_smc_call(uint32_t w0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6, uint32_t w7);
+struct arm_smccc_ret arm_hvc_call(uint32_t w0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6, uint32_t w7);

+ 36 - 2
libcpu/aarch64/common/stack.c

@@ -8,10 +8,9 @@
  * 2011-09-23     Bernard      the first version
  * 2011-10-05     Bernard      add thumb mode
  * 2021-11-04     GuEe-GUI     set sp with SP_ELx
+ * 2021-12-28     GuEe-GUI     add fpu support
  */
 #include <rtthread.h>
-#include <board.h>
-
 #include <armv8.h>
 
 #define INITIAL_SPSR_EL3 (PSTATE_EL3 | SP_ELx)
@@ -35,6 +34,39 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad
 
     stk      = (rt_ubase_t*)stack_addr;
 
+    *(--stk) = (rt_ubase_t) 0;              /* Q0 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q0 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q1 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q1 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q2 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q2 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q3 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q3 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q4 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q4 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q5 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q5 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q6 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q6 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q7 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q7 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q8 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q8 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q9 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q9 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q10 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q10 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q11 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q11 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q12 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q12 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q13 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q13 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q14 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q14 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q15 */
+    *(--stk) = (rt_ubase_t) 0;              /* Q15 */
+
     *(--stk) = ( rt_ubase_t ) 11;           /* X1 */
     *(--stk) = ( rt_ubase_t ) parameter;    /* X0 */
     *(--stk) = ( rt_ubase_t ) 33;           /* X3 */
@@ -65,6 +97,8 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad
     *(--stk) = ( rt_ubase_t ) 26;           /* X26 */
     *(--stk) = ( rt_ubase_t ) 29;           /* X29 */
     *(--stk) = ( rt_ubase_t ) 28;           /* X28 */
+    *(--stk) = ( rt_ubase_t ) 0;            /* FPSR */
+    *(--stk) = ( rt_ubase_t ) 0;            /* FPCR */
     *(--stk) = ( rt_ubase_t ) 0;            /* XZR - has no effect, used so there are an even number of registers. */
     *(--stk) = ( rt_ubase_t ) texit;        /* X30 - procedure call link register. */
 

+ 32 - 5
libcpu/aarch64/common/trap.c

@@ -64,15 +64,16 @@ void rt_hw_trap_irq(void)
     uint32_t irq;
     rt_isr_handler_t isr_func;
     extern struct rt_irq_desc isr_table[];
-    uint32_t value = 0;
-    value = IRQ_PEND_BASIC & 0x3ff;
+    uint32_t value = IRQ_PEND_BASIC & 0x3ff;
 
-#ifdef BSP_USING_CORETIMER
-    uint32_t cpu_id = 0;
 #ifdef RT_USING_SMP
-    cpu_id = rt_hw_cpu_id();
+    uint32_t cpu_id = rt_hw_cpu_id();
+    uint32_t mailbox_data = IPI_MAILBOX_CLEAR(cpu_id);
+#else
+    uint32_t cpu_id = 0;
 #endif
     uint32_t int_source = CORE_IRQSOURCE(cpu_id) & 0x3ff;
+
     if (int_source & 0x02)
     {
         isr_func = isr_table[IRQ_ARM_TIMER].handler;
@@ -84,8 +85,34 @@ void rt_hw_trap_irq(void)
             param = isr_table[IRQ_ARM_TIMER].param;
             isr_func(IRQ_ARM_TIMER, param);
         }
+        return;
     }
+
+#ifdef RT_USING_SMP
+    if (int_source & 0xf0)
+    {
+        /* it's a ipi interrupt */
+        if (mailbox_data & 0x1)
+        {
+            /* clear mailbox */
+            IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data;
+            isr_func = isr_table[IRQ_ARM_MAILBOX].handler;
+#ifdef RT_USING_INTERRUPT_INFO
+            isr_table[IRQ_ARM_MAILBOX].counter++;
 #endif
+            if (isr_func)
+            {
+                param = isr_table[IRQ_ARM_MAILBOX].param;
+                isr_func(IRQ_ARM_MAILBOX, param);
+            }
+        }
+        else
+        {
+            CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data;
+        }
+        return;
+    }
+#endif /* RT_USING_SMP */
 
     /* local interrupt*/
     if (value)

+ 76 - 11
libcpu/aarch64/cortex-a/entry_point.S

@@ -7,16 +7,54 @@
  * 2020-01-15     bigmagic     the first version
  * 2020-08-10     SummerGift   support clang compiler
  * 2021-11-04     GuEe-GUI     set sp with SP_ELx
+ * 2021-12-28     GuEe-GUI     add smp support
  */
 
+#include "rtconfig.h"
 .section ".text.entrypoint","ax"
 
+#define SECONDARY_STACK_SIZE 4096
+
 .globl _start
+.globl secondary_cpu_start
 _start:
-    /* Read cpu id */
     mrs     x1, mpidr_el1
-    and     x1, x1, #3
-    cbz     x1, cpu_setup           /* If cpu id > 0, stop slave cores */
+    and     x1, x1, #0xff
+    cbnz    x1, cpu_idle            /* If cpu id > 0, stop slave cores */
+
+secondary_cpu_start:
+#ifdef RT_USING_SMP
+    /* Read cpu mpidr_el1 */
+    mrs     x1, mpidr_el1
+
+    /* Read cpu id */
+    ldr     x0, =rt_cpu_mpidr_early /* BSP must be defined `rt_cpu_mpidr_early' table in smp */
+    mov     x2, #0
+
+cpu_id_confirm:
+    add     x2, x2, #1              /* Next cpu id inc */
+    ldr     x3, [x0], #8
+    cmp     x3, #0
+    beq     cpu_idle                /* Mean that `rt_cpu_mpidr_early' table is end */
+    cmp     x3, x1
+    bne     cpu_id_confirm
+
+    /* Get cpu id success */
+    sub     x0, x2, #1
+    msr     tpidr_el1, x0           /* Save cpu id global */
+    cbz     x0, cpu_setup           /* Only go to cpu_setup when cpu id = 0 */
+
+    /* Set current cpu's stack top */
+    sub     x0, x0, #1
+    mov     x1, #SECONDARY_STACK_SIZE
+    adr     x2, .secondary_cpu_stack_top
+    msub    x1, x0, x1, x2
+
+    b       cpu_check_el
+#else
+    msr     tpidr_el1, xzr
+    b       cpu_setup
+#endif /* RT_USING_SMP */
 
 cpu_idle:
     wfe
@@ -25,6 +63,7 @@ cpu_idle:
 cpu_setup:
     ldr     x1, =_start
 
+cpu_check_el:
     mrs     x0, CurrentEL           /* CurrentEL Register. bit 2, 3. Others reserved */
     and     x0, x0, #12             /* Clear reserved bits */
 
@@ -84,15 +123,41 @@ cpu_in_el1:
     bic     x1, x1, #(1 << 1)       /* Disable Alignment check */
     msr     sctlr_el1, x1
 
-    ldr     x1, =__bss_start
-    ldr     w2, =__bss_size
-
-clean_bss_loop:
-    cbz     w2, jump_to_entry
-    str     xzr, [x1], #8
-    sub     w2, w2, #8
-    cbnz    w2, clean_bss_loop
+#ifdef RT_USING_SMP
+    ldr     x1, =_start
+    cmp     sp, x1
+    bne     secondary_cpu_c_start
+#endif /* RT_USING_SMP */
+
+    ldr     x0, =__bss_start
+    ldr     x1, =__bss_end
+    sub     x2, x1, x0
+    mov     x3, x1
+    cmp     x2, #7
+    bls     clean_bss_check
+
+clean_bss_loop_quad:
+    str     xzr, [x0], #8
+    sub     x2, x3, x0
+    cmp     x2, #7
+    bhi     clean_bss_loop_quad
+    cmp     x1, x0
+    bls     jump_to_entry
+
+clean_bss_loop_byte:
+    str     xzr, [x0], #1
+
+clean_bss_check:
+    cmp     x1, x0
+    bhi     clean_bss_loop_byte
 
 jump_to_entry:
     b       rtthread_startup
     b       cpu_idle                /* For failsafe, halt this core too */
+
+#ifdef RT_USING_SMP
+.align 12
+.secondary_cpu_stack:
+.space (SECONDARY_STACK_SIZE * (RT_CPUS_NR - 1))
+.secondary_cpu_stack_top:
+#endif