From 740cd9dfb013a26cb5a9106a717deedd4478eff5 Mon Sep 17 00:00:00 2001 From: GuEe-GUI <2991707448@qq.com> Date: Wed, 22 Sep 2021 17:57:45 +0800 Subject: [PATCH] Merge AArch64 libcpu and add some drivers for their bsps --- bsp/qemu-virt64-aarch64/.config | 92 ++- bsp/qemu-virt64-aarch64/README.md | 3 +- bsp/qemu-virt64-aarch64/README_zh.md | 3 +- bsp/qemu-virt64-aarch64/SConstruct | 2 + bsp/qemu-virt64-aarch64/applications/mnt.c | 30 + bsp/qemu-virt64-aarch64/driver/Kconfig | 14 +- bsp/qemu-virt64-aarch64/driver/SConscript | 15 +- bsp/qemu-virt64-aarch64/driver/board.c | 41 +- bsp/qemu-virt64-aarch64/driver/board.h | 22 + bsp/qemu-virt64-aarch64/driver/drv_uart.c | 2 +- .../driver/virtio/SConscript | 11 + .../driver/virtio/drv_virtio_blk.c | 405 ++++++++++ .../driver/virtio/drv_virtio_blk.h | 85 ++ .../driver/virtio/virtio.h | 60 ++ .../driver/virtio/virtio_mmio.c | 61 ++ .../driver/virtio/virtio_mmio.h | 75 ++ bsp/qemu-virt64-aarch64/link.lds | 2 +- bsp/qemu-virt64-aarch64/qemu.bat | 7 +- bsp/qemu-virt64-aarch64/qemu.sh | 5 +- bsp/qemu-virt64-aarch64/rtconfig.h | 34 +- bsp/qemu-virt64-aarch64/rtconfig.py | 2 +- bsp/raspberry-pi/raspi3-64/.config | 230 +++++- bsp/raspberry-pi/raspi3-64/driver/mbox.h | 1 + bsp/raspberry-pi/raspi3-64/driver/raspi.h | 1 + bsp/raspberry-pi/raspi3-64/qemu-64.bat | 10 +- bsp/raspberry-pi/raspi3-64/qemu-64.sh | 4 + bsp/raspberry-pi/raspi3-64/rtconfig.h | 37 +- bsp/raspberry-pi/raspi3-64/rtconfig.py | 2 +- bsp/raspberry-pi/raspi4-64/.config | 359 +++++++-- bsp/raspberry-pi/raspi4-64/README.md | 6 +- bsp/raspberry-pi/raspi4-64/applications/mnt.c | 27 + bsp/raspberry-pi/raspi4-64/driver/Kconfig | 22 +- bsp/raspberry-pi/raspi4-64/driver/board.c | 36 + bsp/raspberry-pi/raspi4-64/driver/drv_eth.c | 723 ++++++++++++++++++ bsp/raspberry-pi/raspi4-64/driver/drv_eth.h | 216 ++++++ bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c | 69 ++ bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h | 47 +- bsp/raspberry-pi/raspi4-64/driver/drv_sdio.c | 720 +++++++++++++++++ bsp/raspberry-pi/raspi4-64/driver/drv_sdio.h | 268 +++++++ bsp/raspberry-pi/raspi4-64/driver/drv_uart.c | 281 ++++++- bsp/raspberry-pi/raspi4-64/driver/drv_uart.h | 24 + bsp/raspberry-pi/raspi4-64/driver/mbox.c | 519 +++++++++++++ bsp/raspberry-pi/raspi4-64/driver/mbox.h | 187 +++++ bsp/raspberry-pi/raspi4-64/driver/raspi4.h | 126 ++- bsp/raspberry-pi/raspi4-64/rtconfig.h | 123 ++- bsp/raspberry-pi/raspi4-64/rtconfig.py | 2 +- libcpu/aarch64/common/SConscript | 6 +- libcpu/aarch64/common/cpuport.h | 31 + libcpu/aarch64/common/gic.c | 504 ++++++++++++ libcpu/aarch64/common/gic.h | 63 ++ libcpu/aarch64/common/gic/SConscript | 30 - libcpu/aarch64/common/gic/gic_pl390.c | 273 ------- libcpu/aarch64/common/gic/gic_pl390.h | 27 - libcpu/aarch64/common/gic/gic_pl400.c | 261 ------- libcpu/aarch64/common/gic/gic_pl400.h | 61 -- libcpu/aarch64/common/interrupt.c | 409 ++++++++++ libcpu/aarch64/common/interrupt.h | 60 ++ libcpu/aarch64/{cortex-a72 => common}/stack.c | 3 +- libcpu/aarch64/common/trap.c | 172 +++++ .../{cortex-a53 => cortex-a}/SConscript | 2 +- libcpu/aarch64/cortex-a/entry_point.S | 97 +++ libcpu/aarch64/cortex-a53/entry_point.S | 116 --- libcpu/aarch64/cortex-a53/interrupt.c | 202 ----- libcpu/aarch64/cortex-a53/interrupt.h | 27 - libcpu/aarch64/cortex-a53/stack.c | 90 --- libcpu/aarch64/cortex-a53/trap.c | 225 ------ libcpu/aarch64/cortex-a72/SConscript | 13 - libcpu/aarch64/cortex-a72/entry_point.S | 111 --- libcpu/aarch64/cortex-a72/interrupt.c | 118 --- libcpu/aarch64/cortex-a72/interrupt.h | 27 - libcpu/aarch64/cortex-a72/trap.c | 98 --- 71 files changed, 6137 insertions(+), 1900 deletions(-) create mode 100644 bsp/qemu-virt64-aarch64/applications/mnt.c create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/SConscript create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio.h create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c create mode 100644 bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h create mode 100644 bsp/raspberry-pi/raspi3-64/qemu-64.sh create mode 100644 bsp/raspberry-pi/raspi4-64/applications/mnt.c create mode 100644 bsp/raspberry-pi/raspi4-64/driver/drv_eth.c create mode 100644 bsp/raspberry-pi/raspi4-64/driver/drv_eth.h create mode 100644 bsp/raspberry-pi/raspi4-64/driver/drv_sdio.c create mode 100644 bsp/raspberry-pi/raspi4-64/driver/drv_sdio.h create mode 100644 bsp/raspberry-pi/raspi4-64/driver/mbox.c create mode 100644 bsp/raspberry-pi/raspi4-64/driver/mbox.h create mode 100644 libcpu/aarch64/common/cpuport.h create mode 100644 libcpu/aarch64/common/gic.c create mode 100644 libcpu/aarch64/common/gic.h delete mode 100644 libcpu/aarch64/common/gic/SConscript delete mode 100644 libcpu/aarch64/common/gic/gic_pl390.c delete mode 100644 libcpu/aarch64/common/gic/gic_pl390.h delete mode 100644 libcpu/aarch64/common/gic/gic_pl400.c delete mode 100644 libcpu/aarch64/common/gic/gic_pl400.h create mode 100644 libcpu/aarch64/common/interrupt.c create mode 100644 libcpu/aarch64/common/interrupt.h rename libcpu/aarch64/{cortex-a72 => common}/stack.c (96%) create mode 100644 libcpu/aarch64/common/trap.c rename libcpu/aarch64/{cortex-a53 => cortex-a}/SConscript (74%) create mode 100644 libcpu/aarch64/cortex-a/entry_point.S delete mode 100644 libcpu/aarch64/cortex-a53/entry_point.S delete mode 100644 libcpu/aarch64/cortex-a53/interrupt.c delete mode 100644 libcpu/aarch64/cortex-a53/interrupt.h delete mode 100644 libcpu/aarch64/cortex-a53/stack.c delete mode 100644 libcpu/aarch64/cortex-a53/trap.c delete mode 100644 libcpu/aarch64/cortex-a72/SConscript delete mode 100644 libcpu/aarch64/cortex-a72/entry_point.S delete mode 100644 libcpu/aarch64/cortex-a72/interrupt.c delete mode 100644 libcpu/aarch64/cortex-a72/interrupt.h delete mode 100644 libcpu/aarch64/cortex-a72/trap.c diff --git a/bsp/qemu-virt64-aarch64/.config b/bsp/qemu-virt64-aarch64/.config index 49d28da1c2..205d54043f 100644 --- a/bsp/qemu-virt64-aarch64/.config +++ b/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 diff --git a/bsp/qemu-virt64-aarch64/README.md b/bsp/qemu-virt64-aarch64/README.md index 15bec15bff..0bbfbd56e7 100644 --- a/bsp/qemu-virt64-aarch64/README.md +++ b/bsp/qemu-virt64-aarch64/README.md @@ -49,4 +49,5 @@ msh /> | Driver | Condition | Remark | | ------ | --------- | ------ | -| UART | Support | UART0 | \ No newline at end of file +| UART | Support | UART0 | +| VIRTIO BLK | Support | VIRTIO BLK0 | \ No newline at end of file diff --git a/bsp/qemu-virt64-aarch64/README_zh.md b/bsp/qemu-virt64-aarch64/README_zh.md index 248cc9d812..686fd2b8da 100644 --- a/bsp/qemu-virt64-aarch64/README_zh.md +++ b/bsp/qemu-virt64-aarch64/README_zh.md @@ -50,4 +50,5 @@ msh /> | 驱动 | 支持情况 | 备注 | | ------ | ---- | :------: | -| UART | 支持 | UART0 | \ No newline at end of file +| UART | 支持 | UART0 | +| VIRTIO BLK | 支持 | VIRTIO BLK0 | \ No newline at end of file diff --git a/bsp/qemu-virt64-aarch64/SConstruct b/bsp/qemu-virt64-aarch64/SConstruct index 2d83f7ada6..a76ace4fb0 100644 --- a/bsp/qemu-virt64-aarch64/SConstruct +++ b/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') diff --git a/bsp/qemu-virt64-aarch64/applications/mnt.c b/bsp/qemu-virt64-aarch64/applications/mnt.c new file mode 100644 index 0000000000..6be00cb037 --- /dev/null +++ b/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 + +#ifdef RT_USING_DFS +#include + +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 diff --git a/bsp/qemu-virt64-aarch64/driver/Kconfig b/bsp/qemu-virt64-aarch64/driver/Kconfig index 5e3d969ab7..4384f0364f 100644 --- a/bsp/qemu-virt64-aarch64/driver/Kconfig +++ b/bsp/qemu-virt64-aarch64/driver/Kconfig @@ -15,11 +15,17 @@ menu "AARCH64 qemu virt64 configs" default y endif + menuconfig BSP_USING_VIRTIO_BLK + bool "Using VirtIO BLK" + default y + + if BSP_USING_VIRTIO_BLK + config RT_USING_VIRTIO_BLK0 + bool "Enabel VirtIO BLK 0" + default y + endif + config BSP_USING_GIC bool default y - - config BSP_USING_GIC390 - bool - default y endmenu diff --git a/bsp/qemu-virt64-aarch64/driver/SConscript b/bsp/qemu-virt64-aarch64/driver/SConscript index 4de25c676a..10f37cc796 100644 --- a/bsp/qemu-virt64-aarch64/driver/SConscript +++ b/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') diff --git a/bsp/qemu-virt64-aarch64/driver/board.c b/bsp/qemu-virt64-aarch64/driver/board.c index 1378b4f2be..f877e4b685 100644 --- a/bsp/qemu-virt64-aarch64/driver/board.c +++ b/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 @@ -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*/ diff --git a/bsp/qemu-virt64-aarch64/driver/board.h b/bsp/qemu-virt64-aarch64/driver/board.h index 87da1852ab..ae98a16521 100644 --- a/bsp/qemu-virt64-aarch64/driver/board.h +++ b/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 +#include +#include 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) { diff --git a/bsp/qemu-virt64-aarch64/driver/drv_uart.c b/bsp/qemu-virt64-aarch64/driver/drv_uart.c index 94df82c9b5..0d6cdaf15b 100644 --- a/bsp/qemu-virt64-aarch64/driver/drv_uart.c +++ b/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 diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/SConscript b/bsp/qemu-virt64-aarch64/driver/virtio/SConscript new file mode 100644 index 0000000000..9c1a9d248c --- /dev/null +++ b/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') diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c b/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.c new file mode 100644 index 0000000000..02e6b7986f --- /dev/null +++ b/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 +#include +#include +#include +#include + +#include "virtio.h" +#include "virtio_mmio.h" +#include "drv_virtio_blk.h" + +#ifdef BSP_USING_VIRTIO_BLK + +#ifdef RT_USING_VIRTIO_BLK0 +static struct virtio_blk blk0; +static struct virtio_blk_device virtio_blk_dev0; +#endif /* RT_USING_VIRTIO_BLK0 */ + +static int alloc_desc(struct virtio_blk *blk) +{ + int i; + for(i = 0; i < QUEUE_SIZE; i++) + { + if (blk->free[i]) + { + blk->free[i] = 0; + return i; + } + } + return -RT_ERROR; +} + +static void free_desc(struct virtio_blk *blk, int i) +{ + if (i >= QUEUE_SIZE) + { + rt_kprintf("Out of queue number"); + RT_ASSERT(0); + } + if (blk0.free[i]) + { + rt_kprintf("Already freed"); + RT_ASSERT(0); + } + blk->desc[i].addr = 0; + blk->desc[i].len = 0; + blk->desc[i].flags = 0; + blk->desc[i].next = 0; + blk->free[i] = 1; +} + +static void free_chain(struct virtio_blk *blk, int i) +{ + int flag, nxt; + for (;;) + { + flag = blk->desc[i].flags; + nxt = blk->desc[i].next; + + free_desc(blk, i); + + if (flag & VRING_DESC_F_NEXT) + { + i = nxt; + } + else + { + break; + } + } +} + +static int alloc3_desc(struct virtio_blk *blk, int *idx) +{ + for (int i = 0; i < 3; ++i) + { + idx[i] = alloc_desc(blk); + if (idx[i] < 0) + { + for (int j = 0; j < i; ++j) + { + free_desc(blk, idx[j]); + } + return -RT_ERROR; + } + } + return 0; +} + +static int virtio_blk_device_init(struct virtio_blk_device *virtio_blk_dev) +{ + uint32_t status = 0; + uint32_t max; + uint64_t features; + int i; + +#ifdef RT_USING_SMP + rt_spin_lock_init(&virtio_blk_dev->spinlock); +#endif + + if (virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_MAGIC_VALUE) != VIRTIO_MMIO_MAGIC || + virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_VERSION) != 1 || + virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DEVICE_ID) != 2 || + virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_VENDOR_ID) != VIRTIO_MMIO_VENDOR) + { + rt_kprintf("Could not find virtio disk"); + + return -RT_ERROR; + } + + status |= VIRTIO_STAT_ACKNOWLEDGE; + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); + + status |= VIRTIO_STAT_DRIVER; + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); + + /* negotiate features */ + features = virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DEVICE_FEATURES); + features &= ~(1 << VIRTIO_BLK_F_RO); + features &= ~(1 << VIRTIO_BLK_F_SCSI); + features &= ~(1 << VIRTIO_BLK_F_CONFIG_WCE); + features &= ~(1 << VIRTIO_BLK_F_MQ); + features &= ~(1 << VIRTIO_F_ANY_LAYOUT); + features &= ~(1 << VIRTIO_RING_F_EVENT_IDX); + features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC); + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_DRIVER_FEATURES, features); + + /* tell device that feature negotiation is complete */ + status |= VIRTIO_STAT_FEATURES_OK; + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); + + /* tell device we're completely ready */ + status |= VIRTIO_STAT_DRIVER_OK; + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_STATUS, status); + + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_GUEST_PAGE_SIZE, PAGE_SIZE); + + /* initialize queue 0 */ + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_SEL, 0); + + max = virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NUM_MAX); + if (max == 0) + { + rt_kprintf("Virtio disk has no queue 0"); + RT_ASSERT(0); + } + if (max < QUEUE_SIZE) + { + rt_kprintf("Virtio disk max queue too short"); + RT_ASSERT(0); + } + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NUM, QUEUE_SIZE); + + rt_memset(virtio_blk_dev->blk->pages, 0, sizeof(virtio_blk_dev->blk->pages)); + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_PFN, ((uint64_t)blk0.pages) >> PAGE_SHIFT); + + virtio_blk_dev->blk->desc = (struct virtq_desc *)virtio_blk_dev->blk->pages; + virtio_blk_dev->blk->avail = (struct virtq_avail *)(virtio_blk_dev->blk->pages + QUEUE_SIZE * sizeof(struct virtq_desc)); + virtio_blk_dev->blk->used = (struct virtq_used *)(virtio_blk_dev->blk->pages + PAGE_SIZE); + + /* all QUEUE_SIZE descriptors start out unused */ + for (i = 0; i < QUEUE_SIZE; ++i) + { + virtio_blk_dev->blk->free[i] = 1; + } + + return RT_EOK; +} + +static void virtio_blk_rw(struct virtio_blk_device *virtio_blk_dev, struct virtio_blk_buf *buf, int flag) +{ + struct virtio_blk *blk = virtio_blk_dev->blk; + uint64_t sector = buf->block_no * (VIRTIO_BLK_BUF_DATA_SIZE / 512); + int idx[3]; + struct virtio_blk_req *req; + +#ifdef RT_USING_SMP + rt_base_t level; + + level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock); +#endif + + /* allocate the three descriptors */ + for (;;) + { + if (alloc3_desc(blk, idx) == 0) + { + break; + } + } + + req = &(blk->ops[idx[0]]); + req->type = flag; + req->reserved = 0; + req->sector = sector; + + blk->desc[idx[0]].addr = (uint64_t)req; + blk->desc[idx[0]].len = sizeof(struct virtio_blk_req); + blk->desc[idx[0]].flags = VRING_DESC_F_NEXT; + blk->desc[idx[0]].next = idx[1]; + + blk->desc[idx[1]].addr = (uint64_t)buf->data; + blk->desc[idx[1]].len = VIRTIO_BLK_BUF_DATA_SIZE; + + blk->desc[idx[1]].flags = flag ? 0 : VRING_DESC_F_WRITE; + + blk->desc[idx[1]].flags |= VRING_DESC_F_NEXT; + blk->desc[idx[1]].next = idx[2]; + + /* device writes 0 on success */ + blk->info[idx[0]].status = 0xff; + blk->desc[idx[2]].addr = (uint64_t)&(blk->info[idx[0]].status); + blk->desc[idx[2]].len = 1; + /* device writes the status */ + blk->desc[idx[2]].flags = VRING_DESC_F_WRITE; + blk->desc[idx[2]].next = 0; + + /* record struct buf for virtio_blk_isr() */ + buf->valid = 1; + blk->info[idx[0]].buf = buf; + + /* tell the device the first index in our chain of descriptors */ + blk->avail->ring[blk->avail->idx % QUEUE_SIZE] = idx[0]; + + rt_hw_dsb(); + + /* tell the device another avail ring entry is available */ + blk->avail->idx += 1; + + rt_hw_dsb(); + + /* value is queue number */ + virtio_mmio_write32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_QUEUE_NOTIFY, 0); + + /* wait for virtio_blk_isr() to done */ + while (buf->valid == 1) + { +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level); +#endif + rt_thread_yield(); +#ifdef RT_USING_SMP + level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock); +#endif + } + + blk->info[idx[0]].buf = 0; + free_chain(blk, idx[0]); + +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level); +#endif +} + +static void virtio_blk_isr(int irqno, void *param) +{ + int id; + struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)param; + struct virtio_blk *blk = virtio_blk_dev->blk; + struct virtio_blk_buf *buf_tmp; + +#ifdef RT_USING_SMP + rt_base_t level; + + level = rt_spin_lock_irqsave(&virtio_blk_dev->spinlock); +#endif + + virtio_mmio_write32( + virtio_blk_dev->mmio_base, + VIRTIO_MMIO_INTERRUPT_ACK, + virtio_mmio_read32(virtio_blk_dev->mmio_base, VIRTIO_MMIO_INTERRUPT_STATUS) & 0x3); + + rt_hw_dsb(); + + /* + * the device increments disk.used->idx + * when it adds an entry to the used ring + */ + while (blk->used_idx != blk->used->idx) + { + rt_hw_dsb(); + id = blk->used->ring[blk->used_idx % QUEUE_SIZE].id; + + if (blk->info[id].status != 0) + { + rt_kprintf("Virtio BLK Status"); + RT_ASSERT(0); + } + + buf_tmp = blk->info[id].buf; + + /* done with buf */ + buf_tmp->valid = 0; + rt_thread_yield(); + + blk->used_idx += 1; + } + +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_blk_dev->spinlock, level); +#endif +} + +static rt_err_t virtio_blk_init(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t virtio_blk_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t virtio_blk_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_size_t virtio_blk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev; + struct virtio_blk_buf buf = + { + .block_no = (uint32_t)pos, + .data = (uint8_t *)buffer + }; + + virtio_blk_rw(virtio_blk_dev, &buf, VIRTIO_BLK_T_IN); + + return size; +} + +static rt_size_t virtio_blk_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + struct virtio_blk_device *virtio_blk_dev = (struct virtio_blk_device *)dev; + struct virtio_blk_buf buf = + { + .block_no = (uint32_t)pos, + .data = (uint8_t *)buffer + }; + + virtio_blk_rw(virtio_blk_dev, &buf, VIRTIO_BLK_T_OUT); + + return size; +} + +static rt_err_t virtio_blk_control(rt_device_t dev, int cmd, void *args) +{ + if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) + { + struct rt_device_blk_geometry *geometry; + + geometry = (struct rt_device_blk_geometry *)args; + if (geometry == RT_NULL) + { + return -RT_ERROR; + } + + geometry->bytes_per_sector = VIRTIO_BLK_BYTES_PER_SECTOR; + geometry->block_size = VIRTIO_BLK_BLOCK_SIZE; + geometry->sector_count = VIRTIO_BLK_SECTOR_COUNT; + } + + return RT_EOK; +} + +const static struct rt_device_ops virtio_blk_ops = +{ + virtio_blk_init, + virtio_blk_open, + virtio_blk_close, + virtio_blk_read, + virtio_blk_write, + virtio_blk_control +}; + +int rt_virtio_blk_init(void) +{ + rt_err_t status = RT_EOK; + +#ifdef RT_USING_VIRTIO_BLK0 + virtio_blk_dev0.parent.type = RT_Device_Class_Block; + virtio_blk_dev0.parent.ops = &virtio_blk_ops; + virtio_blk_dev0.blk = &blk0; + virtio_blk_dev0.mmio_base = (uint32_t *)VIRTIO_MMIO_BLK0_BASE; + + status = virtio_blk_device_init(&virtio_blk_dev0); + rt_device_register((rt_device_t)&virtio_blk_dev0, "virtio-blk0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE); + rt_hw_interrupt_install(VIRTIO_MMIO_BLK0_IRQ, virtio_blk_isr, &virtio_blk_dev0, "virtio-blk0"); + rt_hw_interrupt_umask(VIRTIO_MMIO_BLK0_IRQ); +#endif /* RT_USING_VIRTIO_BLK0 */ + + return status; +} +INIT_DEVICE_EXPORT(rt_virtio_blk_init); +#endif /* BSP_USING_VIRTIO_BLK */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h b/bsp/qemu-virt64-aarch64/driver/virtio/drv_virtio_blk.h new file mode 100644 index 0000000000..3ab23f7afe --- /dev/null +++ b/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 +#include +#include "virtio.h" + +#define VIRTIO_BLK_BUF_DATA_SIZE 512 +#define VIRTIO_BLK_BYTES_PER_SECTOR 512 +#define VIRTIO_BLK_BLOCK_SIZE 512 +#define VIRTIO_BLK_SECTOR_COUNT 0x40000 /* 128MB */ + +#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ +#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ +#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */ +#define VIRTIO_BLK_F_MQ 12 /* Support more than one vq */ + +#define VIRTIO_BLK_T_IN 0 /* Read the blk */ +#define VIRTIO_BLK_T_OUT 1 /* Write the blk */ + +#define VIRTIO_F_ANY_LAYOUT 27 +#define VIRTIO_RING_F_INDIRECT_DESC 28 +#define VIRTIO_RING_F_EVENT_IDX 29 + +struct virtio_blk_buf +{ + int valid; + uint32_t block_no; + uint8_t *data; +}; + +struct virtio_blk_req +{ + uint32_t type; + uint32_t reserved; + uint64_t sector; +}; + +/* + * virtio_blk must be a static variable because + * pages must consist of two contiguous pages of + * page-aligned physical memory + */ +struct virtio_blk +{ + char pages[2 * PAGE_SIZE]; + struct virtq_desc *desc; + struct virtq_avail *avail; + struct virtq_used *used; + + char free[QUEUE_SIZE]; + uint16_t used_idx; + struct + { + struct virtio_blk_buf *buf; + char status; + } info[QUEUE_SIZE]; + + struct virtio_blk_req ops[QUEUE_SIZE]; +} __attribute__ ((aligned (PAGE_SIZE))); + +struct virtio_blk_device +{ + struct rt_device parent; + struct virtio_blk *blk; + + uint32_t *mmio_base; +#ifdef RT_USING_SMP + struct rt_spinlock spinlock; +#endif +}; + +int rt_hw_virtio_blk_init(void); + +#endif /* DRV_VIRTIO_BLK_H__ */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio.h b/bsp/qemu-virt64-aarch64/driver/virtio/virtio.h new file mode 100644 index 0000000000..e87b68cd88 --- /dev/null +++ b/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 + +#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__ */ diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.c new file mode 100644 index 0000000000..72328bf61c --- /dev/null +++ b/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 +#include + +#include "virtio_mmio.h" + +void virtio_mmio_print_configs(uint32_t *device_base) +{ + rt_kprintf("MagicValue:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_MAGIC_VALUE)); + rt_kprintf("Version:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_VERSION)); + rt_kprintf("DeviceID:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_DEVICE_ID)); + rt_kprintf("VendorID:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_VENDOR_ID)); + rt_kprintf("DeviceFeatures0:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES)); + rt_kprintf("DeviceFeaturesSel0:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES_SEL)); + + virtio_mmio_write32(device_base, VIRTIO_MMIO_HOST_FEATURES_SEL, 1); + rt_hw_dsb(); + + rt_kprintf("DeviceFeatures1:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_HOST_FEATURES)); + rt_kprintf("DriverFeatures:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_FEATURES)); + rt_kprintf("DriverFeaturesSel:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_FEATURES_SEL)); + rt_kprintf("PageSize:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_GUEST_PAGE_SIZE)); + + virtio_mmio_write32(device_base, VIRTIO_MMIO_QUEUE_SEL, 0); + rt_hw_dsb(); + + rt_kprintf("QueueSel:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_SEL)); + rt_kprintf("QueueNumMax:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM_MAX)); + rt_kprintf("QueueNum:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM)); + + virtio_mmio_write32(device_base, VIRTIO_MMIO_QUEUE_SEL, 1); + rt_hw_dsb(); + + rt_kprintf("QueueSel:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_SEL)); + rt_kprintf("QueueNumMax1:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM_MAX)); + rt_kprintf("QueueNum1:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NUM)); + rt_kprintf("QueueAlign:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_ALIGN)); + rt_kprintf("QueuePFN:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_PFN)); + rt_kprintf("QueueReady:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_READY)); + rt_kprintf("QueueNotify:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_NOTIFY)); + rt_kprintf("InterruptStatus:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_INTERRUPT_STATUS)); + rt_kprintf("InterruptACK:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_INTERRUPT_ACK)); + rt_kprintf("Status:\t\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_STATUS)); + rt_kprintf("QueueDescLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_DESC_LOW)); + rt_kprintf("QueueDescHigh:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_DESC_HIGH)); + rt_kprintf("QueueDriverLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_AVAIL_LOW)); + rt_kprintf("QueueDriverHigh:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_AVAIL_HIGH)); + rt_kprintf("QueueDeviceLow:\t\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_USED_LOW)); + rt_kprintf("QueueDeviceHigh:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_QUEUE_USED_HIGH)); + rt_kprintf("ConfigGeneration:\t 0x%x\n", virtio_mmio_read32(device_base, VIRTIO_MMIO_CONFIG_GENERATION)); + rt_kprintf("Config:\t\t\t 0x%x\n", virtio_mmio_read32(device_base,VIRTIO_MMIO_CONFIG)); +} diff --git a/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h b/bsp/qemu-virt64-aarch64/driver/virtio/virtio_mmio.h new file mode 100644 index 0000000000..fd7611aa85 --- /dev/null +++ b/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 +#include + +#define VIRTIO_MMIO_MAGIC 0x74726976 +#define VIRTIO_MMIO_VENDOR 0x554d4551 + +#define VIRTIO_MMIO_MAGIC_VALUE 0x000 /* VIRTIO_MMIO_MAGIC */ +#define VIRTIO_MMIO_VERSION 0x004 /* version: 1 is legacy */ +#define VIRTIO_MMIO_DEVICE_ID 0x008 /* device type: 1 is net, 2 is disk */ +#define VIRTIO_MMIO_VENDOR_ID 0x00c /* VIRTIO_MMIO_VENDOR */ +#define VIRTIO_MMIO_DEVICE_FEATURES 0x010 +#define VIRTIO_MMIO_DRIVER_FEATURES 0x020 +#define VIRTIO_MMIO_HOST_FEATURES 0x010 +#define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 +#define VIRTIO_MMIO_GUEST_FEATURES 0x020 +#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024 +#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 /* version 1 only */ +#define VIRTIO_MMIO_QUEUE_SEL 0x030 +#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 +#define VIRTIO_MMIO_QUEUE_NUM 0x038 +#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c /* version 1 only */ +#define VIRTIO_MMIO_QUEUE_PFN 0x040 /* version 1 only */ +#define VIRTIO_MMIO_QUEUE_READY 0x044 /* requires version 2 */ +#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 +#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 +#define VIRTIO_MMIO_INTERRUPT_ACK 0x064 +#define VIRTIO_MMIO_STATUS 0x070 +#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 /* requires version 2 */ +#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 /* requires version 2 */ +#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090 /* requires version 2 */ +#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094 /* requires version 2 */ +#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0 /* requires version 2 */ +#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4 /* requires version 2 */ +#define VIRTIO_MMIO_CONFIG_GENERATION 0x100 /* requires version 2 */ +#define VIRTIO_MMIO_CONFIG 0x100 +#define VIRTIO_MMIO_INT_VRING (1 << 0) +#define VIRTIO_MMIO_INT_CONFIG (1 << 1) +#define VIRTIO_MMIO_VRING_ALIGN 4096 + +static inline uint32_t virtio_mmio_read32(uint32_t *base, size_t offset) +{ + 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 */ diff --git a/bsp/qemu-virt64-aarch64/link.lds b/bsp/qemu-virt64-aarch64/link.lds index 169f206b68..2344d96e3b 100644 --- a/bsp/qemu-virt64-aarch64/link.lds +++ b/bsp/qemu-virt64-aarch64/link.lds @@ -24,7 +24,7 @@ SECTIONS { - . = 0x40000000; + . = 0x40008000; . = ALIGN(4096); .text : { diff --git a/bsp/qemu-virt64-aarch64/qemu.bat b/bsp/qemu-virt64-aarch64/qemu.bat index f8896a3472..a1e60c2871 100644 --- a/bsp/qemu-virt64-aarch64/qemu.bat +++ b/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 \ No newline at end of file diff --git a/bsp/qemu-virt64-aarch64/qemu.sh b/bsp/qemu-virt64-aarch64/qemu.sh index d05fdafd14..aec8d14456 100644 --- a/bsp/qemu-virt64-aarch64/qemu.sh +++ b/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 diff --git a/bsp/qemu-virt64-aarch64/rtconfig.h b/bsp/qemu-virt64-aarch64/rtconfig.h index acd486871d..98afd9a231 100644 --- a/bsp/qemu-virt64-aarch64/rtconfig.h +++ b/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 diff --git a/bsp/qemu-virt64-aarch64/rtconfig.py b/bsp/qemu-virt64-aarch64/rtconfig.py index 5c97f83ed9..e46a4374aa 100644 --- a/bsp/qemu-virt64-aarch64/rtconfig.py +++ b/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'): diff --git a/bsp/raspberry-pi/raspi3-64/.config b/bsp/raspberry-pi/raspi3-64/.config index 6ae8f95f8a..7a48b99438 100644 --- a/bsp/raspberry-pi/raspi3-64/.config +++ b/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,25 +525,50 @@ 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 # -# 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_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_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 @@ -448,17 +577,50 @@ CONFIG_RT_USING_POSIX=y # 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 # 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 diff --git a/bsp/raspberry-pi/raspi3-64/driver/mbox.h b/bsp/raspberry-pi/raspi3-64/driver/mbox.h index b7aa2e95c9..c30a818803 100644 --- a/bsp/raspberry-pi/raspi3-64/driver/mbox.h +++ b/bsp/raspberry-pi/raspi3-64/driver/mbox.h @@ -13,6 +13,7 @@ #define __MBOX_H__ #include +#include /* a properly aligned buffer */ extern volatile unsigned int* mbox; diff --git a/bsp/raspberry-pi/raspi3-64/driver/raspi.h b/bsp/raspberry-pi/raspi3-64/driver/raspi.h index a24640d07d..8e77f1f701 100644 --- a/bsp/raspberry-pi/raspi3-64/driver/raspi.h +++ b/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 diff --git a/bsp/raspberry-pi/raspi3-64/qemu-64.bat b/bsp/raspberry-pi/raspi3-64/qemu-64.bat index db14a102df..b57c8a5b5b 100755 --- a/bsp/raspberry-pi/raspi3-64/qemu-64.bat +++ b/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 \ No newline at end of file +@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 \ No newline at end of file diff --git a/bsp/raspberry-pi/raspi3-64/qemu-64.sh b/bsp/raspberry-pi/raspi3-64/qemu-64.sh new file mode 100644 index 0000000000..db14a102df --- /dev/null +++ b/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 \ No newline at end of file diff --git a/bsp/raspberry-pi/raspi3-64/rtconfig.h b/bsp/raspberry-pi/raspi3-64/rtconfig.h index 6f38809cbd..f321e21207 100644 --- a/bsp/raspberry-pi/raspi3-64/rtconfig.h +++ b/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 */ diff --git a/bsp/raspberry-pi/raspi3-64/rtconfig.py b/bsp/raspberry-pi/raspi3-64/rtconfig.py index e376665083..46a585396a 100644 --- a/bsp/raspberry-pi/raspi3-64/rtconfig.py +++ b/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'): diff --git a/bsp/raspberry-pi/raspi4-64/.config b/bsp/raspberry-pi/raspi4-64/.config index 0ab68e8fe3..377ddb93bd 100644 --- a/bsp/raspberry-pi/raspi4-64/.config +++ b/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,25 +594,50 @@ 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 # -# 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_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_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 @@ -417,17 +646,50 @@ CONFIG_RT_USING_POSIX=y # 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 # 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 diff --git a/bsp/raspberry-pi/raspi4-64/README.md b/bsp/raspberry-pi/raspi4-64/README.md index b2456277b8..7e969d6488 100644 --- a/bsp/raspberry-pi/raspi4-64/README.md +++ b/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. 联系人信息 diff --git a/bsp/raspberry-pi/raspi4-64/applications/mnt.c b/bsp/raspberry-pi/raspi4-64/applications/mnt.c new file mode 100644 index 0000000000..ea67a4a46a --- /dev/null +++ b/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 + +#ifdef BSP_USING_SDIO0 +#include + +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 diff --git a/bsp/raspberry-pi/raspi4-64/driver/Kconfig b/bsp/raspberry-pi/raspi4-64/driver/Kconfig index 208b4b4300..417747e223 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/Kconfig +++ b/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 diff --git a/bsp/raspberry-pi/raspi4-64/driver/board.c b/bsp/raspberry-pi/raspi4-64/driver/board.c index 0fbd4921f8..2c01b08ef3 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/board.c +++ b/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 */ diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_eth.c b/bsp/raspberry-pi/raspi4-64/driver/drv_eth.c new file mode 100644 index 0000000000..4c028d1e65 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include + +#include "mbox.h" +#include "raspi4.h" +#include "drv_eth.h" + +#define DBG_LEVEL DBG_LOG +#include +#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(ð_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 = ð_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(ð_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(ð_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(ð_dev.parent, RT_FALSE); + + return 0; +} +INIT_COMPONENT_EXPORT(rt_hw_eth_init); diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_eth.h b/bsp/raspberry-pi/raspi4-64/driver/drv_eth.h new file mode 100644 index 0000000000..e2cce207e5 --- /dev/null +++ b/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__ */ diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c b/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c index f526ff99e6..8877f626ef 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c +++ b/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; diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h b/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h index 3627b51593..4daa64c2c4 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h +++ b/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__ */ diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_sdio.c b/bsp/raspberry-pi/raspi4-64/driver/drv_sdio.c new file mode 100644 index 0000000000..ff116861d6 --- /dev/null +++ b/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 +#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); diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_sdio.h b/bsp/raspberry-pi/raspi4-64/driver/drv_sdio.h new file mode 100644 index 0000000000..78ee02af05 --- /dev/null +++ b/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 +#include +#include + +#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 diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_uart.c b/bsp/raspberry-pi/raspi4-64/driver/drv_uart.c index 597682df34..195912268a 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_uart.c +++ b/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; + prev_raspi_pin_mode(GPIO_PIN_14, ALT5); + prev_raspi_pin_mode(GPIO_PIN_15, ALT5); - 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*/ + 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) { - ch = PL011_REG_DR(uart->hw_base) & 0xff; + if ((AUX_MU_LSR_REG(uart->hw_base) & 0x01)) + { + ch = AUX_MU_IO_REG(uart->hw_base) & 0xff; + } + } + else + { + 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; - /* register UART1 device */ - rt_hw_serial_register(&_serial0, "uart", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); - rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart"); + 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(&_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, + 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; } diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_uart.h b/bsp/raspberry-pi/raspi4-64/driver/drv_uart.h index 1dfb9b7e04..56cfd9dcc6 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_uart.h +++ b/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__ */ diff --git a/bsp/raspberry-pi/raspi4-64/driver/mbox.c b/bsp/raspberry-pi/raspi4-64/driver/mbox.c new file mode 100644 index 0000000000..6d1c276d78 --- /dev/null +++ b/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]; +} diff --git a/bsp/raspberry-pi/raspi4-64/driver/mbox.h b/bsp/raspberry-pi/raspi4-64/driver/mbox.h new file mode 100644 index 0000000000..c13170afba --- /dev/null +++ b/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 +#include + +// 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 diff --git a/bsp/raspberry-pi/raspi4-64/driver/raspi4.h b/bsp/raspberry-pi/raspi4-64/driver/raspi4.h index 3f18353904..d2abb7ac77 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/raspi4.h +++ b/bsp/raspberry-pi/raspi4-64/driver/raspi4.h @@ -1,29 +1,145 @@ #ifndef __RASPI4_H__ #define __RASPI4_H__ +#include + +#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 diff --git a/bsp/raspberry-pi/raspi4-64/rtconfig.h b/bsp/raspberry-pi/raspi4-64/rtconfig.h index bdde9d5f4a..652022c06c 100644 --- a/bsp/raspberry-pi/raspi4-64/rtconfig.h +++ b/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 */ diff --git a/bsp/raspberry-pi/raspi4-64/rtconfig.py b/bsp/raspberry-pi/raspi4-64/rtconfig.py index a1dd168d3d..fce6e52180 100644 --- a/bsp/raspberry-pi/raspi4-64/rtconfig.py +++ b/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'): diff --git a/libcpu/aarch64/common/SConscript b/libcpu/aarch64/common/SConscript index c51148525b..915b9d29aa 100644 --- a/libcpu/aarch64/common/SConscript +++ b/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) diff --git a/libcpu/aarch64/common/cpuport.h b/libcpu/aarch64/common/cpuport.h new file mode 100644 index 0000000000..91c4a7f77b --- /dev/null +++ b/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 + +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__ */ diff --git a/libcpu/aarch64/common/gic.c b/libcpu/aarch64/common/gic.c new file mode 100644 index 0000000000..d23ece42df --- /dev/null +++ b/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 +#include + +#include +#include + +struct arm_gic +{ + rt_uint64_t offset; /* the first interrupt index in the vector table */ + + rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ + rt_uint64_t cpu_hw_base; /* the base addrees of the gic cpu interface */ +}; + +/* '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); + diff --git a/libcpu/aarch64/common/gic.h b/libcpu/aarch64/common/gic.h new file mode 100644 index 0000000000..54ab2bda18 --- /dev/null +++ b/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 +#include +#include + +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 + diff --git a/libcpu/aarch64/common/gic/SConscript b/libcpu/aarch64/common/gic/SConscript deleted file mode 100644 index 28daac87ff..0000000000 --- a/libcpu/aarch64/common/gic/SConscript +++ /dev/null @@ -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') diff --git a/libcpu/aarch64/common/gic/gic_pl390.c b/libcpu/aarch64/common/gic/gic_pl390.c deleted file mode 100644 index a8e3b10d94..0000000000 --- a/libcpu/aarch64/common/gic/gic_pl390.c +++ /dev/null @@ -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 - -#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); -} - diff --git a/libcpu/aarch64/common/gic/gic_pl390.h b/libcpu/aarch64/common/gic/gic_pl390.h deleted file mode 100644 index 7ea574967d..0000000000 --- a/libcpu/aarch64/common/gic/gic_pl390.h +++ /dev/null @@ -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 - -#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 diff --git a/libcpu/aarch64/common/gic/gic_pl400.c b/libcpu/aarch64/common/gic/gic_pl400.c deleted file mode 100644 index ec690a1cc6..0000000000 --- a/libcpu/aarch64/common/gic/gic_pl400.c +++ /dev/null @@ -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 - -#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_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)); - } -} - diff --git a/libcpu/aarch64/common/gic/gic_pl400.h b/libcpu/aarch64/common/gic/gic_pl400.h deleted file mode 100644 index 9ca4835b9a..0000000000 --- a/libcpu/aarch64/common/gic/gic_pl400.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - */ - -#ifndef __GIC_PL400_H__ -#define __GIC_PL400_H__ - -#include -#include - -#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 - diff --git a/libcpu/aarch64/common/interrupt.c b/libcpu/aarch64/common/interrupt.c new file mode 100644 index 0000000000..c4e3f20b46 --- /dev/null +++ b/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 +#include +#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 + diff --git a/libcpu/aarch64/common/interrupt.h b/libcpu/aarch64/common/interrupt.h new file mode 100644 index 0000000000..dda6c5534a --- /dev/null +++ b/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 +#include + +#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 + diff --git a/libcpu/aarch64/cortex-a72/stack.c b/libcpu/aarch64/common/stack.c similarity index 96% rename from libcpu/aarch64/cortex-a72/stack.c rename to libcpu/aarch64/common/stack.c index 751793d7a3..0fe00d8674 100644 --- a/libcpu/aarch64/cortex-a72/stack.c +++ b/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; diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c new file mode 100644 index 0000000000..e93ad78fc5 --- /dev/null +++ b/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 +#include +#include + +#include +#include + +#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); +} diff --git a/libcpu/aarch64/cortex-a53/SConscript b/libcpu/aarch64/cortex-a/SConscript similarity index 74% rename from libcpu/aarch64/cortex-a53/SConscript rename to libcpu/aarch64/cortex-a/SConscript index 0b74223c6f..c6a4817802 100644 --- a/libcpu/aarch64/cortex-a53/SConscript +++ b/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') diff --git a/libcpu/aarch64/cortex-a/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S new file mode 100644 index 0000000000..ac7b793811 --- /dev/null +++ b/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 */ diff --git a/libcpu/aarch64/cortex-a53/entry_point.S b/libcpu/aarch64/cortex-a53/entry_point.S deleted file mode 100644 index 552e5916ce..0000000000 --- a/libcpu/aarch64/cortex-a53/entry_point.S +++ /dev/null @@ -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: diff --git a/libcpu/aarch64/cortex-a53/interrupt.c b/libcpu/aarch64/cortex-a53/interrupt.c deleted file mode 100644 index ba49be5132..0000000000 --- a/libcpu/aarch64/cortex-a53/interrupt.c +++ /dev/null @@ -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 -#include -#include - -#include "cp15.h" -#include "armv8.h" -#include "interrupt.h" - -#ifdef BSP_USING_GIC390 -#include -#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 diff --git a/libcpu/aarch64/cortex-a53/interrupt.h b/libcpu/aarch64/cortex-a53/interrupt.h deleted file mode 100644 index 72e69bd808..0000000000 --- a/libcpu/aarch64/cortex-a53/interrupt.h +++ /dev/null @@ -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 -#include - -#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 diff --git a/libcpu/aarch64/cortex-a53/stack.c b/libcpu/aarch64/cortex-a53/stack.c deleted file mode 100644 index 751793d7a3..0000000000 --- a/libcpu/aarch64/cortex-a53/stack.c +++ /dev/null @@ -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 -#include - -#include - -#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; -} diff --git a/libcpu/aarch64/cortex-a53/trap.c b/libcpu/aarch64/cortex-a53/trap.c deleted file mode 100644 index 6002713543..0000000000 --- a/libcpu/aarch64/cortex-a53/trap.c +++ /dev/null @@ -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 -#include - -#include "interrupt.h" -#include "armv8.h" - -#ifdef BSP_USING_GIC390 -#include -#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 -} diff --git a/libcpu/aarch64/cortex-a72/SConscript b/libcpu/aarch64/cortex-a72/SConscript deleted file mode 100644 index 0b74223c6f..0000000000 --- a/libcpu/aarch64/cortex-a72/SConscript +++ /dev/null @@ -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') diff --git a/libcpu/aarch64/cortex-a72/entry_point.S b/libcpu/aarch64/cortex-a72/entry_point.S deleted file mode 100644 index 6d2c69226b..0000000000 --- a/libcpu/aarch64/cortex-a72/entry_point.S +++ /dev/null @@ -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 diff --git a/libcpu/aarch64/cortex-a72/interrupt.c b/libcpu/aarch64/cortex-a72/interrupt.c deleted file mode 100644 index 3ecb7750ad..0000000000 --- a/libcpu/aarch64/cortex-a72/interrupt.c +++ /dev/null @@ -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 -#include -#include -#include -#include - -#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); -} diff --git a/libcpu/aarch64/cortex-a72/interrupt.h b/libcpu/aarch64/cortex-a72/interrupt.h deleted file mode 100644 index 72e69bd808..0000000000 --- a/libcpu/aarch64/cortex-a72/interrupt.h +++ /dev/null @@ -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 -#include - -#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 diff --git a/libcpu/aarch64/cortex-a72/trap.c b/libcpu/aarch64/cortex-a72/trap.c deleted file mode 100644 index ba96f03a69..0000000000 --- a/libcpu/aarch64/cortex-a72/trap.c +++ /dev/null @@ -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 -#include - -#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) -{ -}