Răsfoiți Sursa

Merge AArch64 libcpu and add some drivers for their bsps

GuEe-GUI 3 ani în urmă
părinte
comite
740cd9dfb0
71 a modificat fișierele cu 6121 adăugiri și 1884 ștergeri
  1. 64 28
      bsp/qemu-virt64-aarch64/.config
  2. 2 1
      bsp/qemu-virt64-aarch64/README.md
  3. 2 1
      bsp/qemu-virt64-aarch64/README_zh.md
  4. 2 0
      bsp/qemu-virt64-aarch64/SConstruct
  5. 30 0
      bsp/qemu-virt64-aarch64/applications/mnt.c
  6. 10 4
      bsp/qemu-virt64-aarch64/driver/Kconfig
  7. 10 5
      bsp/qemu-virt64-aarch64/driver/SConscript
  8. 20 21
      bsp/qemu-virt64-aarch64/driver/board.c
  9. 22 0
      bsp/qemu-virt64-aarch64/driver/board.h
  10. 1 1
      bsp/qemu-virt64-aarch64/driver/drv_uart.c
  11. 11 0
      bsp/qemu-virt64-aarch64/driver/virtio/SConscript
  12. 405 0
      bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c
  13. 85 0
      bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h
  14. 60 0
      bsp/qemu-virt64-aarch64/driver/virtio/virtio.h
  15. 61 0
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c
  16. 75 0
      bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h
  17. 1 1
      bsp/qemu-virt64-aarch64/link.lds
  18. 6 1
      bsp/qemu-virt64-aarch64/qemu.bat
  19. 4 1
      bsp/qemu-virt64-aarch64/qemu.sh
  20. 24 10
      bsp/qemu-virt64-aarch64/rtconfig.h
  21. 1 1
      bsp/qemu-virt64-aarch64/rtconfig.py
  22. 189 27
      bsp/raspberry-pi/raspi3-64/.config
  23. 1 0
      bsp/raspberry-pi/raspi3-64/driver/mbox.h
  24. 1 0
      bsp/raspberry-pi/raspi3-64/driver/raspi.h
  25. 6 4
      bsp/raspberry-pi/raspi3-64/qemu-64.bat
  26. 4 0
      bsp/raspberry-pi/raspi3-64/qemu-64.sh
  27. 29 8
      bsp/raspberry-pi/raspi3-64/rtconfig.h
  28. 1 1
      bsp/raspberry-pi/raspi3-64/rtconfig.py
  29. 307 38
      bsp/raspberry-pi/raspi4-64/.config
  30. 5 1
      bsp/raspberry-pi/raspi4-64/README.md
  31. 27 0
      bsp/raspberry-pi/raspi4-64/applications/mnt.c
  32. 21 1
      bsp/raspberry-pi/raspi4-64/driver/Kconfig
  33. 36 0
      bsp/raspberry-pi/raspi4-64/driver/board.c
  34. 723 0
      bsp/raspberry-pi/raspi4-64/driver/drv_eth.c
  35. 216 0
      bsp/raspberry-pi/raspi4-64/driver/drv_eth.h
  36. 69 0
      bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c
  37. 46 1
      bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h
  38. 720 0
      bsp/raspberry-pi/raspi4-64/driver/drv_sdio.c
  39. 268 0
      bsp/raspberry-pi/raspi4-64/driver/drv_sdio.h
  40. 246 31
      bsp/raspberry-pi/raspi4-64/driver/drv_uart.c
  41. 24 0
      bsp/raspberry-pi/raspi4-64/driver/drv_uart.h
  42. 519 0
      bsp/raspberry-pi/raspi4-64/driver/mbox.c
  43. 187 0
      bsp/raspberry-pi/raspi4-64/driver/mbox.h
  44. 121 5
      bsp/raspberry-pi/raspi4-64/driver/raspi4.h
  45. 115 8
      bsp/raspberry-pi/raspi4-64/rtconfig.h
  46. 1 1
      bsp/raspberry-pi/raspi4-64/rtconfig.py
  47. 5 1
      libcpu/aarch64/common/SConscript
  48. 31 0
      libcpu/aarch64/common/cpuport.h
  49. 504 0
      libcpu/aarch64/common/gic.c
  50. 63 0
      libcpu/aarch64/common/gic.h
  51. 0 30
      libcpu/aarch64/common/gic/SConscript
  52. 0 273
      libcpu/aarch64/common/gic/gic_pl390.c
  53. 0 27
      libcpu/aarch64/common/gic/gic_pl390.h
  54. 0 261
      libcpu/aarch64/common/gic/gic_pl400.c
  55. 0 61
      libcpu/aarch64/common/gic/gic_pl400.h
  56. 409 0
      libcpu/aarch64/common/interrupt.c
  57. 60 0
      libcpu/aarch64/common/interrupt.h
  58. 1 2
      libcpu/aarch64/common/stack.c
  59. 172 0
      libcpu/aarch64/common/trap.c
  60. 1 1
      libcpu/aarch64/cortex-a/SConscript
  61. 97 0
      libcpu/aarch64/cortex-a/entry_point.S
  62. 0 116
      libcpu/aarch64/cortex-a53/entry_point.S
  63. 0 202
      libcpu/aarch64/cortex-a53/interrupt.c
  64. 0 27
      libcpu/aarch64/cortex-a53/interrupt.h
  65. 0 90
      libcpu/aarch64/cortex-a53/stack.c
  66. 0 225
      libcpu/aarch64/cortex-a53/trap.c
  67. 0 13
      libcpu/aarch64/cortex-a72/SConscript
  68. 0 111
      libcpu/aarch64/cortex-a72/entry_point.S
  69. 0 118
      libcpu/aarch64/cortex-a72/interrupt.c
  70. 0 27
      libcpu/aarch64/cortex-a72/interrupt.h
  71. 0 98
      libcpu/aarch64/cortex-a72/trap.c

+ 64 - 28
bsp/qemu-virt64-aarch64/.config

@@ -14,7 +14,7 @@ CONFIG_RT_ALIGN_SIZE=4
 CONFIG_RT_THREAD_PRIORITY_32=y
 # CONFIG_RT_THREAD_PRIORITY_256 is not set
 CONFIG_RT_THREAD_PRIORITY_MAX=32
-CONFIG_RT_TICK_PER_SECOND=1000
+CONFIG_RT_TICK_PER_SECOND=100
 CONFIG_RT_USING_OVERFLOW_CHECK=y
 CONFIG_RT_USING_HOOK=y
 CONFIG_RT_USING_IDLE_HOOK=y
@@ -29,6 +29,7 @@ CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
 #
 # 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_DEBUG=y
 CONFIG_RT_DEBUG_COLOR=y
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -97,19 +98,19 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # Command shell
 #
 CONFIG_RT_USING_FINSH=y
+CONFIG_RT_USING_MSH=y
+CONFIG_FINSH_USING_MSH=y
 CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
 CONFIG_FINSH_USING_HISTORY=y
 CONFIG_FINSH_HISTORY_LINES=5
 CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
 CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
-CONFIG_FINSH_THREAD_PRIORITY=20
-CONFIG_FINSH_THREAD_STACK_SIZE=4096
-CONFIG_FINSH_CMD_SIZE=80
 # CONFIG_FINSH_USING_AUTH is not set
-CONFIG_FINSH_USING_MSH=y
-CONFIG_FINSH_USING_MSH_DEFAULT=y
-CONFIG_FINSH_USING_MSH_ONLY=y
 CONFIG_FINSH_ARG_MAX=10
 
 #
@@ -121,7 +122,28 @@ CONFIG_DFS_FILESYSTEMS_MAX=2
 CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
 CONFIG_DFS_FD_MAX=16
 # CONFIG_RT_USING_DFS_MNTTABLE is not set
-# CONFIG_RT_USING_DFS_ELMFAT is not set
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+CONFIG_RT_DFS_ELM_USE_LFN_3=y
+CONFIG_RT_DFS_ELM_USE_LFN=3
+CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
+CONFIG_RT_DFS_ELM_LFN_UNICODE=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+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_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
@@ -180,7 +202,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_RT_USING_POSIX_GETLINE is not set
 # CONFIG_RT_USING_POSIX_AIO is not set
 # CONFIG_RT_USING_MODULE is not set
-CONFIG_RT_LIBC_FIXED_TIMEZONE=8
+CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 
 #
 # Network
@@ -312,6 +334,8 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 # CONFIG_PKG_USING_AGILE_MODBUS is not set
 # CONFIG_PKG_USING_AGILE_FTP is not set
 # CONFIG_PKG_USING_EMBEDDEDPROTO is not set
+# CONFIG_PKG_USING_RT_LINK_HW is not set
+# CONFIG_PKG_USING_HM is not set
 
 #
 # security packages
@@ -328,6 +352,7 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 # CONFIG_PKG_USING_LUA is not set
 # CONFIG_PKG_USING_JERRYSCRIPT is not set
 # CONFIG_PKG_USING_MICROPYTHON is not set
+# CONFIG_PKG_USING_PIKASCRIPT is not set
 
 #
 # multimedia packages
@@ -438,6 +463,9 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 # CONFIG_PKG_USING_LPM is not set
 # CONFIG_PKG_USING_TLSF is not set
 # CONFIG_PKG_USING_EVENT_RECORDER is not set
+# CONFIG_PKG_USING_ARM_2D is not set
+# CONFIG_PKG_USING_WCWIDTH is not set
+# CONFIG_PKG_USING_MCUBOOT is not set
 
 #
 # peripheral libraries and drivers
@@ -508,6 +536,9 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 # CONFIG_PKG_USING_KOBUKI is not set
 # CONFIG_PKG_USING_ROSSERIAL is not set
 # CONFIG_PKG_USING_MICRO_ROS is not set
+# CONFIG_PKG_USING_MCP23008 is not set
+# CONFIG_PKG_USING_BLUETRUM_SDK is not set
+# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
 
 #
 # AI packages
@@ -525,6 +556,27 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 #
 # miscellaneous packages
 #
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_CMATRIX is not set
+# CONFIG_PKG_USING_SL is not set
+# CONFIG_PKG_USING_CAL is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
@@ -542,14 +594,6 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 # CONFIG_PKG_USING_DIGITALCTRL is not set
 # CONFIG_PKG_USING_UPACKER is not set
 # CONFIG_PKG_USING_UPARAM is not set
-
-#
-# samples: kernel and components samples
-#
-# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
-# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
-# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
-# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
 # CONFIG_PKG_USING_VI is not set
 # CONFIG_PKG_USING_KI is not set
@@ -557,20 +601,11 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8
 # CONFIG_PKG_USING_VT100 is not set
 # CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_CRCLIB is not set
-
-#
-# entertainment: terminal games and other interesting software packages
-#
-# CONFIG_PKG_USING_THREES is not set
-# CONFIG_PKG_USING_2048 is not set
-# CONFIG_PKG_USING_SNAKE is not set
-# CONFIG_PKG_USING_TETRIS is not set
-# CONFIG_PKG_USING_DONUT is not set
-# CONFIG_PKG_USING_ACLOCK 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_SOC_VIRT64_AARCH64=y
 
 #
@@ -579,5 +614,6 @@ CONFIG_SOC_VIRT64_AARCH64=y
 CONFIG_BSP_SUPPORT_FPU=y
 CONFIG_BSP_USING_UART=y
 CONFIG_RT_USING_UART0=y
+CONFIG_BSP_USING_VIRTIO_BLK=y
+CONFIG_RT_USING_VIRTIO_BLK0=y
 CONFIG_BSP_USING_GIC=y
-CONFIG_BSP_USING_GIC390=y

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

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

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

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

+ 2 - 0
bsp/qemu-virt64-aarch64/SConstruct

@@ -17,6 +17,8 @@ env = Environment(tools = ['mingw'],
     AR   = rtconfig.AR, ARFLAGS = '-rc',
     LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
 env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+env['ASCOM'] = env['ASPPCOM']
+env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group'
 
 Export('RTT_ROOT')
 Export('rtconfig')

+ 30 - 0
bsp/qemu-virt64-aarch64/applications/mnt.c

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      bernard      the first version
+ */
+
+#include <rtthread.h>
+
+#ifdef RT_USING_DFS
+#include <dfs_fs.h>
+
+int mnt_init(void)
+{
+    if(rt_device_find("virtio-blk0"))
+    {
+        /* mount virtio-blk as root directory */
+        if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0)
+        {
+            rt_kprintf("file system initialization done!\n");
+        }
+    }
+
+    return 0;
+}
+INIT_ENV_EXPORT(mnt_init);
+#endif

+ 10 - 4
bsp/qemu-virt64-aarch64/driver/Kconfig

@@ -15,11 +15,17 @@ menu "AARCH64 qemu virt64 configs"
             default y
         endif
 
-    config BSP_USING_GIC
-    bool
-    default y
+    menuconfig BSP_USING_VIRTIO_BLK
+        bool "Using VirtIO BLK"
+        default y
 
-    config BSP_USING_GIC390
+        if BSP_USING_VIRTIO_BLK
+            config RT_USING_VIRTIO_BLK0
+            bool "Enabel VirtIO BLK 0"
+            default y
+        endif
+
+    config BSP_USING_GIC
     bool
     default y
 endmenu

+ 10 - 5
bsp/qemu-virt64-aarch64/driver/SConscript

@@ -3,12 +3,17 @@
 from building import *
 
 cwd     = GetCurrentDir()
-src     = Split('''
-board.c
-drv_uart.c
-''')
+src  	= Glob('*.c')
+list 	= os.listdir(cwd)
 CPPPATH = [cwd]
+objs 	= []
 
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
 
-Return('group')
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+objs = objs + group
+
+Return('objs')

+ 20 - 21
bsp/qemu-virt64-aarch64/driver/board.c

@@ -7,6 +7,7 @@
  * Date           Author         Notes
  * 2019-07-29     zdzn           first version
  * 2021-07-31     GuEe-GUI       config the memory/io address map
+ * 2021-09-11     GuEe-GUI       remove do-while in rt_hw_timer_isr
  */
 
 #include <rthw.h>
@@ -18,38 +19,34 @@
 
 void rt_hw_vector_init(void);
 
-static uint64_t tickval = 0;
+static uint64_t timer_val;
+static uint64_t timer_step;
 
 void rt_hw_timer_isr(int vector, void *parameter)
 {
-    uint64_t cntvct_el0;
-
-    do
-    {
-        tickval += 0xF424;
-        __asm__ volatile ("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
-        __asm__ volatile ("mrs %0, CNTVCT_EL0":"=r"(cntvct_el0));
-    }
-    while (cntvct_el0 >= tickval);
+    timer_val += timer_step;
+    __asm__ volatile ("msr CNTV_CVAL_EL0, %0"::"r"(timer_val));
+    __asm__ volatile ("isb":::"memory");
 
     rt_tick_increase();
 }
 
-int rt_hw_timer_init()
+int rt_hw_timer_init(void)
 {
-    uint64_t val;
-
     rt_hw_interrupt_install(27, rt_hw_timer_isr, RT_NULL, "tick");
     rt_hw_interrupt_umask(27);
 
-    val = 0;
-    __asm__ volatile ("msr CNTV_CTL_EL0, %0"::"r"(val));
-    val = 0x03B9ACA0;
-    __asm__ volatile ("msr CNTFRQ_EL0, %0"::"r"(val));
-    tickval += 0xF424;
-    __asm__ volatile ("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
-    val = 1;
-    __asm__ volatile ("msr CNTV_CTL_EL0, %0"::"r"(val));
+    __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");
+
+    __asm__ volatile ("msr CNTV_CVAL_EL0, %0"::"r"(timer_val));
+    __asm__ volatile ("msr CNTV_CTL_EL0, %0"::"r"(1));
+
     return 0;
 }
 
@@ -73,6 +70,8 @@ void rt_hw_board_init(void)
     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*/

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

@@ -7,12 +7,15 @@
  * Date           Author       Notes
  * 2017-5-30      Bernard      the first version
  * 2021-07-31     GuEe-GUI     add ARM GIC definitions
+ * 2021-09-11     GuEe-GUI     rename right macros for gic
  */
 
 #ifndef BOARD_H__
 #define BOARD_H__
 
 #include <rthw.h>
+#include <rtdef.h>
+#include <stdint.h>
 
 extern unsigned char __bss_start;
 extern unsigned char __bss_end;
@@ -20,17 +23,36 @@ extern unsigned char __bss_end;
 #define RT_HW_HEAP_BEGIN    (void*)&__bss_end
 #define RT_HW_HEAP_END      (void*)(RT_HW_HEAP_BEGIN + 1 * 1024 * 1024)
 
+#define __REG32(x)  (*((volatile unsigned int *)(x)))
+
+#define VIRTIO_SPI_IRQ_BASE         32
+
+/* Virtio BLK */
+#define VIRTIO_MMIO_BLK0_BASE       0x0a000000
+#define VIRTIO_MMIO_BLK0_SIZE       0x00000200
+#define VIRTIO_MMIO_BLK0_IRQ        (VIRTIO_SPI_IRQ_BASE + 0x10)
+
 /* UART */
 #define PL011_UARTDR                0x000
 #define PL011_UARTFR                0x018
 #define PL011_UARTFR_TXFF_BIT       5
 #define PL011_UART0_BASE            0x09000000
 #define PL011_UART0_SIZE            0x00001000
+#define PL011_UART0_IRQNUM          (VIRTIO_SPI_IRQ_BASE + 1)
 
 /* DIST and CPU */
 #define GIC_PL390_DISTRIBUTOR_PPTR  0x08000000
 #define GIC_PL390_CONTROLLER_PPTR   0x08010000
 
+#define MAX_HANDLERS                96
+#define GIC_IRQ_START               0
+/* number of interrupts on board */
+#define ARM_GIC_NR_IRQS             96
+/* only one GIC available */
+#define ARM_GIC_MAX_NR              1
+
+#define IRQ_ARM_VTIMER              27
+
 /* the basic constants and interfaces needed by gic */
 rt_inline rt_uint32_t platform_get_gic_dist_base(void)
 {

+ 1 - 1
bsp/qemu-virt64-aarch64/driver/drv_uart.c

@@ -116,7 +116,7 @@ static void rt_hw_uart_isr(int irqno, void *param)
 static struct hw_uart_device _uart0_device =
 {
     PL011_UART0_BASE,
-    33,
+    PL011_UART0_IRQNUM,
 };
 static struct rt_serial_device _serial0;
 #endif

+ 11 - 0
bsp/qemu-virt64-aarch64/driver/virtio/SConscript

@@ -0,0 +1,11 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd     = GetCurrentDir()
+src  	= Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

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

@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-9-16      GuEe-GUI     the first version
+ */
+
+#include <rtconfig.h>
+#include <rtthread.h>
+#include <rthw.h>
+#include <cpuport.h>
+#include <board.h>
+
+#include "virtio.h"
+#include "virtio_mmio.h"
+#include "drv_virtio_blk.h"
+
+#ifdef BSP_USING_VIRTIO_BLK
+
+#ifdef RT_USING_VIRTIO_BLK0
+static struct virtio_blk blk0;
+static struct virtio_blk_device virtio_blk_dev0;
+#endif /* RT_USING_VIRTIO_BLK0 */
+
+static int alloc_desc(struct virtio_blk *blk)
+{
+    int i;
+    for(i = 0; i < QUEUE_SIZE; i++)
+    {
+        if (blk->free[i])
+        {
+            blk->free[i] = 0;
+            return i;
+        }
+    }
+    return -RT_ERROR;
+}
+
+static void free_desc(struct virtio_blk *blk, int i)
+{
+    if (i >= QUEUE_SIZE)
+    {
+        rt_kprintf("Out of queue number");
+        RT_ASSERT(0);
+    }
+    if (blk0.free[i])
+    {
+        rt_kprintf("Already freed");
+        RT_ASSERT(0);
+    }
+    blk->desc[i].addr = 0;
+    blk->desc[i].len = 0;
+    blk->desc[i].flags = 0;
+    blk->desc[i].next = 0;
+    blk->free[i] = 1;
+}
+
+static void free_chain(struct virtio_blk *blk, int i)
+{
+    int flag, nxt;
+    for (;;)
+    {
+        flag = blk->desc[i].flags;
+        nxt = blk->desc[i].next;
+
+        free_desc(blk, i);
+
+        if (flag & VRING_DESC_F_NEXT)
+        {
+            i = nxt;
+        }
+        else
+        {
+            break;
+        }
+    }
+}
+
+static int alloc3_desc(struct virtio_blk *blk, int *idx)
+{
+    for (int i = 0; i < 3; ++i)
+    {
+        idx[i] = alloc_desc(blk);
+        if (idx[i] < 0)
+        {
+            for (int j = 0; j < i; ++j)
+            {
+                free_desc(blk, idx[j]);
+            }
+            return -RT_ERROR;
+        }
+    }
+    return 0;
+}
+
+static int virtio_blk_device_init(struct virtio_blk_device *virtio_blk_dev)
+{
+    uint32_t status = 0;
+    uint32_t max;
+    uint64_t features;
+    int i;
+
+#ifdef RT_USING_SMP
+    rt_spin_lock_init(&virtio_blk_dev->spinlock);
+#endif
+
+    if (virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_MAGIC_VALUE) != VIRTIO_MMIO_MAGIC ||
+        virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_VERSION) != 1 ||
+        virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DEVICE_ID) != 2 ||
+        virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_VENDOR_ID) != VIRTIO_MMIO_VENDOR)
+    {
+        rt_kprintf("Could not find virtio disk");
+
+        return -RT_ERROR;
+    }
+
+    status |= VIRTIO_STAT_ACKNOWLEDGE;
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status);
+
+    status |= VIRTIO_STAT_DRIVER;
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status);
+
+    /* negotiate features */
+    features = virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DEVICE_FEATURES);
+    features &= ~(1 << VIRTIO_BLK_F_RO);
+    features &= ~(1 << VIRTIO_BLK_F_SCSI);
+    features &= ~(1 << VIRTIO_BLK_F_CONFIG_WCE);
+    features &= ~(1 << VIRTIO_BLK_F_MQ);
+    features &= ~(1 << VIRTIO_F_ANY_LAYOUT);
+    features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
+    features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DRIVER_FEATURES, features);
+
+    /* tell device that feature negotiation is complete */
+    status |= VIRTIO_STAT_FEATURES_OK;
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status);
+
+    /* tell device we're completely ready */
+    status |= VIRTIO_STAT_DRIVER_OK;
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status);
+
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_GUEST_PAGE_SIZE, PAGE_SIZE);
+
+    /* initialize queue 0 */
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_SEL, 0);
+
+    max = virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NUM_MAX);
+    if (max == 0)
+    {
+        rt_kprintf("Virtio disk has no queue 0");
+        RT_ASSERT(0);
+    }
+    if (max < QUEUE_SIZE)
+    {
+        rt_kprintf("Virtio disk max queue too short");
+        RT_ASSERT(0);
+    }
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NUM, QUEUE_SIZE);
+
+    rt_memset(virtio_blk_dev->blk->pages, 0, sizeof(virtio_blk_dev->blk->pages));
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_PFN, ((uint64_t)blk0.pages) >> PAGE_SHIFT);
+
+    virtio_blk_dev->blk->desc = (struct virtq_desc *)virtio_blk_dev->blk->pages;
+    virtio_blk_dev->blk->avail = (struct virtq_avail *)(virtio_blk_dev->blk->pages + QUEUE_SIZE * sizeof(struct virtq_desc));
+    virtio_blk_dev->blk->used = (struct virtq_used *)(virtio_blk_dev->blk->pages + PAGE_SIZE);
+
+    /* all QUEUE_SIZE descriptors start out unused */
+    for (i = 0; i < QUEUE_SIZE; ++i)
+    {
+        virtio_blk_dev->blk->free[i] = 1;
+    }
+
+    return RT_EOK;
+}
+
+static void virtio_blk_rw(struct virtio_blk_device *virtio_blk_dev, struct virtio_blk_buf *buf, int flag)
+{
+    struct virtio_blk *blk = virtio_blk_dev->blk;
+    uint64_t sector = buf->block_no * (VIRTIO_BLK_BUF_DATA_SIZE / 512);
+    int idx[3];
+    struct virtio_blk_req *req;
+
+#ifdef RT_USING_SMP
+    rt_base_t level;
+
+    level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock);
+#endif
+
+    /* allocate the three descriptors */
+    for (;;)
+    {
+        if (alloc3_desc(blk, idx) == 0)
+        {
+            break;
+        }
+    }
+
+    req = &(blk->ops[idx[0]]);
+    req->type = flag;
+    req->reserved = 0;
+    req->sector = sector;
+
+    blk->desc[idx[0]].addr = (uint64_t)req;
+    blk->desc[idx[0]].len = sizeof(struct virtio_blk_req);
+    blk->desc[idx[0]].flags = VRING_DESC_F_NEXT;
+    blk->desc[idx[0]].next = idx[1];
+
+    blk->desc[idx[1]].addr = (uint64_t)buf->data;
+    blk->desc[idx[1]].len = VIRTIO_BLK_BUF_DATA_SIZE;
+
+    blk->desc[idx[1]].flags = flag ? 0 : VRING_DESC_F_WRITE;
+
+    blk->desc[idx[1]].flags |= VRING_DESC_F_NEXT;
+    blk->desc[idx[1]].next = idx[2];
+
+    /* device writes 0 on success */
+    blk->info[idx[0]].status = 0xff;
+    blk->desc[idx[2]].addr = (uint64_t)&(blk->info[idx[0]].status);
+    blk->desc[idx[2]].len = 1;
+    /* device writes the status */
+    blk->desc[idx[2]].flags = VRING_DESC_F_WRITE;
+    blk->desc[idx[2]].next = 0;
+
+    /* record struct buf for virtio_blk_isr() */
+    buf->valid = 1;
+    blk->info[idx[0]].buf = buf;
+
+    /* tell the device the first index in our chain of descriptors */
+    blk->avail->ring[blk->avail->idx % QUEUE_SIZE] = idx[0];
+
+    rt_hw_dsb();
+
+    /* tell the device another avail ring entry is available */
+    blk->avail->idx += 1;
+
+    rt_hw_dsb();
+
+    /* value is queue number */
+    virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NOTIFY, 0);
+
+    /* wait for virtio_blk_isr() to done */
+    while (buf->valid == 1)
+    {
+#ifdef RT_USING_SMP
+        rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level);
+#endif
+        rt_thread_yield();
+#ifdef RT_USING_SMP
+        level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock);
+#endif
+    }
+
+    blk->info[idx[0]].buf = 0;
+    free_chain(blk, idx[0]);
+
+#ifdef RT_USING_SMP
+    rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level);
+#endif
+}
+
+static void virtio_blk_isr(int irqno, void *param)
+{
+    int id;
+    struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)param;
+    struct virtio_blk *blk = virtio_blk_dev->blk;
+    struct virtio_blk_buf *buf_tmp;
+
+#ifdef RT_USING_SMP
+    rt_base_t level;
+
+    level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock);
+#endif
+
+    virtio_mmio_write32(
+        virtio_blk_dev->mmio_base,
+        VIRTIO_MMIO_INTERRUPT_ACK,
+        virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_INTERRUPT_STATUS) & 0x3);
+
+    rt_hw_dsb();
+
+    /*
+     * the device increments disk.used->idx
+     * when it adds an entry to the used ring
+     */
+    while (blk->used_idx != blk->used->idx)
+    {
+        rt_hw_dsb();
+        id = blk->used->ring[blk->used_idx % QUEUE_SIZE].id;
+
+        if (blk->info[id].status != 0)
+        {
+            rt_kprintf("Virtio BLK Status");
+            RT_ASSERT(0);
+        }
+
+        buf_tmp = blk->info[id].buf;
+
+        /* done with buf */
+        buf_tmp->valid = 0;
+        rt_thread_yield();
+
+        blk->used_idx += 1;
+    }
+
+#ifdef RT_USING_SMP
+    rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level);
+#endif
+}
+
+static rt_err_t virtio_blk_init(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t virtio_blk_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t virtio_blk_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_size_t virtio_blk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev;
+    struct virtio_blk_buf buf =
+    {
+        .block_no = (uint32_t)pos,
+        .data = (uint8_t *)buffer
+    };
+
+    virtio_blk_rw(virtio_blk_dev, &buf, VIRTIO_BLK_T_IN);
+
+    return size;
+}
+
+static rt_size_t virtio_blk_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev;
+    struct virtio_blk_buf buf =
+    {
+        .block_no = (uint32_t)pos,
+        .data = (uint8_t *)buffer
+    };
+
+    virtio_blk_rw(virtio_blk_dev, &buf, VIRTIO_BLK_T_OUT);
+
+    return size;
+}
+
+static rt_err_t virtio_blk_control(rt_device_t dev, int cmd, void *args)
+{
+    if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
+    {
+        struct rt_device_blk_geometry *geometry;
+
+        geometry = (struct rt_device_blk_geometry *)args;
+        if (geometry == RT_NULL)
+        {
+            return -RT_ERROR;
+        }
+
+        geometry->bytes_per_sector = VIRTIO_BLK_BYTES_PER_SECTOR;
+        geometry->block_size = VIRTIO_BLK_BLOCK_SIZE;
+        geometry->sector_count = VIRTIO_BLK_SECTOR_COUNT;
+    }
+
+    return RT_EOK;
+}
+
+const static struct rt_device_ops virtio_blk_ops =
+{
+    virtio_blk_init,
+    virtio_blk_open,
+    virtio_blk_close,
+    virtio_blk_read,
+    virtio_blk_write,
+    virtio_blk_control
+};
+
+int rt_virtio_blk_init(void)
+{
+    rt_err_t status = RT_EOK;
+
+#ifdef RT_USING_VIRTIO_BLK0
+    virtio_blk_dev0.parent.type = RT_Device_Class_Block;
+    virtio_blk_dev0.parent.ops  = &virtio_blk_ops;
+    virtio_blk_dev0.blk = &blk0;
+    virtio_blk_dev0.mmio_base = (uint32_t *)VIRTIO_MMIO_BLK0_BASE;
+
+    status = virtio_blk_device_init(&virtio_blk_dev0);
+    rt_device_register((rt_device_t)&virtio_blk_dev0, "virtio-blk0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
+    rt_hw_interrupt_install(VIRTIO_MMIO_BLK0_IRQ, virtio_blk_isr, &virtio_blk_dev0, "virtio-blk0");
+    rt_hw_interrupt_umask(VIRTIO_MMIO_BLK0_IRQ);
+#endif /* RT_USING_VIRTIO_BLK0 */
+
+    return status;
+}
+INIT_DEVICE_EXPORT(rt_virtio_blk_init);
+#endif /* BSP_USING_VIRTIO_BLK */

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

@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-9-16      GuEe-GUI     the first version
+ */
+
+#ifndef DRV_VIRTIO_BLK_H__
+#define DRV_VIRTIO_BLK_H__
+
+#include <rthw.h>
+#include <stdint.h>
+#include "virtio.h"
+
+#define VIRTIO_BLK_BUF_DATA_SIZE        512
+#define VIRTIO_BLK_BYTES_PER_SECTOR     512
+#define VIRTIO_BLK_BLOCK_SIZE           512
+#define VIRTIO_BLK_SECTOR_COUNT         0x40000 /* 128MB */
+
+#define VIRTIO_BLK_F_RO                 5   /* Disk is read-only */
+#define VIRTIO_BLK_F_SCSI               7   /* Supports scsi command passthru */
+#define VIRTIO_BLK_F_CONFIG_WCE         11  /* Writeback mode available in config */
+#define VIRTIO_BLK_F_MQ                 12  /* Support more than one vq */
+
+#define VIRTIO_BLK_T_IN                 0   /* Read the blk */
+#define VIRTIO_BLK_T_OUT                1   /* Write the blk */
+
+#define VIRTIO_F_ANY_LAYOUT             27
+#define VIRTIO_RING_F_INDIRECT_DESC     28
+#define VIRTIO_RING_F_EVENT_IDX         29
+
+struct virtio_blk_buf
+{
+    int valid;
+    uint32_t block_no;
+    uint8_t *data;
+};
+
+struct virtio_blk_req
+{
+    uint32_t type;
+    uint32_t reserved;
+    uint64_t sector;
+};
+
+/*
+ * virtio_blk must be a static variable because
+ * pages must consist of two contiguous pages of
+ * page-aligned physical memory
+ */
+struct virtio_blk
+{
+    char pages[2 * PAGE_SIZE];
+    struct virtq_desc *desc;
+    struct virtq_avail *avail;
+    struct virtq_used *used;
+
+    char free[QUEUE_SIZE];
+    uint16_t used_idx;
+    struct
+    {
+        struct virtio_blk_buf *buf;
+        char status;
+    } info[QUEUE_SIZE];
+
+    struct virtio_blk_req ops[QUEUE_SIZE];
+} __attribute__ ((aligned (PAGE_SIZE)));
+
+struct virtio_blk_device
+{
+    struct rt_device parent;
+    struct virtio_blk *blk;
+
+    uint32_t *mmio_base;
+#ifdef RT_USING_SMP
+    struct rt_spinlock spinlock;
+#endif
+};
+
+int rt_hw_virtio_blk_init(void);
+
+#endif /* DRV_VIRTIO_BLK_H__ */

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

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-9-16      GuEe-GUI     the first version
+ */
+
+#ifndef VIRTIO_H__
+#define VIRTIO_H__
+
+#include <stdint.h>
+
+#define PAGE_SIZE   4096
+#define PAGE_SHIFT  12
+
+#define VIRTIO_STAT_ACKNOWLEDGE     1
+#define VIRTIO_STAT_DRIVER          2
+#define VIRTIO_STAT_DRIVER_OK       4
+#define VIRTIO_STAT_FEATURES_OK     8
+#define VIRTIO_STAT_NEEDS_RESET     64
+#define VIRTIO_STAT_FAILED          128
+
+#define QUEUE_SIZE  8
+
+struct virtq_desc
+{
+    uint64_t addr;
+    uint32_t len;
+    uint16_t flags;
+    uint16_t next;
+};
+
+#define VRING_DESC_F_NEXT  1    // chained with another descriptor
+#define VRING_DESC_F_WRITE 2    // device writes (vs read)
+
+struct virtq_avail
+{
+    uint16_t flags;             // always zero
+    uint16_t idx;               // driver will write ring[idx] next
+    uint16_t ring[QUEUE_SIZE];  // descriptor numbers of chain heads
+    uint16_t unused;
+};
+
+struct virtq_used_elem
+{
+    uint32_t id;   // index of start of completed descriptor chain
+    uint32_t len;
+};
+
+struct virtq_used
+{
+    uint16_t flags;                         // always zero
+    uint16_t idx;                           // device increments when it adds a ring[] entry
+    struct virtq_used_elem ring[QUEUE_SIZE];
+};
+
+#endif /* VIRTIO_H__ */

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

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-9-16      GuEe-GUI     the first version
+ */
+
+#include <rtthread.h>
+#include <cpuport.h>
+
+#include "virtio_mmio.h"
+
+void virtio_mmio_print_configs(uint32_t *device_base)
+{
+    rt_kprintf("MagicValue:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_MAGIC_VALUE));
+    rt_kprintf("Version:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_VERSION));
+    rt_kprintf("DeviceID:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_DEVICE_ID));
+    rt_kprintf("VendorID:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_VENDOR_ID));
+    rt_kprintf("DeviceFeatures0:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES));
+    rt_kprintf("DeviceFeaturesSel0:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES_SEL));
+
+    virtio_mmio_write32(device_base, VIRTIO_MMIO_HOST_FEATURES_SEL, 1);
+    rt_hw_dsb();
+
+    rt_kprintf("DeviceFeatures1:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES));
+    rt_kprintf("DriverFeatures:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_FEATURES));
+    rt_kprintf("DriverFeaturesSel:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_FEATURES_SEL));
+    rt_kprintf("PageSize:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_PAGE_SIZE));
+
+    virtio_mmio_write32(device_base, VIRTIO_MMIO_QUEUE_SEL, 0);
+    rt_hw_dsb();
+
+    rt_kprintf("QueueSel:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_SEL));
+    rt_kprintf("QueueNumMax:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM_MAX));
+    rt_kprintf("QueueNum:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM));
+
+    virtio_mmio_write32(device_base, VIRTIO_MMIO_QUEUE_SEL, 1);
+    rt_hw_dsb();
+
+    rt_kprintf("QueueSel:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_SEL));
+    rt_kprintf("QueueNumMax1:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM_MAX));
+    rt_kprintf("QueueNum1:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM));
+    rt_kprintf("QueueAlign:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_ALIGN));
+    rt_kprintf("QueuePFN:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_PFN));
+    rt_kprintf("QueueReady:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_READY));
+    rt_kprintf("QueueNotify:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NOTIFY));
+    rt_kprintf("InterruptStatus:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_INTERRUPT_STATUS));
+    rt_kprintf("InterruptACK:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_INTERRUPT_ACK));
+    rt_kprintf("Status:\t\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_STATUS));
+    rt_kprintf("QueueDescLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_DESC_LOW));
+    rt_kprintf("QueueDescHigh:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_DESC_HIGH));
+    rt_kprintf("QueueDriverLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_AVAIL_LOW));
+    rt_kprintf("QueueDriverHigh:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_AVAIL_HIGH));
+    rt_kprintf("QueueDeviceLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_USED_LOW));
+    rt_kprintf("QueueDeviceHigh:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_USED_HIGH));
+    rt_kprintf("ConfigGeneration:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_CONFIG_GENERATION));
+    rt_kprintf("Config:\t\t\t 0x%x\n", virtio_mmio_read32(device_base,VIRTIO_MMIO_CONFIG));
+}

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

@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-9-16      GuEe-GUI     the first version
+ */
+
+#ifndef VIRTIO_MMIO_H
+#define VIRTIO_MMIO_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define VIRTIO_MMIO_MAGIC               0x74726976
+#define VIRTIO_MMIO_VENDOR              0x554d4551
+
+#define VIRTIO_MMIO_MAGIC_VALUE         0x000   /* VIRTIO_MMIO_MAGIC */
+#define VIRTIO_MMIO_VERSION             0x004   /* version: 1 is legacy */
+#define VIRTIO_MMIO_DEVICE_ID           0x008   /* device type: 1 is net, 2 is disk */
+#define VIRTIO_MMIO_VENDOR_ID           0x00c   /* VIRTIO_MMIO_VENDOR */
+#define VIRTIO_MMIO_DEVICE_FEATURES     0x010
+#define VIRTIO_MMIO_DRIVER_FEATURES     0x020
+#define VIRTIO_MMIO_HOST_FEATURES       0x010
+#define VIRTIO_MMIO_HOST_FEATURES_SEL   0x014
+#define VIRTIO_MMIO_GUEST_FEATURES      0x020
+#define VIRTIO_MMIO_GUEST_FEATURES_SEL  0x024
+#define VIRTIO_MMIO_GUEST_PAGE_SIZE     0x028   /* version 1 only */
+#define VIRTIO_MMIO_QUEUE_SEL           0x030
+#define VIRTIO_MMIO_QUEUE_NUM_MAX       0x034
+#define VIRTIO_MMIO_QUEUE_NUM           0x038
+#define VIRTIO_MMIO_QUEUE_ALIGN         0x03c   /* version 1 only */
+#define VIRTIO_MMIO_QUEUE_PFN           0x040   /* version 1 only */
+#define VIRTIO_MMIO_QUEUE_READY         0x044   /* requires version 2 */
+#define VIRTIO_MMIO_QUEUE_NOTIFY        0x050
+#define VIRTIO_MMIO_INTERRUPT_STATUS    0x060
+#define VIRTIO_MMIO_INTERRUPT_ACK       0x064
+#define VIRTIO_MMIO_STATUS              0x070
+#define VIRTIO_MMIO_QUEUE_DESC_LOW      0x080   /* requires version 2 */
+#define VIRTIO_MMIO_QUEUE_DESC_HIGH     0x084   /* requires version 2 */
+#define VIRTIO_MMIO_QUEUE_AVAIL_LOW     0x090   /* requires version 2 */
+#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH    0x094   /* requires version 2 */
+#define VIRTIO_MMIO_QUEUE_USED_LOW      0x0a0   /* requires version 2 */
+#define VIRTIO_MMIO_QUEUE_USED_HIGH     0x0a4   /* requires version 2 */
+#define VIRTIO_MMIO_CONFIG_GENERATION   0x100   /* requires version 2 */
+#define VIRTIO_MMIO_CONFIG              0x100
+#define VIRTIO_MMIO_INT_VRING           (1 << 0)
+#define VIRTIO_MMIO_INT_CONFIG          (1 << 1)
+#define VIRTIO_MMIO_VRING_ALIGN         4096
+
+static inline uint32_t virtio_mmio_read32(uint32_t *base, size_t offset)
+{
+    return *((volatile uint32_t*) (((uintptr_t) base) + offset));
+}
+
+static inline uint16_t virtio_mmio_read16(uint32_t *base, size_t offset)
+{
+    return *((volatile uint16_t*) (((uintptr_t) base) + offset));
+}
+
+static inline uint8_t virtio_mmio_read8(uint32_t *base, size_t offset)
+{
+    return *((volatile uint8_t*) (((uintptr_t) base) + offset));
+}
+
+static inline void virtio_mmio_write32(uint32_t *base, size_t offset, uint32_t val)
+{
+    *((volatile uint32_t*) (((uintptr_t) base) + offset)) = val;
+}
+
+void virtio_mmio_print_configs(uint32_t *device_base);
+
+#endif /* VIRTIO_MMIO_H */

+ 1 - 1
bsp/qemu-virt64-aarch64/link.lds

@@ -24,7 +24,7 @@
 
 SECTIONS
 {
-    . = 0x40000000;
+    . = 0x40008000;
     . = ALIGN(4096);
     .text :
     {

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

@@ -1 +1,6 @@
-qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 1 -kernel rtthread.elf -nographic
+@echo off
+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

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

@@ -1 +1,4 @@
-qemu-system-aarch64 -M virt -cpu cortex-a53 -smp 1 -kernel rtthread.elf -nographic -monitor pty
+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

+ 24 - 10
bsp/qemu-virt64-aarch64/rtconfig.h

@@ -10,7 +10,7 @@
 #define RT_ALIGN_SIZE 4
 #define RT_THREAD_PRIORITY_32
 #define RT_THREAD_PRIORITY_MAX 32
-#define RT_TICK_PER_SECOND 1000
+#define RT_TICK_PER_SECOND 100
 #define RT_USING_OVERFLOW_CHECK
 #define RT_USING_HOOK
 #define RT_USING_IDLE_HOOK
@@ -64,17 +64,17 @@
 /* Command shell */
 
 #define RT_USING_FINSH
+#define RT_USING_MSH
+#define FINSH_USING_MSH
 #define FINSH_THREAD_NAME "tshell"
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_USING_HISTORY
 #define FINSH_HISTORY_LINES 5
 #define FINSH_USING_SYMTAB
-#define FINSH_USING_DESCRIPTION
-#define FINSH_THREAD_PRIORITY 20
-#define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_CMD_SIZE 80
-#define FINSH_USING_MSH
-#define FINSH_USING_MSH_DEFAULT
-#define FINSH_USING_MSH_ONLY
+#define MSH_USING_BUILT_IN_COMMANDS
+#define FINSH_USING_DESCRIPTION
 #define FINSH_ARG_MAX 10
 
 /* Device virtual file system */
@@ -84,6 +84,20 @@
 #define DFS_FILESYSTEMS_MAX 2
 #define DFS_FILESYSTEM_TYPES_MAX 2
 #define DFS_FD_MAX 16
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+#define RT_DFS_ELM_USE_LFN_3
+#define RT_DFS_ELM_USE_LFN 3
+#define RT_DFS_ELM_LFN_UNICODE_0
+#define RT_DFS_ELM_LFN_UNICODE 0
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
+#define RT_DFS_ELM_REENTRANT
 #define RT_USING_DFS_DEVFS
 
 /* Device Drivers */
@@ -103,7 +117,7 @@
 
 #define RT_USING_LIBC
 #define RT_USING_POSIX
-#define RT_LIBC_FIXED_TIMEZONE 8
+#define RT_LIBC_DEFAULT_TIMEZONE 8
 
 /* Network */
 
@@ -172,7 +186,6 @@
 
 /* miscellaneous packages */
 
-
 /* samples: kernel and components samples */
 
 
@@ -185,7 +198,8 @@
 #define BSP_SUPPORT_FPU
 #define BSP_USING_UART
 #define RT_USING_UART0
+#define BSP_USING_VIRTIO_BLK
+#define RT_USING_VIRTIO_BLK0
 #define BSP_USING_GIC
-#define BSP_USING_GIC390
 
 #endif

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

@@ -2,7 +2,7 @@ import os
 
 # toolchains options
 ARCH        ='aarch64'
-CPU         ='cortex-a53'
+CPU         ='cortex-a'
 CROSS_TOOL  ='gcc'
 
 if os.getenv('RTT_ROOT'):

+ 189 - 27
bsp/raspberry-pi/raspi3-64/.config

@@ -23,6 +23,13 @@ CONFIG_IDLE_THREAD_STACK_SIZE=2048
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
 CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
+
+#
+# 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_DEBUG=y
 CONFIG_RT_DEBUG_COLOR=y
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -55,6 +62,7 @@ CONFIG_RT_USING_MEMHEAP=y
 CONFIG_RT_USING_SMALL_MEM=y
 # CONFIG_RT_USING_SLAB is not set
 # CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
+# CONFIG_RT_USING_USERHEAP is not set
 CONFIG_RT_USING_MEMTRACE=y
 CONFIG_RT_USING_HEAP=y
 
@@ -67,7 +75,8 @@ CONFIG_RT_USING_DEVICE_OPS=y
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=512
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
-CONFIG_RT_VER_NUM=0x40003
+# CONFIG_RT_PRINTF_LONGLONG is not set
+CONFIG_RT_VER_NUM=0x40004
 CONFIG_ARCH_CPU_64BIT=y
 # CONFIG_RT_USING_CPU_FFS is not set
 CONFIG_ARCH_ARMV8=y
@@ -90,19 +99,19 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # Command shell
 #
 CONFIG_RT_USING_FINSH=y
+CONFIG_RT_USING_MSH=y
+CONFIG_FINSH_USING_MSH=y
 CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
 CONFIG_FINSH_USING_HISTORY=y
 CONFIG_FINSH_HISTORY_LINES=5
 CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
 CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
-CONFIG_FINSH_THREAD_PRIORITY=20
-CONFIG_FINSH_THREAD_STACK_SIZE=4096
-CONFIG_FINSH_CMD_SIZE=80
 # CONFIG_FINSH_USING_AUTH is not set
-CONFIG_FINSH_USING_MSH=y
-CONFIG_FINSH_USING_MSH_DEFAULT=y
-CONFIG_FINSH_USING_MSH_ONLY=y
 CONFIG_FINSH_ARG_MAX=10
 
 #
@@ -126,6 +135,11 @@ CONFIG_RT_DFS_ELM_WORD_ACCESS=y
 # CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
 CONFIG_RT_DFS_ELM_USE_LFN_3=y
 CONFIG_RT_DFS_ELM_USE_LFN=3
+CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
+CONFIG_RT_DFS_ELM_LFN_UNICODE=0
 CONFIG_RT_DFS_ELM_MAX_LFN=255
 CONFIG_RT_DFS_ELM_DRIVES=2
 CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
@@ -134,8 +148,6 @@ CONFIG_RT_DFS_ELM_REENTRANT=y
 CONFIG_RT_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
-# CONFIG_RT_USING_DFS_UFFS is not set
-# CONFIG_RT_USING_DFS_JFFS2 is not set
 
 #
 # Device Drivers
@@ -144,6 +156,8 @@ 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
+# CONFIG_RT_USING_SERIAL_V2 is not set
 # CONFIG_RT_SERIAL_USING_DMA is not set
 CONFIG_RT_SERIAL_RB_BUFSZ=64
 # CONFIG_RT_USING_CAN is not set
@@ -153,8 +167,10 @@ CONFIG_RT_USING_I2C=y
 CONFIG_RT_I2C_DEBUG=y
 CONFIG_RT_USING_I2C_BITOPS=y
 # CONFIG_RT_I2C_BITOPS_DEBUG is not set
+# CONFIG_RT_USING_PHY is not set
 CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_DAC is not set
 # CONFIG_RT_USING_PWM is not set
 # CONFIG_RT_USING_MTD_NOR is not set
 # CONFIG_RT_USING_MTD_NAND is not set
@@ -196,8 +212,10 @@ CONFIG_RT_USING_LIBC=y
 CONFIG_RT_USING_POSIX=y
 # CONFIG_RT_USING_POSIX_MMAP is not set
 # CONFIG_RT_USING_POSIX_TERMIOS is not set
+# CONFIG_RT_USING_POSIX_GETLINE is not set
 # CONFIG_RT_USING_POSIX_AIO is not set
 # CONFIG_RT_USING_MODULE is not set
+CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 
 #
 # Network
@@ -234,6 +252,12 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_RT_USING_RYM is not set
 # CONFIG_RT_USING_ULOG is not set
 # CONFIG_RT_USING_UTEST is not set
+# CONFIG_RT_USING_RT_LINK is not set
+
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
 
 #
 # RT-Thread online packages
@@ -242,7 +266,9 @@ CONFIG_RT_USING_POSIX=y
 #
 # IoT - internet of things
 #
+# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
 # CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_UMQTT is not set
 # CONFIG_PKG_USING_WEBCLIENT is not set
 # CONFIG_PKG_USING_WEBNET is not set
 # CONFIG_PKG_USING_MONGOOSE is not set
@@ -280,6 +306,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_AT_DEVICE is not set
 # CONFIG_PKG_USING_ATSRV_SOCKET is not set
 # CONFIG_PKG_USING_WIZNET is not set
+# CONFIG_PKG_USING_ZB_COORDINATOR is not set
 
 #
 # IoT Cloud
@@ -288,7 +315,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_GAGENT_CLOUD is not set
 # CONFIG_PKG_USING_ALI_IOTKIT is not set
 # CONFIG_PKG_USING_AZURE is not set
-# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
+# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
 # CONFIG_PKG_USING_JIOT-C-SDK is not set
 # CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
 # CONFIG_PKG_USING_JOYLINK is not set
@@ -300,8 +327,6 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_LIBRWS is not set
 # CONFIG_PKG_USING_TCPSERVER is not set
 # CONFIG_PKG_USING_PROTOBUF_C is not set
-# CONFIG_PKG_USING_ONNX_PARSER is not set
-# CONFIG_PKG_USING_ONNX_BACKEND is not set
 # CONFIG_PKG_USING_DLT645 is not set
 # CONFIG_PKG_USING_QXWZ is not set
 # CONFIG_PKG_USING_SMTP_CLIENT is not set
@@ -310,6 +335,20 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_CAPNP is not set
 # CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
 # CONFIG_PKG_USING_AGILE_TELNET is not set
+# CONFIG_PKG_USING_NMEALIB is not set
+# CONFIG_PKG_USING_AGILE_JSMN is not set
+# CONFIG_PKG_USING_PDULIB is not set
+# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
+# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
+# CONFIG_PKG_USING_MAVLINK is not set
+# CONFIG_PKG_USING_RAPIDJSON is not set
+# CONFIG_PKG_USING_BSAL is not set
+# CONFIG_PKG_USING_AGILE_MODBUS is not set
+# CONFIG_PKG_USING_AGILE_FTP is not set
+# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
+# CONFIG_PKG_USING_RT_LINK_HW is not set
+# CONFIG_PKG_USING_HM is not set
 
 #
 # security packages
@@ -318,6 +357,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_libsodium is not set
 # CONFIG_PKG_USING_TINYCRYPT is not set
 # CONFIG_PKG_USING_TFM is not set
+# CONFIG_PKG_USING_YD_CRYPTO is not set
 
 #
 # language packages
@@ -325,6 +365,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_LUA is not set
 # CONFIG_PKG_USING_JERRYSCRIPT is not set
 # CONFIG_PKG_USING_MICROPYTHON is not set
+# CONFIG_PKG_USING_PIKASCRIPT is not set
 
 #
 # multimedia packages
@@ -334,6 +375,13 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_STEMWIN is not set
 # CONFIG_PKG_USING_WAVPLAYER is not set
 # CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
+# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
+# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
+# CONFIG_PKG_USING_MP3PLAYER is not set
+# CONFIG_PKG_USING_TINYJPEG is not set
 
 #
 # tools packages
@@ -342,25 +390,65 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_EASYFLASH is not set
 # CONFIG_PKG_USING_EASYLOGGER is not set
 # CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_SEGGER_RTT is not set
 # CONFIG_PKG_USING_RDB is not set
 # CONFIG_PKG_USING_QRCODE is not set
 # CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
+# CONFIG_PKG_USING_LOGMGR is not set
 # CONFIG_PKG_USING_ADBD is not set
 # CONFIG_PKG_USING_COREMARK is not set
 # CONFIG_PKG_USING_DHRYSTONE is not set
+# CONFIG_PKG_USING_MEMORYPERF is not set
 # CONFIG_PKG_USING_NR_MICRO_SHELL is not set
 # CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
 # CONFIG_PKG_USING_LUNAR_CALENDAR is not set
 # CONFIG_PKG_USING_BS8116A is not set
+# CONFIG_PKG_USING_GPS_RMC is not set
 # CONFIG_PKG_USING_URLENCODE is not set
+# CONFIG_PKG_USING_UMCN is not set
+# CONFIG_PKG_USING_LWRB2RTT is not set
+# CONFIG_PKG_USING_CPU_USAGE is not set
+# CONFIG_PKG_USING_GBK2UTF8 is not set
+# CONFIG_PKG_USING_VCONSOLE is not set
+# CONFIG_PKG_USING_KDB is not set
+# CONFIG_PKG_USING_WAMR is not set
+# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
+# CONFIG_PKG_USING_LWLOG is not set
+# CONFIG_PKG_USING_ANV_TRACE is not set
+# CONFIG_PKG_USING_ANV_MEMLEAK is not set
+# CONFIG_PKG_USING_ANV_TESTSUIT is not set
+# CONFIG_PKG_USING_ANV_BENCH is not set
+# CONFIG_PKG_USING_DEVMEM is not set
+# CONFIG_PKG_USING_REGEX is not set
+# CONFIG_PKG_USING_MEM_SANDBOX is not set
+# CONFIG_PKG_USING_SOLAR_TERMS is not set
+# CONFIG_PKG_USING_GAN_ZHI is not set
 
 #
 # system packages
 #
+
+#
+# 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
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
+# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
 # CONFIG_PKG_USING_GUIENGINE is not set
 # CONFIG_PKG_USING_CAIRO is not set
 # CONFIG_PKG_USING_PIXMAN is not set
-# CONFIG_PKG_USING_LWEXT4 is not set
 # CONFIG_PKG_USING_PARTITION is not set
 # CONFIG_PKG_USING_FAL is not set
 # CONFIG_PKG_USING_FLASHDB is not set
@@ -370,12 +458,27 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_CMSIS is not set
 # CONFIG_PKG_USING_DFS_YAFFS is not set
 # CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_DFS_JFFS2 is not set
+# CONFIG_PKG_USING_DFS_UFFS is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
 # CONFIG_PKG_USING_THREAD_POOL is not set
 # CONFIG_PKG_USING_ROBOTS is not set
 # CONFIG_PKG_USING_EV is not set
 # CONFIG_PKG_USING_SYSWATCH is not set
 # CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
 # CONFIG_PKG_USING_PLCCORE is not set
+# CONFIG_PKG_USING_RAMDISK is not set
+# CONFIG_PKG_USING_MININI is not set
+# CONFIG_PKG_USING_QBOOT is not set
+# CONFIG_PKG_USING_PPOOL is not set
+# CONFIG_PKG_USING_OPENAMP is not set
+# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
+# CONFIG_PKG_USING_LPM is not set
+# CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
+# CONFIG_PKG_USING_ARM_2D is not set
+# CONFIG_PKG_USING_WCWIDTH is not set
+# CONFIG_PKG_USING_MCUBOOT is not set
 
 #
 # peripheral libraries and drivers
@@ -384,6 +487,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_REALTEK_AMEBA is not set
 # CONFIG_PKG_USING_SHT2X is not set
 # CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_AS7341 is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
 # CONFIG_PKG_USING_ICM20608 is not set
 # CONFIG_PKG_USING_U8G2 is not set
@@ -399,7 +503,6 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_WM_LIBRARIES is not set
 # CONFIG_PKG_USING_KENDRYTE_SDK is not set
 # CONFIG_PKG_USING_INFRARED is not set
-# CONFIG_PKG_USING_ROSSERIAL is not set
 # CONFIG_PKG_USING_AGILE_BUTTON is not set
 # CONFIG_PKG_USING_AGILE_LED is not set
 # CONFIG_PKG_USING_AT24CXX is not set
@@ -413,6 +516,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_RPLIDAR is not set
 # CONFIG_PKG_USING_AS608 is not set
 # CONFIG_PKG_USING_RC522 is not set
+# CONFIG_PKG_USING_WS2812B is not set
 # CONFIG_PKG_USING_EMBARC_BSP is not set
 # CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
 # CONFIG_PKG_USING_MULTI_RTIMER is not set
@@ -421,44 +525,102 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_EASYBLINK is not set
 # CONFIG_PKG_USING_PMS_SERIES is not set
 # CONFIG_PKG_USING_CAN_YMODEM is not set
+# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
+# CONFIG_PKG_USING_QLED is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+# CONFIG_PKG_USING_AGILE_CONSOLE is not set
+# CONFIG_PKG_USING_LD3320 is not set
+# CONFIG_PKG_USING_WK2124 is not set
+# CONFIG_PKG_USING_LY68L6400 is not set
+# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
+# CONFIG_PKG_USING_RS485 is not set
+# CONFIG_PKG_USING_NES is not set
+# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
+# CONFIG_PKG_USING_VDEVICE is not set
+# CONFIG_PKG_USING_SGM706 is not set
+# CONFIG_PKG_USING_STM32WB55_SDK is not set
+# CONFIG_PKG_USING_RDA58XX is not set
+# CONFIG_PKG_USING_LIBNFC is not set
+# CONFIG_PKG_USING_MFOC is not set
+# CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
+# CONFIG_PKG_USING_KOBUKI is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_MICRO_ROS is not set
+# CONFIG_PKG_USING_MCP23008 is not set
+# CONFIG_PKG_USING_BLUETRUM_SDK is not set
+# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
+
+#
+# AI packages
+#
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_QUEST is not set
+# CONFIG_PKG_USING_NAXOS is not set
 
 #
 # miscellaneous packages
 #
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_CMATRIX is not set
+# CONFIG_PKG_USING_SL is not set
+# CONFIG_PKG_USING_CAL is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
 # CONFIG_PKG_USING_MINILZO is not set
 # CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_LZMA is not set
 # CONFIG_PKG_USING_MULTIBUTTON is not set
 # CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
 # CONFIG_PKG_USING_CANFESTIVAL is not set
 # CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_MINIZIP is not set
 # CONFIG_PKG_USING_DSTR is not set
 # CONFIG_PKG_USING_TINYFRAME is not set
 # CONFIG_PKG_USING_KENDRYTE_DEMO is not set
 # CONFIG_PKG_USING_DIGITALCTRL is not set
 # CONFIG_PKG_USING_UPACKER is not set
 # CONFIG_PKG_USING_UPARAM is not set
-
-#
-# samples: kernel and components samples
-#
-# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
-# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
-# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
-# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
 # CONFIG_PKG_USING_VI is not set
-# CONFIG_PKG_USING_NNOM is not set
-# CONFIG_PKG_USING_LIBANN is not set
-# CONFIG_PKG_USING_ELAPACK 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_ULAPACK 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_BCM2836_SOC=y
-# CONFIG_BSP_SUPPORT_FPU is not set
+CONFIG_BSP_SUPPORT_FPU=y
 
 #
 # Hardware Drivers Config

+ 1 - 0
bsp/raspberry-pi/raspi3-64/driver/mbox.h

@@ -13,6 +13,7 @@
 #define __MBOX_H__
 
 #include <rtthread.h>
+#include <stdint.h>
 /* a properly aligned buffer */
 extern volatile unsigned int* mbox;
 

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

@@ -118,6 +118,7 @@ typedef enum
 #define BSC2_BASE_OFFSET (0x805000)
 
 /* IRQ */
+#define MAX_HANDLERS       72
 #define IRQ_SYSTEM_TIMER_0 0
 #define IRQ_SYSTEM_TIMER_1  1
 #define IRQ_SYSTEM_TIMER_2 2

+ 6 - 4
bsp/raspberry-pi/raspi3-64/qemu-64.bat

@@ -1,4 +1,6 @@
-if [ ! -f "sd.bin" ]; then
-dd if=/dev/zero of=sd.bin bs=1024 count=65536
-fi
-qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio -sd sd.bin -nographic -monitor pty
+@echo off
+if exist sd.bin goto run
+qemu-img create -f raw sd.bin 64M
+
+:run
+qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio -sd sd.bin

+ 4 - 0
bsp/raspberry-pi/raspi3-64/qemu-64.sh

@@ -0,0 +1,4 @@
+if [ ! -f "sd.bin" ]; then
+dd if=/dev/zero of=sd.bin bs=1024 count=65536
+fi
+qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio -sd sd.bin -nographic -monitor pty

+ 29 - 8
bsp/raspberry-pi/raspi3-64/rtconfig.h

@@ -19,6 +19,9 @@
 #define RT_USING_TIMER_SOFT
 #define RT_TIMER_THREAD_PRIO 4
 #define RT_TIMER_THREAD_STACK_SIZE 2048
+
+/* kservice optimization */
+
 #define RT_DEBUG
 #define RT_DEBUG_COLOR
 
@@ -45,7 +48,7 @@
 #define RT_USING_CONSOLE
 #define RT_CONSOLEBUF_SIZE 512
 #define RT_CONSOLE_DEVICE_NAME "uart1"
-#define RT_VER_NUM 0x40003
+#define RT_VER_NUM 0x40004
 #define ARCH_CPU_64BIT
 #define ARCH_ARMV8
 
@@ -62,17 +65,17 @@
 /* Command shell */
 
 #define RT_USING_FINSH
+#define RT_USING_MSH
+#define FINSH_USING_MSH
 #define FINSH_THREAD_NAME "tshell"
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_USING_HISTORY
 #define FINSH_HISTORY_LINES 5
 #define FINSH_USING_SYMTAB
-#define FINSH_USING_DESCRIPTION
-#define FINSH_THREAD_PRIORITY 20
-#define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_CMD_SIZE 80
-#define FINSH_USING_MSH
-#define FINSH_USING_MSH_DEFAULT
-#define FINSH_USING_MSH_ONLY
+#define MSH_USING_BUILT_IN_COMMANDS
+#define FINSH_USING_DESCRIPTION
 #define FINSH_ARG_MAX 10
 
 /* Device virtual file system */
@@ -90,6 +93,8 @@
 #define RT_DFS_ELM_WORD_ACCESS
 #define RT_DFS_ELM_USE_LFN_3
 #define RT_DFS_ELM_USE_LFN 3
+#define RT_DFS_ELM_LFN_UNICODE_0
+#define RT_DFS_ELM_LFN_UNICODE 0
 #define RT_DFS_ELM_MAX_LFN 255
 #define RT_DFS_ELM_DRIVES 2
 #define RT_DFS_ELM_MAX_SECTOR_SIZE 512
@@ -101,6 +106,7 @@
 #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
 #define RT_USING_HWTIMER
 #define RT_USING_I2C
@@ -124,6 +130,7 @@
 
 #define RT_USING_LIBC
 #define RT_USING_POSIX
+#define RT_LIBC_DEFAULT_TIMEZONE 8
 
 /* Network */
 
@@ -145,6 +152,9 @@
 /* Utilities */
 
 
+/* RT-Thread Utestcases */
+
+
 /* RT-Thread online packages */
 
 /* IoT - internet of things */
@@ -175,16 +185,27 @@
 
 /* system packages */
 
+/* acceleration: Assembly language or algorithmic acceleration packages */
+
+
+/* Micrium: Micrium software products porting for RT-Thread */
+
 
 /* peripheral libraries and drivers */
 
 
-/* miscellaneous packages */
+/* AI packages */
+
 
+/* miscellaneous packages */
 
 /* samples: kernel and components samples */
 
+
+/* entertainment: terminal games and other interesting software packages */
+
 #define BCM2836_SOC
+#define BSP_SUPPORT_FPU
 
 /* Hardware Drivers Config */
 

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

@@ -2,7 +2,7 @@ import os
 
 # toolchains options
 ARCH        ='aarch64'
-CPU         ='cortex-a53'
+CPU         ='cortex-a'
 CROSS_TOOL  ='gcc'
 
 if os.getenv('RTT_ROOT'):

+ 307 - 38
bsp/raspberry-pi/raspi4-64/.config

@@ -23,6 +23,13 @@ CONFIG_IDLE_THREAD_STACK_SIZE=2048
 CONFIG_RT_USING_TIMER_SOFT=y
 CONFIG_RT_TIMER_THREAD_PRIO=4
 CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
+
+#
+# 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_DEBUG=y
 # CONFIG_RT_DEBUG_COLOR is not set
 # CONFIG_RT_DEBUG_INIT_CONFIG is not set
@@ -54,6 +61,7 @@ CONFIG_RT_USING_MEMPOOL=y
 # CONFIG_RT_USING_NOHEAP is not set
 CONFIG_RT_USING_SMALL_MEM=y
 # CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_USERHEAP is not set
 # CONFIG_RT_USING_MEMTRACE is not set
 CONFIG_RT_USING_HEAP=y
 
@@ -65,8 +73,9 @@ CONFIG_RT_USING_DEVICE=y
 # CONFIG_RT_USING_INTERRUPT_INFO is not set
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=128
-CONFIG_RT_CONSOLE_DEVICE_NAME="uart"
-CONFIG_RT_VER_NUM=0x40003
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+# CONFIG_RT_PRINTF_LONGLONG is not set
+CONFIG_RT_VER_NUM=0x40004
 CONFIG_ARCH_CPU_64BIT=y
 # CONFIG_RT_USING_CPU_FFS is not set
 CONFIG_ARCH_ARMV8=y
@@ -89,19 +98,19 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10
 # Command shell
 #
 CONFIG_RT_USING_FINSH=y
+CONFIG_RT_USING_MSH=y
+CONFIG_FINSH_USING_MSH=y
 CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
 CONFIG_FINSH_USING_HISTORY=y
 CONFIG_FINSH_HISTORY_LINES=5
 CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
 CONFIG_FINSH_USING_DESCRIPTION=y
 # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
-CONFIG_FINSH_THREAD_PRIORITY=20
-CONFIG_FINSH_THREAD_STACK_SIZE=4096
-CONFIG_FINSH_CMD_SIZE=80
 # CONFIG_FINSH_USING_AUTH is not set
-CONFIG_FINSH_USING_MSH=y
-CONFIG_FINSH_USING_MSH_DEFAULT=y
-# CONFIG_FINSH_USING_MSH_ONLY is not set
 CONFIG_FINSH_ARG_MAX=10
 
 #
@@ -113,34 +122,68 @@ CONFIG_DFS_FILESYSTEMS_MAX=2
 CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
 CONFIG_DFS_FD_MAX=16
 # CONFIG_RT_USING_DFS_MNTTABLE is not set
-# CONFIG_RT_USING_DFS_ELMFAT is not set
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+CONFIG_RT_DFS_ELM_USE_LFN_3=y
+CONFIG_RT_DFS_ELM_USE_LFN=3
+CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
+CONFIG_RT_DFS_ELM_LFN_UNICODE=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+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_USING_DFS_DEVFS=y
 # CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
-# CONFIG_RT_USING_DFS_UFFS is not set
-# CONFIG_RT_USING_DFS_JFFS2 is not set
+# CONFIG_RT_USING_DFS_NFS is not set
 
 #
 # Device Drivers
 #
 CONFIG_RT_USING_DEVICE_IPC=y
 CONFIG_RT_PIPE_BUFSZ=512
-# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
+CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
+CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
+CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
 CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
 CONFIG_RT_SERIAL_USING_DMA=y
 CONFIG_RT_SERIAL_RB_BUFSZ=64
 # CONFIG_RT_USING_CAN is not set
 # CONFIG_RT_USING_HWTIMER is not set
 # CONFIG_RT_USING_CPUTIME is not set
 # CONFIG_RT_USING_I2C is not set
+# CONFIG_RT_USING_PHY is not set
 CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_DAC is not set
 # CONFIG_RT_USING_PWM is not set
 # CONFIG_RT_USING_MTD_NOR is not set
 # CONFIG_RT_USING_MTD_NAND is not set
 # CONFIG_RT_USING_PM is not set
-# CONFIG_RT_USING_RTC is not set
-# CONFIG_RT_USING_SDIO is not set
+CONFIG_RT_USING_RTC=y
+CONFIG_RT_USING_ALARM=y
+# CONFIG_RT_USING_SOFT_RTC is not set
+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_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_AUDIO is not set
@@ -165,8 +208,10 @@ CONFIG_RT_USING_LIBC=y
 CONFIG_RT_USING_POSIX=y
 # CONFIG_RT_USING_POSIX_MMAP is not set
 # CONFIG_RT_USING_POSIX_TERMIOS is not set
+# CONFIG_RT_USING_POSIX_GETLINE is not set
 # CONFIG_RT_USING_POSIX_AIO is not set
 # CONFIG_RT_USING_MODULE is not set
+CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 
 #
 # Network
@@ -175,22 +220,93 @@ CONFIG_RT_USING_POSIX=y
 #
 # Socket abstraction layer
 #
-# CONFIG_RT_USING_SAL is not set
+CONFIG_RT_USING_SAL=y
+CONFIG_SAL_INTERNET_CHECK=y
+
+#
+# protocol stack implement
+#
+CONFIG_SAL_USING_LWIP=y
+# CONFIG_SAL_USING_POSIX is not set
+CONFIG_SAL_SOCKETS_NUM=16
 
 #
 # Network interface device
 #
-# CONFIG_RT_USING_NETDEV is not set
+CONFIG_RT_USING_NETDEV=y
+CONFIG_NETDEV_USING_IFCONFIG=y
+CONFIG_NETDEV_USING_PING=y
+CONFIG_NETDEV_USING_NETSTAT=y
+CONFIG_NETDEV_USING_AUTO_DEFAULT=y
+# CONFIG_NETDEV_USING_IPV6 is not set
+CONFIG_NETDEV_IPV4=1
+CONFIG_NETDEV_IPV6=0
+# CONFIG_NETDEV_IPV6_SCOPES is not set
 
 #
 # light weight TCP/IP stack
 #
-# CONFIG_RT_USING_LWIP is not set
+CONFIG_RT_USING_LWIP=y
+# CONFIG_RT_USING_LWIP141 is not set
+# CONFIG_RT_USING_LWIP202 is not set
+CONFIG_RT_USING_LWIP203=y
+# CONFIG_RT_USING_LWIP212 is not set
+# CONFIG_RT_USING_LWIP_IPV6 is not set
+CONFIG_RT_LWIP_MEM_ALIGNMENT=4
+CONFIG_RT_LWIP_IGMP=y
+CONFIG_RT_LWIP_ICMP=y
+# CONFIG_RT_LWIP_SNMP is not set
+CONFIG_RT_LWIP_DNS=y
+CONFIG_RT_LWIP_DHCP=y
+CONFIG_IP_SOF_BROADCAST=1
+CONFIG_IP_SOF_BROADCAST_RECV=1
+
+#
+# Static IPv4 Address
+#
+CONFIG_RT_LWIP_IPADDR="192.168.1.30"
+CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
+CONFIG_RT_LWIP_UDP=y
+CONFIG_RT_LWIP_TCP=y
+CONFIG_RT_LWIP_RAW=y
+# CONFIG_RT_LWIP_PPP is not set
+CONFIG_RT_MEMP_NUM_NETCONN=8
+CONFIG_RT_LWIP_PBUF_NUM=16
+CONFIG_RT_LWIP_RAW_PCB_NUM=4
+CONFIG_RT_LWIP_UDP_PCB_NUM=4
+CONFIG_RT_LWIP_TCP_PCB_NUM=4
+CONFIG_RT_LWIP_TCP_SEG_NUM=40
+CONFIG_RT_LWIP_TCP_SND_BUF=8196
+CONFIG_RT_LWIP_TCP_WND=8196
+CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8
+CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=2048
+# 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_MBOX_SIZE=8
+# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
+CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
+CONFIG_LWIP_NETIF_LINK_CALLBACK=1
+CONFIG_SO_REUSE=1
+CONFIG_LWIP_SO_RCVTIMEO=1
+CONFIG_LWIP_SO_SNDTIMEO=1
+CONFIG_LWIP_SO_RCVBUF=1
+CONFIG_LWIP_SO_LINGER=0
+# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
+CONFIG_LWIP_NETIF_LOOPBACK=0
+# CONFIG_RT_LWIP_STATS is not set
+# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
+CONFIG_RT_LWIP_USING_PING=y
+# CONFIG_RT_LWIP_DEBUG is not set
 
 #
 # AT commands
 #
 # CONFIG_RT_USING_AT is not set
+# CONFIG_LWIP_USING_DHCPD is not set
 
 #
 # VBUS(Virtual Software BUS)
@@ -200,9 +316,17 @@ CONFIG_RT_USING_POSIX=y
 #
 # Utilities
 #
-# CONFIG_RT_USING_RYM is not set
+CONFIG_RT_USING_RYM=y
+# CONFIG_YMODEM_USING_CRC_TABLE is not set
+CONFIG_YMODEM_USING_FILE_TRANSFER=y
 # CONFIG_RT_USING_ULOG is not set
 # CONFIG_RT_USING_UTEST is not set
+# CONFIG_RT_USING_RT_LINK is not set
+
+#
+# RT-Thread Utestcases
+#
+# CONFIG_RT_USING_UTESTCASES is not set
 
 #
 # RT-Thread online packages
@@ -211,7 +335,9 @@ CONFIG_RT_USING_POSIX=y
 #
 # IoT - internet of things
 #
+# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
 # CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_UMQTT is not set
 # CONFIG_PKG_USING_WEBCLIENT is not set
 # CONFIG_PKG_USING_WEBNET is not set
 # CONFIG_PKG_USING_MONGOOSE is not set
@@ -249,6 +375,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_AT_DEVICE is not set
 # CONFIG_PKG_USING_ATSRV_SOCKET is not set
 # CONFIG_PKG_USING_WIZNET is not set
+# CONFIG_PKG_USING_ZB_COORDINATOR is not set
 
 #
 # IoT Cloud
@@ -257,7 +384,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_GAGENT_CLOUD is not set
 # CONFIG_PKG_USING_ALI_IOTKIT is not set
 # CONFIG_PKG_USING_AZURE is not set
-# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
+# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
 # CONFIG_PKG_USING_JIOT-C-SDK is not set
 # CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
 # CONFIG_PKG_USING_JOYLINK is not set
@@ -269,8 +396,6 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_LIBRWS is not set
 # CONFIG_PKG_USING_TCPSERVER is not set
 # CONFIG_PKG_USING_PROTOBUF_C is not set
-# CONFIG_PKG_USING_ONNX_PARSER is not set
-# CONFIG_PKG_USING_ONNX_BACKEND is not set
 # CONFIG_PKG_USING_DLT645 is not set
 # CONFIG_PKG_USING_QXWZ is not set
 # CONFIG_PKG_USING_SMTP_CLIENT is not set
@@ -279,6 +404,20 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_CAPNP is not set
 # CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
 # CONFIG_PKG_USING_AGILE_TELNET is not set
+# CONFIG_PKG_USING_NMEALIB is not set
+# CONFIG_PKG_USING_AGILE_JSMN is not set
+# CONFIG_PKG_USING_PDULIB is not set
+# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
+# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
+# CONFIG_PKG_USING_MAVLINK is not set
+# CONFIG_PKG_USING_RAPIDJSON is not set
+# CONFIG_PKG_USING_BSAL is not set
+# CONFIG_PKG_USING_AGILE_MODBUS is not set
+# CONFIG_PKG_USING_AGILE_FTP is not set
+# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
+# CONFIG_PKG_USING_RT_LINK_HW is not set
+# CONFIG_PKG_USING_HM is not set
 
 #
 # security packages
@@ -287,6 +426,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_libsodium is not set
 # CONFIG_PKG_USING_TINYCRYPT is not set
 # CONFIG_PKG_USING_TFM is not set
+# CONFIG_PKG_USING_YD_CRYPTO is not set
 
 #
 # language packages
@@ -294,6 +434,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_LUA is not set
 # CONFIG_PKG_USING_JERRYSCRIPT is not set
 # CONFIG_PKG_USING_MICROPYTHON is not set
+# CONFIG_PKG_USING_PIKASCRIPT is not set
 
 #
 # multimedia packages
@@ -303,6 +444,13 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_STEMWIN is not set
 # CONFIG_PKG_USING_WAVPLAYER is not set
 # CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
+# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
+# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
+# CONFIG_PKG_USING_MP3PLAYER is not set
+# CONFIG_PKG_USING_TINYJPEG is not set
 
 #
 # tools packages
@@ -311,25 +459,65 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_EASYFLASH is not set
 # CONFIG_PKG_USING_EASYLOGGER is not set
 # CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_SEGGER_RTT is not set
 # CONFIG_PKG_USING_RDB is not set
 # CONFIG_PKG_USING_QRCODE is not set
 # CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
+# CONFIG_PKG_USING_LOGMGR is not set
 # CONFIG_PKG_USING_ADBD is not set
 # CONFIG_PKG_USING_COREMARK is not set
 # CONFIG_PKG_USING_DHRYSTONE is not set
+# CONFIG_PKG_USING_MEMORYPERF is not set
 # CONFIG_PKG_USING_NR_MICRO_SHELL is not set
 # CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
 # CONFIG_PKG_USING_LUNAR_CALENDAR is not set
 # CONFIG_PKG_USING_BS8116A is not set
+# CONFIG_PKG_USING_GPS_RMC is not set
 # CONFIG_PKG_USING_URLENCODE is not set
+# CONFIG_PKG_USING_UMCN is not set
+# CONFIG_PKG_USING_LWRB2RTT is not set
+# CONFIG_PKG_USING_CPU_USAGE is not set
+# CONFIG_PKG_USING_GBK2UTF8 is not set
+# CONFIG_PKG_USING_VCONSOLE is not set
+# CONFIG_PKG_USING_KDB is not set
+# CONFIG_PKG_USING_WAMR is not set
+# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
+# CONFIG_PKG_USING_LWLOG is not set
+# CONFIG_PKG_USING_ANV_TRACE is not set
+# CONFIG_PKG_USING_ANV_MEMLEAK is not set
+# CONFIG_PKG_USING_ANV_TESTSUIT is not set
+# CONFIG_PKG_USING_ANV_BENCH is not set
+# CONFIG_PKG_USING_DEVMEM is not set
+# CONFIG_PKG_USING_REGEX is not set
+# CONFIG_PKG_USING_MEM_SANDBOX is not set
+# CONFIG_PKG_USING_SOLAR_TERMS is not set
+# CONFIG_PKG_USING_GAN_ZHI is not set
 
 #
 # system packages
 #
+
+#
+# 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
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
+# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
 # CONFIG_PKG_USING_GUIENGINE is not set
 # CONFIG_PKG_USING_CAIRO is not set
 # CONFIG_PKG_USING_PIXMAN is not set
-# CONFIG_PKG_USING_LWEXT4 is not set
 # CONFIG_PKG_USING_PARTITION is not set
 # CONFIG_PKG_USING_FAL is not set
 # CONFIG_PKG_USING_FLASHDB is not set
@@ -339,12 +527,27 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_CMSIS is not set
 # CONFIG_PKG_USING_DFS_YAFFS is not set
 # CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_DFS_JFFS2 is not set
+# CONFIG_PKG_USING_DFS_UFFS is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
 # CONFIG_PKG_USING_THREAD_POOL is not set
 # CONFIG_PKG_USING_ROBOTS is not set
 # CONFIG_PKG_USING_EV is not set
 # CONFIG_PKG_USING_SYSWATCH is not set
 # CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
 # CONFIG_PKG_USING_PLCCORE is not set
+# CONFIG_PKG_USING_RAMDISK is not set
+# CONFIG_PKG_USING_MININI is not set
+# CONFIG_PKG_USING_QBOOT is not set
+# CONFIG_PKG_USING_PPOOL is not set
+# CONFIG_PKG_USING_OPENAMP is not set
+# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
+# CONFIG_PKG_USING_LPM is not set
+# CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
+# CONFIG_PKG_USING_ARM_2D is not set
+# CONFIG_PKG_USING_WCWIDTH is not set
+# CONFIG_PKG_USING_MCUBOOT is not set
 
 #
 # peripheral libraries and drivers
@@ -353,6 +556,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_REALTEK_AMEBA is not set
 # CONFIG_PKG_USING_SHT2X is not set
 # CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_AS7341 is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
 # CONFIG_PKG_USING_ICM20608 is not set
 # CONFIG_PKG_USING_U8G2 is not set
@@ -368,7 +572,6 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_WM_LIBRARIES is not set
 # CONFIG_PKG_USING_KENDRYTE_SDK is not set
 # CONFIG_PKG_USING_INFRARED is not set
-# CONFIG_PKG_USING_ROSSERIAL is not set
 # CONFIG_PKG_USING_AGILE_BUTTON is not set
 # CONFIG_PKG_USING_AGILE_LED is not set
 # CONFIG_PKG_USING_AT24CXX is not set
@@ -382,6 +585,7 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_RPLIDAR is not set
 # CONFIG_PKG_USING_AS608 is not set
 # CONFIG_PKG_USING_RC522 is not set
+# CONFIG_PKG_USING_WS2812B is not set
 # CONFIG_PKG_USING_EMBARC_BSP is not set
 # CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
 # CONFIG_PKG_USING_MULTI_RTIMER is not set
@@ -390,44 +594,102 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_EASYBLINK is not set
 # CONFIG_PKG_USING_PMS_SERIES is not set
 # CONFIG_PKG_USING_CAN_YMODEM is not set
+# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
+# CONFIG_PKG_USING_QLED is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+# CONFIG_PKG_USING_AGILE_CONSOLE is not set
+# CONFIG_PKG_USING_LD3320 is not set
+# CONFIG_PKG_USING_WK2124 is not set
+# CONFIG_PKG_USING_LY68L6400 is not set
+# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
+# CONFIG_PKG_USING_RS485 is not set
+# CONFIG_PKG_USING_NES is not set
+# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
+# CONFIG_PKG_USING_VDEVICE is not set
+# CONFIG_PKG_USING_SGM706 is not set
+# CONFIG_PKG_USING_STM32WB55_SDK is not set
+# CONFIG_PKG_USING_RDA58XX is not set
+# CONFIG_PKG_USING_LIBNFC is not set
+# CONFIG_PKG_USING_MFOC is not set
+# CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
+# CONFIG_PKG_USING_KOBUKI is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_MICRO_ROS is not set
+# CONFIG_PKG_USING_MCP23008 is not set
+# CONFIG_PKG_USING_BLUETRUM_SDK is not set
+# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
+
+#
+# AI packages
+#
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_QUEST is not set
+# CONFIG_PKG_USING_NAXOS is not set
 
 #
 # miscellaneous packages
 #
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_CMATRIX is not set
+# CONFIG_PKG_USING_SL is not set
+# CONFIG_PKG_USING_CAL is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
 # CONFIG_PKG_USING_MINILZO is not set
 # CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_LZMA is not set
 # CONFIG_PKG_USING_MULTIBUTTON is not set
 # CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
 # CONFIG_PKG_USING_CANFESTIVAL is not set
 # CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_MINIZIP is not set
 # CONFIG_PKG_USING_DSTR is not set
 # CONFIG_PKG_USING_TINYFRAME is not set
 # CONFIG_PKG_USING_KENDRYTE_DEMO is not set
 # CONFIG_PKG_USING_DIGITALCTRL is not set
 # CONFIG_PKG_USING_UPACKER is not set
 # CONFIG_PKG_USING_UPARAM is not set
-
-#
-# samples: kernel and components samples
-#
-# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
-# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
-# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
-# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
 # CONFIG_PKG_USING_VI is not set
-# CONFIG_PKG_USING_NNOM is not set
-# CONFIG_PKG_USING_LIBANN is not set
-# CONFIG_PKG_USING_ELAPACK 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_ULAPACK 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_BCM2711_SOC=y
-# CONFIG_BSP_SUPPORT_FPU is not set
+CONFIG_BSP_SUPPORT_FPU=y
 
 #
 # Hardware Drivers Config
@@ -438,15 +700,22 @@ CONFIG_BCM2711_SOC=y
 #
 CONFIG_BSP_USING_UART=y
 CONFIG_RT_USING_UART0=y
+# CONFIG_RT_USING_UART1 is not set
+# CONFIG_RT_USING_UART3 is not set
+# 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_RTC is not set
-# CONFIG_BSP_USING_SDIO is not set
+CONFIG_BSP_USING_RTC=y
+CONFIG_BSP_USING_ALARM=y
+CONFIG_BSP_USING_SDIO=y
+CONFIG_BSP_USING_SDIO0=y
 
 #
 # Board Peripheral Drivers

+ 5 - 1
bsp/raspberry-pi/raspi4-64/README.md

@@ -101,7 +101,11 @@ msh />
 
 | 驱动 | 支持情况  |  备注  |
 | ------ | ----  | :------:  |
-| UART | 支持 | UART0|
+| UART | 支持 | UART0,UART2,UART3,UART4,UART5 |
+| GPIO | 支持 | - |
+| MAILBOX | 支持 | - |
+| SDIO | 支持 | - |
+| ETH | 支持 | - |
 
 ## 5. 联系人信息
 

+ 27 - 0
bsp/raspberry-pi/raspi4-64/applications/mnt.c

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30     bernard       the first version
+ */
+
+#include <rtthread.h>
+
+#ifdef BSP_USING_SDIO0
+#include <dfs_fs.h>
+
+int mnt_init(void)
+{
+    rt_thread_delay(RT_TICK_PER_SECOND);
+    if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
+    {
+        rt_kprintf("file system initialization done!\n");
+    }
+
+    return 0;
+}
+INIT_ENV_EXPORT(mnt_init);
+#endif

+ 21 - 1
bsp/raspberry-pi/raspi4-64/driver/Kconfig

@@ -14,8 +14,24 @@ menu "Hardware Drivers Config"
                 config RT_USING_UART0
                 bool "Enabel UART 0"
                 default y
+
+                config RT_USING_UART1
+                bool "Enabel UART 1"
+                default n
+
+                config RT_USING_UART3
+                bool "Enabel UART 3"
+                default n
+
+                config RT_USING_UART4
+                bool "Enabel UART 4"
+                default n
+
+                config RT_USING_UART5
+                bool "Enabel UART 5"
+                default n
             endif
-            
+
         menuconfig BSP_USING_GIC
             bool "Enable GIC"
             select RT_USING_GIC
@@ -53,6 +69,10 @@ menu "Hardware Drivers Config"
                 default n
         endif
 
+        config BSP_USING_ETH
+            bool "Enable ETH"
+            default n
+
         config BSP_USING_WDT
             bool "Enable WDT"
             select RT_USING_WDT

+ 36 - 0
bsp/raspberry-pi/raspi4-64/driver/board.c

@@ -16,7 +16,9 @@
 
 #include "cp15.h"
 #include "mmu.h"
+#include "mbox.h"
 
+#ifdef BSP_USING_CORETIMER
 static rt_uint64_t timerStep;
 
 int rt_hw_get_gtimer_frq(void);
@@ -29,15 +31,21 @@ void core0_timer_enable_interrupt_controller(void)
 {
     CORE0_TIMER_IRQ_CTRL |= NON_SECURE_TIMER_IRQ;
 }
+#endif
 
 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();
 }
 
 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();
@@ -48,6 +56,27 @@ void rt_hw_timer_init(void)
     rt_hw_gtimer_enable();
     rt_hw_set_gtimer_val(timerStep);
     core0_timer_enable_interrupt_controller();
+#else
+    rt_uint32_t apb_clock = 0;
+    rt_uint32_t timer_clock = 1000000;
+
+    apb_clock = bcm271x_mbox_clock_get_rate(CORE_CLK_ID);
+    ARM_TIMER_PREDIV = (apb_clock/timer_clock - 1);
+
+    ARM_TIMER_RELOAD = 0;
+    ARM_TIMER_LOAD   = 0;
+    ARM_TIMER_IRQCLR = 0;
+    ARM_TIMER_CTRL   = 0;
+
+    ARM_TIMER_RELOAD = 1000000 / RT_TICK_PER_SECOND;
+    ARM_TIMER_LOAD   = 1000000 / RT_TICK_PER_SECOND;
+
+    /* 23-bit counter, enable interrupt, enable timer */
+    ARM_TIMER_CTRL   = (1 << 1) | (1 << 5) | (1 << 7);
+
+    rt_hw_interrupt_install(ARM_TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
+    rt_hw_interrupt_umask(ARM_TIMER_IRQ);
+#endif
 }
 
 void idle_wfi(void)
@@ -65,6 +94,13 @@ void rt_hw_board_init(void)
     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();
 
     /* initialize hardware interrupt */

+ 723 - 0
bsp/raspberry-pi/raspi4-64/driver/drv_eth.c

@@ -0,0 +1,723 @@
+
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-10-30     bigmagic       first version
+ */
+
+#include <rtdef.h>
+#include <rthw.h>
+#include <stdint.h>
+#include <rtthread.h>
+#include <lwip/sys.h>
+#include <netif/ethernetif.h>
+#include <mmu.h>
+
+#include "mbox.h"
+#include "raspi4.h"
+#include "drv_eth.h"
+
+#define DBG_LEVEL               DBG_LOG
+#include <rtdbg.h>
+#define LOG_TAG                 "drv.eth"
+
+#define RECV_CACHE_BUF          (2048)
+#define SEND_CACHE_BUF          (2048)
+#define DMA_DISC_ADDR_SIZE      (2 * 1024 *1024)
+
+#define RX_DESC_BASE            (MAC_REG_BASE_ADDR + GENET_RX_OFF)
+#define TX_DESC_BASE            (MAC_REG_BASE_ADDR + GENET_TX_OFF)
+
+#define MAX_ADDR_LEN            (6)
+
+#define upper_32_bits(n)        ((rt_uint32_t)(((n) >> 16) >> 16))
+#define lower_32_bits(n)        ((rt_uint32_t)(n))
+
+#define BIT(nr)                 (1UL << (nr))
+
+#define LINK_THREAD_STACK_SIZE  (1024)
+#define LINK_THREAD_PRIORITY    (20)
+#define LINK_THREAD_TIMESLICE   (10)
+
+static int link_speed = 0;
+static int link_flag = 0;
+
+static rt_thread_t link_thread_tid = RT_NULL;
+
+static rt_uint32_t tx_index = 0;
+static rt_uint32_t rx_index = 0;
+static rt_uint32_t index_flag = 0;
+
+
+struct rt_eth_dev
+{
+    struct eth_device parent;
+    rt_uint8_t dev_addr[MAX_ADDR_LEN];
+    char *name;
+    void *iobase;
+    int state;
+    int index;
+    struct rt_timer link_timer;
+    void *priv;
+};
+static struct rt_eth_dev eth_dev;
+
+static struct rt_semaphore send_finsh_sem_lock;
+
+static struct rt_semaphore link_ack;
+
+rt_inline rt_uint32_t read32(void *addr)
+{
+    return (*((volatile unsigned int *)(addr)));
+}
+
+rt_inline void write32(void *addr, rt_uint32_t value)
+{
+    (*((volatile unsigned int *)(addr))) = value;
+}
+
+static void eth_rx_irq(int irq, void *param)
+{
+    rt_uint32_t val = 0;
+
+    val = read32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_STAT);
+    val &= ~read32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_STAT_MASK);
+
+    write32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_CLEAR, val);
+
+    if (val & GENET_IRQ_RXDMA_DONE)
+    {
+        eth_device_ready(&eth_dev.parent);
+    }
+
+    if (val & GENET_IRQ_TXDMA_DONE)
+    {
+        rt_sem_release(&send_finsh_sem_lock);
+    }
+}
+
+/* we only support RGMII (as used on the RPi4) */
+static int bcmgenet_interface_set(void)
+{
+    int phy_mode = PHY_INTERFACE_MODE_RGMII;
+
+    switch (phy_mode)
+    {
+    case PHY_INTERFACE_MODE_RGMII:
+    case PHY_INTERFACE_MODE_RGMII_RXID:
+        write32(MAC_REG_BASE_ADDR + SYS_PORT_CTRL, PORT_MODE_EXT_GPHY);
+        break;
+    default:
+        rt_kprintf("unknown phy mode: %d\n", MAC_REG_BASE_ADDR);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void bcmgenet_umac_reset(void)
+{
+    rt_uint32_t reg;
+
+    reg = read32(MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL);
+    reg |= BIT(1);
+    write32((MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL), reg);
+
+    reg &= ~BIT(1);
+    write32((MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL), reg);
+
+    DELAY_MICROS(10);
+
+    write32((MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL), 0);
+    DELAY_MICROS(10);
+
+    write32(MAC_REG_BASE_ADDR + UMAC_CMD, 0);
+    write32(MAC_REG_BASE_ADDR + UMAC_CMD, (CMD_SW_RESET | CMD_LCL_LOOP_EN));
+    DELAY_MICROS(2);
+
+    write32(MAC_REG_BASE_ADDR + UMAC_CMD, 0);
+    /* clear tx/rx counter */
+    write32(MAC_REG_BASE_ADDR + UMAC_MIB_CTRL, MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT);
+    write32(MAC_REG_BASE_ADDR + UMAC_MIB_CTRL, 0);
+    write32(MAC_REG_BASE_ADDR + UMAC_MAX_FRAME_LEN, ENET_MAX_MTU_SIZE);
+
+    /* init rx registers, enable ip header optimization */
+    reg = read32(MAC_REG_BASE_ADDR + RBUF_CTRL);
+    reg |= RBUF_ALIGN_2B;
+    write32(MAC_REG_BASE_ADDR + RBUF_CTRL, reg);
+    write32(MAC_REG_BASE_ADDR + RBUF_TBUF_SIZE_CTRL, 1);
+}
+
+static void bcmgenet_disable_dma(void)
+{
+    rt_uint32_t tdma_reg = 0, rdma_reg = 0;
+
+    tdma_reg = read32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_CTRL);
+    tdma_reg &= ~(1UL << DMA_EN);
+    write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_CTRL, tdma_reg);
+    rdma_reg = read32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL);
+    rdma_reg &= ~(1UL << DMA_EN);
+    write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL, rdma_reg);
+    write32(MAC_REG_BASE_ADDR + UMAC_TX_FLUSH, 1);
+    DELAY_MICROS(100);
+    write32(MAC_REG_BASE_ADDR + UMAC_TX_FLUSH, 0);
+}
+
+static void bcmgenet_enable_dma(void)
+{
+    rt_uint32_t reg = 0;
+    rt_uint32_t dma_ctrl = 0;
+
+    dma_ctrl = (1 << (DEFAULT_Q + DMA_RING_BUF_EN_SHIFT)) | DMA_EN;
+    write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_CTRL, dma_ctrl);
+
+    reg = read32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL);
+    write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL, dma_ctrl | reg);
+}
+
+static int bcmgenet_mdio_write(rt_uint32_t addr, rt_uint32_t reg, rt_uint32_t value)
+{
+    int count = 10000;
+    rt_uint32_t val;
+    rt_uint32_t reg_val;
+
+    val = MDIO_WR | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT) | (0xffff & value);
+    write32(MAC_REG_BASE_ADDR + MDIO_CMD, val);
+
+    reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
+    reg_val = reg_val | MDIO_START_BUSY;
+    write32(MAC_REG_BASE_ADDR + MDIO_CMD, reg_val);
+
+    while ((read32(MAC_REG_BASE_ADDR + MDIO_CMD) & MDIO_START_BUSY) && (--count))
+    {
+        DELAY_MICROS(1);
+    }
+
+    reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
+
+    return reg_val & 0xffff;
+}
+
+static int bcmgenet_mdio_read(rt_uint32_t addr, rt_uint32_t reg)
+{
+    int count = 10000;
+    rt_uint32_t val = 0;
+    rt_uint32_t reg_val = 0;
+
+    val = MDIO_RD | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT);
+    write32(MAC_REG_BASE_ADDR + MDIO_CMD, val);
+
+    reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
+    reg_val = reg_val | MDIO_START_BUSY;
+    write32(MAC_REG_BASE_ADDR + MDIO_CMD, reg_val);
+
+    while ((read32(MAC_REG_BASE_ADDR + MDIO_CMD) & MDIO_START_BUSY) && (--count))
+    {
+        DELAY_MICROS(1);
+    }
+
+    reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
+
+    return reg_val & 0xffff;
+}
+
+static int bcmgenet_gmac_write_hwaddr(void)
+{
+    rt_uint8_t addr[6];
+    rt_uint32_t reg;
+
+    bcm271x_mbox_hardware_get_mac_address(&addr[0]);
+
+    reg = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3];
+    write32(MAC_REG_BASE_ADDR + UMAC_MAC0, reg);
+
+    reg = addr[4] << 8 | addr[5];
+    write32(MAC_REG_BASE_ADDR + UMAC_MAC1, reg);
+
+    return 0;
+}
+
+static int get_ethernet_uid(void)
+{
+    rt_uint32_t uid_high = 0;
+    rt_uint32_t uid_low = 0;
+    rt_uint32_t uid = 0;
+
+    uid_high = bcmgenet_mdio_read(1, BCM54213PE_PHY_IDENTIFIER_HIGH);
+    uid_low = bcmgenet_mdio_read(1, BCM54213PE_PHY_IDENTIFIER_LOW);
+    uid = (uid_high << 16 | uid_low);
+
+    if (BCM54213PE_VERSION_B1 == uid)
+    {
+        LOG_I("version is B1\n");
+    }
+
+    return uid;
+}
+
+static void bcmgenet_mdio_init(void)
+{
+    /* get ethernet uid */
+    if (get_ethernet_uid() == 0)
+    {
+        return;
+    }
+
+    /* reset phy */
+    bcmgenet_mdio_write(1, BCM54213PE_MII_CONTROL, MII_CONTROL_PHY_RESET);
+    /* read control reg */
+    bcmgenet_mdio_read(1, BCM54213PE_MII_CONTROL);
+    /* reset phy again */
+    bcmgenet_mdio_write(1, BCM54213PE_MII_CONTROL, MII_CONTROL_PHY_RESET);
+    /* read control reg */
+    bcmgenet_mdio_read(1, BCM54213PE_MII_CONTROL);
+    /* read status reg */
+    bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS);
+    /* read status reg */
+    bcmgenet_mdio_read(1, BCM54213PE_IEEE_EXTENDED_STATUS);
+    bcmgenet_mdio_read(1, BCM54213PE_AUTO_NEGOTIATION_ADV);
+
+    bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS);
+    bcmgenet_mdio_read(1, BCM54213PE_CONTROL);
+    /* half full duplex capability */
+    bcmgenet_mdio_write(1, BCM54213PE_CONTROL, (CONTROL_HALF_DUPLEX_CAPABILITY | CONTROL_FULL_DUPLEX_CAPABILITY));
+    bcmgenet_mdio_read(1, BCM54213PE_MII_CONTROL);
+
+    /* set mii control */
+    bcmgenet_mdio_write(1, BCM54213PE_MII_CONTROL, (MII_CONTROL_AUTO_NEGOTIATION_ENABLED | MII_CONTROL_AUTO_NEGOTIATION_RESTART | MII_CONTROL_PHY_FULL_DUPLEX | MII_CONTROL_SPEED_SELECTION));
+}
+
+static void rx_ring_init(void)
+{
+    write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
+    write32(MAC_REG_BASE_ADDR + RDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
+    write32(MAC_REG_BASE_ADDR + RDMA_READ_PTR, 0x0);
+    write32(MAC_REG_BASE_ADDR + RDMA_WRITE_PTR, 0x0);
+    write32(MAC_REG_BASE_ADDR + RDMA_RING_REG_BASE + DMA_END_ADDR, RX_DESCS * DMA_DESC_SIZE / 4 - 1);
+
+    write32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX, 0x0);
+    write32(MAC_REG_BASE_ADDR + RDMA_CONS_INDEX, 0x0);
+    write32(MAC_REG_BASE_ADDR + RDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (RX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
+    write32(MAC_REG_BASE_ADDR + RDMA_XON_XOFF_THRESH, DMA_FC_THRESH_VALUE);
+    write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
+}
+
+static void tx_ring_init(void)
+{
+    write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
+    write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_READ_PTR, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_READ_PTR, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_READ_PTR, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_WRITE_PTR, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_END_ADDR, TX_DESCS * DMA_DESC_SIZE / 4 - 1);
+    write32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_CONS_INDEX, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH, 0x1);
+    write32(MAC_REG_BASE_ADDR + TDMA_FLOW_PERIOD, 0x0);
+    write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (TX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
+    write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
+}
+
+static void rx_descs_init(void)
+{
+    char *rxbuffs = (char *)RECV_DATA_NO_CACHE;
+    rt_uint32_t len_stat, i;
+    void *desc_base = (void *)RX_DESC_BASE;
+
+    len_stat = (RX_BUF_LENGTH << DMA_BUFLENGTH_SHIFT) | DMA_OWN;
+    for (i = 0; i < RX_DESCS; i++)
+    {
+        write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_LO), lower_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
+        write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_HI), upper_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
+        write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_LENGTH_STATUS), len_stat);
+    }
+}
+
+static int bcmgenet_adjust_link(void)
+{
+    rt_uint32_t speed;
+    rt_uint32_t phy_dev_speed = link_speed;
+    rt_uint32_t reg1;
+
+    switch (phy_dev_speed)
+    {
+    case SPEED_1000:
+        speed = UMAC_SPEED_1000;
+        break;
+    case SPEED_100:
+        speed = UMAC_SPEED_100;
+        break;
+    case SPEED_10:
+        speed = UMAC_SPEED_10;
+        break;
+    default:
+        rt_kprintf("bcmgenet: Unsupported PHY speed: %d\n", phy_dev_speed);
+        return -1;
+    }
+
+    reg1 = read32(MAC_REG_BASE_ADDR + EXT_RGMII_OOB_CTRL);
+    reg1 |= (RGMII_LINK | RGMII_MODE_EN | ID_MODE_DIS);
+    write32(MAC_REG_BASE_ADDR + EXT_RGMII_OOB_CTRL, reg1);
+    DELAY_MICROS(1000);
+    write32(MAC_REG_BASE_ADDR + UMAC_CMD, speed << CMD_SPEED_SHIFT);
+
+    return 0;
+}
+
+void link_irq(void *param)
+{
+    if ((bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS) & MII_STATUS_LINK_UP) != 0)
+    {
+        rt_sem_release(&link_ack);
+    }
+}
+
+static int bcmgenet_gmac_eth_start(void)
+{
+    rt_uint32_t ret;
+    rt_uint32_t count = 10000;
+
+    bcmgenet_umac_reset();
+
+    bcmgenet_gmac_write_hwaddr();
+    /* disable RX/TX DMA and flush TX queues */
+    bcmgenet_disable_dma();
+    rx_ring_init();
+    rx_descs_init();
+    tx_ring_init();
+
+    /* enable RX/TX DMA */
+    bcmgenet_enable_dma();
+
+    /* ppdate MAC registers based on PHY property */
+    ret = bcmgenet_adjust_link();
+    if (ret)
+    {
+        rt_kprintf("bcmgenet: adjust PHY link failed: %d\n", ret);
+        return ret;
+    }
+
+    /* wait tx index clear */
+    while ((read32(MAC_REG_BASE_ADDR + TDMA_CONS_INDEX) != 0) && (--count))
+    {
+        DELAY_MICROS(1);
+    }
+
+    tx_index = read32(MAC_REG_BASE_ADDR + TDMA_CONS_INDEX);
+    write32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX, tx_index);
+
+    index_flag = read32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX);
+
+    rx_index = index_flag % RX_DESCS;
+
+    write32(MAC_REG_BASE_ADDR + RDMA_CONS_INDEX, index_flag);
+    write32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX, index_flag);
+
+    /* enable Rx/Tx */
+    rt_uint32_t rx_tx_en;
+    rx_tx_en = read32(MAC_REG_BASE_ADDR + UMAC_CMD);
+    rx_tx_en |= (CMD_TX_EN | CMD_RX_EN);
+
+    write32(MAC_REG_BASE_ADDR + UMAC_CMD, rx_tx_en);
+
+    /* eanble IRQ for TxDMA done and RxDMA done */
+    write32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_CLEAR_MASK, GENET_IRQ_TXDMA_DONE | GENET_IRQ_RXDMA_DONE);
+
+    return 0;
+}
+
+static rt_uint32_t prev_recv_cnt = 0;
+static rt_uint32_t cur_recv_cnt = 0;
+static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
+{
+    void *desc_base;
+    rt_uint32_t length = 0, addr = 0;
+    rt_uint32_t prod_index = read32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX);
+
+    /* no buff */
+    if (prod_index == index_flag)
+    {
+        cur_recv_cnt = index_flag;
+        index_flag = 0x7fffffff;
+
+        return 0;
+    }
+    else
+    {
+        /* no new buff */
+        if (prev_recv_cnt == (prod_index & 0xffff))
+        {
+            return 0;
+        }
+
+        desc_base = RX_DESC_BASE + rx_index * DMA_DESC_SIZE;
+        length = read32(desc_base + DMA_DESC_LENGTH_STATUS);
+        length = (length >> DMA_BUFLENGTH_SHIFT) & DMA_BUFLENGTH_MASK;
+        addr = read32(desc_base + DMA_DESC_ADDRESS_LO);
+        /*
+         * to cater for the IP headepr alignment the hardware does.
+         * This would actually not be needed if we don't program
+         * RBUF_ALIGN_2B
+         */
+
+        /* convert to memory address */
+        addr = addr + RECV_DATA_NO_CACHE - RECV_DATA_NO_CACHE;
+        rt_hw_dcache_invalidate_range(addr, length);
+
+        *packetp = (rt_uint8_t *)(unsigned long)(addr + RX_BUF_OFFSET);
+
+        rx_index = rx_index + 1;
+        if (rx_index >= RX_DESCS)
+        {
+            rx_index = 0;
+        }
+
+        write32(MAC_REG_BASE_ADDR + RDMA_CONS_INDEX, cur_recv_cnt);
+
+        cur_recv_cnt = cur_recv_cnt + 1;
+
+        if (cur_recv_cnt > 0xffff)
+        {
+            cur_recv_cnt = 0;
+        }
+        prev_recv_cnt = cur_recv_cnt;
+
+        return length - RX_BUF_OFFSET;
+    }
+}
+
+
+static int bcmgenet_gmac_eth_send(rt_uint32_t packet, int length, struct pbuf *p)
+{
+    void *desc_base = (TX_DESC_BASE + tx_index * DMA_DESC_SIZE);
+    pbuf_copy_partial(p, (void *)(unsigned long)(packet + tx_index * SEND_CACHE_BUF), p->tot_len, 0);
+    rt_uint32_t len_stat = length << DMA_BUFLENGTH_SHIFT;
+    len_stat |= 0x3F << DMA_TX_QTAG_SHIFT;
+    len_stat |= DMA_TX_APPEND_CRC | DMA_SOP | DMA_EOP;
+    rt_hw_dcache_flush_range(packet + tx_index * SEND_CACHE_BUF, length);
+
+    rt_uint32_t prod_index;
+
+    prod_index = read32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX);
+
+    write32((desc_base + DMA_DESC_ADDRESS_LO), SEND_DATA_NO_CACHE + tx_index * SEND_CACHE_BUF);
+    write32((desc_base + DMA_DESC_ADDRESS_HI), 0);
+    write32((desc_base + DMA_DESC_LENGTH_STATUS), len_stat);
+
+    tx_index++;
+    if (tx_index >= TX_DESCS)
+    {
+        tx_index = 0;
+    }
+    prod_index = prod_index + 1;
+
+    if (prod_index > 0xffff)
+    {
+        prod_index = 0;
+    }
+
+    /* start Transmisson */
+    write32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX, prod_index);
+    return 0;
+}
+
+static void link_task_entry(void *param)
+{
+    struct eth_device *eth_device = (struct eth_device *)param;
+    RT_ASSERT(eth_device != RT_NULL);
+    struct rt_eth_dev *dev = &eth_dev;
+
+    /* start mdio */
+    bcmgenet_mdio_init();
+
+    /* start timer link */
+    rt_timer_init(&dev->link_timer, "link_timer",
+                  link_irq,
+                  NULL,
+                  100,
+                  RT_TIMER_FLAG_PERIODIC);
+    rt_timer_start(&dev->link_timer);
+
+    /* link wait forever */
+    rt_sem_take(&link_ack, RT_WAITING_FOREVER);
+    /* link up */
+    eth_device_linkchange(&eth_dev.parent, RT_TRUE);
+    rt_timer_stop(&dev->link_timer);
+
+    /* set mac */
+    bcmgenet_gmac_write_hwaddr();
+
+    /* check link speed */
+    if ((bcmgenet_mdio_read(1, BCM54213PE_STATUS) & (1 << 10)) || (bcmgenet_mdio_read(1, BCM54213PE_STATUS) & (1 << 11)))
+    {
+        link_speed = 1000;
+        rt_kprintf("Support link mode Speed 1000M\n");
+    }
+    else if ((bcmgenet_mdio_read(1, 0x05) & (1 << 7)) || (bcmgenet_mdio_read(1, 0x05) & (1 << 8)) || (bcmgenet_mdio_read(1, 0x05) & (1 << 9)))
+    {
+        link_speed = 100;
+        rt_kprintf("Support link mode Speed 100M\n");
+    }
+    else
+    {
+        link_speed = 10;
+        rt_kprintf("Support link mode Speed 10M\n");
+    }
+
+    /* convert to memory address */
+    bcmgenet_gmac_eth_start();
+
+    rt_hw_interrupt_install(ETH_IRQ, eth_rx_irq, NULL, "eth_irq");
+    rt_hw_interrupt_umask(ETH_IRQ);
+
+    link_flag = 1;
+}
+
+static rt_err_t bcmgenet_eth_init(rt_device_t device)
+{
+    rt_uint32_t ret = 0;
+    rt_uint32_t hw_reg = 0;
+
+    /* read GENET HW version */
+    rt_uint8_t major = 0;
+    hw_reg = read32(MAC_REG_BASE_ADDR + SYS_REV_CTRL);
+    major = (hw_reg >> 24) & 0x0f;
+
+    if (major != 6)
+    {
+        if (major == 5)
+        {
+            major = 4;
+        }
+        else if (major == 0)
+        {
+            major = 1;
+        }
+
+        rt_kprintf("Uns upported GENETv%d.%d\n", major, (hw_reg >> 16) & 0x0f);
+
+        return RT_ERROR;
+    }
+
+    /* set interface */
+    ret = bcmgenet_interface_set();
+    if (ret)
+    {
+        return ret;
+    }
+
+    /* rbuf clear */
+    write32(MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL, 0);
+
+    /* disable MAC while updating its registers */
+    write32(MAC_REG_BASE_ADDR + UMAC_CMD, 0);
+    /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */
+    write32(MAC_REG_BASE_ADDR + UMAC_CMD, CMD_SW_RESET | CMD_LCL_LOOP_EN);
+
+    link_thread_tid = rt_thread_create("link", link_task_entry, (void *)device,
+                                       LINK_THREAD_STACK_SIZE,
+                                       LINK_THREAD_PRIORITY, LINK_THREAD_TIMESLICE);
+    if (link_thread_tid != RT_NULL)
+    {
+        rt_thread_startup(link_thread_tid);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t bcmgenet_eth_control(rt_device_t dev, int cmd, void *args)
+{
+    switch (cmd)
+    {
+    case NIOCTL_GADDR:
+        if (args)
+        {
+            rt_memcpy(args, eth_dev.dev_addr, 6);
+        }
+        else
+        {
+            return -RT_ERROR;
+        }
+        break;
+    default:
+        break;
+    }
+    return RT_EOK;
+}
+
+rt_err_t rt_eth_tx(rt_device_t device, struct pbuf *p)
+{
+    if (link_flag == 1)
+    {
+        bcmgenet_gmac_eth_send((rt_uint32_t)SEND_DATA_NO_CACHE, p->tot_len, p);
+        rt_sem_take(&send_finsh_sem_lock, RT_WAITING_FOREVER);
+    }
+
+    return RT_EOK;
+}
+
+struct pbuf *rt_eth_rx(rt_device_t device)
+{
+    int recv_len = 0;
+    rt_uint8_t *addr_point = RT_NULL;
+    struct pbuf *pbuf = RT_NULL;
+
+    if (link_flag == 1)
+    {
+        recv_len = bcmgenet_gmac_eth_recv(&addr_point);
+        if (recv_len > 0)
+        {
+            pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
+            if (pbuf)
+            {
+                rt_memcpy(pbuf->payload, addr_point, recv_len);
+            }
+        }
+    }
+
+    return pbuf;
+}
+
+int rt_hw_eth_init(void)
+{
+    rt_uint8_t mac_addr[6];
+    rt_sem_init(&send_finsh_sem_lock, "send_finsh_sem_lock", TX_DESCS, RT_IPC_FLAG_FIFO);
+    rt_sem_init(&link_ack, "link_ack", 0, RT_IPC_FLAG_FIFO);
+    memset(&eth_dev, 0, sizeof(eth_dev));
+    memset((void *)SEND_DATA_NO_CACHE, 0, DMA_DISC_ADDR_SIZE);
+    memset((void *)RECV_DATA_NO_CACHE, 0, DMA_DISC_ADDR_SIZE);
+    bcm271x_mbox_hardware_get_mac_address(&mac_addr[0]);
+
+    eth_dev.iobase = MAC_REG_BASE_ADDR;
+    eth_dev.name = "e0";
+    eth_dev.dev_addr[0] = mac_addr[0];
+    eth_dev.dev_addr[1] = mac_addr[1];
+    eth_dev.dev_addr[2] = mac_addr[2];
+    eth_dev.dev_addr[3] = mac_addr[3];
+    eth_dev.dev_addr[4] = mac_addr[4];
+    eth_dev.dev_addr[5] = mac_addr[5];
+
+    eth_dev.parent.parent.type       = RT_Device_Class_NetIf;
+    eth_dev.parent.parent.init       = bcmgenet_eth_init;
+    eth_dev.parent.parent.open       = RT_NULL;
+    eth_dev.parent.parent.close      = RT_NULL;
+    eth_dev.parent.parent.read       = RT_NULL;
+    eth_dev.parent.parent.write      = RT_NULL;
+    eth_dev.parent.parent.control    = bcmgenet_eth_control;
+    eth_dev.parent.parent.user_data  = RT_NULL;
+
+    eth_dev.parent.eth_tx            = rt_eth_tx;
+    eth_dev.parent.eth_rx            = rt_eth_rx;
+
+    eth_device_init(&(eth_dev.parent), "e0");
+    /* link down */
+    eth_device_linkchange(&eth_dev.parent, RT_FALSE);
+
+    return 0;
+}
+INIT_COMPONENT_EXPORT(rt_hw_eth_init);

+ 216 - 0
bsp/raspberry-pi/raspi4-64/driver/drv_eth.h

@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-10-30     bigmagic       first version
+ */
+
+#ifndef __DRV_ETH_H__
+#define __DRV_ETH_H__
+
+#define MAC_REG             (void *)(0xfd580000)
+
+#define SYS_REV_CTRL        (0x00)
+#define SYS_PORT_CTRL       (0x04)
+#define PORT_MODE_EXT_GPHY  (3)
+
+#define GENET_SYS_OFF       (0x0000)
+#define SYS_RBUF_FLUSH_CTRL (GENET_SYS_OFF  + 0x08)
+#define SYS_TBUF_FLUSH_CTRL (GENET_SYS_OFF  + 0x0c)
+
+#define GENET_EXT_OFF       (0x0080)
+#define EXT_RGMII_OOB_CTRL  (GENET_EXT_OFF + 0x0c)
+#define RGMII_LINK          BIT(4)
+#define OOB_DISABLE         BIT(5)
+#define RGMII_MODE_EN       BIT(6)
+#define ID_MODE_DIS         BIT(16)
+
+#define GENET_RBUF_OFF      (0x0300)
+#define RBUF_TBUF_SIZE_CTRL (GENET_RBUF_OFF + 0xb4)
+#define RBUF_CTRL           (GENET_RBUF_OFF + 0x00)
+#define RBUF_ALIGN_2B       BIT(1)
+
+#define GENET_UMAC_OFF      (0x0800)
+#define UMAC_MIB_CTRL       (GENET_UMAC_OFF + 0x580)
+#define UMAC_MAX_FRAME_LEN  (GENET_UMAC_OFF + 0x014)
+#define UMAC_MAC0           (GENET_UMAC_OFF + 0x00c)
+#define UMAC_MAC1           (GENET_UMAC_OFF + 0x010)
+#define UMAC_CMD            (GENET_UMAC_OFF + 0x008)
+#define MDIO_CMD            (GENET_UMAC_OFF + 0x614)
+#define UMAC_TX_FLUSH       (GENET_UMAC_OFF + 0x334)
+#define MDIO_START_BUSY     BIT(29)
+#define MDIO_READ_FAIL      BIT(28)
+#define MDIO_RD             (2 << 26)
+#define MDIO_WR             BIT(26)
+#define MDIO_PMD_SHIFT      (21)
+#define MDIO_PMD_MASK       (0x1f)
+#define MDIO_REG_SHIFT      (16)
+#define MDIO_REG_MASK       (0x1f)
+
+#define  GENET_INTRL2_OFF               (0x0200)
+#define  GENET_INTRL2_CPU_STAT          (GENET_INTRL2_OFF + 0x00)
+#define  GENET_INTRL2_CPU_CLEAR         (GENET_INTRL2_OFF + 0x08)
+#define  GENET_INTRL2_CPU_STAT_MASK     (GENET_INTRL2_OFF + 0x0c)
+#define  GENET_INTRL2_CPU_SET_MASK      (GENET_INTRL2_OFF + 0x10)
+#define  GENET_INTRL2_CPU_CLEAR_MASK    (GENET_INTRL2_OFF + 0x14)
+#define  GENET_IRQ_MDIO_ERROR           BIT(24)
+#define  GENET_IRQ_MDIO_DONE            BIT(23)
+#define  GENET_IRQ_TXDMA_DONE           BIT(16)
+#define  GENET_IRQ_RXDMA_DONE           BIT(13)
+
+#define CMD_TX_EN           BIT(0)
+#define CMD_RX_EN           BIT(1)
+#define UMAC_SPEED_10       (0)
+#define UMAC_SPEED_100      (1)
+#define UMAC_SPEED_1000     (2)
+#define UMAC_SPEED_2500     (3)
+#define CMD_SPEED_SHIFT     (2)
+#define CMD_SPEED_MASK      (3)
+#define CMD_SW_RESET        BIT(13)
+#define CMD_LCL_LOOP_EN     BIT(15)
+#define CMD_TX_EN           BIT(0)
+#define CMD_RX_EN           BIT(1)
+
+#define MIB_RESET_RX        BIT(0)
+#define MIB_RESET_RUNT      BIT(1)
+#define MIB_RESET_TX        BIT(2)
+
+/* total number of Buffer Descriptors, same for Rx/Tx */
+#define TOTAL_DESCS         (256)
+#define RX_DESCS            TOTAL_DESCS
+#define TX_DESCS            TOTAL_DESCS
+
+#define DEFAULT_Q           (0x10)
+
+#define ETH_DATA_LEN        (1500)
+#define ETH_HLEN            (14)
+#define VLAN_HLEN           (4)
+#define ETH_FCS_LEN         (4)
+/*
+ * Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
+ * 1536 is multiple of 256 bytes
+ */
+#define ENET_BRCM_TAG_LEN   (6)
+#define ENET_PAD            (8)
+#define ENET_MAX_MTU_SIZE   (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
+
+/* Tx/Rx Dma Descriptor common bits */
+#define DMA_EN                     BIT(0)
+#define DMA_RING_BUF_EN_SHIFT      (0x01)
+#define DMA_RING_BUF_EN_MASK       (0xffff)
+#define DMA_BUFLENGTH_MASK         (0x0fff)
+#define DMA_BUFLENGTH_SHIFT        (16)
+#define DMA_RING_SIZE_SHIFT        (16)
+#define DMA_OWN                    (0x8000)
+#define DMA_EOP                    (0x4000)
+#define DMA_SOP                    (0x2000)
+#define DMA_WRAP                   (0x1000)
+#define DMA_MAX_BURST_LENGTH       (0x8)
+/* Tx specific DMA descriptor bits */
+#define DMA_TX_UNDERRUN            (0x0200)
+#define DMA_TX_APPEND_CRC          (0x0040)
+#define DMA_TX_OW_CRC              (0x0020)
+#define DMA_TX_DO_CSUM             (0x0010)
+#define DMA_TX_QTAG_SHIFT          (7)
+
+/* DMA rings size */
+#define DMA_RING_SIZE              (0x40)
+#define DMA_RINGS_SIZE             (DMA_RING_SIZE * (DEFAULT_Q + 1))
+
+/* DMA descriptor */
+#define DMA_DESC_LENGTH_STATUS     (0x00)
+#define DMA_DESC_ADDRESS_LO        (0x04)
+#define DMA_DESC_ADDRESS_HI        (0x08)
+#define DMA_DESC_SIZE              (12)
+
+#define GENET_RX_OFF               (0x2000)
+#define GENET_RDMA_REG_OFF         (GENET_RX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
+#define GENET_TX_OFF               (0x4000)
+#define GENET_TDMA_REG_OFF         (GENET_TX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
+
+#define DMA_FC_THRESH_HI           (RX_DESCS >> 4)
+#define DMA_FC_THRESH_LO           (5)
+#define DMA_FC_THRESH_VALUE        ((DMA_FC_THRESH_LO << 16) | DMA_FC_THRESH_HI)
+
+#define DMA_XOFF_THRESHOLD_SHIFT   (16)
+
+#define TDMA_RING_REG_BASE         (GENET_TDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
+#define TDMA_READ_PTR              (TDMA_RING_REG_BASE + 0x00)
+#define TDMA_CONS_INDEX            (TDMA_RING_REG_BASE + 0x08)
+#define TDMA_PROD_INDEX            (TDMA_RING_REG_BASE + 0x0c)
+#define DMA_RING_BUF_SIZE          (0x10)
+#define DMA_START_ADDR             (0x14)
+#define DMA_END_ADDR               (0x1c)
+#define DMA_MBUF_DONE_THRESH       (0x24)
+#define TDMA_FLOW_PERIOD           (TDMA_RING_REG_BASE + 0x28)
+#define TDMA_WRITE_PTR             (TDMA_RING_REG_BASE + 0x2c)
+
+#define RDMA_RING_REG_BASE         (GENET_RDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
+#define RDMA_WRITE_PTR             (RDMA_RING_REG_BASE + 0x00)
+#define RDMA_PROD_INDEX            (RDMA_RING_REG_BASE + 0x08)
+#define RDMA_CONS_INDEX            (RDMA_RING_REG_BASE + 0x0c)
+#define RDMA_XON_XOFF_THRESH       (RDMA_RING_REG_BASE + 0x28)
+#define RDMA_READ_PTR              (RDMA_RING_REG_BASE + 0x2c)
+
+#define TDMA_REG_BASE              (GENET_TDMA_REG_OFF + DMA_RINGS_SIZE)
+#define RDMA_REG_BASE              (GENET_RDMA_REG_OFF + DMA_RINGS_SIZE)
+#define DMA_RING_CFG               (0x00)
+#define DMA_CTRL                   (0x04)
+#define DMA_SCB_BURST_SIZE         (0x0c)
+
+#define RX_BUF_LENGTH              (2048)
+#define RX_TOTAL_BUFSIZE           (RX_BUF_LENGTH * RX_DESCS)
+#define RX_BUF_OFFSET              (2)
+
+#define PHY_INTERFACE_MODE_RGMII                (7)
+#define PHY_INTERFACE_MODE_RGMII_RXID           (9)
+
+#define  BCM54213PE_MII_CONTROL                 (0x00)
+#define  BCM54213PE_MII_STATUS                  (0x01)
+#define  BCM54213PE_PHY_IDENTIFIER_HIGH         (0x02)
+#define  BCM54213PE_PHY_IDENTIFIER_LOW          (0x03)
+
+#define  BCM54213PE_AUTO_NEGOTIATION_ADV        (0x04)
+#define  BCM54213PE_AUTO_NEGOTIATION_LINK       (0x05)
+#define  BCM54213PE_AUTO_NEGOTIATION_EXPANSION  (0x06)
+
+#define  BCM54213PE_NEXT_PAGE_TX                (0x07)
+
+#define  BCM54213PE_PARTNER_RX                  (0x08)
+
+#define  BCM54213PE_CONTROL                     (0x09)
+#define  BCM54213PE_STATUS                      (0x0A)
+
+#define  BCM54213PE_IEEE_EXTENDED_STATUS        (0x0F)
+#define  BCM54213PE_PHY_EXTENDED_CONTROL        (0x10)
+#define  BCM54213PE_PHY_EXTENDED_STATUS         (0x11)
+
+#define  BCM54213PE_RECEIVE_ERROR_COUNTER       (0x12)
+#define  BCM54213PE_FALSE_C_S_COUNTER           (0x13)
+#define  BCM54213PE_RECEIVE_NOT_OK_COUNTER      (0x14)
+
+#define BCM54213PE_VERSION_B1                   (0x600d84a2)
+#define BCM54213PE_VERSION_X                    (0x600d84a0)
+
+//BCM54213PE_MII_CONTROL
+#define MII_CONTROL_PHY_RESET                   (1 << 15)
+#define MII_CONTROL_AUTO_NEGOTIATION_ENABLED    (1 << 12)
+#define MII_CONTROL_AUTO_NEGOTIATION_RESTART    (1 << 9)
+#define MII_CONTROL_PHY_FULL_DUPLEX             (1 << 8)
+#define MII_CONTROL_SPEED_SELECTION             (1 << 6)
+
+//BCM54213PE_MII_STATUS
+#define MII_STATUS_LINK_UP                      (1 << 2)
+
+//BCM54213PE_CONTROL
+#define CONTROL_FULL_DUPLEX_CAPABILITY          (1 << 9)
+#define CONTROL_HALF_DUPLEX_CAPABILITY          (1 << 8)
+
+#define SPEED_1000  (1000)
+#define SPEED_100   (100)
+#define SPEED_10    (10)
+
+#endif/* __DRV_ETH_H__ */

+ 69 - 0
bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c

@@ -12,6 +12,63 @@
 
 #ifdef BSP_USING_PIN
 
+uint32_t raspi_get_pin_state(uint32_t fselnum)
+{
+    uint32_t gpfsel = 0;
+
+    switch (fselnum)
+    {
+    case 0:
+        gpfsel = GPIO_REG_GPFSEL0(GPIO_BASE);
+        break;
+    case 1:
+        gpfsel = GPIO_REG_GPFSEL1(GPIO_BASE);
+        break;
+    case 2:
+        gpfsel = GPIO_REG_GPFSEL2(GPIO_BASE);
+        break;
+    case 3:
+        gpfsel = GPIO_REG_GPFSEL3(GPIO_BASE);
+        break;
+    case 4:
+        gpfsel = GPIO_REG_GPFSEL4(GPIO_BASE);
+        break;
+    case 5:
+        gpfsel = GPIO_REG_GPFSEL5(GPIO_BASE);
+        break;
+    default:
+        break;
+    }
+    return gpfsel;
+}
+
+void raspi_set_pin_state(uint32_t fselnum, uint32_t gpfsel)
+{
+    switch (fselnum)
+    {
+    case 0:
+        GPIO_REG_GPFSEL0(GPIO_BASE) = gpfsel;
+        break;
+    case 1:
+        GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel;
+        break;
+    case 2:
+        GPIO_REG_GPFSEL2(GPIO_BASE) = gpfsel;
+        break;
+    case 3:
+        GPIO_REG_GPFSEL3(GPIO_BASE) = gpfsel;
+        break;
+    case 4:
+        GPIO_REG_GPFSEL4(GPIO_BASE) = gpfsel;
+        break;
+    case 5:
+        GPIO_REG_GPFSEL5(GPIO_BASE) = gpfsel;
+        break;
+    default:
+        break;
+    }
+}
+
 static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
 {
     uint32_t fselnum = pin / 10;
@@ -46,6 +103,18 @@ static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
     }
 }
 
+void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode)
+{
+    uint32_t fselnum = pin / 10;
+    uint32_t fselrest = pin % 10;
+    uint32_t gpfsel = 0;
+
+    gpfsel = raspi_get_pin_state(fselnum);
+    gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3)));
+    gpfsel |= (uint32_t)(mode << (fselrest * 3));
+    raspi_set_pin_state(fselnum, gpfsel);
+}
+
 static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
 {
     uint32_t num = pin / 32;

+ 46 - 1
bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h

@@ -60,6 +60,50 @@
 #define GPIO_REG_REV9(BASE)                HWREG32(BASE + 0xA0)
 #define GPIO_REG_TEST(BASE)                HWREG32(BASE + 0xA4)
 
+typedef enum {
+    GPIO_PIN_0,
+    GPIO_PIN_1,
+    GPIO_PIN_2,
+    GPIO_PIN_3,
+    GPIO_PIN_4,
+    GPIO_PIN_5,
+    GPIO_PIN_6,
+    GPIO_PIN_7,
+    GPIO_PIN_8,
+    GPIO_PIN_9,
+    GPIO_PIN_10,
+    GPIO_PIN_11,
+    GPIO_PIN_12,
+    GPIO_PIN_13,
+    GPIO_PIN_14,
+    GPIO_PIN_15,
+    GPIO_PIN_16,
+    GPIO_PIN_17,
+    GPIO_PIN_18,
+    GPIO_PIN_19,
+    GPIO_PIN_20,
+    GPIO_PIN_21,
+    GPIO_PIN_22,
+    GPIO_PIN_23,
+    GPIO_PIN_24,
+    GPIO_PIN_25,
+    GPIO_PIN_26,
+    GPIO_PIN_27,
+    GPIO_PIN_28,
+    GPIO_PIN_29,
+    GPIO_PIN_30,
+    GPIO_PIN_31,
+    GPIO_PIN_32,
+    GPIO_PIN_33,
+    GPIO_PIN_34,
+    GPIO_PIN_35,
+    GPIO_PIN_36,
+    GPIO_PIN_37,
+    GPIO_PIN_38,
+    GPIO_PIN_39,
+    GPIO_PIN_40,
+} GPIO_PIN;
+
 typedef enum {
     INPUT = 0b000,
     OUTPUT = 0b001,
@@ -71,7 +115,8 @@ typedef enum {
     ALT5 = 0b010
 } GPIO_FUNC;
 
-
+void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode);
+void prev_raspi_pin_write(GPIO_PIN pin, int pin_value);
 int rt_hw_gpio_init(void);
 
 #endif /* __DRV_GPIO_H__ */

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

@@ -0,0 +1,720 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-10-27     bigmagic       first version
+ */
+
+#include <rtdef.h>
+#include "mbox.h"
+#include "raspi4.h"
+#include "drv_sdio.h"
+
+#include "mmu.h"
+
+static rt_uint32_t mmc_base_clock = 0;
+
+static rt_uint32_t sdCommandTable[] =
+{
+    SD_CMD_INDEX(0),
+    SD_CMD_RESERVED(1),
+    SD_CMD_INDEX(2) | SD_RESP_R2,
+    SD_CMD_INDEX(3) | SD_RESP_R1,
+    SD_CMD_INDEX(4),
+    SD_CMD_RESERVED(5), //SD_CMD_INDEX(5) | SD_RESP_R4,
+    SD_CMD_INDEX(6) | SD_RESP_R1,
+    SD_CMD_INDEX(7) | SD_RESP_R1b,
+    SD_CMD_INDEX(8) | SD_RESP_R1,
+    SD_CMD_INDEX(9) | SD_RESP_R2,
+    SD_CMD_INDEX(10) | SD_RESP_R2,
+    SD_CMD_INDEX(11) | SD_RESP_R1,
+    SD_CMD_INDEX(12) | SD_RESP_R1b | SD_CMD_TYPE_ABORT,
+    SD_CMD_INDEX(13) | SD_RESP_R1,
+    SD_CMD_RESERVED(14),
+    SD_CMD_INDEX(15),
+    SD_CMD_INDEX(16) | SD_RESP_R1,
+    SD_CMD_INDEX(17) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_INDEX(18) | SD_RESP_R1 | SD_DATA_READ | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
+    SD_CMD_INDEX(19) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_INDEX(20) | SD_RESP_R1b,
+    SD_CMD_RESERVED(21),
+    SD_CMD_RESERVED(22),
+    SD_CMD_INDEX(23) | SD_RESP_R1,
+    SD_CMD_INDEX(24) | SD_RESP_R1 | SD_DATA_WRITE,
+    SD_CMD_INDEX(25) | SD_RESP_R1 | SD_DATA_WRITE | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
+    SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE,  // add
+    SD_CMD_INDEX(27) | SD_RESP_R1 | SD_DATA_WRITE,
+    SD_CMD_INDEX(28) | SD_RESP_R1b,
+    SD_CMD_INDEX(29) | SD_RESP_R1b,
+    SD_CMD_INDEX(30) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_RESERVED(31),
+    SD_CMD_INDEX(32) | SD_RESP_R1,
+    SD_CMD_INDEX(33) | SD_RESP_R1,
+    SD_CMD_RESERVED(34),
+    SD_CMD_INDEX(35) | SD_RESP_R1,  // add
+    SD_CMD_INDEX(36) | SD_RESP_R1,  // add
+    SD_CMD_RESERVED(37),
+    SD_CMD_INDEX(38) | SD_RESP_R1b,
+    SD_CMD_INDEX(39) | SD_RESP_R4,  // add
+    SD_CMD_INDEX(40) | SD_RESP_R5,  // add
+    SD_CMD_INDEX(41) | SD_RESP_R3,  // add, mov from harbote
+    SD_CMD_RESERVED(42) | SD_RESP_R1,
+    SD_CMD_RESERVED(43),
+    SD_CMD_RESERVED(44),
+    SD_CMD_RESERVED(45),
+    SD_CMD_RESERVED(46),
+    SD_CMD_RESERVED(47),
+    SD_CMD_RESERVED(48),
+    SD_CMD_RESERVED(49),
+    SD_CMD_RESERVED(50),
+    SD_CMD_INDEX(51) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_RESERVED(52),
+    SD_CMD_RESERVED(53),
+    SD_CMD_RESERVED(54),
+    SD_CMD_INDEX(55) | SD_RESP_R3,
+    SD_CMD_INDEX(56) | SD_RESP_R1 | SD_CMD_ISDATA,
+    SD_CMD_RESERVED(57),
+    SD_CMD_RESERVED(58),
+    SD_CMD_RESERVED(59),
+    SD_CMD_RESERVED(60),
+    SD_CMD_RESERVED(61),
+    SD_CMD_RESERVED(62),
+    SD_CMD_RESERVED(63)
+};
+
+rt_inline rt_uint32_t read32(rt_ubase_t addr)
+{
+    return (*((volatile unsigned int *)(addr)));
+}
+
+rt_inline void write32(rt_ubase_t addr, rt_uint32_t value)
+{
+    (*((volatile unsigned int *)(addr))) = value;
+}
+
+rt_err_t sd_int(struct sdhci_pdata_t *pdat, rt_uint32_t mask)
+{
+    rt_uint32_t r;
+    rt_uint32_t m = mask | INT_ERROR_MASK;
+    int cnt = 1000000;
+    while (!(read32(pdat->virt + EMMC_INTERRUPT) & (m | INT_ERROR_MASK)) && cnt--)
+    {
+        DELAY_MICROS(1);
+    }
+    r = read32(pdat->virt + EMMC_INTERRUPT);
+    if (cnt <= 0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT))
+    {
+        write32(pdat->virt + EMMC_INTERRUPT, r);
+        /* qemu maybe can not use sdcard */
+        rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n", mask, r, read32(pdat->virt + EMMC_STATUS));
+
+        return -RT_ETIMEOUT;
+    }
+    else if (r & INT_ERROR_MASK)
+    {
+        write32(pdat->virt + EMMC_INTERRUPT, r);
+        rt_kprintf("send cmd/data error %x -> %x\n", r, read32(pdat->virt + EMMC_INTERRUPT));
+
+        return -RT_ERROR;
+    }
+    write32(pdat->virt + EMMC_INTERRUPT, mask);
+    return RT_EOK;
+}
+
+rt_err_t sd_status(struct sdhci_pdata_t *pdat, unsigned int mask)
+{
+    int cnt = 500000;
+    while ((read32(pdat->virt + EMMC_STATUS) & mask) && !(read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK) && cnt--)
+    {
+        DELAY_MICROS(1);
+    }
+    if (cnt <= 0)
+    {
+        return -RT_ETIMEOUT;
+    }
+    else if (read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK)
+    {
+        return  -RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t raspi_transfer_command(struct sdhci_pdata_t *pdat, struct sdhci_cmd_t *cmd)
+{
+    rt_uint32_t cmdidx;
+    rt_err_t ret = RT_EOK;
+    ret = sd_status(pdat, SR_CMD_INHIBIT);
+    if (ret)
+    {
+        rt_kprintf("ERROR: EMMC busy %d\n", ret);
+        return ret;
+    }
+
+    cmdidx = sdCommandTable[cmd->cmdidx];
+    if (cmdidx == 0xFFFFFFFF)
+    {
+        return -RT_EINVAL;
+    }
+    if (cmd->datarw == DATA_READ)
+    {
+        cmdidx |= SD_DATA_READ;
+    }
+    if (cmd->datarw == DATA_WRITE)
+    {
+        cmdidx |= SD_DATA_WRITE;
+    }
+
+    mmcsd_dbg("transfer cmd %x(%d) %x %x\n", cmdidx, cmd->cmdidx, cmd->cmdarg, read32(pdat->virt + EMMC_INTERRUPT));
+    write32(pdat->virt + EMMC_INTERRUPT, read32(pdat->virt + EMMC_INTERRUPT));
+    write32(pdat->virt + EMMC_ARG1, cmd->cmdarg);
+    write32(pdat->virt + EMMC_CMDTM, cmdidx);
+    if (cmd->cmdidx == SD_APP_OP_COND)
+    {
+        DELAY_MICROS(1000);
+    }
+    else if ((cmd->cmdidx == SD_SEND_IF_COND) || (cmd->cmdidx == APP_CMD))
+    {
+        DELAY_MICROS(100);
+    }
+
+    ret = sd_int(pdat, INT_CMD_DONE);
+    if (ret)
+    {
+        return ret;
+    }
+    if (cmd->resptype & RESP_MASK)
+    {
+
+        if (cmd->resptype & RESP_R2)
+        {
+            rt_uint32_t resp[4];
+            resp[0] = read32(pdat->virt + EMMC_RESP0);
+            resp[1] = read32(pdat->virt + EMMC_RESP1);
+            resp[2] = read32(pdat->virt + EMMC_RESP2);
+            resp[3] = read32(pdat->virt + EMMC_RESP3);
+            if (cmd->resptype == RESP_R2)
+            {
+                cmd->response[0] = resp[3] << 8 | ((resp[2] >> 24) & 0xff);
+                cmd->response[1] = resp[2] << 8 | ((resp[1] >> 24) & 0xff);
+                cmd->response[2] = resp[1] << 8 | ((resp[0] >> 24) & 0xff);
+                cmd->response[3] = resp[0] << 8 ;
+            }
+            else
+            {
+                cmd->response[0] = resp[0];
+                cmd->response[1] = resp[1];
+                cmd->response[2] = resp[2];
+                cmd->response[3] = resp[3];
+            }
+        }
+        else
+        {
+            cmd->response[0] = read32(pdat->virt + EMMC_RESP0);
+        }
+    }
+
+    mmcsd_dbg("response: %x: %x %x %x %x (%x, %x)\n", cmd->resptype, cmd->response[0], cmd->response[1], cmd->response[2], cmd->response[3], read32(pdat->virt + EMMC_STATUS), read32(pdat->virt + EMMC_INTERRUPT));
+    return ret;
+}
+
+static rt_err_t read_bytes(struct sdhci_pdata_t *pdat, rt_uint32_t *buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+{
+    int c = 0;
+    rt_err_t ret;
+    int d;
+
+    while (c < blkcount)
+    {
+        if ((ret = sd_int(pdat, INT_READ_RDY)))
+        {
+            rt_kprintf("timeout happens when reading block %d\n", c);
+            return ret;
+        }
+        for (d = 0; d < blksize / 4; d++)
+        {
+            if (read32(pdat->virt + EMMC_STATUS) & SR_READ_AVAILABLE)
+            {
+                buf[d] = read32(pdat->virt + EMMC_DATA);
+            }
+        }
+        c++;
+        buf += blksize / 4;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t write_bytes(struct sdhci_pdata_t *pdat, rt_uint32_t *buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+{
+    int c = 0;
+    rt_err_t ret;
+    int d;
+    while (c < blkcount)
+    {
+        if ((ret = sd_int(pdat, INT_WRITE_RDY)))
+        {
+            return ret;
+        }
+        for (d = 0; d < blksize / 4; d++)
+        {
+            write32(pdat->virt + EMMC_DATA, buf[d]);
+        }
+        c++;
+        buf += blksize / 4;
+    }
+
+    if ((ret = sd_int(pdat, INT_DATA_DONE)))
+    {
+        return ret;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t raspi_transfer_data(struct sdhci_pdata_t *pdat, struct sdhci_cmd_t *cmd, struct sdhci_data_t *dat)
+{
+    rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz);
+    rt_err_t ret = sd_status(pdat, SR_DAT_INHIBIT);
+
+    if (ret)
+    {
+        rt_kprintf("ERROR: EMMC busy\n");
+        return ret;
+    }
+    if (dat->blkcnt > 1)
+    {
+        struct sdhci_cmd_t newcmd;
+        newcmd.cmdidx = SET_BLOCK_COUNT;
+        newcmd.cmdarg = dat->blkcnt;
+        newcmd.resptype = RESP_R1;
+        ret = raspi_transfer_command(pdat, &newcmd);
+        if (ret)
+        {
+            return ret;
+        }
+    }
+
+    if (dlen < 512)
+    {
+        write32(pdat->virt + EMMC_BLKSIZECNT, dlen | 1 << 16);
+    }
+    else
+    {
+        write32(pdat->virt + EMMC_BLKSIZECNT, 512 | (dat->blkcnt) << 16);
+    }
+    if (dat->flag & DATA_DIR_READ)
+    {
+        cmd->datarw = DATA_READ;
+        ret = raspi_transfer_command(pdat, cmd);
+        if (ret)
+        {
+            return ret;
+        }
+        mmcsd_dbg("read_block %d, %d\n", dat->blkcnt, dat->blksz);
+        ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+    }
+    else if (dat->flag & DATA_DIR_WRITE)
+    {
+        cmd->datarw = DATA_WRITE;
+        ret = raspi_transfer_command(pdat, cmd);
+        if (ret)
+        {
+            return ret;
+        }
+        mmcsd_dbg("write_block %d, %d", dat->blkcnt, dat->blksz);
+        ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+    }
+    return ret;
+}
+
+static rt_err_t sdhci_transfer(struct sdhci_t *sdhci, struct sdhci_cmd_t *cmd, struct sdhci_data_t *dat)
+{
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)sdhci->priv;
+    if (!dat)
+    {
+        return raspi_transfer_command(pdat, cmd);
+    }
+
+    return raspi_transfer_data(pdat, cmd, dat);
+}
+
+static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
+{
+    struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
+    struct sdhci_cmd_t cmd;
+    struct sdhci_cmd_t stop;
+    struct sdhci_data_t dat;
+    rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t));
+    rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t));
+    rt_memset(&dat, 0, sizeof(struct sdhci_data_t));
+
+    cmd.cmdidx = req->cmd->cmd_code;
+    cmd.cmdarg = req->cmd->arg;
+    cmd.resptype = resp_type(req->cmd);
+    if (req->data)
+    {
+        dat.buf = (rt_uint8_t *)req->data->buf;
+        dat.flag = req->data->flags;
+        dat.blksz = req->data->blksize;
+        dat.blkcnt = req->data->blks;
+
+        req->cmd->err = sdhci_transfer(sdhci, &cmd, &dat);
+    }
+    else
+    {
+        req->cmd->err = sdhci_transfer(sdhci, &cmd, RT_NULL);
+    }
+
+    req->cmd->resp[3] = cmd.response[3];
+    req->cmd->resp[2] = cmd.response[2];
+    req->cmd->resp[1] = cmd.response[1];
+    req->cmd->resp[0] = cmd.response[0];
+
+    if (req->stop)
+    {
+        stop.cmdidx = req->stop->cmd_code;
+        stop.cmdarg = req->stop->arg;
+        cmd.resptype = resp_type(req->stop);
+        req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
+    }
+
+    mmcsd_req_complete(host);
+}
+
+rt_int32_t mmc_card_status(struct rt_mmcsd_host *host)
+{
+    return 0;
+}
+
+static rt_err_t sdhci_detect(struct sdhci_t *sdhci)
+{
+    return RT_EOK;
+}
+
+static rt_err_t sdhci_setwidth(struct sdhci_t *sdhci, rt_uint32_t width)
+{
+    rt_uint32_t temp = 0;
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)sdhci->priv;
+    if (width == MMCSD_BUS_WIDTH_4)
+    {
+        temp = read32((pdat->virt + EMMC_CONTROL0));
+        temp |= C0_HCTL_HS_EN;
+        temp |= C0_HCTL_DWITDH;   // always use 4 data lines:
+        write32((pdat->virt + EMMC_CONTROL0), temp);
+    }
+    return RT_EOK;
+}
+
+
+static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer, rt_uint32_t base_clock, rt_uint32_t target_rate)
+{
+    rt_uint32_t targetted_divisor = 0;
+    rt_uint32_t freq_select = 0;
+    rt_uint32_t upper_bits = 0;
+    rt_uint32_t ret = 0;
+    int divisor = -1;
+
+    if (target_rate > base_clock)
+    {
+        targetted_divisor = 1;
+    }
+    else
+    {
+        targetted_divisor = base_clock / target_rate;
+        rt_uint32_t mod = base_clock % target_rate;
+        if (mod)
+        {
+            targetted_divisor--;
+        }
+    }
+
+    // Decide on the clock mode to use
+
+    // Currently only 10-bit divided clock mode is supported
+
+    // HCI version 3 or greater supports 10-bit divided clock mode
+    // This requires a power-of-two divider
+
+    // Find the first bit set
+    for (int first_bit = 31; first_bit >= 0; first_bit--)
+    {
+        rt_uint32_t bit_test = (1 << first_bit);
+        if (targetted_divisor & bit_test)
+        {
+            divisor = first_bit;
+            targetted_divisor &= ~bit_test;
+            if (targetted_divisor)
+            {
+                // The divisor is not a power-of-two, increase it
+                divisor++;
+            }
+            break;
+        }
+    }
+
+    if (divisor == -1)
+    {
+        divisor = 31;
+    }
+    if (divisor >= 32)
+    {
+        divisor = 31;
+    }
+
+    if (divisor != 0)
+    {
+        divisor = (1 << (divisor - 1));
+    }
+
+    if (divisor >= 0x400)
+    {
+        divisor = 0x3ff;
+    }
+
+    freq_select = divisor & 0xff;
+    upper_bits = (divisor >> 8) & 0x3;
+    ret = (freq_select << 8) | (upper_bits << 6) | (0 << 5);
+
+    return ret;
+}
+
+static rt_err_t sdhci_setclock(struct sdhci_t *sdhci, rt_uint32_t clock)
+{
+    rt_uint32_t temp = 0;
+    rt_uint32_t sdHostVer = 0;
+    int count = 100000;
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)(sdhci->priv);
+
+    while ((read32(pdat->virt + EMMC_STATUS) & (SR_CMD_INHIBIT | SR_DAT_INHIBIT)) && (--count))
+    {
+        DELAY_MICROS(1);
+    }
+    if (count <= 0)
+    {
+        rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n", read32(pdat->virt + EMMC_STATUS));
+        return RT_ERROR;
+    }
+
+    // Switch clock off.
+    temp = read32((pdat->virt + EMMC_CONTROL1));
+    temp &= ~C1_CLK_EN;
+    write32((pdat->virt + EMMC_CONTROL1), temp);
+    DELAY_MICROS(10);
+    // Request the new clock setting and enable the clock
+    temp = read32(pdat->virt + EMMC_SLOTISR_VER);
+    sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
+    int cdiv = sd_get_clock_divider(sdHostVer, mmc_base_clock, clock);
+    temp = read32((pdat->virt + EMMC_CONTROL1));
+    temp |= 1;
+    temp |= cdiv;
+    temp |= (7 << 16);
+
+    temp = (temp & 0xffff003f) | cdiv;
+    write32((pdat->virt + EMMC_CONTROL1), temp);
+    DELAY_MICROS(10);
+
+    // Enable the clock.
+    temp = read32(pdat->virt + EMMC_CONTROL1);
+    temp |= C1_CLK_EN;
+    write32((pdat->virt + EMMC_CONTROL1), temp);
+    DELAY_MICROS(10);
+
+    // wait for clock to be stable.
+    count = 10000;
+    while (!(read32(pdat->virt + EMMC_CONTROL1) & C1_CLK_STABLE) && count--)
+    {
+        DELAY_MICROS(10);
+    }
+
+    if (count <= 0)
+    {
+        rt_kprintf("EMMC: ERROR: failed to get stable clock %d.\n", clock);
+        return RT_ERROR;
+    }
+
+    mmcsd_dbg("set stable clock %d.\n", clock);
+    return RT_EOK;
+}
+
+static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
+{
+    struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
+    sdhci_setclock(sdhci, io_cfg->clock);
+    sdhci_setwidth(sdhci, io_cfg->bus_width);
+}
+
+static const struct rt_mmcsd_host_ops ops =
+{
+    mmc_request_send,
+    mmc_set_iocfg,
+    RT_NULL,
+    RT_NULL,
+};
+
+static rt_err_t reset_emmc(struct sdhci_pdata_t *pdat)
+{
+    rt_uint32_t control1;
+    int cnt = 10000;
+
+    /* reset the controller */
+    control1 = read32((pdat->virt + EMMC_CONTROL1));
+    control1 |= (1 << 24);
+    /* disable clock */
+    control1 &= ~(1 << 2);
+    control1 &= ~(1 << 0);
+    /* temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX; */
+    write32((pdat->virt + EMMC_CONTROL1), control1);
+
+    do
+    {
+        DELAY_MICROS(10);
+        --cnt;
+        if (cnt == 0)
+        {
+            break;
+        }
+    }
+    while ((read32(pdat->virt + EMMC_CONTROL1) & (0x7 << 24)) != 0);
+
+    // Enable SD Bus Power VDD1 at 3.3V
+    rt_uint32_t control0 = read32(pdat->virt + EMMC_CONTROL0);
+    control0 |= 0x0F << 8;
+    write32(pdat->virt + EMMC_CONTROL0, control0);
+
+    rt_thread_delay(100);
+
+    /* check for a valid card */
+    mmcsd_dbg("EMMC: checking for an inserted card\n");
+    cnt = 10000;
+
+    do
+    {
+        DELAY_MICROS(10);
+        --cnt;
+        if (cnt == 0)
+        {
+            break;
+        }
+    }
+    while ((read32(pdat->virt + EMMC_STATUS) & (0x1 << 16)) == 0);
+
+    rt_uint32_t status_reg = read32(pdat->virt + EMMC_STATUS);
+
+    if ((status_reg & (1 << 16)) == 0)
+    {
+        rt_kprintf("EMMC: no card inserted\n");
+        return -1;
+    }
+    else
+    {
+        mmcsd_dbg("EMMC: status: %08x\n", status_reg);
+    }
+
+    /* clear control2 */
+    write32(pdat->virt + EMMC_CONTROL2, 0);
+    /* get the base clock rate */
+    mmc_base_clock = bcm271x_mbox_clock_get_rate(EMMC_CLK_ID);
+    if (mmc_base_clock == 0)
+    {
+        rt_kprintf("EMMC: assuming clock rate to be 100MHz\n");
+        mmc_base_clock = 100000000;
+    }
+    mmcsd_dbg("EMMC: setting clock rate is %d\n", mmc_base_clock);
+
+    return RT_EOK;
+}
+
+#ifdef RT_MMCSD_DBG
+void dump_registers(struct sdhci_pdata_t *pdat)
+{
+    int i = EMMC_ARG2;
+
+    rt_kprintf("EMMC registers:");
+    for (; i <= EMMC_CONTROL2; i += 4)
+    {
+        rt_kprintf("\t%x:%x\n", i, read32(pdat->virt + i));
+    }
+    rt_kprintf("\t%x:%x\n", 0x50, read32(pdat->virt + 0x50));
+    rt_kprintf("\t%x:%x\n", 0x70, read32(pdat->virt + 0x70));
+    rt_kprintf("\t%x:%x\n", 0x74, read32(pdat->virt + 0x74));
+    rt_kprintf("\t%x:%x\n", 0x80, read32(pdat->virt + 0x80));
+    rt_kprintf("\t%x:%x\n", 0x84, read32(pdat->virt + 0x84));
+    rt_kprintf("\t%x:%x\n", 0x88, read32(pdat->virt + 0x88));
+    rt_kprintf("\t%x:%x\n", 0x8c, read32(pdat->virt + 0x8c));
+    rt_kprintf("\t%x:%x\n", 0x90, read32(pdat->virt + 0x90));
+    rt_kprintf("\t%x:%x\n", 0xf0, read32(pdat->virt + 0xf0));
+    rt_kprintf("\t%x:%x\n", 0xfc, read32(pdat->virt + 0xfc));
+}
+#endif
+
+int raspi_sdmmc_init(void)
+{
+    size_t virt;
+    struct rt_mmcsd_host *host = RT_NULL;
+    struct sdhci_pdata_t *pdat = RT_NULL;
+    struct sdhci_t *sdhci = RT_NULL;
+
+#ifdef BSP_USING_SDIO0
+    host = mmcsd_alloc_host();
+    if (!host)
+    {
+        rt_kprintf("alloc host failed");
+        goto err;
+    }
+    sdhci = rt_malloc(sizeof(struct sdhci_t));
+    if (!sdhci)
+    {
+        rt_kprintf("alloc sdhci failed");
+        goto err;
+    }
+    rt_memset(sdhci, 0, sizeof(struct sdhci_t));
+
+    virt = MMC2_BASE_ADDR;
+    pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
+    RT_ASSERT(pdat != RT_NULL);
+
+    pdat->virt = virt;
+    reset_emmc(pdat);
+    sdhci->name = "sd0";
+    sdhci->voltages = VDD_33_34;
+    sdhci->width = MMCSD_BUSWIDTH_4;
+    sdhci->clock = 1000 * 1000 * 1000;
+    sdhci->removeable = RT_TRUE;
+
+    sdhci->detect = sdhci_detect;
+    sdhci->setwidth = sdhci_setwidth;
+    sdhci->setclock = sdhci_setclock;
+    sdhci->transfer = sdhci_transfer;
+    sdhci->priv = pdat;
+    host->ops = &ops;
+    host->freq_min = 400000;
+    host->freq_max = 50000000;
+    host->valid_ocr = VDD_32_33 | VDD_33_34;
+    host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
+    host->max_seg_size = 2048;
+    host->max_dma_segs = 10;
+    host->max_blk_size = 512;
+    host->max_blk_count = 1;
+
+    host->private_data = sdhci;
+    write32((pdat->virt + EMMC_IRPT_EN), 0xffffffff);
+    write32((pdat->virt + EMMC_IRPT_MASK), 0xffffffff);
+
+#ifdef RT_MMCSD_DBG
+    dump_registers(pdat);
+#endif
+    mmcsd_change(host);
+#endif
+    return RT_EOK;
+err:
+    if (host)  rt_free(host);
+    if (sdhci) rt_free(sdhci);
+
+    return -RT_EIO;
+}
+
+INIT_DEVICE_EXPORT(raspi_sdmmc_init);

+ 268 - 0
bsp/raspberry-pi/raspi4-64/driver/drv_sdio.h

@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-10-27     bigmagic       first version
+ */
+
+#ifndef __DRV_SDIO_H__
+#define __DRV_SDIO_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/mmcsd_core.h>
+
+#include "board.h"
+#include "raspi4.h"
+
+/* Struct for Intrrrupt Information */
+#define SDXC_CmdDone       BIT(0)
+#define SDXC_DataDone      BIT(1)
+#define SDXC_BlockGap      BIT(2)
+#define SDXC_WriteRdy      BIT(4)
+#define SDXC_ReadRdy       BIT(5)
+#define SDXC_Card          BIT(8)
+#define SDXC_Retune        BIT(12)
+#define SDXC_BootAck       BIT(13)
+#define SDXC_EndBoot       BIT(14)
+#define SDXC_Err           BIT(15)
+#define SDXC_CTOErr        BIT(16)
+#define SDXC_CCRCErr       BIT(17)
+#define SDXC_CENDErr       BIT(18)
+#define SDXC_CBADErr       BIT(19)
+#define SDXC_DTOErr        BIT(20)
+#define SDXC_DCRCErr       BIT(21)
+#define SDXC_DENDErr       BIT(22)
+#define SDXC_ACMDErr       BIT(24)
+
+#define SDXC_BLKCNT_EN          BIT(1)
+#define SDXC_AUTO_CMD12_EN      BIT(2)
+#define SDXC_AUTO_CMD23_EN      BIT(3)
+#define SDXC_DAT_DIR            BIT(4)   // from card to host
+#define SDXC_MULTI_BLOCK        BIT(5)
+#define SDXC_CMD_RSPNS_136      BIT(16)
+#define SDXC_CMD_RSPNS_48       BIT(17)
+#define SDXC_CMD_RSPNS_48busy   BIT(16)|BIT(17)
+#define SDXC_CHECK_CRC_CMD      BIT(19)
+#define SDXC_CMD_IXCHK_EN       BIT(20)
+#define SDXC_CMD_ISDATA         BIT(21)
+#define SDXC_CMD_SUSPEND        BIT(22)
+#define SDXC_CMD_RESUME         BIT(23)
+#define SDXC_CMD_ABORT          BIT(23)|BIT(22)
+
+#define SDXC_CMD_INHIBIT        BIT(0)
+#define SDXC_DAT_INHIBIT        BIT(1)
+#define SDXC_DAT_ACTIVE         BIT(2)
+#define SDXC_WRITE_TRANSFER     BIT(8)
+#define SDXC_READ_TRANSFER      BIT(9)
+
+struct sdhci_cmd_t
+{
+    rt_uint32_t cmdidx;
+    rt_uint32_t cmdarg;
+    rt_uint32_t resptype;
+    rt_uint32_t datarw;
+#define DATA_READ 1
+#define DATA_WRITE 2
+    rt_uint32_t response[4];
+};
+
+struct sdhci_data_t
+{
+    rt_uint8_t *buf;
+    rt_uint32_t flag;
+    rt_uint32_t blksz;
+    rt_uint32_t blkcnt;
+};
+
+struct sdhci_t
+{
+    char *name;
+    rt_uint32_t voltages;
+    rt_uint32_t width;
+    rt_uint32_t clock;
+    rt_err_t removeable;
+    void *sdcard;
+
+    rt_err_t (*detect)(struct sdhci_t *sdhci);
+    rt_err_t (*setwidth)(struct sdhci_t *sdhci, rt_uint32_t width);
+    rt_err_t (*setclock)(struct sdhci_t *sdhci, rt_uint32_t clock);
+    rt_err_t (*transfer)(struct sdhci_t *sdhci, struct sdhci_cmd_t *cmd, struct sdhci_data_t *dat);
+    void *priv;
+};
+
+struct sdhci_pdata_t
+{
+    size_t virt;
+};
+
+// EMMC command flags
+#define CMD_TYPE_NORMAL     (0x00000000)
+#define CMD_TYPE_SUSPEND    (0x00400000)
+#define CMD_TYPE_RESUME     (0x00800000)
+#define CMD_TYPE_ABORT      (0x00c00000)
+#define CMD_IS_DATA         (0x00200000)
+#define CMD_IXCHK_EN        (0x00100000)
+#define CMD_CRCCHK_EN       (0x00080000)
+#define CMD_RSPNS_NO        (0x00000000)
+#define CMD_RSPNS_136       (0x00010000)
+#define CMD_RSPNS_48        (0x00020000)
+#define CMD_RSPNS_48B       (0x00030000)
+#define TM_MULTI_BLOCK      (0x00000020)
+#define TM_DAT_DIR_HC       (0x00000000)
+#define TM_DAT_DIR_CH       (0x00000010)
+#define TM_AUTO_CMD23       (0x00000008)
+#define TM_AUTO_CMD12       (0x00000004)
+#define TM_BLKCNT_EN        (0x00000002)
+#define TM_MULTI_DATA       (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
+
+#define RCA_NO              (1)
+#define RCA_YES             (2)
+
+// INTERRUPT register settings
+#define INT_AUTO_ERROR      (0x01000000)
+#define INT_DATA_END_ERR    (0x00400000)
+#define INT_DATA_CRC_ERR    (0x00200000)
+#define INT_DATA_TIMEOUT    (0x00100000)
+#define INT_INDEX_ERROR     (0x00080000)
+#define INT_END_ERROR       (0x00040000)
+#define INT_CRC_ERROR       (0x00020000)
+#define INT_CMD_TIMEOUT     (0x00010000)
+#define INT_ERR             (0x00008000)
+#define INT_ENDBOOT         (0x00004000)
+#define INT_BOOTACK         (0x00002000)
+#define INT_RETUNE          (0x00001000)
+#define INT_CARD            (0x00000100)
+#define INT_READ_RDY        (0x00000020)
+#define INT_WRITE_RDY       (0x00000010)
+#define INT_BLOCK_GAP       (0x00000004)
+#define INT_DATA_DONE       (0x00000002)
+#define INT_CMD_DONE        (0x00000001)
+#define INT_ERROR_MASK \
+( \
+    INT_CRC_ERROR | \
+    INT_END_ERROR | \
+    INT_INDEX_ERROR | \
+    INT_DATA_TIMEOUT | \
+    INT_DATA_CRC_ERR | \
+    INT_DATA_END_ERR | \
+    INT_ERR|INT_AUTO_ERROR \
+)
+
+#define INT_ALL_MASK \
+(\
+    INT_CMD_DONE | \
+    INT_DATA_DONE | \
+    INT_READ_RDY | \
+    INT_WRITE_RDY | \
+    INT_ERROR_MASK \
+)
+
+#define EMMC_ARG2           (0x00)
+#define EMMC_BLKSIZECNT     (0x04)
+#define EMMC_ARG1           (0x08)
+#define EMMC_CMDTM          (0x0c)
+#define EMMC_RESP0          (0x10)
+#define EMMC_RESP1          (0x14)
+#define EMMC_RESP2          (0x18)
+#define EMMC_RESP3          (0x1c)
+#define EMMC_DATA           (0x20)
+#define EMMC_STATUS         (0x24)
+#define EMMC_CONTROL0       (0x28)
+#define EMMC_CONTROL1       (0x2c)
+#define EMMC_INTERRUPT      (0x30)
+#define EMMC_IRPT_MASK      (0x34)
+#define EMMC_IRPT_EN        (0x38)
+#define EMMC_CONTROL2       (0x3c)
+#define EMMC_CAPABILITIES_0 (0x40)
+#define EMMC_CAPABILITIES_1 (0x44)
+#define EMMC_BOOT_TIMEOUT   (0x70)
+#define EMMC_EXRDFIFO_EN    (0x84)
+#define EMMC_SPI_INT_SPT    (0xf0)
+#define EMMC_SLOTISR_VER    (0xfc)
+
+// CONTROL register settings
+#define C0_SPI_MODE_EN      (0x00100000)
+#define C0_HCTL_HS_EN       (0x00000004)
+#define C0_HCTL_DWITDH      (0x00000002)
+
+#define C1_SRST_DATA        (0x04000000)
+#define C1_SRST_CMD         (0x02000000)
+#define C1_SRST_HC          (0x01000000)
+#define C1_TOUNIT_DIS       (0x000f0000)
+#define C1_TOUNIT_MAX       (0x000e0000)
+#define C1_CLK_GENSEL       (0x00000020)
+#define C1_CLK_EN           (0x00000004)
+#define C1_CLK_STABLE       (0x00000002)
+#define C1_CLK_INTLEN       (0x00000001)
+
+#define FREQ_SETUP          (400000)    // 400 Khz
+#define FREQ_NORMAL         (25000000)  // 25 Mhz
+
+// SLOTISR_VER values
+#define HOST_SPEC_NUM       0x00ff0000
+#define HOST_SPEC_NUM_SHIFT 16
+#define HOST_SPEC_V3        2
+#define HOST_SPEC_V2        1
+#define HOST_SPEC_V1        0
+
+// STATUS register settings
+#define SR_DAT_LEVEL1       (0x1e000000)
+#define SR_CMD_LEVEL        (0x01000000)
+#define SR_DAT_LEVEL0       (0x00f00000)
+#define SR_DAT3             (0x00800000)
+#define SR_DAT2             (0x00400000)
+#define SR_DAT1             (0x00200000)
+#define SR_DAT0             (0x00100000)
+#define SR_WRITE_PROT       (0x00080000)  // From SDHC spec v2, BCM says reserved
+#define SR_READ_AVAILABLE   (0x00000800)  // ???? undocumented
+#define SR_WRITE_AVAILABLE  (0x00000400)  // ???? undocumented
+#define SR_READ_TRANSFER    (0x00000200)
+#define SR_WRITE_TRANSFER   (0x00000100)
+#define SR_DAT_ACTIVE       (0x00000004)
+#define SR_DAT_INHIBIT      (0x00000002)
+#define SR_CMD_INHIBIT      (0x00000001)
+
+#define CONFIG_MMC_USE_DMA
+#define DMA_ALIGN                   (32U)
+
+#define SD_CMD_INDEX(a)             ((a) << 24)
+#define SD_CMD_RESERVED(a)          (0xffffffff)
+#define SD_CMD_INDEX(a)             ((a) << 24)
+#define SD_CMD_TYPE_NORMAL          (0x0)
+#define SD_CMD_TYPE_SUSPEND         (1 << 22)
+#define SD_CMD_TYPE_RESUME          (2 << 22)
+#define SD_CMD_TYPE_ABORT           (3 << 22)
+#define SD_CMD_TYPE_MASK            (3 << 22)
+#define SD_CMD_ISDATA               (1 << 21)
+#define SD_CMD_IXCHK_EN             (1 << 20)
+#define SD_CMD_CRCCHK_EN            (1 << 19)
+#define SD_CMD_RSPNS_TYPE_NONE      (0)         // For no response
+#define SD_CMD_RSPNS_TYPE_136       (1 << 16)   // For response R2 (with CRC), R3,4 (no CRC)
+#define SD_CMD_RSPNS_TYPE_48        (2 << 16)   // For responses R1, R5, R6, R7 (with CRC)
+#define SD_CMD_RSPNS_TYPE_48B       (3 << 16)   // For responses R1b, R5b (with CRC)
+#define SD_CMD_RSPNS_TYPE_MASK      (3 << 16)
+#define SD_CMD_MULTI_BLOCK          (1 << 5)
+#define SD_CMD_DAT_DIR_HC           (0)
+#define SD_CMD_DAT_DIR_CH           (1 << 4)
+#define SD_CMD_AUTO_CMD_EN_NONE     (0)
+#define SD_CMD_AUTO_CMD_EN_CMD12    (1 << 2)
+#define SD_CMD_AUTO_CMD_EN_CMD23    (2 << 2)
+#define SD_CMD_BLKCNT_EN            (1 << 1)
+#define SD_CMD_DMA                  (1)
+#define SD_RESP_NONE                SD_CMD_RSPNS_TYPE_NONE
+#define SD_RESP_R1                  (SD_CMD_RSPNS_TYPE_48)
+#define SD_RESP_R1b                 (SD_CMD_RSPNS_TYPE_48B)
+#define SD_RESP_R2                  (SD_CMD_RSPNS_TYPE_136)
+#define SD_RESP_R3                  SD_CMD_RSPNS_TYPE_48
+#define SD_RESP_R4                  SD_CMD_RSPNS_TYPE_136
+#define SD_RESP_R5                  (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R5b                 (SD_CMD_RSPNS_TYPE_48B | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R6                  (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R7                  (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_DATA_READ                (SD_CMD_ISDATA | SD_CMD_DAT_DIR_CH)
+#define SD_DATA_WRITE               (SD_CMD_ISDATA | SD_CMD_DAT_DIR_HC)
+#endif

+ 246 - 31
bsp/raspberry-pi/raspi4-64/driver/drv_uart.c

@@ -22,6 +22,26 @@ struct hw_uart_device
     rt_uint32_t irqno;
 };
 
+#ifdef RT_USING_UART0
+static struct rt_serial_device _serial0;
+#endif
+
+#ifdef RT_USING_UART1
+static struct rt_serial_device _serial1;
+#endif
+
+#ifdef RT_USING_UART3
+static struct rt_serial_device _serial3;
+#endif
+
+#ifdef RT_USING_UART4
+static struct rt_serial_device _serial4;
+#endif
+
+#ifdef RT_USING_UART5
+static struct rt_serial_device _serial5;
+#endif
+
 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
 {
     struct hw_uart_device *uart;
@@ -30,26 +50,54 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
 
     RT_ASSERT(serial != RT_NULL);
     uart = (struct hw_uart_device *)serial->parent.user_data;
-    if(uart->hw_base == PL011_BASE)
+
+    if(uart->hw_base == AUX_BASE)
     {
-        uint32_t gpfsel = 0;
-
-        gpfsel &= ~((uint32_t)(0x07 << (4 * 3)));
-        gpfsel |= (uint32_t)(ALT0 << (4 * 3));
-        GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel;
-
-        gpfsel &= ~((uint32_t)(0x07 << (5 * 3)));
-        gpfsel |= (uint32_t)(ALT0 << (5 * 3));
-        GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel;
-
-        PL011_REG_CR(uart->hw_base) = 0;/*Clear UART setting*/
-        PL011_REG_LCRH(uart->hw_base) = 0;/*disable FIFO*/
-        PL011_REG_IBRD(uart->hw_base) = ibrd;
-        PL011_REG_FBRD(uart->hw_base) = (((bauddiv - ibrd * 1000) * 64 + 500) / 1000);
-        PL011_REG_LCRH(uart->hw_base) = PL011_LCRH_WLEN_8;/*FIFO*/
-        PL011_REG_CR(uart->hw_base) = PL011_CR_UARTEN | PL011_CR_TXE | PL011_CR_RXE;/*art enable, TX/RX enable*/
+        prev_raspi_pin_mode(GPIO_PIN_14, ALT5);
+        prev_raspi_pin_mode(GPIO_PIN_15, ALT5);
+
+        AUX_ENABLES(uart->hw_base)      = 1;    /* Enable UART1 */
+        AUX_MU_IER_REG(uart->hw_base)   = 0;    /* Disable interrupt */
+        AUX_MU_CNTL_REG(uart->hw_base)  = 0;    /* Disable Transmitter and Receiver */
+        AUX_MU_LCR_REG(uart->hw_base)   = 3;    /* Works in 8-bit mode */
+        AUX_MU_MCR_REG(uart->hw_base)   = 0;    /* Disable RTS */
+        AUX_MU_IIR_REG(uart->hw_base)   = 0xC6; /* Enable FIFO, Clear FIFO */
+        AUX_MU_BAUD_REG(uart->hw_base)  = 270;  /* 115200 = system clock 250MHz / (8 * (baud + 1)), baud = 270 */
+        AUX_MU_CNTL_REG(uart->hw_base)  = 3;    /* Enable Transmitter and Receiver */
+        return RT_EOK;
     }
 
+    if(uart->hw_base == UART0_BASE)
+    {
+        prev_raspi_pin_mode(GPIO_PIN_14, ALT0);
+        prev_raspi_pin_mode(GPIO_PIN_15, ALT0);
+    }
+
+    if(uart->hw_base == UART3_BASE)
+    {
+        prev_raspi_pin_mode(GPIO_PIN_4, ALT4);
+        prev_raspi_pin_mode(GPIO_PIN_5, ALT4);
+    }
+
+    if(uart->hw_base == UART4_BASE)
+    {
+        prev_raspi_pin_mode(GPIO_PIN_8, ALT4);
+        prev_raspi_pin_mode(GPIO_PIN_9, ALT4);
+    }
+
+    if(uart->hw_base == UART5_BASE)
+    {
+        prev_raspi_pin_mode(GPIO_PIN_12, ALT4);
+        prev_raspi_pin_mode(GPIO_PIN_13, ALT4);
+    }
+
+    PL011_REG_CR(uart->hw_base) = 0;/*Clear UART setting*/
+    PL011_REG_LCRH(uart->hw_base) = 0;/*disable FIFO*/
+    PL011_REG_IBRD(uart->hw_base) = ibrd;
+    PL011_REG_FBRD(uart->hw_base) = (((bauddiv - ibrd * 1000) * 64 + 500) / 1000);
+    PL011_REG_LCRH(uart->hw_base) = PL011_LCRH_WLEN_8;/*FIFO*/
+    PL011_REG_CR(uart->hw_base) = PL011_CR_UARTEN | PL011_CR_TXE | PL011_CR_RXE;/*art enable, TX/RX enable*/
+
     return RT_EOK;
 }
 
@@ -70,7 +118,14 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg
 
     case RT_DEVICE_CTRL_SET_INT:
         /* enable rx irq */
-        PL011_REG_IMSC(uart->hw_base) |= PL011_IMSC_RXIM;
+        if(uart->hw_base == AUX_BASE)
+        {
+            AUX_MU_IER_REG(uart->hw_base) = 0x1;
+        }
+        else
+        {
+            PL011_REG_IMSC(uart->hw_base) |= PL011_IMSC_RXIM;
+        }
         rt_hw_interrupt_umask(uart->irqno);
         break;
     }
@@ -85,8 +140,16 @@ static int uart_putc(struct rt_serial_device *serial, char c)
     RT_ASSERT(serial != RT_NULL);
     uart = (struct hw_uart_device *)serial->parent.user_data;
 
-    while ((PL011_REG_FR(uart->hw_base) & PL011_FR_TXFF));
-    PL011_REG_DR(uart->hw_base) = (uint8_t)c;
+    if(uart->hw_base == AUX_BASE)
+    {
+        while (!(AUX_MU_LSR_REG(uart->hw_base) & 0x20));
+        AUX_MU_IO_REG(uart->hw_base) = c;
+    }
+    else
+    {
+        while ((PL011_REG_FR(uart->hw_base) & PL011_FR_TXFF));
+        PL011_REG_DR(uart->hw_base) = (uint8_t)c;
+    }
 
     return 1;
 }
@@ -99,9 +162,19 @@ static int uart_getc(struct rt_serial_device *serial)
     RT_ASSERT(serial != RT_NULL);
     uart = (struct hw_uart_device *)serial->parent.user_data;
 
-    if((PL011_REG_FR(uart->hw_base) & PL011_FR_RXFE) == 0)
+    if(uart->hw_base == AUX_BASE)
+    {
+        if ((AUX_MU_LSR_REG(uart->hw_base) & 0x01))
+        {
+            ch = AUX_MU_IO_REG(uart->hw_base) & 0xff;
+        }
+    }
+    else
     {
-        ch = PL011_REG_DR(uart->hw_base) & 0xff;
+        if((PL011_REG_FR(uart->hw_base) & PL011_FR_RXFE) == 0)
+        {
+            ch = PL011_REG_DR(uart->hw_base) & 0xff;
+        }
     }
 
     return ch;
@@ -115,38 +188,180 @@ static const struct rt_uart_ops _uart_ops =
     uart_getc,
 };
 
-static void rt_hw_uart_isr(int irqno, void *param)
+#ifdef RT_USING_UART1
+static void rt_hw_aux_uart_isr(int irqno, void *param)
 {
     struct rt_serial_device *serial = (struct rt_serial_device*)param;
     rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
-    PL011_REG_ICR(UART0_BASE) = PL011_INTERRUPT_RECEIVE;
 }
+#endif
+
+static void rt_hw_uart_isr(int irqno, void *param)
+{
+#ifdef RT_USING_UART0
+    if((PACTL_CS & IRQ_UART0) == IRQ_UART0)
+    {
+        PACTL_CS &=  ~(IRQ_UART0);
+        rt_hw_serial_isr(&_serial0, RT_SERIAL_EVENT_RX_IND);
+        PL011_REG_ICR(UART0_BASE) = PL011_INTERRUPT_RECEIVE;
+    }
+#endif
+
+#ifdef RT_USING_UART3
+    if((PACTL_CS & IRQ_UART3) == IRQ_UART3)
+    {
+        PACTL_CS &=  ~(IRQ_UART3);
+        rt_hw_serial_isr(&_serial3, RT_SERIAL_EVENT_RX_IND);
+        PL011_REG_ICR(uart3_addr) = PL011_INTERRUPT_RECEIVE;
+    }
+#endif
+
+#ifdef RT_USING_UART4
+    if((PACTL_CS & IRQ_UART4) == IRQ_UART4)
+    {
+        PACTL_CS &=  ~(IRQ_UART4);
+        rt_hw_serial_isr(&_serial4, RT_SERIAL_EVENT_RX_IND);
+        PL011_REG_ICR(uart4_addr) = PL011_INTERRUPT_RECEIVE;
+    }
+#endif
 
+#ifdef RT_USING_UART5
+    if((PACTL_CS & IRQ_UART5) == IRQ_UART5)
+    {
+        PACTL_CS &=  ~(IRQ_UART5);
+        rt_hw_serial_isr(&_serial5, RT_SERIAL_EVENT_RX_IND);
+        PL011_REG_ICR(uart5_addr) = PL011_INTERRUPT_RECEIVE;
+    }
+#endif
+}
 
+#ifdef RT_USING_UART0
 /* UART device driver structure */
 static struct hw_uart_device _uart0_device =
 {
-    PL011_BASE,
+    UART0_BASE,
     IRQ_PL011,
 };
+#endif
+
+#ifdef RT_USING_UART1
+/* UART device driver structure */
+static struct hw_uart_device _uart1_device =
+{
+    AUX_BASE,
+    IRQ_AUX_UART,
+};
+#endif
+
+#ifdef RT_USING_UART3
+static struct hw_uart_device _uart3_device =
+{
+    UART3_BASE,
+    IRQ_PL011,
+};
+#endif
+
+#ifdef RT_USING_UART4
+static struct hw_uart_device _uart4_device =
+{
+    UART4_BASE,
+    IRQ_PL011,
+};
+#endif
+
+#ifdef RT_USING_UART5
+static struct hw_uart_device _uart5_device =
+{
+    UART5_BASE,
+    IRQ_PL011,
+};
+#endif
 
 static struct rt_serial_device _serial0;
 
 int rt_hw_uart_init(void)
 {
-    struct hw_uart_device *uart;
     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
-
-    uart = &_uart0_device;
+#ifdef RT_USING_UART0
+    struct hw_uart_device *uart0;
+    uart0 = &_uart0_device;
 
     _serial0.ops    = &_uart_ops;
     _serial0.config = config;
 
+    uart0->hw_base = UART0_BASE;
+
+
+    /* register UART0 device */
+    rt_hw_serial_register(&_serial0, "uart0",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart0);
+    rt_hw_interrupt_install(uart0->irqno, rt_hw_uart_isr, &_serial0, "uart0");
+
+#endif
+
+#ifdef RT_USING_UART1
+    struct hw_uart_device *uart1;
+    uart1 = &_uart1_device;
+
+    _serial1.ops    = &_uart_ops;
+    _serial1.config = config;
+
+    uart1->hw_base = AUX_BASE;
+
     /* register UART1 device */
-    rt_hw_serial_register(&_serial0, "uart",
+    rt_hw_serial_register(&_serial1, "uart1",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart1);
+    rt_hw_interrupt_install(uart1->irqno, rt_hw_aux_uart_isr, &_serial1, "uart1");
+#endif
+
+#ifdef RT_USING_UART3
+    struct hw_uart_device *uart3;
+    uart3 = &_uart3_device;
+
+    _serial3.ops    = &_uart_ops;
+    _serial3.config = config;
+
+    uart3_addr = UART3_BASE;
+
+    /* register UART3 device */
+    rt_hw_serial_register(&_serial3, "uart3",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart3);
+    rt_hw_interrupt_install(uart3->irqno, rt_hw_uart_isr, &_serial3, "uart3");
+#endif
+
+#ifdef RT_USING_UART4
+    struct hw_uart_device *uart4;
+    uart4 = &_uart4_device;
+
+    _serial4.ops    = &_uart_ops;
+    _serial4.config = config;
+
+    uart4_addr = UART4_BASE;
+
+    /* register UART4 device */
+    rt_hw_serial_register(&_serial4, "uart4",
                           RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
-                          uart);
-    rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart");
+                          uart4);
+    rt_hw_interrupt_install(uart4->irqno, rt_hw_uart_isr, &_serial4, "uart4");
+#endif
+
+#ifdef RT_USING_UART5
+    struct hw_uart_device *uart5;
+    uart5 = &_uart5_device;
+
+    _serial5.ops    = &_uart_ops;
+    _serial5.config = config;
 
+    uart5_addr = UART5_BASE;
+
+    /* register UART5 device */
+    rt_hw_serial_register(&_serial5, "uart5",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart5);
+    rt_hw_interrupt_install(uart5->irqno, rt_hw_uart_isr, &_serial5, "uart5");
+#endif
     return 0;
 }

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

@@ -78,6 +78,30 @@
 #define PL011_REG_ITOP(BASE)            HWREG32(BASE + 0x88)
 #define PL011_REG_TDR(BASE)             HWREG32(BASE + 0x8C)
 
+/*
+ *  Auxiliary
+ */
+#define AUX_IRQ(BASE)                   HWREG32(BASE + 0x00)   /* Auxiliary Interrupt status 3 */
+#define AUX_ENABLES(BASE)               HWREG32(BASE + 0x04)   /* Auxiliary enables 3bit */
+#define AUX_MU_IO_REG(BASE)             HWREG32(BASE + 0x40)   /* Mini Uart I/O Data 8bit */
+#define AUX_MU_IER_REG(BASE)            HWREG32(BASE + 0x44)   /* Mini Uart Interrupt Enable 8bit */
+#define AUX_MU_IIR_REG(BASE)            HWREG32(BASE + 0x48)   /* Mini Uart Interrupt Identify 8bit */
+#define AUX_MU_LCR_REG(BASE)            HWREG32(BASE + 0x4C)   /* Mini Uart Line Control 8bit */
+#define AUX_MU_MCR_REG(BASE)            HWREG32(BASE + 0x50)   /* Mini Uart Modem Control 8bit */
+#define AUX_MU_LSR_REG(BASE)            HWREG32(BASE + 0x54)   /* Mini Uart Line Status 8bit */
+#define AUX_MU_MSR_REG(BASE)            HWREG32(BASE + 0x58)   /* Mini Uart Modem Status 8bit */
+#define AUX_MU_SCRATCH(BASE)            HWREG32(BASE + 0x5C)   /* Mini Uart Scratch 8bit */
+#define AUX_MU_CNTL_REG(BASE)           HWREG32(BASE + 0x60)   /* Mini Uart Extra Control 8bit */
+#define AUX_MU_STAT_REG(BASE)           HWREG32(BASE + 0x64)   /* Mini Uart Extra Status 32bit */
+#define AUX_MU_BAUD_REG(BASE)           HWREG32(BASE + 0x68)   /* Mini Uart Baudrate 16bit */
+#define AUX_SPI0_CNTL0_REG(BASE)        HWREG32(BASE + 0x80)   /* SPI 1 Control register 0 32bit */
+#define AUX_SPI0_CNTL1_REG(BASE)        HWREG32(BASE + 0x84)   /* SPI 1 Control register 1 8bit */
+#define AUX_SPI0_STAT_REG(BASE)         HWREG32(BASE + 0x88)   /* SPI 1 Status 32bit */
+#define AUX_SPI0_IO_REG(BASE)           HWREG32(BASE + 0x90)   /* SPI 1 Data 32bit */
+#define AUX_SPI0_PEEK_REG(BASE)         HWREG32(BASE + 0x94)   /* SPI 1 Peek 16bit */
+#define AUX_SPI1_CNTL0_REG(BASE)        HWREG32(BASE + 0xC0)   /* SPI 2 Control register 0 32bit */
+#define AUX_SPI1_CNTL1_REG(BASE)        HWREG32(BASE + 0xC4)   /* SPI 2 Control register 1 8bit */
+
 int rt_hw_uart_init(void);
 
 #endif /* DRV_UART_H__ */

+ 519 - 0
bsp/raspberry-pi/raspi4-64/driver/mbox.c

@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ * 2020-09-10     bigmagic       add other mbox option
+ */
+
+/* mailbox message buffer */
+#include "mbox.h"
+#include "mmu.h"
+
+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
+ */
+int mbox_call(unsigned char ch, int mmu_enable)
+{
+    unsigned int r = (((MBOX_ADDR) & ~0xF) | (ch & 0xF));
+    if (mmu_enable)
+    {
+        r = BUS_ADDRESS(r);
+    }
+    /* wait until we can write to the mailbox */
+    do
+    {
+        __asm__ volatile ("nop");
+    }
+    while (*MBOX_STATUS & MBOX_FULL);
+    /* write the address of our message to the mailbox with channel identifier */
+    *MBOX_WRITE = r;
+    /* now wait for the response */
+    while (1)
+    {
+        /* is there a response? */
+        do
+        {
+            __asm__ volatile ("nop");
+        }
+        while (*MBOX_STATUS & MBOX_EMPTY);
+        /* is it a response to our message? */
+        if (r == *MBOX_READ)
+        {
+            /* is it a valid successful response? */
+            return mbox[1] == MBOX_RESPONSE;
+        }
+    }
+    return 0;
+}
+
+int bcm271x_mbox_get_touch(void)
+{
+    mbox[0] = 8 * 4;                    // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+
+    mbox[2] = MBOX_TAG_GET_TOUCHBUF;
+    mbox[3] = 4;                        // buffer size
+    mbox[4] = 0;                        // len
+
+    mbox[5] = 0;                       // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    return (int)(mbox[5] &  ~0xC0000000);
+}
+
+int bcm271x_notify_reboot(void)
+{
+    mbox[0] = 7 * 4;                        // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+    mbox[2] = MBOX_TAG_NOTIFY_REBOOT;       // (the tag id)
+    mbox[3] = 0x00000004;                   // length + 4
+    mbox[4] = 0x00000000;                   // size of the data
+    mbox[5] = 0x00000000;                   // request
+
+    mbox[6] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+    return 0;
+}
+
+int bcm271x_notify_xhci_reset(void)
+{
+    mbox[0] = 7 * 4;                        // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+    mbox[2] = MBOX_TAG_NOTIFY_XHCI_RESET;   // (the tag id)
+    mbox[3] = 0x00000004;                   // length + 4
+    mbox[4] = 0x00000004;                   // size of the data
+    mbox[5] = 0x00100000;                   // request
+    mbox[6] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+    return 0;
+}
+
+int bcm271x_gpu_enable(void)
+{
+    mbox[0] = 12 * 4;                        // length of the message
+    mbox[1] = MBOX_REQUEST;                  // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_SET_RATE;
+    mbox[3] = 0x00000008;                   // (the tag id)
+    mbox[4] = 0x00000008;                   // (the tag id)
+    mbox[5] = 5;                            // V3D
+    mbox[6] = 250 * 1000 * 1000;
+    mbox[7] = MBOX_TAG_ENABLE_QPU;                   // (the tag id)
+    mbox[8] = 0x00000004;                   // (size of the buffer)
+    mbox[9] = 0x00000004;                   // (size of the data)
+    mbox[10] = 0x00000001;
+    mbox[11] = MBOX_TAG_LAST;               // end tag
+    mbox_call(8, MMU_DISABLE);
+    return mbox[1];
+}
+
+int bcm271x_mbox_hardware_get_model(void)
+{
+    mbox[0] = 8 * 4;                        // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+
+    mbox[2] = MBOX_TAG_HARDWARE_GET_MODEL;
+    mbox[3] = 4;                            // buffer size
+    mbox[4] = 0;                            // len
+
+    mbox[5] = 0;
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    return mbox[5];
+}
+
+int bcm271x_mbox_hardware_get_revison(void)
+{
+    mbox[0] = 8 * 4;                        // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+
+    mbox[2] = MBOX_TAG_HARDWARE_GET_REV;
+    mbox[3] = 4;                            // buffer size
+    mbox[4] = 0;                            // len
+
+    mbox[5] = 0;
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    return mbox[5];
+}
+
+int bcm271x_mbox_hardware_get_mac_address(uint8_t *mac)
+{
+    mbox[0] = 8 * 4;                               // length of the message
+    mbox[1] = MBOX_REQUEST;                        // this is a request message
+
+    mbox[2] = MBOX_TAG_HARDWARE_GET_MAC_ADDRESS;
+    mbox[3] = 6;                                   // buffer size
+    mbox[4] = 0;                                   // len
+
+    mbox[5] = 0;
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    char *mac_str = (char *)&mbox[5];
+    mac[0] = mac_str[0];
+    mac[1] = mac_str[1];
+    mac[2] = mac_str[2];
+    mac[3] = mac_str[3];
+    mac[4] = mac_str[4];
+    mac[5] = mac_str[5];
+    return 0;
+}
+
+
+int bcm271x_mbox_hardware_get_serial(rt_uint64_t *sn)
+{
+    mbox[0] = 8 * 4;                            // length of the message
+    mbox[1] = MBOX_REQUEST;                     // this is a request message
+
+    mbox[2] = MBOX_TAG_HARDWARE_GET_SERIAL;
+    mbox[3] = 8;                                // buffer size
+    mbox[4] = 0;                                // len
+
+    mbox[5] = 0;
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    sn = (rt_uint64_t *)&mbox[5];
+
+    return 0;
+}
+
+int bcm271x_mbox_hardware_get_arm_memory(rt_uint32_t *base, rt_uint32_t *size)
+{
+    mbox[0] = 8 * 4;                                // length of the message
+    mbox[1] = MBOX_REQUEST;                         // this is a request message
+
+    mbox[2] = MBOX_TAG_HARDWARE_GET_ARM_MEMORY;
+    mbox[3] = 8;                                    // buffer size
+    mbox[4] = 0;                                    // len
+
+    mbox[5] = 0;
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    *base = mbox[5];
+    *size = mbox[6];
+
+    return 0;
+
+}
+
+int bcm271x_mbox_hardware_get_vc_memory(rt_uint32_t *base, rt_uint32_t *size)
+{
+    mbox[0] = 8 * 4;                             // length of the message
+    mbox[1] = MBOX_REQUEST;                      // this is a request message
+
+    mbox[2] = MBOX_TAG_HARDWARE_GET_VC_MEMORY;
+    mbox[3] = 8;                                 // buffer size
+    mbox[4] = 0;                                 // len
+
+    mbox[5] = 0;
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    *base = mbox[5];
+    *size = mbox[6];
+
+    return 0;
+}
+
+int bcm271x_mbox_clock_get_turbo(void)
+{
+    mbox[0] = 8 * 4;                    // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_GET_TURBO;
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 4;                        // len
+
+    mbox[5] = 0;                        // id
+    mbox[6] = 0;                        // val
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm271x_mbox_clock_set_turbo(int level)
+{
+    mbox[0] = 8 * 4;                    // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_SET_TURBO;
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 8;                        // len
+
+    mbox[5] = 0;                        // id
+    mbox[6] = level ? 1 : 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm271x_mbox_clock_get_state(int id)
+{
+    mbox[0] = 8 * 4;                     // length of the message
+    mbox[1] = MBOX_REQUEST;              // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_GET_STATE;
+    mbox[3] = 8;                         // buffer size
+    mbox[4] = 4;                         // len
+
+    mbox[5] = id;                        // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm271x_mbox_clock_set_state(int id, int state)
+{
+    mbox[0] = 8 * 4;                    // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_SET_STATE;
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 8;                        // len
+
+    mbox[5] = id;                       // id
+    mbox[6] = state & 0x3;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm271x_mbox_clock_get_rate(int id)
+{
+    mbox[0] = 8 * 4;                    // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_GET_RATE;
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 4;                        // len
+
+    mbox[5] = id;                       // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm271x_mbox_clock_set_rate(int id, int rate)
+{
+    mbox[0] = 8 * 4;                    // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_SET_RATE;
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 8;                        // len
+
+    mbox[5] = id;                       // id
+    mbox[6] = rate;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm271x_mbox_clock_get_max_rate(int id)
+{
+    mbox[0] = 8 * 4;                        // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_GET_MAX_RATE;
+    mbox[3] = 8;                            // buffer size
+    mbox[4] = 4;                            // len
+
+    mbox[5] = id;                           // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm271x_mbox_clock_get_min_rate(int id)
+{
+    mbox[0] = 8 * 4;                        // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+
+    mbox[2] = MBOX_TAG_CLOCK_GET_MIN_RATE;
+    mbox[3] = 8;                            // buffer size
+    mbox[4] = 4;                            // len
+
+    mbox[5] = id;                           // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm271x_mbox_power_get_state(int id)
+{
+    mbox[0] = 8 * 4;                // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+
+    mbox[2] = MBOX_TAG_POWER_GET_STATE;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 4;                    // len
+
+    mbox[5] = id;                   // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm271x_mbox_power_set_state(int id, int state)
+{
+    mbox[0] = 8 * 4;                // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+
+    mbox[2] = MBOX_TAG_POWER_SET_STATE;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 8;                    // len
+
+    mbox[5] = id;                    // id
+    mbox[6] = state & 0x3;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm271x_mbox_temp_get(void)
+{
+    mbox[0] = 8 * 4;                // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+
+    mbox[2] = MBOX_TAG_TEMP_GET;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 4;                    // len
+
+    mbox[5] = 0;                    //id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm271x_mbox_temp_get_max(void)
+{
+    mbox[0] = 8 * 4;                // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+
+    mbox[2] = MBOX_TAG_TEMP_GET_MAX;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 4;                    // len
+
+    mbox[5] = 0;                    // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if (mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}

+ 187 - 0
bsp/raspberry-pi/raspi4-64/driver/mbox.h

@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-09-10     bigmagic       first version
+ */
+
+#ifndef __MBOX_H__
+#define __MBOX_H__
+
+#include <rtthread.h>
+#include <stdint.h>
+
+// https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+// https://github.com/hermanhermitage/videocoreiv
+
+/* a properly aligned buffer */
+extern volatile unsigned int *mbox;
+
+#define MBOX_REQUEST            0
+
+/* channels */
+#define MBOX_CH_POWER           0
+#define MBOX_CH_FB              1
+#define MBOX_CH_VUART           2
+#define MBOX_CH_VCHIQ           3
+#define MBOX_CH_LEDS            4
+#define MBOX_CH_BTNS            5
+#define MBOX_CH_TOUCH           6
+#define MBOX_CH_COUNT           7
+#define MBOX_CH_PROP            8
+
+/* tags */
+#define MBOX_TAG_SETPOWER       0x28001
+#define MBOX_TAG_SETCLKRATE     0x38002
+#define MBOX_GET_MAC_ADDRESS    0x10003
+#define MBOX_TAG_LAST           0
+
+#define MMIO_BASE               0xFE000000
+#define VIDEOCORE_MBOX          (MMIO_BASE+0x0000B880)
+#define MBOX_READ               ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
+#define MBOX_POLL               ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
+#define MBOX_SENDER             ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
+#define MBOX_STATUS             ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
+#define MBOX_CONFIG             ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
+#define MBOX_WRITE              ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
+#define MBOX_RESPONSE           0x80000000
+#define MBOX_FULL               0x80000000
+#define MBOX_EMPTY              0x40000000
+
+#define DEVICE_ID_SD_CARD       (0)
+#define DEVICE_ID_USB_HCD       (3)
+#define POWER_STATE_OFF         (0 << 0)
+#define POWER_STATE_ON          (1 << 0)
+#define POWER_STATE_WAIT        (1 << 1)
+#define POWER_STATE_NO_DEVICE   (1 << 1)    // in response
+#define MMU_ENABLE              (1)
+#define MMU_DISABLE             (0)
+
+/*
+ * raspi hardware info
+ */
+enum
+{
+    MBOX_TAG_HARDWARE_GET_MODEL         = 0x00010001,
+    MBOX_TAG_HARDWARE_GET_REV           = 0x00010002,
+    MBOX_TAG_HARDWARE_GET_MAC_ADDRESS   = 0x00010003,
+    MBOX_TAG_HARDWARE_GET_SERIAL        = 0x00010004,
+    MBOX_TAG_HARDWARE_GET_ARM_MEMORY    = 0x00010005,
+    MBOX_TAG_HARDWARE_GET_VC_MEMORY     = 0x00010006,
+    MBOX_TAG_HARDWARE_GET_CLOCKS        = 0x00010007,
+};
+
+/*
+ * raspi clock
+ */
+enum
+{
+    MBOX_TAG_CLOCK_GET_TURBO    = 0x00030009,
+    MBOX_TAG_CLOCK_SET_TURBO    = 0x00038009,
+    MBOX_TAG_CLOCK_GET_STATE    = 0x00030001,
+    MBOX_TAG_CLOCK_SET_STATE    = 0x00038001,
+    MBOX_TAG_CLOCK_GET_RATE     = 0x00030002,
+    MBOX_TAG_CLOCK_SET_RATE     = 0x00038002,
+    MBOX_TAG_CLOCK_GET_MAX_RATE = 0x00030004,
+    MBOX_TAG_CLOCK_GET_MIN_RATE = 0x00030007,
+};
+
+/*
+ * raspi power
+ */
+enum
+{
+    MBOX_TAG_POWER_GET_STATE    = 0x00020001,
+    MBOX_TAG_POWER_SET_STATE    = 0x00028001,
+};
+
+/*
+ * raspi temperature
+ */
+enum
+{
+    MBOX_TAG_TEMP_GET       = 0x00030006,
+    MBOX_TAG_TEMP_GET_MAX   = 0x0003000A,
+};
+
+/*
+ * raspi Memory
+ */
+enum
+{
+    MBOX_TAG_ALLOCATE_MEMORY = 0x0003000C,  // Memory: Allocates Contiguous Memory On The GPU (Response: Handle)
+    MBOX_TAG_LOCK_MEMORY     = 0x0003000D,  // Memory: Unlock Buffer (Response: Status)
+    MBOX_TAG_UNLOCK_MEMORY   = 0x0003000E,  // Memory: Unlock Buffer (Response: Status)
+    MBOX_TAG_RELEASE_MEMORY  = 0x0003000F,  // Memory: Free The Memory Buffer (Response: Status)
+    MBOX_TAG_EXECUTE_CODE    = 0x00030010,  // Memory: Calls The Function At Given (Bus) Address And With Arguments Given
+};
+
+/*
+ * raspi GPU
+ */
+enum
+{
+    MBOX_TAG_EXECUTE_QPU = 0x00030011,      // QPU: Calls The QPU Function At Given (Bus) Address And With Arguments Given
+    //      (Response: Number Of QPUs, Control, No Flush, Timeout In ms)
+    MBOX_TAG_ENABLE_QPU  = 0x00030012,      // QPU: Enables The QPU (Response: Enable State)
+};
+
+/*
+ * raspi HDMI
+ */
+#define MBOX_TAG_GET_EDID_BLOCK        0x00030020   // HDMI: Read Specificed EDID Block From Attached HDMI/DVI Device
+//      (Response: Block Number, Status, EDID Block (128 Bytes))
+
+/*
+ * raspi NOTIFY
+ */
+#define MBOX_TAG_NOTIFY_REBOOT         0x00030048
+#define MBOX_TAG_NOTIFY_XHCI_RESET     0x00030058
+
+/*
+* touch
+*/
+#define MBOX_TAG_GET_TOUCHBUF          (0x0004000F)
+
+#define MBOX_ADDR 0x08000000
+
+#define RES_CLK_ID                      (0x000000000)
+#define EMMC_CLK_ID                     (0x000000001)
+#define UART_CLK_ID                     (0x000000002)
+#define ARM_CLK_ID                      (0x000000003)
+#define CORE_CLK_ID                     (0x000000004)
+#define V3D_CLK_ID                      (0x000000005)
+#define H264_CLK_ID                     (0x000000006)
+#define ISP_CLK_ID                      (0x000000007)
+#define SDRAM_CLK_ID                    (0x000000008)
+#define PIXEL_CLK_ID                    (0x000000009)
+#define PWM_CLK_ID                      (0x00000000a)
+
+int mbox_call(unsigned char ch, int mmu_enable);
+int bcm271x_mbox_get_touch(void);
+int bcm271x_notify_reboot(void);
+int bcm271x_notify_xhci_reset(void);
+int bcm271x_gpu_enable(void);
+int bcm271x_mbox_hardware_get_model(void);
+int bcm271x_mbox_hardware_get_revison(void);
+int bcm271x_mbox_hardware_get_mac_address(uint8_t *mac);
+int bcm271x_mbox_hardware_get_serial(rt_uint64_t *sn);
+int bcm271x_mbox_hardware_get_arm_memory(rt_uint32_t *base, rt_uint32_t *size);
+int bcm271x_mbox_hardware_get_vc_memory(rt_uint32_t *base, rt_uint32_t *size);
+int bcm271x_mbox_clock_get_turbo(void);
+int bcm271x_mbox_clock_set_turbo(int level);
+int bcm271x_mbox_clock_get_state(int id);
+int bcm271x_mbox_clock_set_state(int id, int state);
+int bcm271x_mbox_clock_get_rate(int id);
+int bcm271x_mbox_clock_set_rate(int id, int rate);
+int bcm271x_mbox_clock_get_max_rate(int id);
+int bcm271x_mbox_clock_get_min_rate(int id);
+int bcm271x_mbox_power_get_state(int id);
+int bcm271x_mbox_power_set_state(int id, int state);
+int bcm271x_mbox_temp_get(void);
+int bcm271x_mbox_temp_get_max(void);
+
+#endif

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

@@ -1,29 +1,145 @@
 #ifndef __RASPI4_H__
 #define __RASPI4_H__
 
+#include <rthw.h>
+
+#define __REG32(x)              (*((volatile unsigned int *)(x)))
+
+//base address
+#define PER_BASE                (0xFE000000)
+
+//gpio offset
+#define GPIO_BASE_OFFSET        (0x00200000)
+
+//pl011 offset
+#define PL011_UART_BASE_OFFSET  (0x00201000)
+
+//pactl cs offset
+#define PACTL_CS_OFFSET         (0x00204E00)
+
+//aux offset
+#define AUX_BASE_OFFSET         (0x00215000)
+
 //gpio
-#define GPIO_BASE (0xFE000000 + 0x00200000)
+#define GPIO_BASE               (PER_BASE + GPIO_BASE_OFFSET)
+#define GPIO_IRQ_NUM            (3)         //40 pin mode
+#define IRQ_GPIO0               (96 + 49)   //bank0 (0 to 27)
+#define IRQ_GPIO1               (96 + 50)   //bank1 (28 to 45)
+#define IRQ_GPIO2               (96 + 51)   //bank2 (46 to 57)
+#define IRQ_GPIO3               (96 + 52)   //bank3
+
+//system timer
+#define ARM_TIMER_IRQ           (64)
+#define ARM_TIMER_BASE          (PER_BASE + 0xB000)
+#define ARM_TIMER_LOAD          HWREG32(ARM_TIMER_BASE + 0x400)
+#define ARM_TIMER_VALUE         HWREG32(ARM_TIMER_BASE + 0x404)
+#define ARM_TIMER_CTRL          HWREG32(ARM_TIMER_BASE + 0x408)
+#define ARM_TIMER_IRQCLR        HWREG32(ARM_TIMER_BASE + 0x40C)
+#define ARM_TIMER_RAWIRQ        HWREG32(ARM_TIMER_BASE + 0x410)
+#define ARM_TIMER_MASKIRQ       HWREG32(ARM_TIMER_BASE + 0x414)
+#define ARM_TIMER_RELOAD        HWREG32(ARM_TIMER_BASE + 0x418)
+#define ARM_TIMER_PREDIV        HWREG32(ARM_TIMER_BASE + 0x41C)
+#define ARM_TIMER_CNTR          HWREG32(ARM_TIMER_BASE + 0x420)
 
 //uart
-#define UART0_BASE                  (0xFE000000 + 0x00201000)
-#define PL011_BASE                  UART0_BASE
-#define IRQ_PL011                   (121 + 32)
-#define UART_REFERENCE_CLOCK        (48000000)
+#define UART_BASE               (PER_BASE + PL011_UART_BASE_OFFSET)
+#define UART0_BASE              (UART_BASE + 0x0)
+#define UART2_BASE              (UART_BASE + 0x400)
+#define UART3_BASE              (UART_BASE + 0x600)
+#define UART4_BASE              (UART_BASE + 0x800)
+#define UART5_BASE              (UART_BASE + 0xA00)
+#define IRQ_AUX_UART            (96 + 29)
+#define UART_REFERENCE_CLOCK    (48000000)
+
+//aux
+#define AUX_BASE                (PER_BASE + AUX_BASE_OFFSET)
+#define IRQ_PL011               (96 + 57)
+
+//pactl cs
+#define PACTL_CS_ADDR           (PER_BASE + PACTL_CS_OFFSET)
+#define PACTL_CS                HWREG32(PACTL_CS_ADDR)
+typedef enum
+{
+    IRQ_SPI0 = 0x00000000,
+    IRQ_SPI1 = 0x00000002,
+    IRQ_SPI2 = 0x00000004,
+    IRQ_SPI3 = 0x00000008,
+    IRQ_SPI4 = 0x00000010,
+    IRQ_SPI5 = 0x00000020,
+    IRQ_SPI6 = 0x00000040,
+    IRQ_I2C0 = 0x00000100,
+    IRQ_I2C1 = 0x00000200,
+    IRQ_I2C2 = 0x00000400,
+    IRQ_I2C3 = 0x00000800,
+    IRQ_I2C4 = 0x00001000,
+    IRQ_I2C5 = 0x00002000,
+    IRQ_I2C6 = 0x00004000,
+    IRQ_I2C7 = 0x00008000,
+    IRQ_UART5 = 0x00010000,
+    IRQ_UART4 = 0x00020000,
+    IRQ_UART3 = 0x00040000,
+    IRQ_UART2 = 0x00080000,
+    IRQ_UART0 = 0x00100000
+} PACTL_CS_VAL;
 
 // 0x40, 0x44, 0x48, 0x4c: Core 0~3 Timers interrupt control
 #define CORE0_TIMER_IRQ_CTRL    HWREG32(0xFF800040)
 #define TIMER_IRQ               30
 #define NON_SECURE_TIMER_IRQ    (1 << 1)
 
+//core timer
+#define ST_BASE_OFFSET          (0x003000)
+#define STIMER_BASE             (PER_BASE  + ST_BASE_OFFSET)
+#define STIMER_CS               HWREG32(STIMER_BASE + 0x0000)
+#define STIMER_CLO              HWREG32(STIMER_BASE + 0x0004)
+#define STIMER_CHI              HWREG32(STIMER_BASE + 0x0008)
+#define STIMER_C0               HWREG32(STIMER_BASE + 0x000C)
+#define STIMER_C1               HWREG32(STIMER_BASE + 0x0010)
+#define STIMER_C2               HWREG32(STIMER_BASE + 0x0014)
+#define STIMER_C3               HWREG32(STIMER_BASE + 0x0018)
+
+#define DELAY_MICROS(micros) \
+do { \
+    rt_uint32_t compare = STIMER_CLO + micros * 25; \
+    while (STIMER_CLO < compare); \
+} while (0) \
+
+//mmc
+#define MMC0_BASE_ADDR          (PER_BASE + 0x300000)
+#define MMC2_BASE_ADDR          (PER_BASE + 0x340000)
+
+//eth
+#define MAC_REG_BASE_ADDR       (void *)(0xfd580000)
+#define ETH_IRQ                 (160 + 29)
+#define SEND_DATA_NO_CACHE      (0x08200000)
+#define RECV_DATA_NO_CACHE      (0x08400000)
+
 //gic max
+#define MAX_HANDLERS                (256)
 #define ARM_GIC_NR_IRQS             (512)
 #define INTC_BASE                   (0xff800000)
+#define ARM_GIC_MAX_NR              (512)
+#define GIC_V2_BASE                 (INTC_BASE + 0x00040000)
 #define GIC_V2_DISTRIBUTOR_BASE     (INTC_BASE + 0x00041000)
 #define GIC_V2_CPU_INTERFACE_BASE   (INTC_BASE + 0x00042000)
 #define GIC_V2_HYPERVISOR_BASE      (INTC_BASE + 0x00044000)
 #define GIC_V2_VIRTUAL_CPU_BASE     (INTC_BASE + 0x00046000)
 
+#define GIC_IRQ_START               0
+#define GIC_ACK_INTID_MASK          0x000003ff
+
 #define GIC_PL400_DISTRIBUTOR_PPTR  GIC_V2_DISTRIBUTOR_BASE
 #define GIC_PL400_CONTROLLER_PPTR   GIC_V2_CPU_INTERFACE_BASE
 
+/* the basic constants and interfaces needed by gic */
+rt_inline rt_uint32_t platform_get_gic_dist_base(void)
+{
+    return GIC_PL400_DISTRIBUTOR_PPTR;
+}
+
+rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
+{
+    return GIC_PL400_CONTROLLER_PPTR;
+}
+
 #endif

+ 115 - 8
bsp/raspberry-pi/raspi4-64/rtconfig.h

@@ -19,6 +19,9 @@
 #define RT_USING_TIMER_SOFT
 #define RT_TIMER_THREAD_PRIO 4
 #define RT_TIMER_THREAD_STACK_SIZE 2048
+
+/* kservice optimization */
+
 #define RT_DEBUG
 
 /* Inter-Thread communication */
@@ -40,8 +43,8 @@
 #define RT_USING_DEVICE
 #define RT_USING_CONSOLE
 #define RT_CONSOLEBUF_SIZE 128
-#define RT_CONSOLE_DEVICE_NAME "uart"
-#define RT_VER_NUM 0x40003
+#define RT_CONSOLE_DEVICE_NAME "uart0"
+#define RT_VER_NUM 0x40004
 #define ARCH_CPU_64BIT
 #define ARCH_ARMV8
 
@@ -58,16 +61,17 @@
 /* Command shell */
 
 #define RT_USING_FINSH
+#define RT_USING_MSH
+#define FINSH_USING_MSH
 #define FINSH_THREAD_NAME "tshell"
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_USING_HISTORY
 #define FINSH_HISTORY_LINES 5
 #define FINSH_USING_SYMTAB
-#define FINSH_USING_DESCRIPTION
-#define FINSH_THREAD_PRIORITY 20
-#define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_CMD_SIZE 80
-#define FINSH_USING_MSH
-#define FINSH_USING_MSH_DEFAULT
+#define MSH_USING_BUILT_IN_COMMANDS
+#define FINSH_USING_DESCRIPTION
 #define FINSH_ARG_MAX 10
 
 /* Device virtual file system */
@@ -77,16 +81,42 @@
 #define DFS_FILESYSTEMS_MAX 2
 #define DFS_FILESYSTEM_TYPES_MAX 2
 #define DFS_FD_MAX 16
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+#define RT_DFS_ELM_USE_LFN_3
+#define RT_DFS_ELM_USE_LFN 3
+#define RT_DFS_ELM_LFN_UNICODE_0
+#define RT_DFS_ELM_LFN_UNICODE 0
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
+#define RT_DFS_ELM_REENTRANT
 #define RT_USING_DFS_DEVFS
 
 /* 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_PRIORITY 23
 #define RT_USING_SERIAL
+#define RT_USING_SERIAL_V1
 #define RT_SERIAL_USING_DMA
 #define RT_SERIAL_RB_BUFSZ 64
 #define RT_USING_PIN
+#define RT_USING_RTC
+#define RT_USING_ALARM
+#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_THREAD_PREORITY 22
+#define RT_MMCSD_MAX_PARTITION 16
 
 /* Using USB */
 
@@ -95,17 +125,73 @@
 
 #define RT_USING_LIBC
 #define RT_USING_POSIX
+#define RT_LIBC_DEFAULT_TIMEZONE 8
 
 /* Network */
 
 /* Socket abstraction layer */
 
+#define RT_USING_SAL
+#define SAL_INTERNET_CHECK
+
+/* protocol stack implement */
+
+#define SAL_USING_LWIP
+#define SAL_SOCKETS_NUM 16
 
 /* Network interface device */
 
+#define RT_USING_NETDEV
+#define NETDEV_USING_IFCONFIG
+#define NETDEV_USING_PING
+#define NETDEV_USING_NETSTAT
+#define NETDEV_USING_AUTO_DEFAULT
+#define NETDEV_IPV4 1
+#define NETDEV_IPV6 0
 
 /* light weight TCP/IP stack */
 
+#define RT_USING_LWIP
+#define RT_USING_LWIP203
+#define RT_LWIP_MEM_ALIGNMENT 4
+#define RT_LWIP_IGMP
+#define RT_LWIP_ICMP
+#define RT_LWIP_DNS
+#define RT_LWIP_DHCP
+#define IP_SOF_BROADCAST 1
+#define IP_SOF_BROADCAST_RECV 1
+
+/* Static IPv4 Address */
+
+#define RT_LWIP_IPADDR "192.168.1.30"
+#define RT_LWIP_GWADDR "192.168.1.1"
+#define RT_LWIP_MSKADDR "255.255.255.0"
+#define RT_LWIP_UDP
+#define RT_LWIP_TCP
+#define RT_LWIP_RAW
+#define RT_MEMP_NUM_NETCONN 8
+#define RT_LWIP_PBUF_NUM 16
+#define RT_LWIP_RAW_PCB_NUM 4
+#define RT_LWIP_UDP_PCB_NUM 4
+#define RT_LWIP_TCP_PCB_NUM 4
+#define RT_LWIP_TCP_SEG_NUM 40
+#define RT_LWIP_TCP_SND_BUF 8196
+#define RT_LWIP_TCP_WND 8196
+#define RT_LWIP_TCPTHREAD_PRIORITY 10
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
+#define RT_LWIP_TCPTHREAD_STACKSIZE 2048
+#define RT_LWIP_ETHTHREAD_PRIORITY 12
+#define RT_LWIP_ETHTHREAD_STACKSIZE 2048
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_LINK_CALLBACK 1
+#define SO_REUSE 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_SNDTIMEO 1
+#define LWIP_SO_RCVBUF 1
+#define LWIP_SO_LINGER 0
+#define LWIP_NETIF_LOOPBACK 0
+#define RT_LWIP_USING_PING
 
 /* AT commands */
 
@@ -115,6 +201,11 @@
 
 /* Utilities */
 
+#define RT_USING_RYM
+#define YMODEM_USING_FILE_TRANSFER
+
+/* RT-Thread Utestcases */
+
 
 /* RT-Thread online packages */
 
@@ -146,16 +237,27 @@
 
 /* system packages */
 
+/* acceleration: Assembly language or algorithmic acceleration packages */
+
+
+/* Micrium: Micrium software products porting for RT-Thread */
+
 
 /* peripheral libraries and drivers */
 
 
-/* miscellaneous packages */
+/* AI packages */
+
 
+/* miscellaneous packages */
 
 /* samples: kernel and components samples */
 
+
+/* entertainment: terminal games and other interesting software packages */
+
 #define BCM2711_SOC
+#define BSP_SUPPORT_FPU
 
 /* Hardware Drivers Config */
 
@@ -167,6 +269,11 @@
 #define BSP_USING_GIC400
 #define BSP_USING_PIN
 #define BSP_USING_CORETIMER
+#define BSP_USING_ETH
+#define BSP_USING_RTC
+#define BSP_USING_ALARM
+#define BSP_USING_SDIO
+#define BSP_USING_SDIO0
 
 /* Board Peripheral Drivers */
 

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

@@ -2,7 +2,7 @@ import os
 
 # toolchains options
 ARCH        ='aarch64'
-CPU         ='cortex-a72'
+CPU         ='cortex-a'
 CROSS_TOOL  ='gcc'
 
 if os.getenv('RTT_ROOT'):

+ 5 - 1
libcpu/aarch64/common/SConscript

@@ -6,9 +6,13 @@ Import('rtconfig')
 
 cwd     = GetCurrentDir()
 src     = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
+
+if not GetDepend('BSP_USING_GIC'):
+    SrcRemove(src, 'gic.c')
+
 CPPPATH = [cwd]
 
-group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
+group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH)
 
 # build for sub-directory
 list = os.listdir(cwd)

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

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-10     GuEe-GUI     first version
+ */
+
+#ifndef __CPUPORT_H__
+#define __CPUPORT_H__
+
+#include <rtdef.h>
+
+rt_inline void rt_hw_isb(void)
+{
+    __asm__ volatile ("isb":::"memory");
+}
+
+rt_inline void rt_hw_dmb(void)
+{
+    __asm__ volatile ("dmb sy":::"memory");
+}
+
+rt_inline void rt_hw_dsb(void)
+{
+    __asm__ volatile ("dsb sy":::"memory");
+}
+
+#endif /* __CPUPORT_H__ */

+ 504 - 0
libcpu/aarch64/common/gic.c

@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-20     Bernard      first version
+ * 2014-04-03     Grissiom     many enhancements
+ * 2018-11-22     Jesven       add rt_hw_ipi_send()
+ *                             add rt_hw_ipi_handler_install()
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <gic.h>
+#include <cp15.h>
+
+struct arm_gic
+{
+    rt_uint64_t offset;         /* the first interrupt index in the vector table */
+
+    rt_uint64_t dist_hw_base;   /* the base address of the gic distributor */
+    rt_uint64_t cpu_hw_base;    /* the base addrees of the gic cpu interface */
+};
+
+/* 'ARM_GIC_MAX_NR' is the number of cores */
+static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
+
+/** Macro to access the Generic Interrupt Controller Interface (GICC)
+*/
+#define GIC_CPU_CTRL(hw_base)               __REG32((hw_base) + 0x00U)
+#define GIC_CPU_PRIMASK(hw_base)            __REG32((hw_base) + 0x04U)
+#define GIC_CPU_BINPOINT(hw_base)           __REG32((hw_base) + 0x08U)
+#define GIC_CPU_INTACK(hw_base)             __REG32((hw_base) + 0x0cU)
+#define GIC_CPU_EOI(hw_base)                __REG32((hw_base) + 0x10U)
+#define GIC_CPU_RUNNINGPRI(hw_base)         __REG32((hw_base) + 0x14U)
+#define GIC_CPU_HIGHPRI(hw_base)            __REG32((hw_base) + 0x18U)
+#define GIC_CPU_IIDR(hw_base)               __REG32((hw_base) + 0xFCU)
+
+/** Macro to access the Generic Interrupt Controller Distributor (GICD)
+*/
+#define GIC_DIST_CTRL(hw_base)              __REG32((hw_base) + 0x000U)
+#define GIC_DIST_TYPE(hw_base)              __REG32((hw_base) + 0x004U)
+#define GIC_DIST_IGROUP(hw_base, n)         __REG32((hw_base) + 0x080U + ((n)/32U) * 4U)
+#define GIC_DIST_ENABLE_SET(hw_base, n)     __REG32((hw_base) + 0x100U + ((n)/32U) * 4U)
+#define GIC_DIST_ENABLE_CLEAR(hw_base, n)   __REG32((hw_base) + 0x180U + ((n)/32U) * 4U)
+#define GIC_DIST_PENDING_SET(hw_base, n)    __REG32((hw_base) + 0x200U + ((n)/32U) * 4U)
+#define GIC_DIST_PENDING_CLEAR(hw_base, n)  __REG32((hw_base) + 0x280U + ((n)/32U) * 4U)
+#define GIC_DIST_ACTIVE_SET(hw_base, n)     __REG32((hw_base) + 0x300U + ((n)/32U) * 4U)
+#define GIC_DIST_ACTIVE_CLEAR(hw_base, n)   __REG32((hw_base) + 0x380U + ((n)/32U) * 4U)
+#define GIC_DIST_PRI(hw_base, n)            __REG32((hw_base) + 0x400U +  ((n)/4U) * 4U)
+#define GIC_DIST_TARGET(hw_base, n)         __REG32((hw_base) + 0x800U +  ((n)/4U) * 4U)
+#define GIC_DIST_CONFIG(hw_base, n)         __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U)
+#define GIC_DIST_SOFTINT(hw_base)           __REG32((hw_base) + 0xf00U)
+#define GIC_DIST_CPENDSGI(hw_base, n)       __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U)
+#define GIC_DIST_SPENDSGI(hw_base, n)       __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U)
+#define GIC_DIST_ICPIDR2(hw_base)           __REG32((hw_base) + 0xfe8U)
+
+static unsigned int _gic_max_irq;
+
+int arm_gic_get_active_irq(rt_uint64_t index)
+{
+    int irq;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base);
+    irq += _gic_table[index].offset;
+    return irq;
+}
+
+void arm_gic_ack(rt_uint64_t index, int irq)
+{
+    rt_uint64_t mask = 1U << (irq % 32U);
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+    GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq;
+}
+
+void arm_gic_mask(rt_uint64_t index, int irq)
+{
+    rt_uint64_t mask = 1U << (irq % 32U);
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+void arm_gic_umask(rt_uint64_t index, int irq)
+{
+    rt_uint64_t mask = 1U << (irq % 32U);
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq)
+{
+    rt_uint64_t pend;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    if (irq >= 16U)
+    {
+        pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
+    }
+    else
+    {
+        /* INTID 0-15 Software Generated Interrupt */
+        pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL;
+        /* No CPU identification offered */
+        if (pend != 0U)
+        {
+            pend = 1U;
+        }
+        else
+        {
+            pend = 0U;
+        }
+    }
+
+    return (pend);
+}
+
+void arm_gic_set_pending_irq(rt_uint64_t index, int irq)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    if (irq >= 16U)
+    {
+        GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1U << (irq % 32U);
+    }
+    else
+    {
+        /* INTID 0-15 Software Generated Interrupt */
+        /* Forward the interrupt to the CPU interface that requested it */
+        GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000U);
+    }
+}
+
+void arm_gic_clear_pending_irq(rt_uint64_t index, int irq)
+{
+    rt_uint64_t mask;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    if (irq >= 16U)
+    {
+        mask = 1U << (irq % 32U);
+        GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+    }
+    else
+    {
+        mask =  1U << ((irq % 4U) * 8U);
+        GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask;
+    }
+}
+
+void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config)
+{
+    rt_uint64_t icfgr;
+    rt_uint64_t shift;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq);
+    shift = (irq % 16U) << 1U;
+
+    icfgr &= (~(3U << shift));
+    icfgr |= (config << shift);
+
+    GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr;
+}
+
+rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> ((irq % 16U) >> 1U));
+}
+
+void arm_gic_clear_active(rt_uint64_t index, int irq)
+{
+    rt_uint64_t mask = 1U << (irq % 32U);
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+/* Set up the cpu mask for the specific interrupt */
+void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask)
+{
+    rt_uint64_t old_tgt;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq);
+
+    old_tgt &= ~(0x0FFUL << ((irq % 4U)*8U));
+    old_tgt |= cpumask << ((irq % 4U)*8U);
+
+    GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt;
+}
+
+rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    return (GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL;
+}
+
+void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority)
+{
+    rt_uint64_t mask;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq);
+    mask &= ~(0xFFUL << ((irq % 4U) * 8U));
+    mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U));
+    GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL;
+}
+
+void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    /* set priority mask */
+    GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base) = priority & 0xFFUL;
+}
+
+rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    return GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base);
+}
+
+void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point)
+{
+    GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base) = binary_point & 0x7U;
+}
+
+rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index)
+{
+    return GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base);
+}
+
+rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq)
+{
+    rt_uint64_t pending;
+    rt_uint64_t active;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
+    pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
+
+    return ((active << 1U) | pending);
+}
+
+void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_uint64_t filter_list)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) =
+        ((filter_list & 0x3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (irq & 0x0FUL);
+}
+
+rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    return GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base);
+}
+
+rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    return GIC_CPU_IIDR(_gic_table[index].cpu_hw_base);
+}
+
+void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group)
+{
+    uint32_t igroupr;
+    uint32_t shift;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+    RT_ASSERT(group <= 1U);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq);
+    shift = (irq % 32U);
+    igroupr &= (~(1U << shift));
+    igroupr |= ((group & 0x1U) << shift);
+
+    GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr;
+}
+
+rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    irq = irq - _gic_table[index].offset;
+    RT_ASSERT(irq >= 0U);
+
+    return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
+}
+
+int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start)
+{
+    unsigned int gic_type, i;
+    rt_uint64_t cpumask = 1U << 0U;
+
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    _gic_table[index].dist_hw_base = dist_base;
+    _gic_table[index].offset = irq_start;
+
+    /* Find out how many interrupts are supported. */
+    gic_type = GIC_DIST_TYPE(dist_base);
+    _gic_max_irq = ((gic_type & 0x1fU) + 1U) * 32U;
+
+    /*
+     * The GIC only supports up to 1020 interrupt sources.
+     * Limit this to either the architected maximum, or the
+     * platform maximum.
+     */
+    if (_gic_max_irq > 1020U)
+    {
+        _gic_max_irq = 1020U;
+    }
+    if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */
+    {
+        _gic_max_irq = ARM_GIC_NR_IRQS;
+    }
+
+    cpumask |= cpumask << 8U;
+    cpumask |= cpumask << 16U;
+    cpumask |= cpumask << 24U;
+
+    GIC_DIST_CTRL(dist_base) = 0x0U;
+
+    /* Set all global interrupts to be level triggered, active low. */
+    for (i = 32U; i < _gic_max_irq; i += 16U)
+    {
+        GIC_DIST_CONFIG(dist_base, i) = 0x0U;
+    }
+
+    /* Set all global interrupts to this CPU only. */
+    for (i = 32U; i < _gic_max_irq; i += 4U)
+    {
+        GIC_DIST_TARGET(dist_base, i) = cpumask;
+    }
+
+    /* Set priority on all interrupts. */
+    for (i = 0U; i < _gic_max_irq; i += 4U)
+    {
+        GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0U;
+    }
+
+    /* Disable all interrupts. */
+    for (i = 0U; i < _gic_max_irq; i += 32U)
+    {
+        GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffffU;
+    }
+
+    /* All interrupts defaults to IGROUP1(IRQ). */
+    for (i = 0U; i < _gic_max_irq; i += 32U)
+    {
+        GIC_DIST_IGROUP(dist_base, i) = 0U;
+    }
+
+    /* Enable group0 and group1 interrupt forwarding. */
+    GIC_DIST_CTRL(dist_base) = 0x01U;
+
+    return 0;
+}
+
+int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base)
+{
+    RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+    if (!_gic_table[index].cpu_hw_base)
+    {
+        _gic_table[index].cpu_hw_base = cpu_base;
+    }
+    cpu_base = _gic_table[index].cpu_hw_base;
+
+    GIC_CPU_PRIMASK(cpu_base) = 0xf0U;
+    GIC_CPU_BINPOINT(cpu_base) = 0x7U;
+    /* Enable CPU interrupt */
+    GIC_CPU_CTRL(cpu_base) = 0x01U;
+
+    return 0;
+}
+
+void arm_gic_dump_type(rt_uint64_t index)
+{
+    unsigned int gic_type;
+
+    gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base);
+    rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n",
+               (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4U) & 0xfUL,
+               _gic_table[index].dist_hw_base,
+               _gic_max_irq,
+               gic_type & (1U << 10U) ? "has" : "no",
+               gic_type);
+}
+
+void arm_gic_dump(rt_uint64_t index)
+{
+    unsigned int i, k;
+
+    k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base);
+    rt_kprintf("--- high pending priority: %d(%08x)\n", k, k);
+    rt_kprintf("--- hw mask ---\n");
+    for (i = 0U; i < _gic_max_irq / 32U; i++)
+    {
+        rt_kprintf("0x%08x, ", GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, i * 32U));
+    }
+    rt_kprintf("\n--- hw pending ---\n");
+    for (i = 0U; i < _gic_max_irq / 32U; i++)
+    {
+        rt_kprintf("0x%08x, ", GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, i * 32U));
+    }
+    rt_kprintf("\n--- hw active ---\n");
+    for (i = 0U; i < _gic_max_irq / 32U; i++)
+    {
+        rt_kprintf("0x%08x, ", GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, i * 32U));
+    }
+    rt_kprintf("\n");
+}
+
+long gic_dump(void)
+{
+    arm_gic_dump_type(0);
+    arm_gic_dump(0);
+
+    return 0;
+}
+MSH_CMD_EXPORT(gic_dump, show gic status);
+

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

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-20     Bernard      first version
+ */
+
+#ifndef __GIC_H__
+#define __GIC_H__
+
+#include <rthw.h>
+#include <stdint.h>
+#include <board.h>
+
+int arm_gic_get_active_irq(rt_uint64_t index);
+void arm_gic_ack(rt_uint64_t index, int irq);
+
+void arm_gic_mask(rt_uint64_t index, int irq);
+void arm_gic_umask(rt_uint64_t index, int irq);
+
+rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq);
+void arm_gic_set_pending_irq(rt_uint64_t index, int irq);
+void arm_gic_clear_pending_irq(rt_uint64_t index, int irq);
+
+void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config);
+rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq);
+
+void arm_gic_clear_active(rt_uint64_t index, int irq);
+
+void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask);
+rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq);
+
+void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority);
+rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq);
+
+void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority);
+rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index);
+
+void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point);
+rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index);
+
+rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq);
+
+void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_uint64_t filter_list);
+
+rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index);
+
+rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index);
+
+void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group);
+rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq);
+
+int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start);
+int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base);
+
+void arm_gic_dump_type(rt_uint64_t index);
+void arm_gic_dump(rt_uint64_t index);
+
+#endif
+

+ 0 - 30
libcpu/aarch64/common/gic/SConscript

@@ -1,30 +0,0 @@
-# RT-Thread building script for component
-
-from building import *
-
-cwd     = GetCurrentDir()
-CPPPATH = [cwd]
-
-gic390_group = Split('''
-gic_pl390.c
-''')
-
-gic400_group = Split('''
-gic_pl400.c
-''')
-
-gic500_group = Split('''
-gic_pl500.c
-''')
-
-src = ()
-if GetDepend('BSP_USING_GIC390'):
-	src = gic390_group
-if GetDepend('BSP_USING_GIC400'):
-	src = gic400_group
-if GetDepend('BSP_USING_GIC500'):
-	src = gic500_group
-
-group = DefineGroup('gic', src, depend = ['BSP_USING_GIC'], CPPPATH = CPPPATH)
-
-Return('group')

+ 0 - 273
libcpu/aarch64/common/gic/gic_pl390.c

@@ -1,273 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2021-07-31     GuEe-GUI     the first version
- */
-#include <rtthread.h>
-
-#include "gic_pl390.h"
-
-#define BIT(n)              (1ul<<(n))
-#define MASK(n)             (BIT(n)-1ul)
-
-#define IRQ_REG(IRQ)        ((IRQ) / 32)
-#define IRQ_BIT(IRQ)        BIT((IRQ) % 32)
-#define IRQ_MASK            MASK(10)
-#define IRQ_SET_ALL         0xffffffff
-#define IS_IRQ_VALID(X)     (((X)&IRQ_MASK) < GIC390_SPECIAL_IRQ_START)
-
-#define TARGET_CPU_ALLINT(CPU)  \
-(                               \
-    (((CPU) & 0xff) << 0 ) |    \
-    (((CPU) & 0xff) << 8 ) |    \
-    (((CPU) & 0xff) << 16) |    \
-    (((CPU) & 0xff) << 24)      \
-)
-#define CPU(X)              (1<<(X))
-#define TARGET_CPU0_ALLINT  TARGET_CPU_ALLINT(CPU(0))
-
-/* memory map for GIC distributor */
-struct gic_dist_map
-{
-    rt_uint32_t enable;                 /* 0x000 */
-    rt_uint32_t ic_type;                /* 0x004 */
-    rt_uint32_t dist_ident;             /* 0x008 */
-    rt_uint32_t res1[29];               /* [0x00C, 0x080) */
-
-    rt_uint32_t security[32];           /* [0x080, 0x100) */
-
-    rt_uint32_t enable_set[32];         /* [0x100, 0x180) */
-    rt_uint32_t enable_clr[32];         /* [0x180, 0x200) */
-    rt_uint32_t pending_set[32];        /* [0x200, 0x280) */
-    rt_uint32_t pending_clr[32];        /* [0x280, 0x300) */
-    rt_uint32_t active[32];             /* [0x300, 0x380) */
-    rt_uint32_t res2[32];               /* [0x380, 0x400) */
-
-    rt_uint32_t priority[255];          /* [0x400, 0x7FC) */
-    rt_uint32_t res3;                   /* 0x7FC */
-
-    rt_uint32_t targets[255];           /* [0x800, 0xBFC) */
-    rt_uint32_t res4;                   /* 0xBFC */
-
-    rt_uint32_t config[64];             /* [0xC00, 0xD00) */
-
-    rt_uint32_t spi[32];                /* [0xD00, 0xD80) */
-    rt_uint32_t res5[20];               /* [0xD80, 0xDD0) */
-    rt_uint32_t res6;                   /* 0xDD0 */
-    rt_uint32_t legacy_int;             /* 0xDD4 */
-    rt_uint32_t res7[2];                /* [0xDD8, 0xDE0) */
-    rt_uint32_t match_d;                /* 0xDE0 */
-    rt_uint32_t enable_d;               /* 0xDE4 */
-    rt_uint32_t res8[70];               /* [0xDE8, 0xF00) */
-
-    rt_uint32_t sgi_control;            /* 0xF00 */
-    rt_uint32_t res9[3];                /* [0xF04, 0xF10) */
-    rt_uint32_t sgi_pending_clr[4];     /* [0xF10, 0xF20) */
-    rt_uint32_t res10[40];              /* [0xF20, 0xFC0) */
-
-    rt_uint32_t periph_id[12];          /* [0xFC0, 0xFF0) */
-    rt_uint32_t component_id[4];        /* [0xFF0, 0xFFF] */
-};
-
-/* memory map for GIC CPU interface */
-struct gic_cpu_iface_map
-{
-    rt_uint32_t icontrol;               /* 0x000 */
-    rt_uint32_t pri_msk_c;              /* 0x004 */
-    rt_uint32_t pb_c;                   /* 0x008 */
-    rt_uint32_t int_ack;                /* 0x00C */
-    rt_uint32_t eoi;                    /* 0x010 */
-    rt_uint32_t run_priority;           /* 0x014 */
-    rt_uint32_t hi_pend;                /* 0x018 */
-    rt_uint32_t ns_alias_bp_c;          /* 0x01C */
-    rt_uint32_t ns_alias_ack;           /* 0x020 GIC400 only */
-    rt_uint32_t ns_alias_eoi;           /* 0x024 GIC400 only */
-    rt_uint32_t ns_alias_hi_pend;       /* 0x028 GIC400 only */
-
-    rt_uint32_t res1[5];                /* [0x02C, 0x040) */
-
-    rt_uint32_t integ_en_c;             /* 0x040 PL390 only */
-    rt_uint32_t interrupt_out;          /* 0x044 PL390 only */
-    rt_uint32_t res2[2];                /* [0x048, 0x050) */
-
-    rt_uint32_t match_c;                /* 0x050 PL390 only */
-    rt_uint32_t enable_c;               /* 0x054 PL390 only */
-
-    rt_uint32_t res3[30];               /* [0x058, 0x0FC) */
-    rt_uint32_t active_priority[4];     /* [0x0D0, 0xDC] GIC400 only */
-    rt_uint32_t ns_active_priority[4];  /* [0xE0,0xEC] GIC400 only */
-    rt_uint32_t res4[3];
-
-    rt_uint32_t cpu_if_ident;           /* 0x0FC */
-    rt_uint32_t res5[948];              /* [0x100. 0xFC0) */
-
-    rt_uint32_t periph_id[8];           /* [0xFC0, 9xFF0) PL390 only */
-    rt_uint32_t component_id[4];        /* [0xFF0, 0xFFF] PL390 only */
-};
-
-volatile struct gic_dist_map *gic_dist =
-    (volatile struct gic_dist_map*)(GIC_PL390_DISTRIBUTOR_PPTR);
-
-volatile struct gic_cpu_iface_map *gic_cpuiface =
-    (volatile struct gic_cpu_iface_map*)(GIC_PL390_CONTROLLER_PPTR);
-
-/*
- * The only sane way to get an GIC IRQ number that can be properly
- * ACKED later is through the int_ack register. Unfortunately, reading
- * this register changes the interrupt state to pending so future
- * reads will not return the same value For this reason, we have a
- * global variable to store the IRQ number.
- */
-static rt_uint32_t active_irq = GIC390_IRQ_NONE;
-
-rt_inline int is_irq_edge_triggered(int irq)
-{
-    int word = irq / 16;
-    int bit = ((irq & 0xf) * 2);
-
-    return !!(gic_dist->config[word] & BIT(bit + 1));
-}
-
-rt_inline void dist_pending_clr(int irq)
-{
-    int word = irq / 32;
-    int bit = irq & 0x1f;
-    gic_dist->pending_clr[word] = BIT(bit);
-}
-
-rt_inline void dist_init(void)
-{
-    int i;
-    int nirqs = 32 * ((gic_dist->ic_type & 0x1f) + 1);
-    gic_dist->enable = 0;
-
-    for (i = 0; i < nirqs; i += 32)
-    {
-        /* disable */
-        gic_dist->enable_clr[i / 32] = IRQ_SET_ALL;
-        /* clear pending */
-        gic_dist->pending_clr[i / 32] = IRQ_SET_ALL;
-    }
-
-    /* reset interrupts priority */
-    for (i = 32; i < nirqs; i += 4)
-    {
-        gic_dist->priority[i / 4] = 0x0;
-    }
-
-    /*
-     * reset int target to cpu 0
-     * (Should really query which processor we're running on and use that)
-     */
-    for (i = 0; i < nirqs; i += 4)
-    {
-        gic_dist->targets[i / 4] = TARGET_CPU0_ALLINT;
-    }
-
-    /* level-triggered, 1-N */
-    for (i = 64; i < nirqs; i += 32)
-    {
-        gic_dist->config[i / 32] = 0;
-    }
-    /* enable the int controller */
-    gic_dist->enable = 1;
-}
-
-rt_inline void cpu_iface_init(void)
-{
-    rt_uint32_t i;
-
-    /* For non-Exynos4, the registers are banked per CPU, need to clear them */
-    gic_dist->enable_clr[0] = IRQ_SET_ALL;
-    gic_dist->pending_clr[0] = IRQ_SET_ALL;
-    gic_dist->priority[0] = 0x00;
-    /* put everything in group 0 */
-
-    /* clear any software generated interrupts */
-    for (i = 0; i < 16; i += 4)
-    {
-        gic_dist->sgi_pending_clr[i / 4] = IRQ_SET_ALL;
-    }
-
-    gic_cpuiface->icontrol = 0;
-    gic_cpuiface->pri_msk_c = 0x000000f0;
-    gic_cpuiface->pb_c = 0x00000003;
-
-    while (((i = gic_cpuiface->int_ack) & IRQ_MASK) != GIC390_IRQ_NONE)
-    {
-        gic_cpuiface->eoi = i;
-    }
-    gic_cpuiface->icontrol = 0x1;
-}
-
-
-void arm_gic_irq_init(void)
-{
-    dist_init();
-    cpu_iface_init();
-}
-
-int arm_gic_get_active_irq(void)
-{
-    int irq;
-    if (!IS_IRQ_VALID(active_irq))
-    {
-        active_irq = gic_cpuiface->int_ack;
-    }
-
-    if (IS_IRQ_VALID(active_irq))
-    {
-        irq = active_irq & IRQ_MASK;
-    }
-    else
-    {
-        irq = GIC390_IRQ_NONE;
-    }
-
-    return irq;
-}
-
-void arm_gic_mask(int irq)
-{
-    int word = irq / 32;
-    int bit = irq & 0x1f;
-
-    gic_dist->enable_clr[word] = BIT(bit);
-}
-
-void arm_gic_umask(int irq)
-{
-    int word = irq / 32;
-    int bit = irq & 0x1f;
-    gic_dist->enable_set[word] = BIT(bit);
-}
-
-void arm_gic_ack(int irq)
-{
-    if (!(IS_IRQ_VALID(active_irq) && (active_irq & IRQ_MASK) == irq))
-    {
-        return;
-    }
-    if (is_irq_edge_triggered(irq))
-    {
-        dist_pending_clr(irq);
-    }
-
-    gic_cpuiface->eoi = active_irq;
-    active_irq = GIC390_IRQ_NONE;
-}
-
-int rt_hw_interrupt_get_irq(void)
-{
-    return arm_gic_get_active_irq();
-}
-
-void rt_hw_interrupt_ack(int fiq_irq)
-{
-    return arm_gic_ack(fiq_irq);
-}
-

+ 0 - 27
libcpu/aarch64/common/gic/gic_pl390.h

@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2021-07-31     GuEe-GUI     the first version
- */
-
-#ifndef GIC_PL390_H__
-#define GIC_PL390_H__
-
-#include <board.h>
-
-#define GIC390_SPECIAL_IRQ_START    1020
-#define GIC390_IRQ_NONE             1023
-
-void arm_gic_irq_init(void);
-
-int arm_gic_get_active_irq(void);
-void arm_gic_ack(int irq);
-
-void arm_gic_mask(int irq);
-void arm_gic_umask(int irq);
-
-#endif

+ 0 - 261
libcpu/aarch64/common/gic/gic_pl400.c

@@ -1,261 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-20     Bernard      first version
- * 2014-04-03     Grissiom     many enhancements
- * 2018-11-22     Jesven       add rt_hw_ipi_send()
- *                             add rt_hw_ipi_handler_install()
- */
-#include <rtthread.h>
-
-#include "gic_pl400.h"
-#include "cp15.h"
-
-#define ARM_GIC_MAX_NR 1
-struct arm_gic
-{
-    rt_uint32_t offset;         /* the first interrupt index in the vector table */
-
-    rt_uint32_t dist_hw_base;   /* the base address of the gic distributor */
-    rt_uint32_t cpu_hw_base;    /* the base addrees of the gic cpu interface */
-};
-
-/* 'ARM_GIC_MAX_NR' is the number of cores */
-static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
-
-static unsigned int _gic_max_irq;
-
-int arm_gic_get_active_irq(rt_uint32_t index)
-{
-    int irq;
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base);
-    irq += _gic_table[index].offset;
-    return irq;
-}
-
-void arm_gic_ack(rt_uint32_t index, int irq)
-{
-    rt_uint32_t mask = 1 << (irq % 32);
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    irq = irq - _gic_table[index].offset;
-    RT_ASSERT(irq >= 0);
-
-    GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
-    GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq;
-    GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask;
-}
-
-void arm_gic_mask(rt_uint32_t index, int irq)
-{
-    rt_uint32_t mask = 1 << (irq % 32);
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    irq = irq - _gic_table[index].offset;
-    RT_ASSERT(irq >= 0);
-
-    GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
-}
-
-void arm_gic_clear_pending(rt_uint32_t index, int irq)
-{
-    rt_uint32_t mask = 1 << (irq % 32);
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    irq = irq - _gic_table[index].offset;
-    RT_ASSERT(irq >= 0);
-
-    GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
-}
-
-void arm_gic_clear_active(rt_uint32_t index, int irq)
-{
-    rt_uint32_t mask = 1 << (irq % 32);
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    irq = irq - _gic_table[index].offset;
-    RT_ASSERT(irq >= 0);
-
-    GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
-}
-
-/* Set up the cpu mask for the specific interrupt */
-void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask)
-{
-    rt_uint32_t old_tgt;
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    irq = irq - _gic_table[index].offset;
-    RT_ASSERT(irq >= 0);
-
-    old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq);
-
-    old_tgt &= ~(0x0FFUL << ((irq % 4)*8));
-    old_tgt |=   cpumask << ((irq % 4)*8);
-
-    GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt;
-}
-
-void arm_gic_umask(rt_uint32_t index, int irq)
-{
-    rt_uint32_t mask = 1 << (irq % 32);
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    irq = irq - _gic_table[index].offset;
-    RT_ASSERT(irq >= 0);
-
-    GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask;
-}
-
-void arm_gic_dump_type(rt_uint32_t index)
-{
-    unsigned int gic_type;
-
-    gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base);
-    rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n",
-               (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf,
-               _gic_table[index].dist_hw_base,
-               _gic_max_irq,
-               gic_type & (1 << 10) ? "has" : "no",
-               gic_type);
-}
-
-void arm_gic_dump(rt_uint32_t index)
-{
-    unsigned int i, k;
-
-    k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base);
-    rt_kprintf("--- high pending priority: %d(%08x)\n", k, k);
-    rt_kprintf("--- hw mask ---\n");
-    for (i = 0; i < _gic_max_irq / 32; i++)
-    {
-        rt_kprintf("0x%08x, ",
-                   GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base,
-                                       i * 32));
-    }
-    rt_kprintf("\n--- hw pending ---\n");
-    for (i = 0; i < _gic_max_irq / 32; i++)
-    {
-        rt_kprintf("0x%08x, ",
-                   GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base,
-                                        i * 32));
-    }
-    rt_kprintf("\n--- hw active ---\n");
-    for (i = 0; i < _gic_max_irq / 32; i++)
-    {
-        rt_kprintf("0x%08x, ",
-                   GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base,
-                                       i * 32));
-    }
-    rt_kprintf("\n");
-}
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-FINSH_FUNCTION_EXPORT_ALIAS(arm_gic_dump, gic, show gic status);
-#endif
-
-int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start)
-{
-    unsigned int gic_type, i;
-    rt_uint32_t cpumask = 1 << 0;
-
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    _gic_table[index].dist_hw_base = dist_base;
-    _gic_table[index].offset = irq_start;
-
-    /* Find out how many interrupts are supported. */
-    gic_type = GIC_DIST_TYPE(dist_base);
-    _gic_max_irq = ((gic_type & 0x1f) + 1) * 32;
-
-    /*
-     * The GIC only supports up to 1020 interrupt sources.
-     * Limit this to either the architected maximum, or the
-     * platform maximum.
-     */
-    if (_gic_max_irq > 1020)
-        _gic_max_irq = 1020;
-    if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */
-        _gic_max_irq = ARM_GIC_NR_IRQS;
-
-    cpumask |= cpumask << 8;
-    cpumask |= cpumask << 16;
-    cpumask |= cpumask << 24;
-
-    GIC_DIST_CTRL(dist_base) = 0x0;
-
-    /* Set all global interrupts to be level triggered, active low. */
-    for (i = 32; i < _gic_max_irq; i += 16)
-        GIC_DIST_CONFIG(dist_base, i) = 0x0;
-
-    /* Set all global interrupts to this CPU only. */
-    for (i = 32; i < _gic_max_irq; i += 4)
-        GIC_DIST_TARGET(dist_base, i) = cpumask;
-
-    /* Set priority on all interrupts. */
-    for (i = 0; i < _gic_max_irq; i += 4)
-        GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0;
-
-    /* Disable all interrupts. */
-    for (i = 0; i < _gic_max_irq; i += 32)
-        GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff;
-
-#if 0
-    /* All interrupts defaults to IGROUP1(IRQ). */
-    for (i = 0; i < _gic_max_irq; i += 32)
-        GIC_DIST_IGROUP(dist_base, i) = 0xffffffff;
-#endif
-    for (i = 0; i < _gic_max_irq; i += 32)
-        GIC_DIST_IGROUP(dist_base, i) = 0;
-
-    /* Enable group0 and group1 interrupt forwarding. */
-    GIC_DIST_CTRL(dist_base) = 0x01;
-
-    return 0;
-}
-
-int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base)
-{
-    RT_ASSERT(index < ARM_GIC_MAX_NR);
-
-    _gic_table[index].cpu_hw_base = cpu_base;
-
-    GIC_CPU_PRIMASK(cpu_base) = 0xf0;
-    GIC_CPU_BINPOINT(cpu_base) = 0x7;
-    /* Enable CPU interrupt */
-    GIC_CPU_CTRL(cpu_base) = 0x01;
-
-    return 0;
-}
-
-void arm_gic_set_group(rt_uint32_t index, int vector, int group)
-{
-    /* As for GICv2, there are only group0 and group1. */
-    RT_ASSERT(group <= 1);
-    RT_ASSERT(vector < _gic_max_irq);
-
-    if (group == 0)
-    {
-        GIC_DIST_IGROUP(_gic_table[index].dist_hw_base,
-                        vector) &= ~(1 << (vector % 32));
-    }
-    else if (group == 1)
-    {
-        GIC_DIST_IGROUP(_gic_table[index].dist_hw_base,
-                        vector) |=  (1 << (vector % 32));
-    }
-}
-

+ 0 - 61
libcpu/aarch64/common/gic/gic_pl400.h

@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-20     Bernard      first version
- */
-
-#ifndef __GIC_PL400_H__
-#define __GIC_PL400_H__
-
-#include <rthw.h>
-#include <board.h>
-
-#define __REG32(x) (*((volatile unsigned int*)((rt_uint64_t)x)))
-
-#define GIC_CPU_CTRL(hw_base)               __REG32((hw_base) + 0x00)
-#define GIC_CPU_PRIMASK(hw_base)            __REG32((hw_base) + 0x04)
-#define GIC_CPU_BINPOINT(hw_base)           __REG32((hw_base) + 0x08)
-#define GIC_CPU_INTACK(hw_base)             __REG32((hw_base) + 0x0c)
-#define GIC_CPU_EOI(hw_base)                __REG32((hw_base) + 0x10)
-#define GIC_CPU_RUNNINGPRI(hw_base)         __REG32((hw_base) + 0x14)
-#define GIC_CPU_HIGHPRI(hw_base)            __REG32((hw_base) + 0x18)
-
-#define GIC_DIST_CTRL(hw_base)              __REG32((hw_base) + 0x000)
-#define GIC_DIST_TYPE(hw_base)              __REG32((hw_base) + 0x004)
-#define GIC_DIST_IGROUP(hw_base, n)         __REG32((hw_base) + 0x080 + ((n)/32) * 4)
-#define GIC_DIST_ENABLE_SET(hw_base, n)     __REG32((hw_base) + 0x100 + ((n)/32) * 4)
-#define GIC_DIST_ENABLE_CLEAR(hw_base, n)   __REG32((hw_base) + 0x180 + ((n)/32) * 4)
-#define GIC_DIST_PENDING_SET(hw_base, n)    __REG32((hw_base) + 0x200 + ((n)/32) * 4)
-#define GIC_DIST_PENDING_CLEAR(hw_base, n)  __REG32((hw_base) + 0x280 + ((n)/32) * 4)
-#define GIC_DIST_ACTIVE_SET(hw_base, n)     __REG32((hw_base) + 0x300 + ((n)/32) * 4)
-#define GIC_DIST_ACTIVE_CLEAR(hw_base, n)   __REG32((hw_base) + 0x380 + ((n)/32) * 4)
-#define GIC_DIST_PRI(hw_base, n)            __REG32((hw_base) + 0x400 +  ((n)/4) * 4)
-#define GIC_DIST_TARGET(hw_base, n)         __REG32((hw_base) + 0x800 +  ((n)/4) * 4)
-#define GIC_DIST_CONFIG(hw_base, n)         __REG32((hw_base) + 0xc00 + ((n)/16) * 4)
-#define GIC_DIST_SOFTINT(hw_base)           __REG32((hw_base) + 0xf00)
-#define GIC_DIST_CPENDSGI(hw_base, n)       __REG32((hw_base) + 0xf10 + ((n)/4) * 4)
-#define GIC_DIST_ICPIDR2(hw_base)           __REG32((hw_base) + 0xfe8)
-
-int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start);
-int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base);
-
-void arm_gic_mask(rt_uint32_t index, int irq);
-void arm_gic_umask(rt_uint32_t index, int irq);
-void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask);
-void arm_gic_set_group(rt_uint32_t index, int vector, int group);
-
-int arm_gic_get_active_irq(rt_uint32_t index);
-void arm_gic_ack(rt_uint32_t index, int irq);
-
-void arm_gic_clear_active(rt_uint32_t index, int irq);
-void arm_gic_clear_pending(rt_uint32_t index, int irq);
-
-void arm_gic_dump_type(rt_uint32_t index);
-void arm_gic_dump(rt_uint32_t index);
-
-#endif
-

+ 409 - 0
libcpu/aarch64/common/interrupt.c

@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-06     Bernard      first version
+ * 2018-11-22     Jesven       add smp support
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "interrupt.h"
+#include "gic.h"
+#include "armv8.h"
+#include "mmu.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;
+
+#ifdef RT_USING_SMP
+#define rt_interrupt_nest rt_cpu_self()->irq_nest
+#else
+extern volatile rt_uint8_t rt_interrupt_nest;
+#endif
+
+#ifndef BSP_USING_GIC
+static void default_isr_handler(int vector, void *param)
+{
+#ifdef RT_USING_SMP
+    rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector);
+#else
+    rt_kprintf("unhandled irq: %d\n",vector);
+#endif
+}
+#endif
+
+void rt_hw_vector_init(void)
+{
+    rt_hw_set_current_vbar((rt_ubase_t)&system_vectors);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+#ifndef BSP_USING_GIC
+    rt_uint32_t index;
+    /* initialize vector table */
+    rt_hw_vector_init();
+
+    /* initialize exceptions table */
+    rt_memset(isr_table, 0x00, sizeof(isr_table));
+
+    /* mask all of interrupts */
+    IRQ_DISABLE_BASIC = 0x000000ff;
+    IRQ_DISABLE1      = 0xffffffff;
+    IRQ_DISABLE2      = 0xffffffff;
+    for (index = 0; index < MAX_HANDLERS; index ++)
+    {
+        isr_table[index].handler = default_isr_handler;
+        isr_table[index].param = RT_NULL;
+#ifdef RT_USING_INTERRUPT_INFO
+        rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX);
+        isr_table[index].counter = 0;
+#endif
+    }
+
+    /* init interrupt nest, and context in thread sp */
+    rt_interrupt_nest = 0;
+    rt_interrupt_from_thread = 0;
+    rt_interrupt_to_thread = 0;
+    rt_thread_switch_interrupt_flag = 0;
+#else
+    rt_uint64_t gic_cpu_base;
+    rt_uint64_t gic_dist_base;
+    rt_uint64_t gic_irq_start;
+
+    /* initialize vector table */
+    rt_hw_vector_init();
+
+    /* initialize exceptions table */
+    rt_memset(isr_table, 0x00, sizeof(isr_table));
+
+    /* initialize ARM GIC */
+    gic_dist_base = platform_get_gic_dist_base();
+    gic_cpu_base = platform_get_gic_cpu_base();
+
+    gic_irq_start = GIC_IRQ_START;
+
+    arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
+    arm_gic_cpu_init(0, gic_cpu_base);
+#endif
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+#ifndef BSP_USING_GIC
+    if (vector < 32)
+    {
+        IRQ_DISABLE1 = (1 << vector);
+    }
+    else if (vector < 64)
+    {
+        vector = vector % 32;
+        IRQ_DISABLE2 = (1 << vector);
+    }
+    else
+    {
+        vector = vector - 64;
+        IRQ_DISABLE_BASIC = (1 << vector);
+    }
+#else
+    arm_gic_mask(0, vector);
+#endif
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+#ifndef BSP_USING_GIC
+if (vector < 32)
+    {
+        IRQ_ENABLE1 = (1 << vector);
+    }
+    else if (vector < 64)
+    {
+        vector = vector % 32;
+        IRQ_ENABLE2 = (1 << vector);
+    }
+    else
+    {
+        vector = vector - 64;
+        IRQ_ENABLE_BASIC = (1 << vector);
+    }
+#else
+    arm_gic_umask(0, vector);
+#endif
+}
+
+/**
+ * This function returns the active interrupt number.
+ * @param none
+ */
+int rt_hw_interrupt_get_irq(void)
+{
+#ifdef BSP_USING_GIC
+    return arm_gic_get_active_irq(0);
+#else
+    return 0;
+#endif
+}
+
+/**
+ * This function acknowledges the interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_ack(int vector)
+{
+#ifdef BSP_USING_GIC
+    arm_gic_ack(0, vector);
+#endif
+}
+
+/**
+ * This function set interrupt CPU targets.
+ * @param vector:   the interrupt number
+ *        cpu_mask: target cpus mask, one bit for one core
+ */
+void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask)
+{
+#ifdef BSP_USING_GIC
+    arm_gic_set_cpu(0, vector, cpu_mask);
+#endif
+}
+
+/**
+ * This function get interrupt CPU targets.
+ * @param vector: the interrupt number
+ * @return target cpus mask, one bit for one core
+ */
+unsigned int rt_hw_interrupt_get_target_cpus(int vector)
+{
+#ifdef BSP_USING_GIC
+    return arm_gic_get_target_cpu(0, vector);
+#else
+    return -RT_ERROR;
+#endif
+}
+
+/**
+ * This function set interrupt triger mode.
+ * @param vector: the interrupt number
+ *        mode:   interrupt triger mode; 0: level triger, 1: edge triger
+ */
+void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode)
+{
+#ifdef BSP_USING_GIC
+    arm_gic_set_configuration(0, vector, mode);
+#endif
+}
+
+/**
+ * This function get interrupt triger mode.
+ * @param vector: the interrupt number
+ * @return interrupt triger mode; 0: level triger, 1: edge triger
+ */
+unsigned int rt_hw_interrupt_get_triger_mode(int vector)
+{
+#ifdef BSP_USING_GIC
+    return arm_gic_get_configuration(0, vector);
+#else
+    return -RT_ERROR;
+#endif
+}
+
+/**
+ * This function set interrupt pending flag.
+ * @param vector: the interrupt number
+ */
+void rt_hw_interrupt_set_pending(int vector)
+{
+#ifdef BSP_USING_GIC
+    arm_gic_set_pending_irq(0, vector);
+#endif
+}
+
+/**
+ * This function get interrupt pending flag.
+ * @param vector: the interrupt number
+ * @return interrupt pending flag, 0: not pending; 1: pending
+ */
+unsigned int rt_hw_interrupt_get_pending(int vector)
+{
+#ifdef BSP_USING_GIC
+    return arm_gic_get_pending_irq(0, vector);
+#else
+    return -RT_ERROR;
+#endif
+}
+
+/**
+ * This function clear interrupt pending flag.
+ * @param vector: the interrupt number
+ */
+void rt_hw_interrupt_clear_pending(int vector)
+{
+#ifdef BSP_USING_GIC
+    arm_gic_clear_pending_irq(0, vector);
+#endif
+}
+
+/**
+ * This function set interrupt priority value.
+ * @param vector: the interrupt number
+ *        priority: the priority of interrupt to set
+ */
+void rt_hw_interrupt_set_priority(int vector, unsigned int priority)
+{
+#ifdef BSP_USING_GIC
+    arm_gic_set_priority(0, vector, priority);
+#endif
+}
+
+/**
+ * This function get interrupt priority.
+ * @param vector: the interrupt number
+ * @return interrupt priority value
+ */
+unsigned int rt_hw_interrupt_get_priority(int vector)
+{
+#ifdef BSP_USING_GIC
+    return arm_gic_get_priority(0, vector);
+#else
+    return -RT_ERROR;
+#endif
+}
+
+/**
+ * This function set priority masking threshold.
+ * @param priority: priority masking threshold
+ */
+void rt_hw_interrupt_set_priority_mask(unsigned int priority)
+{
+#ifdef BSP_USING_GIC
+    arm_gic_set_interface_prior_mask(0, priority);
+#endif
+}
+
+/**
+ * This function get priority masking threshold.
+ * @param none
+ * @return priority masking threshold
+ */
+unsigned int rt_hw_interrupt_get_priority_mask(void)
+{
+#ifdef BSP_USING_GIC
+    return arm_gic_get_interface_prior_mask(0);
+#else
+    return -RT_ERROR;
+#endif
+}
+
+/**
+ * This function set priority grouping field split point.
+ * @param bits: priority grouping field split point
+ * @return 0: success; -1: failed
+ */
+int rt_hw_interrupt_set_prior_group_bits(unsigned int bits)
+{
+#ifdef BSP_USING_GIC
+    int status;
+
+    if (bits < 8)
+    {
+        arm_gic_set_binary_point(0, (7 - bits));
+        status = 0;
+    }
+    else
+    {
+        status = -1;
+    }
+
+    return (status);
+#else
+    return -RT_ERROR;
+#endif
+}
+
+/**
+ * This function get priority grouping field split point.
+ * @param none
+ * @return priority grouping field split point
+ */
+unsigned int rt_hw_interrupt_get_prior_group_bits(void)
+{
+#ifdef BSP_USING_GIC
+    unsigned int bp;
+
+    bp = arm_gic_get_binary_point(0) & 0x07;
+
+    return (7 - bp);
+#else
+    return -RT_ERROR;
+#endif
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+        void *param, const char *name)
+{
+    rt_isr_handler_t old_handler = RT_NULL;
+
+    if (vector < MAX_HANDLERS)
+    {
+        old_handler = isr_table[vector].handler;
+
+        if (handler != RT_NULL)
+        {
+#ifdef RT_USING_INTERRUPT_INFO
+            rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
+#endif /* RT_USING_INTERRUPT_INFO */
+            isr_table[vector].handler = handler;
+            isr_table[vector].param = param;
+        }
+    }
+
+    return old_handler;
+}
+
+#ifdef RT_USING_SMP
+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);
+#endif
+}
+
+void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)
+{
+    /* note: ipi_vector maybe different with irq_vector */
+    rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER");
+}
+#endif
+

+ 60 - 0
libcpu/aarch64/common/interrupt.h

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-06     Bernard      first version
+ */
+
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+#include <rthw.h>
+#include <board.h>
+
+#define INT_IRQ     0x00
+#define INT_FIQ     0x01
+
+#define IRQ_MODE_TRIG_LEVEL         (0x00) /* Trigger: level triggered interrupt */
+#define IRQ_MODE_TRIG_EDGE          (0x01) /* Trigger: edge triggered interrupt */
+
+void rt_hw_vector_init(void);
+
+void rt_hw_interrupt_init(void);
+void rt_hw_interrupt_mask(int vector);
+void rt_hw_interrupt_umask(int vector);
+
+int rt_hw_interrupt_get_irq(void);
+void rt_hw_interrupt_ack(int vector);
+
+void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask);
+unsigned int rt_hw_interrupt_get_target_cpus(int vector);
+
+void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode);
+unsigned int rt_hw_interrupt_get_triger_mode(int vector);
+
+void rt_hw_interrupt_set_pending(int vector);
+unsigned int rt_hw_interrupt_get_pending(int vector);
+void rt_hw_interrupt_clear_pending(int vector);
+
+void rt_hw_interrupt_set_priority(int vector, unsigned int priority);
+unsigned int rt_hw_interrupt_get_priority(int vector);
+
+void rt_hw_interrupt_set_priority_mask(unsigned int priority);
+unsigned int rt_hw_interrupt_get_priority_mask(void);
+
+int rt_hw_interrupt_set_prior_group_bits(unsigned int bits);
+unsigned int rt_hw_interrupt_get_prior_group_bits(void);
+
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+        void *param, const char *name);
+
+#ifdef RT_USING_SMP
+void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask);
+void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
+#endif
+
+#endif
+

+ 1 - 2
libcpu/aarch64/cortex-a72/stack.c → libcpu/aarch64/common/stack.c

@@ -27,8 +27,7 @@
  *
  * @return stack address
  */
-rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
-    rt_uint8_t *stack_addr, void *texit)
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
 {
     rt_ubase_t *stk;
     rt_ubase_t current_el;

+ 172 - 0
libcpu/aarch64/common/trap.c

@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-20     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <board.h>
+
+#include <armv8.h>
+#include <interrupt.h>
+
+#ifdef RT_USING_FINSH
+extern long list_thread(void);
+#endif
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+void rt_hw_show_register(struct rt_hw_exp_stack *regs)
+{
+    rt_kprintf("Execption:\n");
+    rt_kprintf("X00:0x%16.16p X01:0x%16.16p X02:0x%16.16p X03:0x%16.16p\n", (void *)regs->x0, (void *)regs->x1, (void *)regs->x2, (void *)regs->x3);
+    rt_kprintf("X04:0x%16.16p X05:0x%16.16p X06:0x%16.16p X07:0x%16.16p\n", (void *)regs->x4, (void *)regs->x5, (void *)regs->x6, (void *)regs->x7);
+    rt_kprintf("X08:0x%16.16p X09:0x%16.16p X10:0x%16.16p X11:0x%16.16p\n", (void *)regs->x8, (void *)regs->x9, (void *)regs->x10, (void *)regs->x11);
+    rt_kprintf("X12:0x%16.16p X13:0x%16.16p X14:0x%16.16p X15:0x%16.16p\n", (void *)regs->x12, (void *)regs->x13, (void *)regs->x14, (void *)regs->x15);
+    rt_kprintf("X16:0x%16.16p X17:0x%16.16p X18:0x%16.16p X19:0x%16.16p\n", (void *)regs->x16, (void *)regs->x17, (void *)regs->x18, (void *)regs->x19);
+    rt_kprintf("X20:0x%16.16p X21:0x%16.16p X22:0x%16.16p X23:0x%16.16p\n", (void *)regs->x20, (void *)regs->x21, (void *)regs->x22, (void *)regs->x23);
+    rt_kprintf("X24:0x%16.16p X25:0x%16.16p X26:0x%16.16p X27:0x%16.16p\n", (void *)regs->x24, (void *)regs->x25, (void *)regs->x26, (void *)regs->x27);
+    rt_kprintf("X28:0x%16.16p X29:0x%16.16p X30:0x%16.16p\n", (void *)regs->x28, (void *)regs->x29, (void *)regs->x30);
+    rt_kprintf("SPSR  :0x%16.16p\n", (void *)regs->spsr);
+    rt_kprintf("EPC   :0x%16.16p\n", (void *)regs->pc);
+}
+
+/**
+ * When comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_error(struct rt_hw_exp_stack *regs)
+{
+    rt_kprintf("error exception:\n");
+    rt_hw_show_register(regs);
+#ifdef RT_USING_FINSH
+    list_thread();
+#endif
+    rt_hw_cpu_shutdown();
+}
+
+void rt_hw_trap_irq(void)
+{
+#ifndef BSP_USING_GIC
+    void *param;
+    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;
+
+#ifdef BSP_USING_CORETIMER
+    uint32_t cpu_id = 0;
+#ifdef RT_USING_SMP
+    cpu_id = rt_hw_cpu_id();
+#endif
+    uint32_t int_source = CORE_IRQSOURCE(cpu_id) & 0x3ff;
+    if (int_source & 0x02)
+    {
+        isr_func = isr_table[IRQ_ARM_TIMER].handler;
+#ifdef RT_USING_INTERRUPT_INFO
+        isr_table[IRQ_ARM_TIMER].counter++;
+#endif
+        if (isr_func)
+        {
+            param = isr_table[IRQ_ARM_TIMER].param;
+            isr_func(IRQ_ARM_TIMER, param);
+        }
+    }
+#endif
+
+    /* local interrupt*/
+    if (value)
+    {
+        if (value & (1 << 8))
+        {
+            value = IRQ_PEND1;
+            irq = __rt_ffs(value) - 1;
+        }
+        else if (value & (1 << 9))
+        {
+            value = IRQ_PEND2;
+            irq = __rt_ffs(value) + 31;
+        }
+        else
+        {
+            value &= 0x0f;
+            irq = __rt_ffs(value) + 63;
+        }
+
+        /* get interrupt service routine */
+        isr_func = isr_table[irq].handler;
+#ifdef RT_USING_INTERRUPT_INFO
+        isr_table[irq].counter++;
+#endif
+        if (isr_func)
+        {
+            /* Interrupt for myself. */
+            param = isr_table[irq].param;
+            /* turn to interrupt service routine */
+            isr_func(irq, param);
+        }
+    }
+#else
+    void *param;
+    int ir;
+    rt_isr_handler_t isr_func;
+    extern struct rt_irq_desc isr_table[];
+
+    ir = rt_hw_interrupt_get_irq();
+
+    if (ir == 1023)
+    {
+        /* Spurious interrupt */
+        return;
+    }
+
+    /* get interrupt service routine */
+    isr_func = isr_table[ir].handler;
+#ifdef RT_USING_INTERRUPT_INFO
+    isr_table[ir].counter++;
+#endif
+    if (isr_func)
+    {
+        /* Interrupt for myself. */
+        param = isr_table[ir].param;
+        /* turn to interrupt service routine */
+        isr_func(ir, param);
+    }
+
+    /* end of interrupt */
+    rt_hw_interrupt_ack(ir);
+#endif
+}
+
+void rt_hw_trap_fiq(void)
+{
+    void *param;
+    int ir;
+    rt_isr_handler_t isr_func;
+    extern struct rt_irq_desc isr_table[];
+
+    ir = rt_hw_interrupt_get_irq();
+
+    /* get interrupt service routine */
+    isr_func = isr_table[ir].handler;
+    param = isr_table[ir].param;
+
+    /* turn to interrupt service routine */
+    isr_func(ir, param);
+
+    /* end of interrupt */
+    rt_hw_interrupt_ack(ir);
+}

+ 1 - 1
libcpu/aarch64/cortex-a53/SConscript → libcpu/aarch64/cortex-a/SConscript

@@ -8,6 +8,6 @@ cwd     = GetCurrentDir()
 src     = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
 CPPPATH = [cwd]
 
-group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
+group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH)
 
 Return('group')

+ 97 - 0
libcpu/aarch64/cortex-a/entry_point.S

@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date           Author       Notes
+ * 2020-01-15     bigmagic     the first version
+ * 2020-08-10     SummerGift   support clang compiler
+ */
+
+.section ".text.entrypoint","ax"
+
+.globl _start
+_start:
+    /* Read cpu id */
+    mrs     x1, mpidr_el1
+    and     x1, x1, #3
+    cbz     x1, cpu_setup           /* If cpu id > 0, stop slave cores */
+
+cpu_idle:
+    wfe
+    b       cpu_idle
+
+cpu_setup:
+    ldr     x1, =_start
+
+    mrs     x0, CurrentEL           /* CurrentEL Register. bit 2, 3. Others reserved */
+    and     x0, x0, #12             /* Clear reserved bits */
+
+    /* Running at EL3? */
+    cmp     x0, #12                 /* EL3 value is 0b1100 */
+    bne     cpu_not_in_el3
+
+    /* Should never be executed, just for completeness. (EL3) */
+    mov     x0, #(1 << 0)           /* EL0 and EL1 are in Non-Secure state */
+    orr     x0, x0, #(1 << 4)       /* RES1 */
+    orr     x0, x0, #(1 << 5)       /* RES1 */
+    orr     x0, x0, #(1 << 7)       /* SMC instructions are undefined at EL1 and above */
+    orr     x0, x0, #(1 << 8)       /* HVC instructions are enabled at EL1 and above */
+    orr     x0, x0, #(1 << 10)      /* The next lower level is AArch64 */
+    msr     scr_el3, x2
+
+    mov     x2, #0x3c9
+    msr     spsr_el3, x2            /* 0b1111001001 */
+    adr     x2, cpu_not_in_el3
+    msr     elr_el3, x2
+    eret                            /* Exception Return: from EL3, continue from cpu_not_in_el3 */
+
+cpu_not_in_el3:                     /* Running at EL2 or EL1 */
+    cmp     x0, #4                  /* EL1 = 0100  */
+    beq     cpu_in_el1              /* Halt this core if running in El1 */
+
+cpu_in_el2:
+    msr     sp_el1, x1
+
+    /* Enable CNTP for EL1 */
+    mrs     x0, cnthctl_el2         /* Counter-timer Hypervisor Control register */
+    orr     x0, x0, #3
+    msr     cnthctl_el2, x0
+    msr     cntvoff_el2, xzr
+
+    mov     x0, #(1 << 31)          /* Enable AArch64 in EL1 */
+    orr     x0, x0, #(1 << 1)       /* SWIO hardwired on Pi3 */
+    msr     hcr_el2, x0
+
+    /* Change execution level to EL1 */
+    mov     x2, #0x3c4
+    msr     spsr_el2, x2            /* 0b1111000100 */
+    adr     x2, cpu_in_el1
+    msr     elr_el2, x2
+    eret
+
+cpu_in_el1:
+    mov     sp, x1                  /* Set sp in el1 */
+
+    /* Avoid trap from SIMD or float point instruction */
+    mov     x1, #0x00300000         /* Don't trap any SIMD/FP instructions in both EL0 and EL1 */
+    msr     cpacr_el1, x1
+
+    mrs     x1, sctlr_el1
+    orr     x1, x1, #(1 << 12)      /* Enable Instruction */
+    bic     x1, x1, #(3 << 3)       /* Disable SP Alignment check */
+    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, #1
+    cbnz    w2, clean_bss_loop
+
+jump_to_entry:
+    b       rtthread_startup
+    b       cpu_idle                /* For failsafe, halt this core too */

+ 0 - 116
libcpu/aarch64/cortex-a53/entry_point.S

@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2006-2020, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Date           Author       Notes
- * 2020-01-15     bigmagic    the first version
- */
-
-.section ".text.entrypoint"
-
-.set EL1_stack,         __el1_stack
-
-.global _start
-
-// This symbol is set to 0x80000 in ld script. That is the address that raspi3's firmware
-// loads 'kernel8.img' file in.
-_start:
-    // read cpu id, stop slave cores
-    mrs     x1, mpidr_el1            // MPIDR_EL1: Multi-Processor Affinity Register
-    and     x1, x1, #3
-    cbz     x1, .L__cpu_0             // .L prefix is the local label in ELF 
-
-    // cpu id > 0, stop
-    // cpu id == 0 will also goto here after returned from entry() if possible
-.L__current_cpu_idle:
-    wfe
-    b       .L__current_cpu_idle
-
-.L__cpu_0:  // cpu id == 0
-
-    // set stack before our code
-
-	/* Define stack pointer for current exception level */
-	// ldr	x2, =EL1_stack
-	// mov	sp, x2
-
-    ldr     x1, =init_el1_stack_limit
-
-    // set up EL1
-    mrs     x0, CurrentEL           // CurrentEL Register. bit 2, 3. Others reserved
-    and     x0, x0, #12             // clear reserved bits
-
-    // running at EL3?
-    cmp     x0, #12                // 1100b. So, EL3
-    bne     .L__not_in_el3         // 11?  !EL3 -> 5:
-
-    // should never be executed, just for completeness. (EL3)
-    mov     x2, #0x5b1
-    msr     scr_el3, x2            // SCR_ELn  Secure Configuration Register
-    mov     x2, #0x3c9
-    msr     spsr_el3, x2           // SPSR_ELn. Saved Program Status Register. 1111001001
-    adr     x2, .L__not_in_el3   
-    msr     elr_el3, x2
-    eret                           // Exception Return: from EL3, continue from .L__not_in_el3
-
-    // running at EL2 or EL1
-.L__not_in_el3:    
-    cmp     x0, #4                 // 0x04  0100 EL1
-    beq     .L__in_el1             // EL1 -> 5:
-
-    // in EL2
-    msr     sp_el1, x1             // Set sp of EL1 to _start
-
-    // enable CNTP for EL1
-    mrs     x0, cnthctl_el2         // Counter-timer Hypervisor Control register
-    orr     x0, x0, #3
-    msr     cnthctl_el2, x0
-    msr     cntvoff_el2, xzr
-
-    // enable AArch64 in EL1
-    mov     x0, #(1 << 31)          // AArch64
-    orr     x0, x0, #(1 << 1)       // SWIO hardwired on Pi3
-    msr     hcr_el2, x0
-    mrs     x0, hcr_el2
-
-    // change execution level to EL1
-    mov     x2, #0x3c4
-    msr     spsr_el2, x2        // 1111000100
-    adr     x2, .L__in_el1
-    msr     elr_el2, x2
-    eret                        // exception return. from EL2. continue from .L__in_el1
-
-.L__in_el1:
-    mov     sp, x1             // in EL1. Set sp to _start
-
-    // Set CPACR_EL1 (Architecture Feature Access Control Register) to avoid trap from SIMD or float point instruction
-    mov     x1, #0x00300000       // Don't trap any SIMD/FP instructions in both EL0 and EL1
-    msr     cpacr_el1, x1
-
-    mrs x1, sctlr_el1
-    orr x1, x1, #(1 << 12)
-    bic x1, x1, #(3 << 3)
-    bic x1, x1, #(1 << 1)
-    msr sctlr_el1, x1
-
-    // clear bss
-    ldr     x1, =__bss_start
-    ldr     w2, =__bss_size
-
-.L__clean_bss_loop:
-    cbz     w2, .L__jump_to_entry
-    str     xzr, [x1], #8
-    sub     w2, w2, #1
-    cbnz    w2, .L__clean_bss_loop
-
-    // jump to C code, should not return
-.L__jump_to_entry:
-    bl      entry
-    // for failsafe, halt this core too
-    b       .L__current_cpu_idle
-.bss
-.align 3
-init_el1_stack:
-    .space 4096
-init_el1_stack_limit:

+ 0 - 202
libcpu/aarch64/cortex-a53/interrupt.c

@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2018/5/3       Bernard      first version
- * 2019-07-28     zdzn         add smp support
- * 2019-08-09     zhangjun     fixup the problem of smp startup and scheduling issues,
- *                             write addr to mailbox3 to startup smp, and we use mailbox0 for ipi
- * 2021-07-31     GuEe-GUI     Add gic pl390 branch
- */
-
-#include <rthw.h>
-#include <board.h>
-#include <rtthread.h>
-
-#include "cp15.h"
-#include "armv8.h"
-#include "interrupt.h"
-
-#ifdef BSP_USING_GIC390
-#include <gic_pl390.h>
-#endif
-
-#define MAX_HANDLERS                72
-
-#ifdef RT_USING_SMP
-#define rt_interrupt_nest rt_cpu_self()->irq_nest
-#else
-extern volatile rt_uint8_t rt_interrupt_nest;
-#endif
-
-extern int system_vectors;
-
-/* exception and interrupt handler table */
-struct rt_irq_desc isr_table[MAX_HANDLERS];
-
-rt_ubase_t rt_interrupt_from_thread;
-rt_ubase_t rt_interrupt_to_thread;
-rt_ubase_t rt_thread_switch_interrupt_flag;
-
-void rt_hw_vector_init(void)
-{
-    rt_hw_set_current_vbar((rt_ubase_t)&system_vectors);  // cpu_gcc.S
-}
-
-#ifndef BSP_USING_GIC
-static void default_isr_handler(int vector, void *param)
-{
-#ifdef RT_USING_SMP
-    rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector);
-#else
-    rt_kprintf("unhandled irq: %d\n",vector);
-#endif
-}
-#endif
-
-/**
- * This function will initialize hardware interrupt
- */
-void rt_hw_interrupt_init(void)
-{
-#ifdef BSP_USING_GIC390
-    arm_gic_irq_init();
-#else
-    rt_uint32_t index;
-
-    /* mask all of interrupts */
-    IRQ_DISABLE_BASIC = 0x000000ff;
-    IRQ_DISABLE1      = 0xffffffff;
-    IRQ_DISABLE2      = 0xffffffff;
-    for (index = 0; index < MAX_HANDLERS; index ++)
-    {
-        isr_table[index].handler = default_isr_handler;
-        isr_table[index].param = NULL;
-#ifdef RT_USING_INTERRUPT_INFO
-        rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX);
-        isr_table[index].counter = 0;
-#endif
-    }
-
-    /* init interrupt nest, and context in thread sp */
-    rt_interrupt_nest = 0;
-    rt_interrupt_from_thread = 0;
-    rt_interrupt_to_thread = 0;
-    rt_thread_switch_interrupt_flag = 0;
-#endif
-}
-
-/**
- * This function will mask a interrupt.
- * @param vector the interrupt number
- */
-void rt_hw_interrupt_mask(int vector)
-{
-#ifdef BSP_USING_GIC390
-    arm_gic_mask(vector);
-#else
-    if (vector < 32)
-    {
-        IRQ_DISABLE1 = (1 << vector);
-    }
-    else if (vector<64)
-    {
-        vector = vector % 32;
-        IRQ_DISABLE2 = (1 << vector);
-    }
-    else
-    {
-        vector = vector - 64;
-        IRQ_DISABLE_BASIC = (1 << vector);
-    }
-#endif
-}
-
-/**
- * This function will un-mask a interrupt.
- * @param vector the interrupt number
- */
-void rt_hw_interrupt_umask(int vector)
-{
-#ifdef BSP_USING_GIC390
-    arm_gic_umask(vector);
-#else
-    if (vector < 32)
-    {
-        IRQ_ENABLE1 = (1 << vector);
-    }
-    else if (vector < 64)
-    {
-        vector = vector % 32;
-        IRQ_ENABLE2 = (1 << vector);
-    }
-    else
-    {
-        vector = vector - 64;
-        IRQ_ENABLE_BASIC = (1 << vector);
-    }
-#endif
-}
-
-/**
- * This function will install a interrupt service routine to a interrupt.
- * @param vector the interrupt number
- * @param new_handler the interrupt service routine to be installed
- * @param old_handler the old interrupt service routine
- */
-rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
-        void *param, const char *name)
-{
-    rt_isr_handler_t old_handler = RT_NULL;
-
-    if (vector < MAX_HANDLERS)
-    {
-        old_handler = isr_table[vector].handler;
-
-        if (handler != RT_NULL)
-        {
-#ifdef RT_USING_INTERRUPT_INFO
-            rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
-#endif /* RT_USING_INTERRUPT_INFO */
-            isr_table[vector].handler = handler;
-            isr_table[vector].param = param;
-        }
-    }
-
-    return old_handler;
-}
-
-#ifdef RT_USING_SMP
-void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
-{
-    __DSB();
-    if(cpu_mask & 0x1)
-    {
-        send_ipi_msg(0, ipi_vector);
-    }
-    if(cpu_mask & 0x2)
-    {
-        send_ipi_msg(1, ipi_vector);
-    }
-    if(cpu_mask & 0x4)
-    {
-        send_ipi_msg(2, ipi_vector);
-    }
-    if(cpu_mask & 0x8)
-    {
-        send_ipi_msg(3, ipi_vector);
-    }
-    __DSB();
-}
-#endif
-
-#ifdef RT_USING_SMP
-void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)
-{
-    /* note: ipi_vector maybe different with irq_vector */
-    rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER");
-}
-#endif

+ 0 - 27
libcpu/aarch64/cortex-a53/interrupt.h

@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author         Notes
- * 2020-04-16     bigmagic       first version
- */
-
-#ifndef __INTERRUPT_H__
-#define __INTERRUPT_H__
-
-#include <rthw.h>
-#include <board.h>
-
-#define INT_IRQ     0x00
-#define INT_FIQ     0x01
-
-void rt_hw_interrupt_init(void);
-void rt_hw_interrupt_mask(int vector);
-void rt_hw_interrupt_umask(int vector);
-
-rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
-        void *param, const char *name);
-
-#endif

+ 0 - 90
libcpu/aarch64/cortex-a53/stack.c

@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2011-09-23     Bernard      the first version
- * 2011-10-05     Bernard      add thumb mode
- */
-#include <rtthread.h>
-#include <board.h>
-
-#include <armv8.h>
-
-#define INITIAL_SPSR_EL3 (PSTATE_EL3 | SP_EL0)
-#define INITIAL_SPSR_EL2 (PSTATE_EL2 | SP_EL0)
-#define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_EL0)
-
-/**
- * This function will initialize thread stack
- *
- * @param tentry the entry of thread
- * @param parameter the parameter of entry
- * @param stack_addr the beginning stack address
- * @param texit the function will be called when thread exit
- *
- * @return stack address
- */
-rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
-    rt_uint8_t *stack_addr, void *texit)
-{
-    rt_ubase_t *stk;
-    rt_ubase_t current_el;
-
-    stk      = (rt_ubase_t*)stack_addr;
-
-    *(--stk) = ( rt_ubase_t ) 11;           /* X1 */
-    *(--stk) = ( rt_ubase_t ) parameter;    /* X0 */
-    *(--stk) = ( rt_ubase_t ) 33;           /* X3 */
-    *(--stk) = ( rt_ubase_t ) 22;           /* X2 */
-    *(--stk) = ( rt_ubase_t ) 55;           /* X5 */
-    *(--stk) = ( rt_ubase_t ) 44;           /* X4 */
-    *(--stk) = ( rt_ubase_t ) 77;           /* X7 */
-    *(--stk) = ( rt_ubase_t ) 66;           /* X6 */
-    *(--stk) = ( rt_ubase_t ) 99;           /* X9 */
-    *(--stk) = ( rt_ubase_t ) 88;           /* X8 */
-    *(--stk) = ( rt_ubase_t ) 11;           /* X11 */
-    *(--stk) = ( rt_ubase_t ) 10;           /* X10 */
-    *(--stk) = ( rt_ubase_t ) 13;           /* X13 */
-    *(--stk) = ( rt_ubase_t ) 12;           /* X12 */
-    *(--stk) = ( rt_ubase_t ) 15;           /* X15 */
-    *(--stk) = ( rt_ubase_t ) 14;           /* X14 */
-    *(--stk) = ( rt_ubase_t ) 17;           /* X17 */
-    *(--stk) = ( rt_ubase_t ) 16;           /* X16 */
-    *(--stk) = ( rt_ubase_t ) 19;           /* X19 */
-    *(--stk) = ( rt_ubase_t ) 18;           /* X18 */
-    *(--stk) = ( rt_ubase_t ) 21;           /* X21 */
-    *(--stk) = ( rt_ubase_t ) 20;           /* X20 */
-    *(--stk) = ( rt_ubase_t ) 23;           /* X23 */
-    *(--stk) = ( rt_ubase_t ) 22;           /* X22 */
-    *(--stk) = ( rt_ubase_t ) 25;           /* X25 */
-    *(--stk) = ( rt_ubase_t ) 24;           /* X24 */
-    *(--stk) = ( rt_ubase_t ) 27;           /* X27 */
-    *(--stk) = ( rt_ubase_t ) 26;           /* X26 */
-    *(--stk) = ( rt_ubase_t ) 29;           /* X29 */
-    *(--stk) = ( rt_ubase_t ) 28;           /* X28 */
-    *(--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. */
-
-    current_el = rt_hw_get_current_el();
-
-    if(current_el == 3)
-    {
-        *(--stk) = INITIAL_SPSR_EL3;
-    }
-    else if(current_el == 2)
-    {
-        *(--stk) = INITIAL_SPSR_EL2;
-    }
-    else
-    {
-        *(--stk) = INITIAL_SPSR_EL1;
-    }
-
-    *(--stk) = ( rt_ubase_t ) tentry;       /* Exception return address. */
-
-    /* return task's current stack address */
-    return (rt_uint8_t *)stk;
-}

+ 0 - 225
libcpu/aarch64/cortex-a53/trap.c

@@ -1,225 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Date           Author       Notes
- * 2018-10-06     ZhaoXiaowei  the first version
- * 2021-07-31     GuEe-GUI     Add gic_pl390 branch
- */
-
-#include <rtthread.h>
-#include <rthw.h>
-
-#include "interrupt.h"
-#include "armv8.h"
-
-#ifdef BSP_USING_GIC390
-#include <gic_pl390.h>
-#endif
-
-extern struct rt_thread *rt_current_thread;
-#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
-extern long list_thread(void);
-#endif
-
-/**
- * this function will show registers of CPU
- *
- * @param regs the registers point
- */
-void rt_hw_show_register(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("Execption:\n");
-    rt_kprintf("r00:0x%16.16lx r01:0x%16.16lx r02:0x%16.16lx r03:0x%16.16lx\n", regs->x0, regs->x1, regs->x2, regs->x3);
-    rt_kprintf("r04:0x%16.16lx r05:0x%16.16lx r06:0x%16.16lx r07:0x%16.16lx\n", regs->x4, regs->x5, regs->x6, regs->x7);
-    rt_kprintf("r08:0x%16.16lx r09:0x%16.16lx r10:0x%16.16lx r11:0x%16.16lx\n", regs->x8, regs->x9, regs->x10, regs->x11);
-    rt_kprintf("r12:0x%16.16lx r13:0x%16.16lx r14:0x%16.16lx r15:0x%16.16lx\n", regs->x12, regs->x13, regs->x14, regs->x15);
-    rt_kprintf("r16:0x%16.16lx r17:0x%16.16lx r18:0x%16.16lx r19:0x%16.16lx\n", regs->x16, regs->x17, regs->x18, regs->x19);
-    rt_kprintf("r20:0x%16.16lx r21:0x%16.16lx r22:0x%16.16lx r23:0x%16.16lx\n", regs->x20, regs->x21, regs->x22, regs->x23);
-    rt_kprintf("r24:0x%16.16lx r25:0x%16.16lx r26:0x%16.16lx r27:0x%16.16lx\n", regs->x24, regs->x25, regs->x26, regs->x27);
-    rt_kprintf("r28:0x%16.16lx r29:0x%16.16lx r30:0x%16.16lx\n", regs->x28, regs->x29, regs->x30);
-    rt_kprintf("spsr:0x%16.16lx\n", regs->spsr);
-    rt_kprintf("return pc:0x%16.16lx\n", regs->pc);
-}
-
-/**
- * When comes across an instruction which it cannot handle,
- * it takes the undefined instruction trap.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_error(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("error exception:\n");
-    rt_hw_show_register(regs);
-#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
-    list_thread();
-#endif
-    rt_hw_cpu_shutdown();
-}
-
-#define GIC_ACK_INTID_MASK              (0x000003ff)
-#define CORE0_IRQ_SOURCE                (0x40000060)
-
-void rt_hw_trap_irq(void)
-{
-    void *param;
-    uint32_t irq;
-    rt_isr_handler_t isr_func;
-    extern struct rt_irq_desc isr_table[];
-
-#ifndef BSP_USING_GIC390
-    uint32_t value = 0;
-    value = IRQ_PEND_BASIC & 0x3ff;
-#ifdef BSP_USING_CORETIMER
-    uint32_t int_source = HWREG32(CORE0_IRQ_SOURCE)  & 0x3ff;
-    if (int_source & 0x02)
-    {
-        isr_func = isr_table[IRQ_ARM_TIMER].handler;
-        #ifdef RT_USING_INTERRUPT_INFO
-                    isr_table[IRQ_ARM_TIMER].counter++;
-        #endif
-        if (isr_func)
-        {
-            param = isr_table[IRQ_ARM_TIMER].param;
-            isr_func(IRQ_ARM_TIMER, param);
-        }
-    }
-#endif
-    /* local interrupt*/
-    if (value)
-    {
-        if (value & (1 << 8))
-        {
-            value = IRQ_PEND1;
-            irq = __rt_ffs(value) - 1;
-        }
-        else if (value & (1 << 9))
-        {
-            value = IRQ_PEND2;
-            irq = __rt_ffs(value) + 31;
-        }
-        else
-        {
-            value &= 0x0f;
-            irq = __rt_ffs(value) + 63;
-        }
-#else
-    irq = arm_gic_get_active_irq();
-
-    if (irq == GIC390_IRQ_NONE)
-    {
-        /* Spurious interrupt */
-        return;
-    }
-#endif
-
-        /* get interrupt service routine */
-        isr_func = isr_table[irq].handler;
-#ifdef RT_USING_INTERRUPT_INFO
-        isr_table[irq].counter++;
-#endif
-        if (isr_func)
-        {
-            /* Interrupt for myself. */
-            param = isr_table[irq].param;
-            /* turn to interrupt service routine */
-            isr_func(irq, param);
-        }
-#ifndef BSP_USING_GIC390
-    }
-#else
-    /* end of interrupt */
-    arm_gic_ack(irq);
-#endif
-}
-
-void rt_hw_trap_fiq(void)
-{
-#ifndef BSP_USING_GIC390
-    void *param;
-    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;
-#ifdef RT_USING_SMP
-    uint32_t mailbox_data;
-    uint32_t cpu_id = rt_hw_cpu_id();
-    uint32_t int_source = CORE_IRQSOURCE(cpu_id);
-    mailbox_data = IPI_MAILBOX_CLEAR(cpu_id);
-    if (int_source & 0x0f)
-    {
-        if (int_source & 0x08)
-        {
-            isr_func = isr_table[IRQ_ARM_TIMER].handler;
-#ifdef RT_USING_INTERRUPT_INFO
-            isr_table[IRQ_ARM_TIMER].counter++;
-#endif
-            if (isr_func)
-            {
-                param = isr_table[IRQ_ARM_TIMER].param;
-                isr_func(IRQ_ARM_TIMER, param);
-            }
-        }
-    }
-    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;
-    }
-#endif
-    /* local interrupt*/
-    if (value)
-    {
-        if (value & (1 << 8))
-        {
-            value = IRQ_PEND1;
-            irq = __rt_ffs(value) - 1;
-        }
-        else if (value & (1 << 9))
-        {
-            value = IRQ_PEND2;
-            irq = __rt_ffs(value) + 31;
-        }
-        else
-        {
-            value &= 0x0f;
-            irq = __rt_ffs(value) + 63;
-        }
-
-        /* get interrupt service routine */
-        isr_func = isr_table[irq].handler;
-#ifdef RT_USING_INTERRUPT_INFO
-        isr_table[irq].counter++;
-#endif
-        if (irq > 1)
-            rt_kprintf("interrupt fiq %d\n", irq);
-        if (isr_func)
-        {
-            /* Interrupt for myself. */
-            param = isr_table[irq].param;
-            /* turn to interrupt service routine */
-            isr_func(irq, param);
-        }
-    }
-#endif
-}

+ 0 - 13
libcpu/aarch64/cortex-a72/SConscript

@@ -1,13 +0,0 @@
-# RT-Thread building script for component
-
-from building import *
-
-Import('rtconfig')
-
-cwd     = GetCurrentDir()
-src     = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
-CPPPATH = [cwd]
-
-group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
-
-Return('group')

+ 0 - 111
libcpu/aarch64/cortex-a72/entry_point.S

@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2006-2020, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Date           Author       Notes
- * 2020-01-15     bigmagic    the first version
- */
-
-.section ".text.entrypoint"
-
-.set EL1_stack,         __el1_stack
-
-.global _start
-
-// This symbol is set to 0x80000 in ld script. That is the address that raspi3's firmware
-// loads 'kernel8.img' file in.
-_start:
-    // read cpu id, stop slave cores
-    mrs     x1, mpidr_el1            // MPIDR_EL1: Multi-Processor Affinity Register
-    and     x1, x1, #3
-    cbz     x1, .L__cpu_0             // .L prefix is the local label in ELF 
-
-    // cpu id > 0, stop
-    // cpu id == 0 will also goto here after returned from entry() if possible
-.L__current_cpu_idle:
-    wfe
-    b       .L__current_cpu_idle
-
-.L__cpu_0:  // cpu id == 0
-
-    // set stack before our code
-
-	/* Define stack pointer for current exception level */
-	// ldr	x2, =EL1_stack
-	// mov	sp, x2
-
-    ldr     x1, =_start
-
-    // set up EL1
-    mrs     x0, CurrentEL           // CurrentEL Register. bit 2, 3. Others reserved
-    and     x0, x0, #12             // clear reserved bits
-
-    // running at EL3?
-    cmp     x0, #12                // 1100b. So, EL3
-    bne     .L__not_in_el3         // 11?  !EL3 -> 5:
-
-    // should never be executed, just for completeness. (EL3)
-    mov     x2, #0x5b1
-    msr     scr_el3, x2            // SCR_ELn  Secure Configuration Register
-    mov     x2, #0x3c9
-    msr     spsr_el3, x2           // SPSR_ELn. Saved Program Status Register. 1111001001
-    adr     x2, .L__not_in_el3   
-    msr     elr_el3, x2
-    eret                           // Exception Return: from EL3, continue from .L__not_in_el3
-
-    // running at EL2 or EL1
-.L__not_in_el3:    
-    cmp     x0, #4                 // 0x04  0100 EL1
-    beq     .L__in_el1             // EL1 -> 5:
-
-    // in EL2
-    msr     sp_el1, x1             // Set sp of EL1 to _start
-
-    // enable CNTP for EL1
-    mrs     x0, cnthctl_el2         // Counter-timer Hypervisor Control register
-    orr     x0, x0, #3
-    msr     cnthctl_el2, x0
-    msr     cntvoff_el2, xzr
-
-    // enable AArch64 in EL1
-    mov     x0, #(1 << 31)          // AArch64
-    orr     x0, x0, #(1 << 1)       // SWIO hardwired on Pi3
-    msr     hcr_el2, x0
-    mrs     x0, hcr_el2
-
-    // change execution level to EL1
-    mov     x2, #0x3c4
-    msr     spsr_el2, x2        // 1111000100
-    adr     x2, .L__in_el1
-    msr     elr_el2, x2
-    eret                        // exception return. from EL2. continue from .L__in_el1
-
-.L__in_el1:
-    mov     sp, x1             // in EL1. Set sp to _start
-
-    // Set CPACR_EL1 (Architecture Feature Access Control Register) to avoid trap from SIMD or float point instruction
-    mov     x1, #0x00300000       // Don't trap any SIMD/FP instructions in both EL0 and EL1
-    msr     cpacr_el1, x1
-
-    mrs x1, sctlr_el1
-    orr x1, x1, #(1 << 12)
-    bic x1, x1, #(3 << 3)
-    bic x1, x1, #(1 << 1)
-    msr sctlr_el1, x1
-
-    // clear bss
-    ldr     x1, =__bss_start
-    ldr     w2, =__bss_size
-
-.L__clean_bss_loop:
-    cbz     w2, .L__jump_to_entry
-    str     xzr, [x1], #8
-    sub     w2, w2, #1
-    cbnz    w2, .L__clean_bss_loop
-
-    // jump to C code, should not return
-.L__jump_to_entry:
-    bl      entry
-    // for failsafe, halt this core too
-    b       .L__current_cpu_idle

+ 0 - 118
libcpu/aarch64/cortex-a72/interrupt.c

@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author         Notes
- * 2020-04-16     bigmagic       first version
- */
-
-#include <rthw.h>
-#include <rtthread.h>
-#include <gic_pl400.h>
-#include <board.h>
-#include <armv8.h>
-
-#define MAX_HANDLERS                256
-#define GIC_ACK_INTID_MASK          0x000003ff
-
-#ifdef RT_USING_SMP
-#define rt_interrupt_nest rt_cpu_self()->irq_nest
-#else
-extern volatile rt_uint8_t rt_interrupt_nest;
-#endif
-
-extern int system_vectors;
-
-/* exception and interrupt handler table */
-struct rt_irq_desc isr_table[MAX_HANDLERS];
-
-rt_ubase_t rt_interrupt_from_thread;
-rt_ubase_t rt_interrupt_to_thread;
-rt_ubase_t rt_thread_switch_interrupt_flag;
-
-void rt_hw_vector_init(void)
-{
-    rt_hw_set_current_vbar((rt_ubase_t)&system_vectors);  // cpu_gcc.S
-}
-
-/**
- * This function will initialize hardware interrupt
- */
-void rt_hw_interrupt_init(void)
-{
-
-    rt_uint32_t gic_cpu_base = 0;
-    rt_uint32_t gic_dist_base = 0;
-
-    /* initialize ARM GIC */
-    gic_dist_base = GIC_PL400_DISTRIBUTOR_PPTR;
-    gic_cpu_base = GIC_PL400_CONTROLLER_PPTR;
-    arm_gic_dist_init(0, gic_dist_base, 0);
-    arm_gic_cpu_init(0, gic_cpu_base);
-}
-
-/**
- * This function will install a interrupt service routine to a interrupt.
- * @param vector the interrupt number
- * @param new_handler the interrupt service routine to be installed
- * @param old_handler the old interrupt service routine
- */
-rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
-        void *param, const char *name)
-{
-    rt_isr_handler_t old_handler = RT_NULL;
-
-    if (vector < MAX_HANDLERS)
-    {
-        old_handler = isr_table[vector].handler;
-
-        if (handler != RT_NULL)
-        {
-#ifdef RT_USING_INTERRUPT_INFO
-            rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
-#endif /* RT_USING_INTERRUPT_INFO */
-            isr_table[vector].handler = handler;
-            isr_table[vector].param = param;
-        }
-    }
-
-    return old_handler;
-}
-
-/**
- * This function will mask a interrupt.
- * @param vector the interrupt number
- */
-void rt_hw_interrupt_mask(int vector)
-{
-    arm_gic_mask(0, vector);
-}
-
-/**
- * This function will un-mask a interrupt.
- * @param vector the interrupt number
- */
-void rt_hw_interrupt_umask(int vector)
-{
-    arm_gic_umask(0, vector);
-}
-
-/**
- * This function returns the active interrupt number.
- * @param none
- */
-int rt_hw_interrupt_get_irq(void)
-{
-    return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK;
-}
-
-/**
- * This function acknowledges the interrupt.
- * @param vector the interrupt number
- */
-void rt_hw_interrupt_ack(int vector)
-{
-    arm_gic_ack(0, vector);
-}

+ 0 - 27
libcpu/aarch64/cortex-a72/interrupt.h

@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author         Notes
- * 2020-04-16     bigmagic       first version
- */
-
-#ifndef __INTERRUPT_H__
-#define __INTERRUPT_H__
-
-#include <rthw.h>
-#include <board.h>
-
-#define INT_IRQ     0x00
-#define INT_FIQ     0x01
-
-void rt_hw_interrupt_init(void);
-void rt_hw_interrupt_mask(int vector);
-void rt_hw_interrupt_umask(int vector);
-
-rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
-        void *param, const char *name);
-
-#endif

+ 0 - 98
libcpu/aarch64/cortex-a72/trap.c

@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Date           Author       Notes
- * 2018-10-06     ZhaoXiaowei    the first version
- */
-
-#include <rtthread.h>
-#include <rthw.h>
-
-#include "interrupt.h"
-#include "armv8.h"
-
-extern struct rt_thread *rt_current_thread;
-#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
-extern long list_thread(void);
-#endif
-
-/**
- * this function will show registers of CPU
- *
- * @param regs the registers point
- */
-void rt_hw_show_register(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("Execption:\n");
-    rt_kprintf("r00:0x%16.16lx r01:0x%16.16lx r02:0x%16.16lx r03:0x%16.16lx\n", regs->x0, regs->x1, regs->x2, regs->x3);
-    rt_kprintf("r04:0x%16.16lx r05:0x%16.16lx r06:0x%16.16lx r07:0x%16.16lx\n", regs->x4, regs->x5, regs->x6, regs->x7);
-    rt_kprintf("r08:0x%16.16lx r09:0x%16.16lx r10:0x%16.16lx r11:0x%16.16lx\n", regs->x8, regs->x9, regs->x10, regs->x11);
-    rt_kprintf("r12:0x%16.16lx r13:0x%16.16lx r14:0x%16.16lx r15:0x%16.16lx\n", regs->x12, regs->x13, regs->x14, regs->x15);
-    rt_kprintf("r16:0x%16.16lx r17:0x%16.16lx r18:0x%16.16lx r19:0x%16.16lx\n", regs->x16, regs->x17, regs->x18, regs->x19);
-    rt_kprintf("r20:0x%16.16lx r21:0x%16.16lx r22:0x%16.16lx r23:0x%16.16lx\n", regs->x20, regs->x21, regs->x22, regs->x23);
-    rt_kprintf("r24:0x%16.16lx r25:0x%16.16lx r26:0x%16.16lx r27:0x%16.16lx\n", regs->x24, regs->x25, regs->x26, regs->x27);
-    rt_kprintf("r28:0x%16.16lx r29:0x%16.16lx r30:0x%16.16lx\n", regs->x28, regs->x29, regs->x30);
-    rt_kprintf("spsr:0x%16.16lx\n", regs->spsr);
-    rt_kprintf("return pc:0x%16.16lx\n", regs->pc);
-}
-
-/**
- * When comes across an instruction which it cannot handle,
- * it takes the undefined instruction trap.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_error(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("error exception:\n");
-    rt_hw_show_register(regs);
-#if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
-    list_thread();
-#endif
-    rt_hw_cpu_shutdown();
-}
-
-#define GIC_ACK_INTID_MASK              0x000003ff
-
-int rt_hw_interrupt_get_irq(void);
-void rt_hw_interrupt_ack(int fiq_irq);
-
-void rt_hw_trap_irq(void)
-{
-    void *param;
-    int ir;
-    rt_isr_handler_t isr_func;
-    extern struct rt_irq_desc isr_table[];
-
-    ir = rt_hw_interrupt_get_irq();
-    if (ir == 1023)
-    {
-        /* Spurious interrupt */
-        return;
-    }
-
-    /* get interrupt service routine */
-    isr_func = isr_table[ir].handler;
-#ifdef RT_USING_INTERRUPT_INFO
-    isr_table[ir].counter++;
-#endif
-    if (isr_func)
-    {
-        /* Interrupt for myself. */
-        param = isr_table[ir].param;
-        /* turn to interrupt service routine */
-        isr_func(ir, param);
-    }
-
-    /* end of interrupt */
-    rt_hw_interrupt_ack(ir);
-
-}
-
-void rt_hw_trap_fiq(void)
-{
-}