From 7d894a6258ca2d5cb6a86352e1b1d3abd30c4355 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Fri, 14 May 2021 17:04:40 +0800 Subject: [PATCH 1/4] update libcpu aarch64, el1 use sp_el1 add qemu-vexpress-a53 add aarch64 lwp support fix warning --- bsp/qemu-vexpress-a53/.config | 689 +++++++++++++ bsp/qemu-vexpress-a53/.cproject | 175 ++++ bsp/qemu-vexpress-a53/.gitignore | 45 + bsp/qemu-vexpress-a53/.project | 54 + bsp/qemu-vexpress-a53/Kconfig | 31 + bsp/qemu-vexpress-a53/README.md | 105 ++ bsp/qemu-vexpress-a53/SConscript | 14 + bsp/qemu-vexpress-a53/SConstruct | 43 + bsp/qemu-vexpress-a53/applications/.config | 631 ++++++++++++ .../applications}/SConscript | 10 +- bsp/qemu-vexpress-a53/applications/lcd_init.c | 19 + bsp/qemu-vexpress-a53/applications/main.c | 16 + bsp/qemu-vexpress-a53/applications/mnt.c | 29 + bsp/qemu-vexpress-a53/drivers/Kconfig | 30 + bsp/qemu-vexpress-a53/drivers/SConscript | 23 + .../drivers/audio/SConscript | 9 + .../drivers/audio/drv_ac97.c | 121 +++ .../drivers/audio/drv_ac97.h | 63 ++ .../drivers/audio/drv_pl041.c | 409 ++++++++ .../drivers/audio/drv_pl041.h | 237 +++++ .../drivers/audio/drv_sound.c | 342 +++++++ .../drivers/audio/drv_sound.h | 15 + bsp/qemu-vexpress-a53/drivers/board.c | 93 ++ bsp/qemu-vexpress-a53/drivers/board.h | 45 + bsp/qemu-vexpress-a53/drivers/drv_clcd.c | 180 ++++ bsp/qemu-vexpress-a53/drivers/drv_clcd.h | 16 + bsp/qemu-vexpress-a53/drivers/drv_keyboard.c | 474 +++++++++ bsp/qemu-vexpress-a53/drivers/drv_keyboard.h | 6 + bsp/qemu-vexpress-a53/drivers/drv_mouse.c | 300 ++++++ bsp/qemu-vexpress-a53/drivers/drv_mouse.h | 18 + bsp/qemu-vexpress-a53/drivers/drv_sdio.c | 469 +++++++++ bsp/qemu-vexpress-a53/drivers/drv_sdio.h | 47 + bsp/qemu-vexpress-a53/drivers/drv_smc911x.c | 561 ++++++++++ bsp/qemu-vexpress-a53/drivers/drv_smc911x.h | 402 ++++++++ bsp/qemu-vexpress-a53/drivers/drv_timer.c | 144 +++ bsp/qemu-vexpress-a53/drivers/drv_timer.h | 17 + bsp/qemu-vexpress-a53/drivers/realview.h | 331 ++++++ bsp/qemu-vexpress-a53/drivers/rt_lcd.h | 59 ++ bsp/qemu-vexpress-a53/drivers/secondary_cpu.c | 75 ++ bsp/qemu-vexpress-a53/drivers/serial.c | 187 ++++ bsp/qemu-vexpress-a53/drivers/serial.h | 39 + bsp/qemu-vexpress-a53/drivers/vexpress_a9.h | 37 + bsp/qemu-vexpress-a53/link.lds | 109 ++ bsp/qemu-vexpress-a53/makefile.targets | 4 + bsp/qemu-vexpress-a53/qemu-dbg.sh | 6 + bsp/qemu-vexpress-a53/qemu-nographic.sh | 5 + bsp/qemu-vexpress-a53/qemu.sh | 5 + bsp/qemu-vexpress-a53/rtconfig.h | 292 ++++++ bsp/qemu-vexpress-a53/rtconfig.py | 70 ++ components/dfs/src/dfs.c | 8 +- components/drivers/serial/serial.c | 2 +- components/libc/aio/posix_aio.c | 2 +- components/libc/termios/posix_termios.c | 4 +- components/lwp/SConscript | 2 +- components/lwp/arch/aarch64/common/reloc.c | 28 + .../aarch64/cortex-a/arch_user_space_init.c | 58 ++ .../arch/aarch64/cortex-a/arch_user_stack.c | 39 + .../lwp/arch/aarch64/cortex-a/lwp_arch.h | 45 + .../lwp/arch/aarch64/cortex-a/lwp_gcc.S | 405 ++++++++ .../arch/arm/cortex-a/arch_user_space_init.c | 2 +- components/lwp/arch/arm/cortex-a/lwp_arch.h | 1 + components/lwp/arch/arm/cortex-a/lwp_gcc.S | 7 + components/lwp/arch/risc-v/virt64/lwp_arch.h | 1 + components/lwp/lwp.c | 88 +- components/lwp/lwp.h | 7 +- components/lwp/lwp_elf.h | 22 +- components/lwp/lwp_syscall.c | 2 +- components/lwp/lwp_user_mm.c | 49 +- components/net/lwip-2.0.2/src/arch/sys_arch.c | 6 +- components/net/sal_socket/dfs_net/dfs_net.c | 10 +- components/net/sal_socket/impl/af_inet_lwip.c | 8 +- .../net/sal_socket/socket/net_sockets.c | 4 +- components/net/sal_socket/src/sal_socket.c | 36 +- include/rtdef.h | 6 + libcpu/aarch64/common/armv8.h | 82 +- libcpu/aarch64/common/asm-fpu.h | 46 + libcpu/aarch64/common/cache.S | 56 +- libcpu/aarch64/common/cache_ops.c | 102 ++ libcpu/aarch64/common/context_gcc.S | 444 ++++---- libcpu/aarch64/common/cpu_gcc.S | 20 +- libcpu/aarch64/common/cpuport.h | 30 + libcpu/aarch64/common/exception.c | 227 +++++ libcpu/aarch64/common/gic.c | 516 ++++++++++ libcpu/aarch64/common/gic.h | 62 ++ libcpu/aarch64/common/gic/SConscript | 24 - libcpu/aarch64/common/gic/gic_pl400.c | 261 ----- libcpu/aarch64/common/gic/gic_pl400.h | 61 -- .../{cortex-a53 => common}/interrupt.c | 282 ++++- libcpu/aarch64/common/interrupt.h | 60 ++ libcpu/aarch64/common/mmu.c | 964 ++++++++++++++---- libcpu/aarch64/common/mmu.h | 176 ++-- libcpu/aarch64/common/page.c | 426 ++++++++ libcpu/aarch64/common/page.h | 40 + libcpu/aarch64/{cortex-a53 => common}/stack.c | 80 +- libcpu/aarch64/common/startup_gcc.S | 5 + libcpu/aarch64/common/trap.c | 279 +++++ libcpu/aarch64/common/vector_gcc.S | 32 +- .../{cortex-a53 => cortex-a}/SConscript | 0 .../{cortex-a72 => cortex-a}/entry_point.S | 83 +- libcpu/aarch64/cortex-a53/entry_point.S | 111 -- libcpu/aarch64/cortex-a53/interrupt.h | 29 - libcpu/aarch64/cortex-a53/trap.c | 202 ---- libcpu/aarch64/cortex-a72/interrupt.c | 118 --- libcpu/aarch64/cortex-a72/interrupt.h | 27 - libcpu/aarch64/cortex-a72/stack.c | 90 -- libcpu/aarch64/cortex-a72/trap.c | 98 -- libcpu/arm/cortex-a/context_gcc.S | 18 +- libcpu/arm/cortex-a/start_gcc.S | 16 +- src/kservice.c | 6 +- src/scheduler.c | 10 + 110 files changed, 11234 insertions(+), 1792 deletions(-) create mode 100644 bsp/qemu-vexpress-a53/.config create mode 100644 bsp/qemu-vexpress-a53/.cproject create mode 100644 bsp/qemu-vexpress-a53/.gitignore create mode 100644 bsp/qemu-vexpress-a53/.project create mode 100644 bsp/qemu-vexpress-a53/Kconfig create mode 100644 bsp/qemu-vexpress-a53/README.md create mode 100644 bsp/qemu-vexpress-a53/SConscript create mode 100644 bsp/qemu-vexpress-a53/SConstruct create mode 100644 bsp/qemu-vexpress-a53/applications/.config rename {libcpu/aarch64/cortex-a72 => bsp/qemu-vexpress-a53/applications}/SConscript (38%) create mode 100644 bsp/qemu-vexpress-a53/applications/lcd_init.c create mode 100644 bsp/qemu-vexpress-a53/applications/main.c create mode 100644 bsp/qemu-vexpress-a53/applications/mnt.c create mode 100644 bsp/qemu-vexpress-a53/drivers/Kconfig create mode 100644 bsp/qemu-vexpress-a53/drivers/SConscript create mode 100644 bsp/qemu-vexpress-a53/drivers/audio/SConscript create mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c create mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h create mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c create mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h create mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c create mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h create mode 100644 bsp/qemu-vexpress-a53/drivers/board.c create mode 100644 bsp/qemu-vexpress-a53/drivers/board.h create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_clcd.c create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_clcd.h create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_keyboard.c create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_keyboard.h create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_mouse.c create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_mouse.h create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_sdio.c create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_sdio.h create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_smc911x.c create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_smc911x.h create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_timer.c create mode 100644 bsp/qemu-vexpress-a53/drivers/drv_timer.h create mode 100644 bsp/qemu-vexpress-a53/drivers/realview.h create mode 100644 bsp/qemu-vexpress-a53/drivers/rt_lcd.h create mode 100644 bsp/qemu-vexpress-a53/drivers/secondary_cpu.c create mode 100644 bsp/qemu-vexpress-a53/drivers/serial.c create mode 100644 bsp/qemu-vexpress-a53/drivers/serial.h create mode 100644 bsp/qemu-vexpress-a53/drivers/vexpress_a9.h create mode 100644 bsp/qemu-vexpress-a53/link.lds create mode 100644 bsp/qemu-vexpress-a53/makefile.targets create mode 100755 bsp/qemu-vexpress-a53/qemu-dbg.sh create mode 100755 bsp/qemu-vexpress-a53/qemu-nographic.sh create mode 100755 bsp/qemu-vexpress-a53/qemu.sh create mode 100644 bsp/qemu-vexpress-a53/rtconfig.h create mode 100644 bsp/qemu-vexpress-a53/rtconfig.py create mode 100644 components/lwp/arch/aarch64/common/reloc.c create mode 100644 components/lwp/arch/aarch64/cortex-a/arch_user_space_init.c create mode 100644 components/lwp/arch/aarch64/cortex-a/arch_user_stack.c create mode 100644 components/lwp/arch/aarch64/cortex-a/lwp_arch.h create mode 100644 components/lwp/arch/aarch64/cortex-a/lwp_gcc.S create mode 100644 libcpu/aarch64/common/asm-fpu.h create mode 100644 libcpu/aarch64/common/cache_ops.c create mode 100644 libcpu/aarch64/common/cpuport.h create mode 100644 libcpu/aarch64/common/exception.c 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_pl400.c delete mode 100644 libcpu/aarch64/common/gic/gic_pl400.h rename libcpu/aarch64/{cortex-a53 => common}/interrupt.c (37%) create mode 100644 libcpu/aarch64/common/interrupt.h create mode 100644 libcpu/aarch64/common/page.c create mode 100644 libcpu/aarch64/common/page.h rename libcpu/aarch64/{cortex-a53 => common}/stack.c (43%) create mode 100644 libcpu/aarch64/common/trap.c rename libcpu/aarch64/{cortex-a53 => cortex-a}/SConscript (100%) rename libcpu/aarch64/{cortex-a72 => cortex-a}/entry_point.S (72%) delete mode 100644 libcpu/aarch64/cortex-a53/entry_point.S delete mode 100644 libcpu/aarch64/cortex-a53/interrupt.h delete mode 100644 libcpu/aarch64/cortex-a53/trap.c 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/stack.c delete mode 100644 libcpu/aarch64/cortex-a72/trap.c diff --git a/bsp/qemu-vexpress-a53/.config b/bsp/qemu-vexpress-a53/.config new file mode 100644 index 0000000000..62bc14309a --- /dev/null +++ b/bsp/qemu-vexpress-a53/.config @@ -0,0 +1,689 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=8192 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=8192 +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +CONFIG_RT_USING_SIGNALS=y + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_MEMHEAP=y +# CONFIG_RT_USING_NOHEAP is not set +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_MEMTRACE=y +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +CONFIG_RT_USING_DEVICE_OPS=y +CONFIG_RT_USING_INTERRUPT_INFO=y +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" +CONFIG_RT_VER_NUM=0x50000 +CONFIG_ARCH_CPU_64BIT=y +CONFIG_RT_USING_CACHE=y +# CONFIG_RT_USING_CPU_FFS is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_ARCH_ARM_MMU=y +CONFIG_RT_USING_USERSPACE=y +CONFIG_KERNEL_VADDR_START=0xffff000000000000 +CONFIG_PV_OFFSET=0x1000060000000 +CONFIG_ARCH_ARMV8=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# C++ features +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Command shell +# +CONFIG_RT_USING_FINSH=y +CONFIG_RT_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=10 +CONFIG_FINSH_USING_SYMTAB=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=256 +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# Device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=8 +CONFIG_DFS_FD_MAX=32 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_RT_USING_DFS_ELMFAT=y + +# +# 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_MAX_LFN=255 +CONFIG_RT_DFS_ELM_DRIVES=2 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 +# 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=y +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# 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=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=256 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +CONFIG_RT_USING_I2C=y +# CONFIG_RT_I2C_DEBUG is not set +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_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +CONFIG_RT_USING_MTD_NOR=y +CONFIG_RT_USING_MTD_NAND=y +CONFIG_RT_MTD_NAND_DEBUG=y +# CONFIG_RT_USING_PM is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +CONFIG_RT_USING_SOFT_RTC=y +CONFIG_RT_USING_SDIO=y +CONFIG_RT_SDIO_STACK_SIZE=512 +CONFIG_RT_SDIO_THREAD_PRIORITY=15 +CONFIG_RT_MMCSD_STACK_SIZE=8192 +CONFIG_RT_MMCSD_THREAD_PREORITY=22 +CONFIG_RT_MMCSD_MAX_PARTITION=16 +# CONFIG_RT_SDIO_DEBUG is not set +CONFIG_RT_USING_SPI=y +# CONFIG_RT_USING_QSPI is not set +CONFIG_RT_USING_SPI_MSD=y +CONFIG_RT_USING_SFUD=y +CONFIG_RT_SFUD_USING_SFDP=y +CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y +# CONFIG_RT_SFUD_USING_QSPI is not set +CONFIG_RT_SFUD_SPI_MAX_HZ=50000000 +# CONFIG_RT_DEBUG_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +CONFIG_RT_USING_WDT=y +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# POSIX layer and C standard library +# +CONFIG_RT_USING_LIBC=y +# CONFIG_RT_USING_NEWLIB is not set +CONFIG_RT_USING_MUSL=y +# CONFIG_RT_USING_PTHREADS is not set +CONFIG_RT_USING_POSIX=y +CONFIG_RT_USING_POSIX_MMAP=y +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_GETLINE is not set +CONFIG_RT_USING_POSIX_AIO=y +CONFIG_RT_USING_POSIX_CLOCKTIME=y +# CONFIG_RT_USING_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +CONFIG_RT_USING_SAL=y + +# +# protocol stack implement +# +CONFIG_SAL_USING_LWIP=y +CONFIG_SAL_USING_POSIX=y + +# +# Network interface device +# +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=y +# CONFIG_RT_USING_LWIP141 is not set +CONFIG_RT_USING_LWIP202=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 is not set + +# +# Static IPv4 Address +# +CONFIG_RT_LWIP_IPADDR="10.0.2.100" +CONFIG_RT_LWIP_GWADDR="10.0.2.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=8192 +# 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=8192 +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) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +# CONFIG_RT_USING_GDBSERVER is not set +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_RT_LWP_SHM_MAX_NR=64 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set + +# +# RT-Thread online packages +# + +# +# 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 +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_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 +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_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 + +# +# system packages +# +# 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 +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# 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_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 + +# +# 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_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# 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 +# CONFIG_PKG_USING_LPM is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_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 +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_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 + +# +# 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_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_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI 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_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 + +# +# games: games run on RT-Thread console +# +# 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_LWGPS is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set + +# +# Privated Packages of RealThread +# +# CONFIG_PKG_USING_CODEC is not set +# CONFIG_PKG_USING_PLAYER is not set +# CONFIG_PKG_USING_MPLAYER is not set +# CONFIG_PKG_USING_PERSIMMON_SRC is not set +# CONFIG_PKG_USING_JS_PERSIMMON is not set +# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set + +# +# Network Utilities +# +# CONFIG_PKG_USING_MDNS is not set +# CONFIG_PKG_USING_UPNP is not set +# CONFIG_PKG_USING_WICED is not set +# CONFIG_PKG_USING_CLOUDSDK is not set +# CONFIG_PKG_USING_POWER_MANAGER is not set +# CONFIG_PKG_USING_RT_OTA is not set +# CONFIG_PKG_USING_RDBD_SRC is not set +# CONFIG_PKG_USING_RTINSIGHT is not set +# CONFIG_PKG_USING_SMARTCONFIG is not set +# CONFIG_PKG_USING_RTX is not set +# CONFIG_RT_USING_TESTCASE is not set +# CONFIG_PKG_USING_NGHTTP2 is not set +# CONFIG_PKG_USING_AVS is not set +# CONFIG_PKG_USING_ALI_LINKKIT is not set +# CONFIG_PKG_USING_STS is not set +# CONFIG_PKG_USING_DLMS is not set +# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set +# CONFIG_PKG_USING_ZBAR is not set +# CONFIG_PKG_USING_MCF is not set +# CONFIG_PKG_USING_URPC is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_DCM is not set +# CONFIG_PKG_USING_EMQ is not set +# CONFIG_PKG_USING_CFGM is not set +# CONFIG_PKG_USING_RT_CMSIS_DAP is not set +# CONFIG_PKG_USING_SMODULE is not set +# CONFIG_PKG_USING_SNFD is not set +# CONFIG_PKG_USING_UDBD is not set +# CONFIG_PKG_USING_BENCHMARK is not set +# CONFIG_PKG_USING_UBJSON is not set +# CONFIG_PKG_USING_DATATYPE is not set +# CONFIG_PKG_USING_FASTFS is not set +CONFIG_SOC_VEXPRESS_A53=y +CONFIG_RT_USING_UART0=y +CONFIG_RT_USING_UART1=y +CONFIG_BSP_DRV_CLCD=y +CONFIG_BSP_LCD_WIDTH=640 +CONFIG_BSP_LCD_HEIGHT=480 +CONFIG_BSP_DRV_EMAC=y +# CONFIG_BSP_DRV_AUDIO is not set diff --git a/bsp/qemu-vexpress-a53/.cproject b/bsp/qemu-vexpress-a53/.cproject new file mode 100644 index 0000000000..31c328ad90 --- /dev/null +++ b/bsp/qemu-vexpress-a53/.cproject @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/qemu-vexpress-a53/.gitignore b/bsp/qemu-vexpress-a53/.gitignore new file mode 100644 index 0000000000..0ce2d51447 --- /dev/null +++ b/bsp/qemu-vexpress-a53/.gitignore @@ -0,0 +1,45 @@ +*.pyc +*.map +*.dblite +*.elf +*.bin +*.hex +*.axf +*.exe +*.pdb +*.idb +*.ilk +*.old +build +Debug +documentation/html +packages/ +*~ +*.o +*.obj +*.out +*.bak +*.dep +*.lib +*.i +*.d +.DS_Stor* +.config 3 +.config 4 +.config 5 +Midea-X1 +*.uimg +GPATH +GRTAGS +GTAGS +.vscode +JLinkLog.txt +JLinkSettings.ini +DebugConfig/ +RTE/ +settings/ +*.uvguix* +cconfig.h +.settings +drivers/automac.h +romfs.c diff --git a/bsp/qemu-vexpress-a53/.project b/bsp/qemu-vexpress-a53/.project new file mode 100644 index 0000000000..e5f00228c0 --- /dev/null +++ b/bsp/qemu-vexpress-a53/.project @@ -0,0 +1,54 @@ + + + qemu-vexpress-a9 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.rttnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + rt-thread + 2 + virtual:/virtual + + + rt-thread/components + 2 + $%7BPARENT-2-PROJECT_LOC%7D/components + + + rt-thread/include + 2 + $%7BPARENT-2-PROJECT_LOC%7D/include + + + rt-thread/libcpu + 2 + $%7BPARENT-2-PROJECT_LOC%7D/libcpu + + + rt-thread/src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/src + + + diff --git a/bsp/qemu-vexpress-a53/Kconfig b/bsp/qemu-vexpress-a53/Kconfig new file mode 100644 index 0000000000..7c153bfe46 --- /dev/null +++ b/bsp/qemu-vexpress-a53/Kconfig @@ -0,0 +1,31 @@ +mainmenu "RT-Thread Project Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" + +config SOC_VEXPRESS_A53 + bool + select ARCH_ARMV8 + select ARCH_CPU_64BIT + select RT_USING_CACHE + select ARCH_ARM_MMU + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +source "$BSP_DIR/drivers/Kconfig" diff --git a/bsp/qemu-vexpress-a53/README.md b/bsp/qemu-vexpress-a53/README.md new file mode 100644 index 0000000000..7ad3f30aa8 --- /dev/null +++ b/bsp/qemu-vexpress-a53/README.md @@ -0,0 +1,105 @@ +# QEMU/VExpress A9板级支持包说明 + +## 1. 简介 + +Versatile Express系统由ARM Ltd提供,作为CortexA9四核处理器的开发环境,硬件由uATX主板和CoreTile Express A9x4子板组成。有关该系统的详细信息,可以访问 [ARM官方页面][1] 。 + +Versatile Express的核心是一套FPGA的开发环境,Cortex-A芯片基于FPGA上的硬件逻辑,所以本身是不存在这么一款真实芯片。 + +QEMU/VExpress A9是QEMU模拟器针对ARM VExpress-A9 FPGA开发板进行软件模拟的指令级虚拟机。QEMU/VExpress因为是软件仿真模式,可以配置成多种模式,例如单核Cortex-A9,多核Cortex-A9,以及多核Cortex-A15等。同时也能够模拟出VExpress FPGA开发板上大多数的外设。 + +这份RT-Thread BSP是针对QEMU/VExpress-A9的一份移植,也并未在真实的VExpress FPGA开发板上运行过,主要是提供给开发者一定的便利,能够使用、验证一定的功能。对于真实FPGA开发板的执行情况,不做任何假设。 + +当前QEMU/VExpress-A9对应的硬件特性: + +| 硬件 | 描述 | +| -- | -- | +| CPU | ARM Cortex-A9(单核) | +| 主频 | NA | +| Memory | 128MB(0x60000000 - 0x68000000) | + +## 2. 编译说明 + +推荐使用[env工具][2],可以在console下进入到`bsp/qemu-vexpress-a9`目录中,运行以下命令: + + scons + +来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。在QEMU中一般使用elf方式来运行,所以只需要使用rtthread.elf文件即可。 + +**注:** RT-Thread/ENV中携带的工具版本是: + + gcc version 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496] + +如果在Linux下使用,请自行下载[GNU GCC工具链][3]。 + +## 3. 执行 + +当要执行编译好的RT-Thread时,在这个bsp目录下已经提供了运行脚本文件:qemu.bat/qemu.sh + +这个执行脚本默认把串口输出到stdio(即控制台)上,所以直接执行脚本后就可以输出结果了。 + +```text + \ | / +- RT - Thread Operating System + / | \ 3.0.4 build May 4 2018 + 2006 - 2018 Copyright by rt-thread team +SD card capacity 65536 KB +probe mmcsd block device! +hello rt-thread +msh /> +``` + +## 4. 支持情况 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | UART0/1 | +| SD/MMC | 支持 | | +| CLCD | 支持 | | +| Key | 支持 | | +| Mouse | 支持 | | +| EMAC | 支持 | | + +### 4.1 使用VSCode编辑、编译、调试 + +在qemu-vexpress-a9中已经携带了部分vscode的配置,需要配合着env一起来使用。步骤包括: + +先使用env打开console,然后在console中切换都qemu-vexpress-a9 bsp的目录下, + +```bash +scons --target=vsc -s +``` + +更新vscode需要用到的C/C++头文件搜索路径信息(不是每次都需要更新,只有在使用了menuconfig重新配置了RT-Thread或更改了rtconfig.h头文件时才需要) + +然后在console下输入 + +```bash +code . +``` + +启动vscode。使用vscode,目前包含如下的一些功能: + +* 编译 `Ctrl+Shift+B` - 开启vscode内置终端,调用scons进行编译;如果有编译错误也会侦测问题,双击问题跳到指定代码文件、代码行; +* 包含执行`qemu`模拟器,`scons -c`进行目标文件清理的任务 +* `F5` 一键开启QEMU调试模式,并断点停留在`main`函数上;(需要更改下qemu-dbg.bat文件,在qemu-system-arm前加入`start`),即 + +```batch +@echo off +if exist sd.bin goto run +qemu-img create -f raw sd.bin 64M + +:run +start qemu-system-arm -M vexpress-a9 -kernel rtthread.elf -serial stdio -sd sd.bin -S -s +``` + +**已知问题** 如果在vscode的目录中额外添加了文件夹,会导致调试不能够启动。 + +## 5. 联系人信息 + +维护人:[bernard][4] + + [1]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.boards.express/index.html + [2]: https://www.rt-thread.org/page/download.html + [3]: https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q3-update/+download/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2 + [4]: https://github.com/BernardXiong diff --git a/bsp/qemu-vexpress-a53/SConscript b/bsp/qemu-vexpress-a53/SConscript new file mode 100644 index 0000000000..c7ef7659ec --- /dev/null +++ b/bsp/qemu-vexpress-a53/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/qemu-vexpress-a53/SConstruct b/bsp/qemu-vexpress-a53/SConstruct new file mode 100644 index 0000000000..266405fb6b --- /dev/null +++ b/bsp/qemu-vexpress-a53/SConstruct @@ -0,0 +1,43 @@ +import os +import sys +import rtconfig +import re + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.join(os.getcwd(), '..', '..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT +TRACE_CONFIG = "" + +content = "" +with open("rtconfig.h") as f: + for line in f.readlines(): + if line.find("RT_BACKTRACE_FUNCTION_NAME") != -1: + for token in line.split(" "): + if re.match(r'RT_BACKTRACE_FUNCTION_NAME$', token, flags=0): + TRACE_CONFIG = " " + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS + TRACE_CONFIG, + CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS + TRACE_CONFIG, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS + TRACE_CONFIG, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +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') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/qemu-vexpress-a53/applications/.config b/bsp/qemu-vexpress-a53/applications/.config new file mode 100644 index 0000000000..a83891a3f5 --- /dev/null +++ b/bsp/qemu-vexpress-a53/applications/.config @@ -0,0 +1,631 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y +CONFIG_RT_USING_SMP=y +CONFIG_RT_CPUS_NR=2 +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=4096 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=1024 +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +CONFIG_RT_USING_SIGNALS=y + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_MEMHEAP=y +# CONFIG_RT_USING_NOHEAP is not set +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_MEMTRACE=y +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +CONFIG_RT_USING_DEVICE_OPS=y +CONFIG_RT_USING_INTERRUPT_INFO=y +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" +CONFIG_RT_VER_NUM=0x40003 +CONFIG_RT_USING_CACHE=y +# CONFIG_RT_USING_CPU_FFS is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_MMU=y +CONFIG_RT_USING_USERSPACE=y +CONFIG_KERNEL_VADDR_START=0xc0000000 +CONFIG_PV_OFFSET=0xa0000000 +# CONFIG_RT_IOREMAP_LATE is not set +CONFIG_ARCH_ARM_CORTEX_A=y +CONFIG_ARCH_ARM_CORTEX_A9=y +CONFIG_RT_BACKTRACE_FUNCTION_NAME=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# C++ features +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Command shell +# +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=10 +CONFIG_FINSH_USING_SYMTAB=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=256 +# 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 + +# +# Device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=8 +CONFIG_DFS_FD_MAX=32 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_RT_USING_DFS_ELMFAT=y + +# +# 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_MAX_LFN=255 +CONFIG_RT_DFS_ELM_DRIVES=2 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 +# 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=y +# CONFIG_RT_USING_DFS_CROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# 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=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=256 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +CONFIG_RT_USING_I2C=y +# CONFIG_RT_I2C_DEBUG is not set +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_NULL is not set +CONFIG_RT_USING_RANDOM=y +# CONFIG_RT_USING_PWM is not set +CONFIG_RT_USING_MTD_NOR=y +CONFIG_RT_USING_MTD_NAND=y +CONFIG_RT_MTD_NAND_DEBUG=y +# CONFIG_RT_USING_PM is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +CONFIG_RT_USING_SOFT_RTC=y +CONFIG_RT_USING_SDIO=y +CONFIG_RT_SDIO_STACK_SIZE=512 +CONFIG_RT_SDIO_THREAD_PRIORITY=15 +CONFIG_RT_MMCSD_STACK_SIZE=1024 +CONFIG_RT_MMCSD_THREAD_PREORITY=22 +CONFIG_RT_MMCSD_MAX_PARTITION=16 +# CONFIG_RT_SDIO_DEBUG is not set +CONFIG_RT_USING_SPI=y +# CONFIG_RT_USING_QSPI is not set +CONFIG_RT_USING_SPI_MSD=y +CONFIG_RT_USING_SFUD=y +CONFIG_RT_SFUD_USING_SFDP=y +CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y +# CONFIG_RT_SFUD_USING_QSPI is not set +CONFIG_RT_SFUD_SPI_MAX_HZ=50000000 +# CONFIG_RT_DEBUG_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +CONFIG_RT_USING_WDT=y +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# POSIX layer and C standard library +# +CONFIG_RT_USING_LIBC=y +# CONFIG_RT_USING_NEWLIB is not set +CONFIG_RT_USING_MUSL=y +# CONFIG_RT_USING_PTHREADS is not set +CONFIG_RT_USING_POSIX=y +CONFIG_RT_USING_POSIX_MMAP=y +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_GETLINE is not set +CONFIG_RT_USING_POSIX_AIO=y +# CONFIG_RT_USING_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +CONFIG_RT_USING_SAL=y + +# +# protocol stack implement +# +CONFIG_SAL_USING_LWIP=y +CONFIG_SAL_USING_POSIX=y + +# +# Network interface device +# +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=y +# CONFIG_RT_USING_LWIP141 is not set +CONFIG_RT_USING_LWIP202=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 is not set +CONFIG_RT_LWIP_ICMP=y +# CONFIG_RT_LWIP_SNMP is not set +CONFIG_RT_LWIP_DNS=y +# CONFIG_RT_LWIP_DHCP is not set + +# +# Static IPv4 Address +# +CONFIG_RT_LWIP_IPADDR="10.0.2.100" +CONFIG_RT_LWIP_GWADDR="10.0.2.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=1024 +CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8 +CONFIG_RT_LWIP_REASSEMBLY_FRAG=y +CONFIG_LWIP_NETIF_STATUS_CALLBACK=1 +CONFIG_LWIP_NETIF_LINK_CALLBACK=1 +CONFIG_SO_REUSE=1 +CONFIG_LWIP_SO_RCVTIMEO=1 +CONFIG_LWIP_SO_SNDTIMEO=1 +CONFIG_LWIP_SO_RCVBUF=1 +CONFIG_LWIP_SO_LINGER=0 +# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=0 +# CONFIG_RT_LWIP_STATS is not set +# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set +CONFIG_RT_LWIP_USING_PING=y +# CONFIG_RT_LWIP_DEBUG is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT is not set +# CONFIG_LWIP_USING_DHCPD is not set + +# +# VBUS(Virtual Software BUS) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +CONFIG_RT_USING_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +# CONFIG_RT_USING_GDBSERVER is not set +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_RT_LWP_SHM_MAX_NR=64 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 + +# +# RT-Thread online packages +# + +# +# 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 +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_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 +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH 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 + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_PERSIMMON 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 +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# 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_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 + +# +# 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_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_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 +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE 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_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_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI 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_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 + +# +# games: games run on RT-Thread console +# +# 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_LWGPS is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +CONFIG_SOC_VEXPRESS_A9=y +CONFIG_RT_USING_UART0=y +CONFIG_RT_USING_UART1=y +CONFIG_BSP_DRV_CLCD=y +CONFIG_BSP_LCD_WIDTH=640 +CONFIG_BSP_LCD_HEIGHT=480 +CONFIG_BSP_DRV_EMAC=y +# CONFIG_BSP_DRV_AUDIO is not set diff --git a/libcpu/aarch64/cortex-a72/SConscript b/bsp/qemu-vexpress-a53/applications/SConscript similarity index 38% rename from libcpu/aarch64/cortex-a72/SConscript rename to bsp/qemu-vexpress-a53/applications/SConscript index c6a4817802..89083a964a 100644 --- a/libcpu/aarch64/cortex-a72/SConscript +++ b/bsp/qemu-vexpress-a53/applications/SConscript @@ -1,13 +1,11 @@ -# RT-Thread building script for component - -from building import * - +Import('RTT_ROOT') Import('rtconfig') +from building import * cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') +src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] -group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/bsp/qemu-vexpress-a53/applications/lcd_init.c b/bsp/qemu-vexpress-a53/applications/lcd_init.c new file mode 100644 index 0000000000..6a870440a8 --- /dev/null +++ b/bsp/qemu-vexpress-a53/applications/lcd_init.c @@ -0,0 +1,19 @@ +#include + +#if defined(RT_USING_RTGUI) || defined(PKG_USING_GUIENGINE) + +#include +int lcd_init(void) +{ + struct rt_device *device; + device = rt_device_find("lcd"); + if (device) + { + rtgui_graphic_set_device(device); + } + + return 0; +} +INIT_APP_EXPORT(lcd_init); + +#endif diff --git a/bsp/qemu-vexpress-a53/applications/main.c b/bsp/qemu-vexpress-a53/applications/main.c new file mode 100644 index 0000000000..9d5dfd21e7 --- /dev/null +++ b/bsp/qemu-vexpress-a53/applications/main.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020/10/7 bernard the first version + */ +#include + +int main(void) +{ + printf("hello rt-thread\n"); + return 0; +} diff --git a/bsp/qemu-vexpress-a53/applications/mnt.c b/bsp/qemu-vexpress-a53/applications/mnt.c new file mode 100644 index 0000000000..625f003c76 --- /dev/null +++ b/bsp/qemu-vexpress-a53/applications/mnt.c @@ -0,0 +1,29 @@ +#include + +#ifdef RT_USING_DFS +#include +#include + +int mnt_init(void) +{ + /* + if (dfs_mount(RT_NULL, "/", "rom", 0, &romfs_root) != 0) + { + rt_kprintf("Dir / mount failed!\n"); + return -1; + } + */ + + rt_thread_mdelay(200); + if (dfs_mount("sd0", "/", "elm", 0, NULL) != 0) + { + rt_kprintf("Dir / mount failed!\n"); + return -1; + } + + rt_kprintf("file system initialization done!\n"); + return 0; +} +INIT_ENV_EXPORT(mnt_init); +#endif + diff --git a/bsp/qemu-vexpress-a53/drivers/Kconfig b/bsp/qemu-vexpress-a53/drivers/Kconfig new file mode 100644 index 0000000000..ce3d2c3978 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/Kconfig @@ -0,0 +1,30 @@ +config RT_USING_UART0 + bool "Enable UART0" + default n + +config RT_USING_UART1 + bool "Enable UART1" + default y + +config BSP_DRV_CLCD + bool "CLCD driver" + default y + +if BSP_DRV_CLCD + config BSP_LCD_WIDTH + int "Width of LCD panel" + default 640 + + config BSP_LCD_HEIGHT + int "Height of LCD panel" + default 480 +endif + +config BSP_DRV_EMAC + bool "EMAC driver" + default y + +config BSP_DRV_AUDIO + bool "Audio driver" + select RT_USING_AUDIO + default n diff --git a/bsp/qemu-vexpress-a53/drivers/SConscript b/bsp/qemu-vexpress-a53/drivers/SConscript new file mode 100644 index 0000000000..4f10c26217 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/SConscript @@ -0,0 +1,23 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +list = os.listdir(cwd) +CPPPATH = [cwd] +objs = [] + +if not GetDepend('BSP_DRV_EMAC'): + SrcRemove(src, ['drv_smc911x.c']) + +if not GetDepend('BSP_DRV_CLCD'): + SrcRemove(src, ['drv_clcd.c']) + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) +objs = objs + group + +Return('objs') diff --git a/bsp/qemu-vexpress-a53/drivers/audio/SConscript b/bsp/qemu-vexpress-a53/drivers/audio/SConscript new file mode 100644 index 0000000000..2118631608 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/audio/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.S') +CPPPATH = [cwd] + +group = DefineGroup('drv_audio', src, depend = ['BSP_DRV_AUDIO'], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c b/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c new file mode 100644 index 0000000000..46ea2e0fea --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c @@ -0,0 +1,121 @@ +/* + * File : drv_ac97.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-05-25 RT-Thread the first version + */ + +#include +#include +#include "drv_pl041.h" +#include "drv_ac97.h" + +void ac97_reset(void) +{ + aaci_ac97_write(AC97_RESET, 0xFFFF); +} + +rt_err_t ac97_set_vol(int vol) +{ + rt_uint16_t tmp = vol | (vol << 8); + + if (vol < 0 || vol > 0x3f) + { + return -RT_ERROR; + } + + aaci_ac97_write(AC97_MASTER, tmp); + aaci_ac97_write(AC97_HEADPHONE, tmp); + aaci_ac97_write(AC97_MASTER_MONO, tmp); + aaci_ac97_write(AC97_PCM, tmp); + + return RT_EOK; +} + +int ac97_get_vol(void) +{ + rt_uint16_t v; + + v = aaci_ac97_read(AC97_MASTER); + if (v == (~0x0)) + { + v = 0; + } + return 0x3F & v; +} + +rt_err_t ac97_set_rate(int rate) +{ + if (rate < 0) + { + return -RT_ERROR; + } + aaci_ac97_write(AC97_PCM_FRONT_DAC_RATE, rate); + return 0; +} + +int ac97_get_rate(void) +{ + rt_uint16_t v; + + v = aaci_ac97_read(AC97_PCM_FRONT_DAC_RATE); + if (v == (~0x0)) + { + v = 0; + } + return v; +} + +#if 0 +#define AC97_DUMP(_v) rt_kprintf("%32s:addr:0x%08x data:0x%08x\n", #_v, (_v), (aaci_ac97_read(_v))) +int _ac97_reg_dump(int argc, char **argv) +{ + AC97_DUMP(AC97_RESET); + AC97_DUMP(AC97_MASTER); + AC97_DUMP(AC97_HEADPHONE); + AC97_DUMP(AC97_MASTER_MONO); + AC97_DUMP(AC97_MASTER_TONE); + AC97_DUMP(AC97_PC_BEEP); + AC97_DUMP(AC97_PHONE); + AC97_DUMP(AC97_MIC); + AC97_DUMP(AC97_LINE); + AC97_DUMP(AC97_CD); + AC97_DUMP(AC97_VIDEO); + AC97_DUMP(AC97_AUX); + AC97_DUMP(AC97_PCM); + AC97_DUMP(AC97_REC_SEL); + AC97_DUMP(AC97_REC_GAIN); + AC97_DUMP(AC97_REC_GAIN_MIC); + AC97_DUMP(AC97_GENERAL_PURPOSE); + AC97_DUMP(AC97_3D_CONTROL); + AC97_DUMP(AC97_INT_PAGING); + AC97_DUMP(AC97_POWERDOWN); + AC97_DUMP(AC97_PCM_FRONT_DAC_RATE); + AC97_DUMP(AC97_PCM_SURR_DAC_RATE); + AC97_DUMP(AC97_PCM_LFE_DAC_RATE); + AC97_DUMP(AC97_PCM_LR_ADC_RATE); + AC97_DUMP(AC97_PCM_MIC_ADC_RATE); + AC97_DUMP(AC97_DAC_SLOT_MAP); + AC97_DUMP(AC97_ADC_SLOT_MAP); + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(_ac97_reg_dump, __cmd_ac97_dump, ac97 dump reg.); + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h b/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h new file mode 100644 index 0000000000..31d496024d --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h @@ -0,0 +1,63 @@ +/* + * File : drv_ac97.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-05-25 RT-Thread the first version + */ + +#ifndef __DRV_AC97_H__ +#define __DRV_AC97_H__ + +/* Register offsets */ +#define AC97_RESET 0x00 +#define AC97_MASTER 0x02 +#define AC97_HEADPHONE 0x04 +#define AC97_MASTER_MONO 0x06 +#define AC97_MASTER_TONE 0x08 +#define AC97_PC_BEEP 0x0A //mixer volume +#define AC97_PHONE 0x0C +#define AC97_MIC 0x0E //qwert db +#define AC97_LINE 0x10 +#define AC97_CD 0x12 +#define AC97_VIDEO 0x14 +#define AC97_AUX 0x16 +#define AC97_PCM 0x18 +#define AC97_REC_SEL 0x1A //0 represent mic +#define AC97_REC_GAIN 0x1C +#define AC97_REC_GAIN_MIC 0x1E +#define AC97_GENERAL_PURPOSE 0x20 +#define AC97_3D_CONTROL 0x22 +#define AC97_INT_PAGING 0x24 //qwert +#define AC97_POWERDOWN 0x26 +#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */ +#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */ +#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */ +#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */ +#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */ +#define AC97_DAC_SLOT_MAP 0x6C +#define AC97_ADC_SLOT_MAP 0x6E + +void ac97_reset(void); +rt_err_t ac97_set_vol(int vol); +int ac97_get_vol(void); +rt_err_t ac97_set_rate(int rate); +int ac97_get_rate(void); + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c b/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c new file mode 100644 index 0000000000..334e22f701 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c @@ -0,0 +1,409 @@ +/* + * File : drv_pl041.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-05-25 RT-Thread the first version + */ + +#include +#include +#include "drv_pl041.h" +#include "drv_ac97.h" +#include "realview.h" + +#define DBG_TAG "PL041" +// #define DBG_LVL DBG_LOG +// #define DBG_LVL DBG_INFO +#define DBG_LVL DBG_WARNING +// #define DBG_LVL DBG_ERROR +#include + +#define FRAME_PERIOD_US (50) +#define PL041_CHANNEL_NUM (4) + +#define PL041_READ(_a) (*(volatile rt_uint32_t *)(_a)) +#define PL041_WRITE(_a, _v) (*(volatile rt_uint32_t *)(_a) = (_v)) + +struct pl041_irq_def +{ + pl041_irq_fun_t fun; + void *user_data; +}; + +static struct pl041_irq_def irq_tbl[PL041_CHANNEL_NUM]; + +static void aaci_pl041_delay(rt_uint32_t us) +{ + volatile int i; + + for (i = us * 10; i != 0; i--); +} + +static void aaci_ac97_select_codec(void) +{ + rt_uint32_t v, maincr; + + maincr = AACI_MAINCR_SCRA(0) | AACI_MAINCR_IE | AACI_MAINCR_SL1RXEN | \ + AACI_MAINCR_SL1TXEN | AACI_MAINCR_SL2RXEN | AACI_MAINCR_SL2TXEN; + + v = PL041_READ(&PL041->slfr); + if (v & AACI_SLFR_2RXV) + { + PL041_READ(&PL041->sl2rx); + } + if (v & AACI_SLFR_1RXV) + { + PL041_READ(&PL041->sl1rx); + } + + if (maincr != PL041_READ(&PL041->maincr)) + { + PL041_WRITE(&PL041->maincr, maincr); + aaci_pl041_delay(1); + } +} + +void aaci_ac97_write(rt_uint16_t reg, rt_uint16_t val) +{ + rt_uint32_t v, timeout; + + aaci_ac97_select_codec(); + + PL041_WRITE(&PL041->sl2tx, val << 4); + PL041_WRITE(&PL041->sl1tx, reg << 12); + + aaci_pl041_delay(FRAME_PERIOD_US); + + timeout = FRAME_PERIOD_US * 8; + do + { + aaci_pl041_delay(1); + v = PL041_READ(&PL041->slfr); + } + while ((v & (AACI_SLFR_1TXB | AACI_SLFR_2TXB)) && --timeout); + + if (v & (AACI_SLFR_1TXB | AACI_SLFR_2TXB)) + { + LOG_E("timeout waiting for write to complete"); + } +} + +rt_uint16_t aaci_ac97_read(rt_uint16_t reg) +{ + rt_uint32_t v, timeout, retries = 10; + + aaci_ac97_select_codec(); + + PL041_WRITE(&PL041->sl1tx, (reg << 12) | (1 << 19)); + aaci_pl041_delay(FRAME_PERIOD_US); + + timeout = FRAME_PERIOD_US * 8; + do + { + aaci_pl041_delay(1); + v = PL041_READ(&PL041->slfr); + } + while ((v & AACI_SLFR_1TXB) && --timeout); + + if (v & AACI_SLFR_1TXB) + { + LOG_E("timeout on slot 1 TX busy"); + v = ~0x0; + return v; + } + + aaci_pl041_delay(FRAME_PERIOD_US); + timeout = FRAME_PERIOD_US * 8; + do + { + aaci_pl041_delay(1); + v = PL041_READ(&PL041->slfr) & (AACI_SLFR_1RXV | AACI_SLFR_2RXV); + } + while ((v != (AACI_SLFR_1RXV | AACI_SLFR_2RXV)) && --timeout); + + if (v != (AACI_SLFR_1RXV | AACI_SLFR_2RXV)) + { + LOG_E("timeout on RX valid"); + v = ~0x0; + return v; + } + + do + { + v = PL041_READ(&PL041->sl1rx) >> 12; + if (v == reg) + { + v = PL041_READ(&PL041->sl2rx) >> 4; + break; + } + else if (--retries) + { + LOG_E("ac97 read back fail. retry"); + continue; + } + else + { + LOG_E("wrong ac97 register read back (%x != %x)", v, reg); + v = ~0x0; + } + } + while (retries); + + return v; +} + +int aaci_pl041_channel_disable(int channel) +{ + rt_uint32_t v; + void *p_rx, *p_tx; + + p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channel * 0x14); + p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channel * 0x14); + v = PL041_READ(p_rx); + v &= ~AACI_CR_EN; + PL041_WRITE(p_rx, v); + v = PL041_READ(p_tx); + v &= ~AACI_CR_EN; + PL041_WRITE(p_tx, v); + return 0; +} + +int aaci_pl041_channel_enable(int channel) +{ + rt_uint32_t v; + void *p_rx, *p_tx; + + p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channel * 0x14); + p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channel * 0x14); + v = PL041_READ(p_rx); + v |= AACI_CR_EN; + PL041_WRITE(p_rx, v); + v = PL041_READ(p_tx); + v |= AACI_CR_EN; + PL041_WRITE(p_tx, v); + return 0; +} + +int aaci_pl041_channel_read(int channel, rt_uint16_t *buff, int count) +{ + void *p_data, *p_status; + int i = 0; + + p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channel * 0x14); + p_data = (void *)((rt_uint32_t)(&(PL041->dr1[0])) + channel * 0x20); + for (i = 0; (!(PL041_READ(p_status) & AACI_SR_RXFE)) && (i < count); i++) + { + buff[i] = (rt_uint16_t)PL041_READ(p_data); + } + return i; +} + +int aaci_pl041_channel_write(int channel, rt_uint16_t *buff, int count) +{ + void *p_data, *p_status; + int i = 0; + + p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channel * 0x14); + p_data = (void *)((rt_uint32_t)(&(PL041->dr1[0])) + channel * 0x20); + for (i = 0; (!(PL041_READ(p_status) & AACI_SR_TXFF)) && (i < count); i++) + { + PL041_WRITE(p_data, buff[i]); + } + return i; +} + +int aaci_pl041_channel_cfg(int channel, pl041_cfg_t cgf) +{ + rt_uint32_t v; + void *p_rx, *p_tx; + + p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channel * 0x14); + p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channel * 0x14); + v = AACI_CR_FEN | AACI_CR_SZ16 | cgf->itype; + PL041_WRITE(p_rx, v); + v = AACI_CR_FEN | AACI_CR_SZ16 | cgf->otype; + PL041_WRITE(p_tx, v); + + ac97_set_vol(cgf->vol); + ac97_set_rate(cgf->rate); + + return 0; +} + +void aaci_pl041_irq_enable(int channel, rt_uint32_t vector) +{ + rt_uint32_t v; + void *p_irq; + + vector &= vector & 0x7f; + p_irq = (void *)((rt_uint32_t)(&PL041->iie1) + channel * 0x14); + v = PL041_READ(p_irq); + v |= vector; + PL041_WRITE(p_irq, v); +} + +void aaci_pl041_irq_disable(int channel, rt_uint32_t vector) +{ + rt_uint32_t v; + void *p_irq; + + vector &= vector & 0x7f; + p_irq = (void *)((rt_uint32_t)(&PL041->iie1) + channel * 0x14); + v = PL041_READ(p_irq); + v &= ~vector; + PL041_WRITE(p_irq, v); +} + +rt_err_t aaci_pl041_irq_register(int channel, pl041_irq_fun_t fun, void *user_data) +{ + if (channel < 0 || channel >= PL041_CHANNEL_NUM) + { + LOG_E("%s channel:%d err.", __FUNCTION__, channel); + return -RT_ERROR; + } + irq_tbl[channel].fun = fun; + irq_tbl[channel].user_data = user_data; + return RT_EOK; +} + +rt_err_t aaci_pl041_irq_unregister(int channel) +{ + if (channel < 0 || channel >= PL041_CHANNEL_NUM) + { + LOG_E("%s channel:%d err.", __FUNCTION__, channel); + return -RT_ERROR; + } + irq_tbl[channel].fun = RT_NULL; + irq_tbl[channel].user_data = RT_NULL; + return RT_EOK; +} + +static void aaci_pl041_irq_handle(int irqno, void *param) +{ + rt_uint32_t mask, channel, m; + struct pl041_irq_def *_irq = param; + void *p_status; + + mask = PL041_READ(&PL041->allints); + PL041_WRITE(&PL041->intclr, mask); + + for (channel = 0; (channel < PL041_CHANNEL_NUM) && (mask); channel++) + { + mask = mask >> 7; + m = mask & 0x7f; + if (m & AACI_ISR_ORINTR) + { + LOG_W("RX overrun on chan %d", channel); + } + + if (m & AACI_ISR_RXTOINTR) + { + LOG_W("RX timeout on chan %d", channel); + } + + if (mask & AACI_ISR_URINTR) + { + LOG_W("TX underrun on chan %d", channel); + } + + p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channel * 0x14); + if (_irq[channel].fun != RT_NULL) + { + _irq[channel].fun(PL041_READ(p_status), _irq[channel].user_data); + } + } +} + +rt_err_t aaci_pl041_init(void) +{ + rt_uint32_t i, maincr; + + maincr = AACI_MAINCR_SCRA(0) | AACI_MAINCR_IE | AACI_MAINCR_SL1RXEN | \ + AACI_MAINCR_SL1TXEN | AACI_MAINCR_SL2RXEN | AACI_MAINCR_SL2TXEN; + + for (i = 0; i < 4; i++) + { + void *base = (void *)((rt_uint32_t)(&PL041->rxcr1) + i * 0x14); + + PL041_WRITE(base + AACI_IE, 0); + PL041_WRITE(base + AACI_TXCR, 0); + PL041_WRITE(base + AACI_RXCR, 0); + } + + PL041_WRITE(&PL041->intclr, 0x1fff); + PL041_WRITE(&PL041->maincr, maincr); + + PL041_WRITE(&PL041->reset, 0); + aaci_pl041_delay(2); + PL041_WRITE(&PL041->reset, RESET_NRST); + + rt_hw_interrupt_install(43, aaci_pl041_irq_handle, &irq_tbl, "aaci_pl041"); + rt_hw_interrupt_umask(43); + + return 0; +} + +#if 0 +#define PL041_DUMP(_v) rt_kprintf("%32s:addr:0x%08x data:0x%08x\n", #_v, &(_v), (_v)) +int _aaci_pl041_reg_dump(int argc, char **argv) +{ + PL041_DUMP(PL041->rxcr1); + PL041_DUMP(PL041->txcr1); + PL041_DUMP(PL041->sr1); + PL041_DUMP(PL041->isr1); + PL041_DUMP(PL041->iie1); + PL041_DUMP(PL041->rxcr2); + PL041_DUMP(PL041->txcr2); + PL041_DUMP(PL041->sr2); + PL041_DUMP(PL041->isr2); + PL041_DUMP(PL041->iie2); + PL041_DUMP(PL041->rxcr3); + PL041_DUMP(PL041->txcr3); + PL041_DUMP(PL041->sr3); + PL041_DUMP(PL041->isr3); + PL041_DUMP(PL041->iie3); + PL041_DUMP(PL041->rxcr4); + PL041_DUMP(PL041->txcr4); + PL041_DUMP(PL041->sr4); + PL041_DUMP(PL041->isr4); + PL041_DUMP(PL041->iie4); + PL041_DUMP(PL041->sl1rx); + PL041_DUMP(PL041->sl1tx); + PL041_DUMP(PL041->sl2rx); + PL041_DUMP(PL041->sl2tx); + PL041_DUMP(PL041->sl12rx); + PL041_DUMP(PL041->sl12tx); + PL041_DUMP(PL041->slfr); + PL041_DUMP(PL041->slistat); + PL041_DUMP(PL041->slien); + PL041_DUMP(PL041->intclr); + PL041_DUMP(PL041->maincr); + PL041_DUMP(PL041->reset); + PL041_DUMP(PL041->sync); + PL041_DUMP(PL041->allints); + PL041_DUMP(PL041->mainfr); + PL041_DUMP(PL041->dr1[0]); + PL041_DUMP(PL041->dr2[0]); + PL041_DUMP(PL041->dr3[0]); + PL041_DUMP(PL041->dr4[0]); + return 0; +} +FINSH_FUNCTION_EXPORT_ALIAS(_aaci_pl041_reg_dump, __cmd_pl041_dump, aaci pl041 dump reg.); +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h b/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h new file mode 100644 index 0000000000..cd972b5bdd --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h @@ -0,0 +1,237 @@ +/* + * File : drv_pl041.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2018-05-25 RT-Thread the first version + */ + +#ifndef __DRV_PL041_H__ +#define __DRV_PL041_H__ + +#define PL041_BASE_ADDR (0x10004000) + +/* offsets in CTRL_CH */ +#define AACI_RXCR 0x00 /* 29 bits Control Rx FIFO */ +#define AACI_TXCR 0x04 /* 17 bits Control Tx FIFO */ +#define AACI_SR 0x08 /* 12 bits Status */ +#define AACI_ISR 0x0C /* 7 bits Int Status */ +#define AACI_IE 0x10 /* 7 bits Int Enable */ + +/* both for AACI_RXCR and AACI_TXCR */ +#define AACI_CR_FEN (1 << 16) /* fifo enable */ +#define AACI_CR_COMPACT (1 << 15) /* compact mode */ +#define AACI_CR_SZ16 (0 << 13) /* 16 bits */ +#define AACI_CR_SZ18 (1 << 13) /* 18 bits */ +#define AACI_CR_SZ20 (2 << 13) /* 20 bits */ +#define AACI_CR_SZ12 (3 << 13) /* 12 bits */ +#define AACI_CR_SL12 (1 << 12) +#define AACI_CR_SL11 (1 << 11) +#define AACI_CR_SL10 (1 << 10) +#define AACI_CR_SL9 (1 << 9) +#define AACI_CR_SL8 (1 << 8) +#define AACI_CR_SL7 (1 << 7) +#define AACI_CR_SL6 (1 << 6) +#define AACI_CR_SL5 (1 << 5) +#define AACI_CR_SL4 (1 << 4) +#define AACI_CR_SL3 (1 << 3) +#define AACI_CR_SL2 (1 << 2) +#define AACI_CR_SL1 (1 << 1) +#define AACI_CR_EN (1 << 0) /* receive enable */ + +/* status register bits */ +#define AACI_SR_RXTOFE (1 << 11) /* rx timeout fifo empty */ +#define AACI_SR_TXTO (1 << 10) /* rx timeout fifo nonempty */ +#define AACI_SR_TXU (1 << 9) /* tx underrun */ +#define AACI_SR_RXO (1 << 8) /* rx overrun */ +#define AACI_SR_TXB (1 << 7) /* tx busy */ +#define AACI_SR_RXB (1 << 6) /* rx busy */ +#define AACI_SR_TXFF (1 << 5) /* tx fifo full */ +#define AACI_SR_RXFF (1 << 4) /* rx fifo full */ +#define AACI_SR_TXHE (1 << 3) /* tx fifo half empty */ +#define AACI_SR_RXHF (1 << 2) /* rx fifo half full */ +#define AACI_SR_TXFE (1 << 1) /* tx fifo empty */ +#define AACI_SR_RXFE (1 << 0) /* rx fifo empty */ + +#define AACI_ISR_RXTOFEINTR (1 << 6) /* rx fifo empty */ +#define AACI_ISR_URINTR (1 << 5) /* tx underflow */ +#define AACI_ISR_ORINTR (1 << 4) /* rx overflow */ +#define AACI_ISR_RXINTR (1 << 3) /* rx fifo */ +#define AACI_ISR_TXINTR (1 << 2) /* tx fifo intr */ +#define AACI_ISR_RXTOINTR (1 << 1) /* rx timeout */ +#define AACI_ISR_TXCINTR (1 << 0) /* tx complete */ + +/* interrupt enable */ +#define AACI_IE_RXTOIE (1 << 6) /*rx timeout interrupt enable*/ +#define AACI_IE_URIE (1 << 5) /*Transmit underrun interrupt enable*/ +#define AACI_IE_ORIE (1 << 4) /*Overrun receive interrupt enable*/ +#define AACI_IE_RXIE (1 << 3) /*Receive interrupt enable*/ +#define AACI_IE_TXIE (1 << 2) /*Transmit interrupt enable*/ +#define AACI_IE_RXTIE (1 << 1) /*Receive timeout interrupt enable*/ +#define AACI_IE_TXCIE (1 << 0) /*Transmit complete interrupt enable*/ + +/* interrupt status */ +#define AACI_ISR_RXTOFE (1 << 6) /* rx timeout fifo empty */ +#define AACI_ISR_UR (1 << 5) /* tx fifo underrun */ +#define AACI_ISR_OR (1 << 4) /* rx fifo overrun */ +#define AACI_ISR_RX (1 << 3) /* rx interrupt status */ +#define AACI_ISR_TX (1 << 2) /* tx interrupt status */ +#define AACI_ISR_RXTO (1 << 1) /* rx timeout */ +#define AACI_ISR_TXC (1 << 0) /* tx complete */ + +/* interrupt enable */ +#define AACI_IE_RXTOFE (1 << 6) /* rx timeout fifo empty */ +#define AACI_IE_UR (1 << 5) /* tx fifo underrun */ +#define AACI_IE_OR (1 << 4) /* rx fifo overrun */ +#define AACI_IE_RX (1 << 3) /* rx interrupt status */ +#define AACI_IE_TX (1 << 2) /* tx interrupt status */ +#define AACI_IE_RXTO (1 << 1) /* rx timeout */ +#define AACI_IE_TXC (1 << 0) /* tx complete */ + +/* slot flag register bits */ +#define AACI_SLFR_RWIS (1 << 13) /* raw wake-up interrupt status */ +#define AACI_SLFR_RGPIOINTR (1 << 12) /* raw gpio interrupt */ +#define AACI_SLFR_12TXE (1 << 11) /* slot 12 tx empty */ +#define AACI_SLFR_12RXV (1 << 10) /* slot 12 rx valid */ +#define AACI_SLFR_2TXE (1 << 9) /* slot 2 tx empty */ +#define AACI_SLFR_2RXV (1 << 8) /* slot 2 rx valid */ +#define AACI_SLFR_1TXE (1 << 7) /* slot 1 tx empty */ +#define AACI_SLFR_1RXV (1 << 6) /* slot 1 rx valid */ +#define AACI_SLFR_12TXB (1 << 5) /* slot 12 tx busy */ +#define AACI_SLFR_12RXB (1 << 4) /* slot 12 rx busy */ +#define AACI_SLFR_2TXB (1 << 3) /* slot 2 tx busy */ +#define AACI_SLFR_2RXB (1 << 2) /* slot 2 rx busy */ +#define AACI_SLFR_1TXB (1 << 1) /* slot 1 tx busy */ +#define AACI_SLFR_1RXB (1 << 0) /* slot 1 rx busy */ + +/* Interrupt clear register */ +#define AACI_ICLR_RXTOFEC4 (1 << 12) /* Receive timeout FIFO empty clear */ +#define AACI_ICLR_RXTOFEC3 (1 << 11) /* Receive timeout FIFO empty clear */ +#define AACI_ICLR_RXTOFEC2 (1 << 10) /* Receive timeout FIFO empty clear */ +#define AACI_ICLR_RXTOFEC1 (1 << 9) /* Receive timeout FIFO empty clear */ +#define AACI_ICLR_TXUEC4 (1 << 8) /* Transmit underrun error clear */ +#define AACI_ICLR_TXUEC3 (1 << 7) /* Transmit underrun error clear */ +#define AACI_ICLR_TXUEC2 (1 << 6) /* Transmit underrun error clear*/ +#define AACI_ICLR_TXUEC1 (1 << 5) /* Transmit underrun error clear */ +#define AACI_ICLR_RXOEC4 (1 << 4) /* Receive overrun error clear */ +#define AACI_ICLR_RXOEC3 (1 << 3) /* Receive overrun error clear */ +#define AACI_ICLR_RXOEC2 (1 << 2) /* Receive overrun error clear */ +#define AACI_ICLR_RXOEC1 (1 << 1) /* Receive overrun error clear */ +#define AACI_ICLR_WISC (1 << 0) /* Wake-up interrupt status clear */ + +/* Main control register bits AACI_MAINCR */ +#define AACI_MAINCR_SCRA(x) ((x) << 10) /* secondary codec reg access */ +#define AACI_MAINCR_DMAEN (1 << 9) /* dma enable */ +#define AACI_MAINCR_SL12TXEN (1 << 8) /* slot 12 transmit enable */ +#define AACI_MAINCR_SL12RXEN (1 << 7) /* slot 12 receive enable */ +#define AACI_MAINCR_SL2TXEN (1 << 6) /* slot 2 transmit enable */ +#define AACI_MAINCR_SL2RXEN (1 << 5) /* slot 2 receive enable */ +#define AACI_MAINCR_SL1TXEN (1 << 4) /* slot 1 transmit enable */ +#define AACI_MAINCR_SL1RXEN (1 << 3) /* slot 1 receive enable */ +#define AACI_MAINCR_LPM (1 << 2) /* low power mode */ +#define AACI_MAINCR_LOOPBK (1 << 1) /* loopback */ +#define AACI_MAINCR_IE (1 << 0) /* aaci interface enable */ + +/* Reset register bits. P65 */ +#define RESET_NRST (1 << 0) + +/* Sync register bits. P65 */ +#define SYNC_FORCE (1 << 0) + +/* Main flag register bits. P66 */ +#define MAINFR_TXB (1 << 1) /* transmit busy */ +#define MAINFR_RXB (1 << 0) /* receive busy */ + +#define PL041_CHANNEL_LEFT_DAC (0x1 << 3) +#define PL041_CHANNEL_RIGHT_DAC (0x1 << 3) +#define PL041_CHANNEL_LEFT_ADC (0x1 << 3) +#define PL041_CHANNEL_RIGHT_ADC (0x1 << 3) + +struct reg_pl041 +{ +volatile rt_uint32_t rxcr1; /* 0x000 */ +volatile rt_uint32_t txcr1; /* 0x004 */ +volatile rt_uint32_t sr1; /* 0x008 */ +volatile rt_uint32_t isr1; /* 0x00c */ +volatile rt_uint32_t iie1; /* 0x010 */ +volatile rt_uint32_t rxcr2; /* 0x014 */ +volatile rt_uint32_t txcr2; /* 0x018 */ +volatile rt_uint32_t sr2; /* 0x01c */ +volatile rt_uint32_t isr2; /* 0x020 */ +volatile rt_uint32_t iie2; /* 0x024 */ +volatile rt_uint32_t rxcr3; /* 0x028 */ +volatile rt_uint32_t txcr3; /* 0x02c */ +volatile rt_uint32_t sr3; /* 0x030 */ +volatile rt_uint32_t isr3; /* 0x034 */ +volatile rt_uint32_t iie3; /* 0x038 */ +volatile rt_uint32_t rxcr4; /* 0x03c */ +volatile rt_uint32_t txcr4; /* 0x040 */ +volatile rt_uint32_t sr4; /* 0x044 */ +volatile rt_uint32_t isr4; /* 0x048 */ +volatile rt_uint32_t iie4; /* 0x04c */ +volatile rt_uint32_t sl1rx; /* 0x050 */ +volatile rt_uint32_t sl1tx; /* 0x054 */ +volatile rt_uint32_t sl2rx; /* 0x058 */ +volatile rt_uint32_t sl2tx; /* 0x05c */ +volatile rt_uint32_t sl12rx; /* 0x060 */ +volatile rt_uint32_t sl12tx; /* 0x064 */ +volatile rt_uint32_t slfr; /* 0x068 */ +volatile rt_uint32_t slistat; /* 0x06c */ +volatile rt_uint32_t slien; /* 0x070 */ +volatile rt_uint32_t intclr; /* 0x074 */ +volatile rt_uint32_t maincr; /* 0x078 */ +volatile rt_uint32_t reset; /* 0x07c */ +volatile rt_uint32_t sync; /* 0x080 */ +volatile rt_uint32_t allints; /* 0x084 */ +volatile rt_uint32_t mainfr; /* 0x088 */ +volatile rt_uint32_t res08c; +volatile rt_uint32_t dr1[8]; /* 0x090 */ +volatile rt_uint32_t dr2[8]; /* 0x0b0 */ +volatile rt_uint32_t dr3[8]; /* 0x0d0 */ +volatile rt_uint32_t dr4[8]; /* 0x0f0 */ +}; + +typedef struct reg_pl041 *reg_pl041_t; + +#define PL041 ((reg_pl041_t)PL041_BASE_ADDR) + +struct pl041_cfg +{ + rt_uint32_t itype; + rt_uint32_t otype; + int vol; + int rate; +}; +typedef struct pl041_cfg *pl041_cfg_t; + +typedef void (*pl041_irq_fun_t)(rt_uint32_t status, void * user_data); + +rt_err_t aaci_pl041_init(void); +void aaci_ac97_write(rt_uint16_t reg, rt_uint16_t val); +rt_uint16_t aaci_ac97_read(rt_uint16_t reg); +int aaci_pl041_channel_cfg(int channel, pl041_cfg_t cfg); +int aaci_pl041_channel_write(int channel, rt_uint16_t *buff, int count); +int aaci_pl041_channel_read(int channel, rt_uint16_t *buff, int count); +int aaci_pl041_channel_enable(int channel); +int aaci_pl041_channel_disable(int channel); +rt_err_t aaci_pl041_irq_register(int channel, pl041_irq_fun_t fun, void *user_data); +rt_err_t aaci_pl041_irq_unregister(int channel); +void aaci_pl041_irq_disable(int channel, rt_uint32_t vector); +void aaci_pl041_irq_enable(int channel, rt_uint32_t vector); +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c b/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c new file mode 100644 index 0000000000..a2b46831b8 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-23 Zero-Free first implementation + */ + +#include +#include + +#include +#include +#include + +#define DBG_TAG "drv.sound" +#define DBG_LVL DBG_INFO +#include + +#define TX_FIFO_SIZE (3840) + +struct sound_device +{ + struct rt_audio_device audio; + struct rt_audio_configure replay_config; + rt_uint8_t *tx_fifo; + rt_uint8_t volume; +}; + +static struct sound_device snd_dev = {0}; + +static void rt_hw_aaci_isr(rt_uint32_t status, void *user_data) +{ + if (status & AACI_SR_TXHE) + { + rt_audio_tx_complete(&snd_dev.audio); + } +} + +static rt_err_t sound_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps) +{ + rt_err_t result = RT_EOK; + struct sound_device *snd_dev; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + switch (caps->main_type) + { + case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */ + { + switch (caps->sub_type) + { + case AUDIO_TYPE_QUERY: + caps->udata.mask = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_MIXER; + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_OUTPUT: /* Provide capabilities of OUTPUT unit */ + { + switch (caps->sub_type) + { + case AUDIO_DSP_PARAM: + caps->udata.config.samplerate = snd_dev->replay_config.samplerate; + caps->udata.config.channels = snd_dev->replay_config.channels; + caps->udata.config.samplebits = snd_dev->replay_config.samplebits; + break; + + case AUDIO_DSP_SAMPLERATE: + caps->udata.config.samplerate = snd_dev->replay_config.samplerate; + break; + + case AUDIO_DSP_CHANNELS: + caps->udata.config.channels = snd_dev->replay_config.channels; + break; + + case AUDIO_DSP_SAMPLEBITS: + caps->udata.config.samplebits = snd_dev->replay_config.samplebits; + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_MIXER: /* report the Mixer Units */ + { + switch (caps->sub_type) + { + case AUDIO_MIXER_QUERY: + caps->udata.mask = AUDIO_MIXER_VOLUME; + break; + + case AUDIO_MIXER_VOLUME: + caps->udata.value = snd_dev->volume; + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + default: + result = -RT_ERROR; + break; + } + + return result; +} + +static rt_err_t sound_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps) +{ + rt_err_t result = RT_EOK; + struct sound_device *snd_dev; + struct rt_audio_replay *replay; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + switch (caps->main_type) + { + case AUDIO_TYPE_MIXER: + { + switch (caps->sub_type) + { + case AUDIO_MIXER_VOLUME: + { + rt_uint8_t volume = caps->udata.value; + + snd_dev->volume = volume; + ac97_set_vol(volume); + LOG_I("set volume %d", volume); + break; + } + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_OUTPUT: + { + switch (caps->sub_type) + { + case AUDIO_DSP_PARAM: + { + /* set samplerate */ + ac97_set_rate(caps->udata.config.samplerate); + + /* update buffer fifo informaition according samplerate */ + replay = snd_dev->audio.replay; + replay->buf_info.total_size = caps->udata.config.samplerate / 50 * 4; + replay->buf_info.block_size = replay->buf_info.total_size / 2; + + /* save configs */ + snd_dev->replay_config.samplerate = caps->udata.config.samplerate; + snd_dev->replay_config.channels = caps->udata.config.channels; + snd_dev->replay_config.samplebits = caps->udata.config.samplebits; + LOG_D("set samplerate %d", snd_dev->replay_config.samplerate); + break; + } + + case AUDIO_DSP_SAMPLERATE: + { + ac97_set_rate(caps->udata.config.samplerate); + + snd_dev->replay_config.samplerate = caps->udata.config.samplerate; + LOG_D("set samplerate %d", snd_dev->replay_config.samplerate); + break; + } + + case AUDIO_DSP_CHANNELS: + { + /* not support */ + snd_dev->replay_config.channels = caps->udata.config.channels; + LOG_D("set channels %d", snd_dev->replay_config.channels); + break; + } + + case AUDIO_DSP_SAMPLEBITS: + { + /* not support */ + snd_dev->replay_config.samplebits = caps->udata.config.samplebits; + break; + } + + default: + result = -RT_ERROR; + break; + } + + break; + } + + default: + break; + } + + return result; +} + +static rt_err_t sound_init(struct rt_audio_device *audio) +{ + rt_err_t result = RT_EOK; + struct sound_device *snd_dev; + struct pl041_cfg _cfg; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + aaci_pl041_init(); + + _cfg.itype = PL041_CHANNEL_LEFT_ADC | PL041_CHANNEL_RIGHT_ADC; + _cfg.otype = PL041_CHANNEL_LEFT_DAC | PL041_CHANNEL_RIGHT_DAC; + _cfg.vol = snd_dev->volume; + _cfg.rate = snd_dev->replay_config.samplerate; + + ac97_reset(); + aaci_pl041_channel_cfg(0, &_cfg); + aaci_pl041_irq_register(0, rt_hw_aaci_isr, RT_NULL); + + return result; +} + +static rt_err_t sound_start(struct rt_audio_device *audio, int stream) +{ + RT_ASSERT(audio != RT_NULL); + + if (stream == AUDIO_STREAM_REPLAY) + { + LOG_D("open sound device"); + aaci_pl041_channel_enable(0); + aaci_pl041_irq_enable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); + } + + return RT_EOK; +} + +static rt_err_t sound_stop(struct rt_audio_device *audio, int stream) +{ + RT_ASSERT(audio != RT_NULL); + + if (stream == AUDIO_STREAM_REPLAY) + { + /* wait codec free */ + rt_thread_mdelay(100); + /* disable irq and channels 0 */ + aaci_pl041_irq_disable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); + aaci_pl041_channel_disable(0); + LOG_D("close sound device"); + } + + return RT_EOK; +} + +static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info) +{ + struct sound_device *snd_dev; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + /** + * TX_FIFO + * +----------------+----------------+ + * | block1 | block2 | + * +----------------+----------------+ + * \ block_size / + */ + info->buffer = snd_dev->tx_fifo; + info->total_size = TX_FIFO_SIZE; + info->block_size = TX_FIFO_SIZE/2; + info->block_count = 2; +} + +static rt_size_t sound_transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size) +{ + RT_ASSERT(audio != RT_NULL); + + /* write data to channel_0 fifo */ + aaci_pl041_channel_write(0, (rt_uint16_t *)writeBuf, size >> 1); + + return size; +} + +static struct rt_audio_ops snd_ops = +{ + .getcaps = sound_getcaps, + .configure = sound_configure, + .init = sound_init, + .start = sound_start, + .stop = sound_stop, + .transmit = sound_transmit, + .buffer_info = sound_buffer_info, +}; + +int rt_hw_audio_init(void) +{ + rt_uint8_t *tx_fifo; + + if (snd_dev.tx_fifo) + return RT_EOK; + + tx_fifo = rt_malloc(TX_FIFO_SIZE); + if (tx_fifo == RT_NULL) + return -RT_ENOMEM; + rt_memset(tx_fifo, 0, TX_FIFO_SIZE); + snd_dev.tx_fifo = tx_fifo; + + /* init default configuration */ + { + snd_dev.replay_config.samplerate = 44100; + snd_dev.replay_config.channels = 2; + snd_dev.replay_config.samplebits = 16; + snd_dev.volume = 55; + } + + /* register sound device */ + snd_dev.audio.ops = &snd_ops; + rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev); + + return RT_EOK; +} + +INIT_DEVICE_EXPORT(rt_hw_audio_init); diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h b/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h new file mode 100644 index 0000000000..7cb47532be --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-23 Zero-Free first implementation + */ + +#ifndef __DRV_SOUND_H__ +#define __DRV_SOUND_H__ + +int rt_hw_audio_init(void); + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/board.c b/bsp/qemu-vexpress-a53/drivers/board.c new file mode 100644 index 0000000000..fbe741a546 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/board.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-11-20 Bernard the first version + * 2018-11-22 Jesven add rt_hw_spin_lock + * add rt_hw_spin_unlock + * add smp ipi init + */ + +#include +#include + +#include "board.h" +#include "drv_timer.h" + +#include +#ifdef RT_USING_USERSPACE +#include +#include +#endif + +#ifdef RT_USING_USERSPACE +struct mem_desc platform_mem_desc[] = { + {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM} +}; +#else +struct mem_desc platform_mem_desc[] = { + {0x10000000, 0x50000000, 0x10000000, DEVICE_MEM}, + {0x60000000, 0x70000000, 0x60000000, NORMAL_MEM} +}; +#endif + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]); + +#define SYS_CTRL __REG32(REALVIEW_SCTL_BASE) + +extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); + +void idle_wfi(void) +{ + asm volatile ("wfi"); +} + +/** + * This function will initialize board + */ + +rt_mmu_info mmu_info; + +extern size_t MMUTable[]; + +#ifdef RT_USING_USERSPACE +rt_region_t init_page_region = { + PAGE_START, + PAGE_END, +}; +#endif + +void rt_hw_board_init(void) +{ +#ifdef RT_USING_USERSPACE + rt_page_init(init_page_region); + + rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size); + + rt_hw_mmu_map_init(&mmu_info, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET); + + arch_kuser_init(&mmu_info, (void*)0xffffffffffff0000); +#else + rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0); + rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000); +#endif + + /* initialize hardware interrupt */ + rt_hw_interrupt_init(); + + /* initialize system heap */ + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); + + rt_components_board_init(); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); + + rt_thread_idle_sethook(idle_wfi); + +#ifdef RT_USING_SMP + /* install IPI handle */ + rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler); +#endif +} diff --git a/bsp/qemu-vexpress-a53/drivers/board.h b/bsp/qemu-vexpress-a53/drivers/board.h new file mode 100644 index 0000000000..003845f39d --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/board.h @@ -0,0 +1,45 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard the first version + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include +#include +#include "vexpress_a9.h" + +#include "mmu.h" +#include "ioremap.h" + +#if defined(__CC_ARM) +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN ((void*)&Image$$RW_IRAM1$$ZI$$Limit) +#elif defined(__GNUC__) +extern int __bss_end; +#define HEAP_BEGIN ((void*)&__bss_end) +#endif + +#ifdef RT_USING_USERSPACE +#define HEAP_END ((size_t)KERNEL_VADDR_START + 16 * 1024 * 1024) +#define PAGE_START HEAP_END +#define PAGE_END ((size_t)KERNEL_VADDR_START + 128 * 1024 * 1024) +#else +#define HEAP_END ((size_t)0x60000000 + 64 * 1024 * 1024) +#endif + +void rt_hw_board_init(void); + +extern rt_mmu_info mmu_info; + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_clcd.c b/bsp/qemu-vexpress-a53/drivers/drv_clcd.c new file mode 100644 index 0000000000..e194be9da4 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_clcd.c @@ -0,0 +1,180 @@ +#include +#include +#include + +#include +#include + +#include +#include + +#include "drv_clcd.h" +#include "rt_lcd.h" + +#define CLCD_WIDTH (BSP_LCD_WIDTH) +#define CLCD_HEIGHT (BSP_LCD_HEIGHT) + +#define CLCD_DEVICE(dev) (struct drv_clcd_device*)(dev) + +#define PL111_CR_EN 0x001 +#define PL111_CR_PWR 0x800 +#define PL111_IOBASE 0x10020000 +#define PL111_PALBASE (PL111_IOBASE + 0x200) + +typedef struct _PL111MMIO +{ + uint32_t volatile tim0; //0 + uint32_t volatile tim1; //4 + uint32_t volatile tim2; //8 + uint32_t volatile tim3; //c + uint32_t volatile upbase; //10 + uint32_t volatile f; //14 + uint32_t volatile control; //18 + uint32_t volatile g; //1c +} PL111MMIO; + +struct drv_clcd_device +{ + struct rt_device parent; + + int width; + int height; + + uint8_t *fb; + uint8_t *fb_virt; +}; +struct drv_clcd_device _lcd; + +static rt_err_t drv_clcd_init(struct rt_device *device) +{ + struct drv_clcd_device *lcd = CLCD_DEVICE(device); + + (void)lcd; /* nothing, right now */ + return RT_EOK; +} + +static rt_err_t drv_clcd_control(struct rt_device *device, int cmd, void *args) +{ + struct drv_clcd_device *lcd = CLCD_DEVICE(device); + + switch (cmd) + { + case RTGRAPHIC_CTRL_RECT_UPDATE: + { + struct rt_device_rect_info *info = (struct rt_device_rect_info*)args; + + (void)info; /* nothing, right now */ + rt_kprintf("update screen...\n"); + } + break; + + case RTGRAPHIC_CTRL_GET_INFO: + { + struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args; + + RT_ASSERT(info != RT_NULL); + info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; + info->bits_per_pixel= 16; + info->width = lcd->width; + info->height = lcd->height; + info->framebuffer = lcd->fb; + } + break; + + case FBIOGET_FSCREENINFO: + { +#ifdef RT_USING_USERSPACE + struct fb_fix_screeninfo *info = (struct fb_fix_screeninfo *)args; + strncpy(info->id, "lcd", sizeof(info->id)); + info->smem_len = lcd->width * lcd->height * 2; + info->smem_start = (size_t)lwp_map_user_phy(lwp_self(), RT_NULL, lcd->fb, + info->smem_len, 1); + info->line_length = lcd->width * 2; +#endif + } + break; + + case FBIOGET_VSCREENINFO: + { + struct fb_var_screeninfo *info = (struct fb_var_screeninfo *)args; + info->bits_per_pixel = 16; + info->xres = lcd->width; + info->yres = lcd->height; + } + break; + + case FBIOGET_DISPINFO: + break; + } + + return RT_EOK; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops clcd_ops = +{ + drv_clcd_init, + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + drv_clcd_control +}; +#endif + +int drv_clcd_hw_init(void) +{ + PL111MMIO *plio; + struct rt_device *device = &_lcd.parent; + + /* memset _lcd to zero */ + memset(&_lcd, 0x0, sizeof(_lcd)); + + _lcd.width = CLCD_WIDTH; + _lcd.height = CLCD_HEIGHT; + rt_kprintf("try to allocate fb... | w - %d, h - %d | ", _lcd.width, _lcd.height); +#ifdef RT_USING_USERSPACE + _lcd.fb_virt= rt_pages_alloc (rt_page_bits(_lcd.width * _lcd.height * 2)); + _lcd.fb = _lcd.fb_virt + PV_OFFSET; + rt_kprintf("done!\n"); + rt_kprintf("fb => 0x%08x\n", _lcd.fb); + if (_lcd.fb == NULL) + { + rt_kprintf("initialize frame buffer failed!\n"); + return -1; + } + + memset(_lcd.fb_virt, 0xff, _lcd.width * _lcd.height * 2); +#else + _lcd.fb = rt_malloc(_lcd.width * _lcd.height * 2); + if (_lcd.fb == NULL) + { + rt_kprintf("initialize frame buffer failed!\n"); + return -1; + } + + memset(_lcd.fb, 0xff, _lcd.width * _lcd.height * 2); +#endif + + plio = (PL111MMIO *)rt_ioremap((void*)PL111_IOBASE, 0x1000); + + plio->tim0 = 0x3F1F3C00 | ((CLCD_WIDTH / 16 - 1) << 2); + plio->tim1 = 0x080B6000 | (CLCD_HEIGHT - 1); + + plio->upbase = (uint32_t)(size_t)_lcd.fb; + /* 16-bit 565 color */ + plio->control = 0x1921 | (0x6 << 1); + + device->type = RT_Device_Class_Graphic; +#ifdef RT_USING_DEVICE_OPS + device->ops = &clcd_ops; +#else + device->init = drv_clcd_init; + device->control = drv_clcd_control; +#endif + + rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR); + + return 0; +} +INIT_DEVICE_EXPORT(drv_clcd_hw_init); diff --git a/bsp/qemu-vexpress-a53/drivers/drv_clcd.h b/bsp/qemu-vexpress-a53/drivers/drv_clcd.h new file mode 100644 index 0000000000..4ed3136981 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_clcd.h @@ -0,0 +1,16 @@ +#ifndef DRV_CLCD_H__ +#define DRV_CLCD_H__ + +#include + +#ifndef BSP_LCD_WIDTH +#define BSP_LCD_WIDTH 640 +#endif + +#ifndef BSP_LCD_HEIGHT +#define BSP_LCD_HEIGHT 480 +#endif + +int drv_clcd_hw_init(void); + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_keyboard.c b/bsp/qemu-vexpress-a53/drivers/drv_keyboard.c new file mode 100644 index 0000000000..3f961b40ae --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_keyboard.c @@ -0,0 +1,474 @@ +#include +#include +#include + +#include "board.h" +#include "interrupt.h" +#include "drv_keyboard.h" + +#define DBG_LVL DBG_INFO +#include "rtdbg.h" + +#define KEYBOARD_ADDRESS (0x10006000) +#define KEYBOARD_IRQ_NUM (IRQ_VEXPRESS_A9_KBD) + +#ifdef PKG_USING_GUIENGINE + +#include +#include + +typedef rt_uint32_t virtual_addr_t; + +enum{ + KEYBOARD_CR = 0x00, + KEYBOARD_STAT = 0x04, + KEYBOARD_DATA = 0x08, + KEYBOARD_CLKDIV = 0x0c, + KEYBOARD_IIR = 0x10, +}; + +struct keyboard_pl050_pdata_t +{ + virtual_addr_t virt; + int irq; +}; + +enum decode_state { + DECODE_STATE_MAKE_CODE, + DECODE_STATE_BREAK_CODE, + DECODE_STATE_LONG_MAKE_CODE, + DECODE_STATE_LONG_BREAK_CODE +}; + +struct keymap { + rt_uint8_t data; + rt_uint32_t key; + rt_uint32_t unicode; + char *normal_key; +}; + +enum key_value_t { + KEY_BUTTON_UP, + KEY_BUTTON_DOWN, +}; + +enum { + KBD_LEFT_SHIFT = (0x1 << 0), + KBD_RIGHT_SHIFT = (0x1 << 1), + KBD_LEFT_CTRL = (0x1 << 2), + KBD_RIGHT_CTRL = (0x1 << 3), + KBD_CAPS_LOCK = (0x1 << 6), + KBD_NUM_LOCK = (0x1 << 7), + KBD_SCROLL_LOCK = (0x1 << 8), +}; + +static const struct keymap map[] = { + {0x1c, RTGUIK_a, 0, "a", }, + {0x32, RTGUIK_b, 0, "b", }, + {0x21, RTGUIK_c, 0, "c", }, + {0x23, RTGUIK_d, 0, "d", }, + {0x24, RTGUIK_e, 0, "e", }, + {0x2b, RTGUIK_f, 0, "f", }, + {0x34, RTGUIK_g, 0, "g", }, + {0x33, RTGUIK_h, 0, "h", }, + {0x43, RTGUIK_i, 0, "i", }, + {0x3b, RTGUIK_j, 0, "j", }, + {0x42, RTGUIK_k, 0, "k", }, + {0x4b, RTGUIK_l, 0, "l", }, + {0x3a, RTGUIK_m, 0, "m", }, + {0x31, RTGUIK_n, 0, "n", }, + {0x44, RTGUIK_o, 0, "o", }, + {0x4d, RTGUIK_p, 0, "p", }, + {0x15, RTGUIK_q, 0, "q", }, + {0x2d, RTGUIK_r, 0, "r", }, + {0x1b, RTGUIK_s, 0, "s", }, + {0x2c, RTGUIK_k, 0, "k", }, + {0x3c, RTGUIK_u, 0, "u", }, + {0x2a, RTGUIK_v, 0, "v", }, + {0x1d, RTGUIK_w, 0, "w", }, + {0x22, RTGUIK_x, 0, "x", }, + {0x35, RTGUIK_y, 0, "y", }, + {0x1a, RTGUIK_z, 0, "z", }, + + {0x45, RTGUIK_0, 0, "0", }, + {0x16, RTGUIK_1, 0, "1", }, + {0x1e, RTGUIK_2, 0, "2", }, + {0x26, RTGUIK_3, 0, "3", }, + {0x25, RTGUIK_4, 0, "4", }, + {0x2e, RTGUIK_5, 0, "5", }, + {0x36, RTGUIK_6, 0, "6", }, + {0x3d, RTGUIK_7, 0, "7", }, + {0x3e, RTGUIK_8, 0, "8", }, + {0x46, RTGUIK_9, 0, "9", }, + + {0x05, RTGUIK_F1, 0, "F1", }, + {0x06, RTGUIK_F2, 0, "F2", }, + {0x04, RTGUIK_F3, 0, "F3", }, + {0x0c, RTGUIK_F4, 0, "F4", }, + {0x03, RTGUIK_F5, 0, "F5", }, + {0x0b, RTGUIK_F6, 0, "F6", }, + {0x83, RTGUIK_F7, 0, "F7", }, + {0x0a, RTGUIK_F8, 0, "F8", }, + {0x01, RTGUIK_F9, 0, "F9", }, + {0x09, RTGUIK_F10, 0, "F10", }, + {0x78, RTGUIK_F11, 0, "F11", }, + {0x07, RTGUIK_F12, 0, "F12", }, + + {0x29, RTGUIK_SPACE, 0, "SPACE" }, + {0x71, RTGUIK_DELETE, 0, "DELETE" }, + {0x52, RTGUIK_QUOTE, 0, "'" }, + {0x55, RTGUIK_EQUALS, 0, "=" }, + {0x41, RTGUIK_COMMA, 0, "," }, + {0x4e, RTGUIK_MINUS, 0, "-" }, + // {0x49, RTGUIK_, 0, "." }, + {0x4a, RTGUIK_SLASH, 0, "/" }, + {0x4c, RTGUIK_SEMICOLON, 0, ";" }, + {0x54, RTGUIK_LEFTBRACKET, 0, "[" }, + {0x5d, RTGUIK_BACKSLASH, 0, "\\" }, + {0x5b, RTGUIK_RIGHTBRACKET, 0, "]"}, + {0x75, RTGUIK_UP, 0, "UP" }, + {0x72, RTGUIK_DOWN, 0, "DOWN" }, + {0x6b, RTGUIK_LEFT, 0, "LEFT" }, + {0x74, RTGUIK_RIGHT, 0, "RIGHT" }, + {0x0d, RTGUIK_TAB, 0, "TAB" }, + {0x76, RTGUIK_ESCAPE, 0, "ESC" }, + {0x37, RTGUIK_POWER, 0, "POWER" }, + {0x5a, RTGUIK_KP_ENTER, 0, "ENTER"}, + {0x66, RTGUIK_BACKSPACE, 0, "BACKSPACE"}, +}; + +rt_inline rt_uint8_t read8(uint32_t addr) +{ + return (*((volatile rt_uint8_t *)(addr))); +} + +rt_inline void write8(uint32_t addr, rt_uint8_t value) +{ + *((volatile rt_uint8_t *)(addr)) = value; +} + +rt_inline rt_uint32_t read32(uint32_t addr) +{ + return (*((volatile rt_uint32_t *)(addr))); +} + +rt_inline void write32(uint32_t addr, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr)) = value; +} + +rt_inline int kmi_write(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t value) +{ + int timeout = 1000; + + while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 6)) == 0 && timeout--); + + if(timeout) + { + write8(pdat->virt + KEYBOARD_DATA, value); + while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4)) == 0); + + if(read8(pdat->virt + KEYBOARD_DATA) == 0xfa) + return RT_TRUE; + } + return RT_FALSE; +} + +rt_inline int kmi_read(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t * value) +{ + if((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4))) + { + *value = read8(pdat->virt + KEYBOARD_DATA); + return RT_TRUE; + } + return RT_FALSE; +} + +static void keyboard_report_event(void * device, rt_uint32_t flag, rt_uint8_t data, enum key_value_t press) +{ + struct rtgui_event_kbd key_event; + rt_uint16_t i = 0, mod = 0, find_key = 0; + + for(i = 0; i < sizeof(map)/sizeof(map[0]); i++) + { + if (map[i].data == data) + { + LOG_D("KEY info:"); + if (flag & KBD_CAPS_LOCK) + { + LOG_D("CAPS:LOCK"); + } + else + { + LOG_D("CAPS:UNLOCK"); + } + + if (flag & KBD_LEFT_SHIFT) + { + mod |= RTGUI_KMOD_LSHIFT; + LOG_D("SHIFT:LEFT"); + } + else if (flag & KBD_RIGHT_SHIFT) + { + mod |= RTGUI_KMOD_RSHIFT; + LOG_D("SHIFT:RIGHT"); + } + else + { + LOG_D("SHIFT:NULL"); + } + + if (flag & KBD_LEFT_CTRL) + { + mod |= RTGUI_KMOD_LCTRL; + LOG_D("CTRL:LEFT"); + } + else if (flag & KBD_RIGHT_CTRL) + { + mod |= RTGUI_KMOD_RCTRL; + LOG_D("CTRL:RIGHT"); + } + else + { + LOG_D("CTRL:NULL"); + } + + LOG_D("flag:0x%08x value:0x%x key:%s status:%s", \ + flag, data, map[i].normal_key, press ==0 ? "UP" : "DOWN"); + find_key = 1; + break; + } + } + if (find_key == 0) + { + LOG_D("flag:0x%08x value:0x%x key:%s status:%s", \ + flag, data, "UNKNOWN", press ==0 ? "UP" : "DOWN"); + return; + } + + key_event.parent.sender = RT_NULL; + key_event.parent.type = RTGUI_EVENT_KBD; + key_event.type = (press == 0 ? RTGUI_KEYUP : RTGUI_KEYDOWN); + key_event.key = map[i].key; + key_event.mod = mod; + key_event.unicode = map[i].unicode; + rtgui_server_post_event(&key_event.parent, sizeof(key_event)); +} + +static void keyboard_pl050_interrupt(int irq, void *data) +{ + struct keyboard_pl050_pdata_t * pdat = (struct keyboard_pl050_pdata_t *)data; + static enum decode_state ds = DECODE_STATE_MAKE_CODE; + static rt_uint32_t kbd_flag = KBD_NUM_LOCK; + rt_uint8_t status, value; + + status = read8(pdat->virt + KEYBOARD_IIR); + + while(status & (1 << 0)) + { + value = read8(pdat->virt + KEYBOARD_DATA); + + switch(ds) + { + case DECODE_STATE_MAKE_CODE: + /* break code */ + if(value == 0xf0) + { + ds = DECODE_STATE_BREAK_CODE; + } + /* long make code */ + else if(value == 0xe0) + { + ds = DECODE_STATE_LONG_MAKE_CODE; + } + else + { + ds = DECODE_STATE_MAKE_CODE; + + /* left shift */ + if(value == 0x12) + { + kbd_flag |= KBD_LEFT_SHIFT; + } + /* right shift */ + else if(value == 0x59) + { + kbd_flag |= KBD_RIGHT_SHIFT; + } + /* left ctrl */ + else if(value == 0x14) + { + kbd_flag |= KBD_LEFT_CTRL; + } + /* caps lock */ + else if(value == 0x58) + { + if(kbd_flag & KBD_CAPS_LOCK) + kbd_flag &= ~KBD_CAPS_LOCK; + else + kbd_flag |= KBD_CAPS_LOCK; + } + /* scroll lock */ + else if(value == 0x7e) + { + if(kbd_flag & KBD_SCROLL_LOCK) + kbd_flag &= ~KBD_SCROLL_LOCK; + else + kbd_flag |= KBD_SCROLL_LOCK; + } + /* num lock */ + else if(value == 0x77) + { + if(kbd_flag & KBD_NUM_LOCK) + kbd_flag &= ~KBD_NUM_LOCK; + else + kbd_flag |= KBD_NUM_LOCK; + } + /* others */ + else + { + keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN); + } + } + break; + + case DECODE_STATE_BREAK_CODE: + if( (value != 0xf0) && (value != 0xe0)) + { + ds = DECODE_STATE_MAKE_CODE; + + /* left shift */ + if(value == 0x12) + { + kbd_flag &= ~KBD_LEFT_SHIFT; + } + /* right shift */ + else if(value == 0x59) + { + kbd_flag &= ~KBD_RIGHT_SHIFT; + } + /* left ctrl */ + else if(value == 0x14) + { + kbd_flag &= ~KBD_LEFT_CTRL; + } + /* others */ + else + { + keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP); + } + } + else + { + ds = DECODE_STATE_BREAK_CODE; + } + break; + + case DECODE_STATE_LONG_MAKE_CODE: + if( value != 0xf0 && value!= 0xe0) + { + ds = DECODE_STATE_MAKE_CODE; + + /* left ctrl */ + if(value == 0x14) + { + kbd_flag |= KBD_RIGHT_CTRL; + } + /* others */ + else + { + keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN); + } + } + else + { + ds = DECODE_STATE_LONG_BREAK_CODE; + } + break; + + case DECODE_STATE_LONG_BREAK_CODE: + if( (value != 0xf0) && (value != 0xe0)) + { + ds = DECODE_STATE_MAKE_CODE; + + /* left ctrl */ + if(value == 0x14) + { + kbd_flag &= ~KBD_RIGHT_CTRL; + } + /* others */ + else + { + keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP); + } + } + else + { + ds = DECODE_STATE_LONG_BREAK_CODE; + } + break; + + default: + ds = DECODE_STATE_MAKE_CODE; + break; + } + + status = read8(pdat->virt + KEYBOARD_IIR); + } +} + +int rt_hw_keyboard_init(void) +{ + rt_uint8_t value; + rt_uint32_t id; + struct keyboard_pl050_pdata_t *pdat; + virtual_addr_t virt; + int irq = KEYBOARD_IRQ_NUM; + + virt = (virtual_addr_t)rt_ioremap((void*)KEYBOARD_ADDRESS, 0x1000); + + id = (((read32(virt + 0xfec) & 0xff) << 24) | + ((read32(virt + 0xfe8) & 0xff) << 16) | + ((read32(virt + 0xfe4) & 0xff) << 8) | + ((read32(virt + 0xfe0) & 0xff) << 0)); + + if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050) + { + LOG_E("read id fail id:0x%08x", id); + return RT_ERROR; + } + + pdat = rt_malloc(sizeof(struct keyboard_pl050_pdata_t)); + if(!pdat) + { + LOG_E("malloc memory failed"); + return RT_ERROR; + } + rt_memset(pdat, 0, sizeof(struct keyboard_pl050_pdata_t)); + + pdat->virt = virt; + pdat->irq = irq; + + write8(pdat->virt + KEYBOARD_CLKDIV, 0); + write8(pdat->virt + KEYBOARD_CR, (1 << 2)); + kmi_read(pdat, &value); + kmi_write(pdat, 0xff); + kmi_read(pdat, &value); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 0x2b); + kmi_write(pdat, 0xf0); + kmi_write(pdat, 0x02); + kmi_write(pdat, 0xfa); + kmi_write(pdat, 0xed); + kmi_write(pdat, 0x02); + write8(pdat->virt + KEYBOARD_CR, (1 << 2) | (1 << 4)); + + rt_hw_interrupt_install(irq, keyboard_pl050_interrupt, (void *)pdat, "keyboard"); + rt_hw_interrupt_umask(irq); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_keyboard_init); + +#endif + diff --git a/bsp/qemu-vexpress-a53/drivers/drv_keyboard.h b/bsp/qemu-vexpress-a53/drivers/drv_keyboard.h new file mode 100644 index 0000000000..6d5acb7427 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_keyboard.h @@ -0,0 +1,6 @@ +#ifndef __DEV_KEYBOARD_H__ +#define __DEV_KEYBOARD_H__ + +int rt_hw_keyboard_init(void); + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_mouse.c b/bsp/qemu-vexpress-a53/drivers/drv_mouse.c new file mode 100644 index 0000000000..d3244bcd29 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_mouse.c @@ -0,0 +1,300 @@ +#include +#include +#include + +#include "board.h" +#include "interrupt.h" +#include "drv_mouse.h" +#include "drv_clcd.h" + +#define DBG_TAG "drv.mouse" +#define DBG_LVL DBG_INFO +#include "rtdbg.h" + +#define MOUSE_ADDRESS (0x10007000) +#define MOUSE_IRQ_NUM (IRQ_VEXPRESS_A9_MOUSE) +#define MOUSE_XMAX (BSP_LCD_WIDTH) +#define MOUSE_YMAX (BSP_LCD_HEIGHT) + +#define MOUSE_BUTTON_LEFT (0x01) +#define MOUSE_BUTTON_RIGHT (0x02) +#define MOUSE_BUTTON_MIDDLE (0x04) +#define MOUSE_BUTTON_DOWN (0x10) +#define MOUSE_BUTTON_UP (0x20) +#define MOUSE_BUTTON_MOVE (0x40) +#define MOUSE_BUTTON_WHELL (0x80) + +#ifdef PKG_USING_GUIENGINE + +#include +#include + +typedef rt_uint32_t virtual_addr_t; + +enum { + MOUSE_CR = 0x00, + MOUSE_STAT = 0x04, + MOUSE_DATA = 0x08, + MOUSE_CLKDIV = 0x0c, + MOUSE_IIR = 0x10, +}; + +struct mouse_pl050_pdata_t { + virtual_addr_t virt; + int irq; + int xmax, ymax; + int xpos, ypos; + unsigned char packet[4]; + int index; + int obtn; + int type; +}; + +rt_inline rt_uint8_t read8(uint32_t addr) +{ + return (*((volatile rt_uint8_t *)(addr))); +} + +rt_inline void write8(uint32_t addr, rt_uint8_t value) +{ + *((volatile rt_uint8_t *)(addr)) = value; +} + +rt_inline rt_uint32_t read32(uint32_t addr) +{ + return (*((volatile rt_uint32_t *)(addr))); +} + +rt_inline void write32(uint32_t addr, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr)) = value; +} + +rt_inline int kmi_write(struct mouse_pl050_pdata_t * pdat, rt_uint8_t value) +{ + int timeout = 1000; + + while((read8(pdat->virt + MOUSE_STAT) & (1 << 6)) == 0 && timeout--); + + if(timeout) + { + write8(pdat->virt + MOUSE_DATA, value); + while((read8(pdat->virt + MOUSE_STAT) & (1 << 4)) == 0); + + if(read8(pdat->virt + MOUSE_DATA) == 0xfa) + return RT_TRUE; + } + return RT_FALSE; +} + +rt_inline int kmi_read(struct mouse_pl050_pdata_t * pdat, rt_uint8_t * value) +{ + if((read8(pdat->virt + MOUSE_STAT) & (1 << 4))) + { + *value = read8(pdat->virt + MOUSE_DATA); + return RT_TRUE; + } + return RT_FALSE; +} + +static rt_uint32_t emouse_id; + +void push_event_touch_move(int x, int y) +{ + struct rtgui_event_mouse emouse; + + emouse.parent.sender = RT_NULL; + emouse.wid = RT_NULL; + + emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN; + emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION; + emouse.x = x; + emouse.y = y; + emouse.ts = rt_tick_get(); + emouse.id = emouse_id; + + LOG_D("[line]:%d motion event id:%d x:%d y:%d", __LINE__, emouse.id, x, y); + rtgui_server_post_event(&emouse.parent, sizeof(emouse)); +} + +void push_event_touch_begin(int x, int y) +{ + struct rtgui_event_mouse emouse; + + emouse_id = rt_tick_get(); + + emouse.parent.sender = RT_NULL; + emouse.wid = RT_NULL; + + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN; + emouse.x = x; + emouse.y = y; + emouse.ts = rt_tick_get(); + emouse.id = emouse_id; + LOG_D("[line]:%d down event id:%d x:%d y:%d", __LINE__, emouse.id, x, y); + rtgui_server_post_event(&emouse.parent, sizeof(emouse)); +} + +void push_event_touch_end(int x, int y) +{ + struct rtgui_event_mouse emouse; + + emouse.parent.sender = RT_NULL; + emouse.wid = RT_NULL; + + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP; + emouse.x = x; + emouse.y = y; + emouse.ts = rt_tick_get(); + emouse.id = emouse_id; + + LOG_D("[line]:%d up event id:%d x:%d y:%d", __LINE__, emouse.id, x, y); + rtgui_server_post_event(&emouse.parent, sizeof(emouse)); +} + +static void mouse_pl050_interrupt(int irq, void * data) +{ + struct mouse_pl050_pdata_t * pdat = (struct mouse_pl050_pdata_t *)data; + int x, y, relx, rely, delta; + int btndown, btnup, btn; + int status = 0; + + status = read8(pdat->virt + MOUSE_IIR); + while(status & (1 << 0)) + { + pdat->packet[pdat->index] = read8(pdat->virt + MOUSE_DATA); + pdat->index = (pdat->index + 1) & 0x3; + + if(pdat->index == 0) + { + btn = pdat->packet[0] & 0x7; + btndown = (btn ^ pdat->obtn) & btn; + btnup = (btn ^ pdat->obtn) & pdat->obtn; + pdat->obtn = btn; + + if(pdat->packet[0] & 0x10) + relx = 0xffffff00 | pdat->packet[1]; + else + relx = pdat->packet[1]; + + if(pdat->packet[0] & 0x20) + rely = 0xffffff00 | pdat->packet[2]; + else + rely = pdat->packet[2]; + rely = -rely; + + delta = pdat->packet[3] & 0xf; + if(delta == 0xf) + delta = -1; + + if(relx != 0) + { + pdat->xpos = pdat->xpos + relx; + if(pdat->xpos < 0) + pdat->xpos = 0; + if(pdat->xpos > pdat->xmax - 1) + pdat->xpos = pdat->xmax - 1; + } + if(rely != 0) + { + pdat->ypos = pdat->ypos + rely; + if(pdat->ypos < 0) + pdat->ypos = 0; + if(pdat->ypos > pdat->ymax - 1) + pdat->ypos = pdat->ymax - 1; + } + x = pdat->xpos; + y = pdat->ypos; + + if((btn & (0x01 << 0)) && ((relx != 0) || (rely != 0))) + push_event_touch_move(x, y); + + if(btndown & (0x01 << 0)) + push_event_touch_begin(x, y); + + if(btnup & (0x01 << 0)) + push_event_touch_end(x, y); + } + + status = read8(pdat->virt + MOUSE_IIR); + } +} + +int rt_hw_mouse_init(void) +{ + rt_uint8_t value; + rt_uint32_t id; + struct mouse_pl050_pdata_t *pdat; + virtual_addr_t virt; + int irq = MOUSE_IRQ_NUM; + + virt = (virtual_addr_t)rt_ioremap((void*)MOUSE_ADDRESS, 0x1000); + + id = (((read32(virt + 0xfec) & 0xff) << 24) | + ((read32(virt + 0xfe8) & 0xff) << 16) | + ((read32(virt + 0xfe4) & 0xff) << 8) | + ((read32(virt + 0xfe0) & 0xff) << 0)); + + if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050) + { + LOG_E("read id fail id:0x%08x", id); + return RT_ERROR; + } + + pdat = rt_malloc(sizeof(struct mouse_pl050_pdata_t)); + if(!pdat) + { + LOG_E("malloc memory failed"); + return RT_ERROR; + } + rt_memset(pdat, 0, sizeof(struct mouse_pl050_pdata_t)); + + pdat->virt = virt; + pdat->irq = irq; + pdat->xmax = MOUSE_XMAX; + pdat->ymax = MOUSE_YMAX; + pdat->xpos = pdat->xmax / 2; + pdat->ypos = pdat->ymax / 2; + pdat->packet[0] = 0; + pdat->packet[1] = 0; + pdat->packet[2] = 0; + pdat->packet[3] = 0; + pdat->index = 0; + pdat->obtn = 0; + + write8(pdat->virt + MOUSE_CLKDIV, 0); + write8(pdat->virt + MOUSE_CR, (1 << 2)); + kmi_write(pdat, 0xff); + kmi_read(pdat, &value); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 200); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 100); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 80); + kmi_write(pdat, 0xf2); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 100); + kmi_write(pdat, 0xe8); + kmi_write(pdat, 0x02); + kmi_write(pdat, 0xe6); + kmi_write(pdat, 0xf4); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + write8(pdat->virt + MOUSE_CR, (1 << 2) | (1 << 4)); + + rt_hw_interrupt_install(pdat->irq, mouse_pl050_interrupt, (void *)pdat, "mouse"); + rt_hw_interrupt_umask(pdat->irq); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_mouse_init); + +#endif + diff --git a/bsp/qemu-vexpress-a53/drivers/drv_mouse.h b/bsp/qemu-vexpress-a53/drivers/drv_mouse.h new file mode 100644 index 0000000000..cfceabc00d --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_mouse.h @@ -0,0 +1,18 @@ +#ifndef __DRV_MOUSE_H__ +#define __DRV_MOUSE_H__ + +int rt_hw_mouse_init(void); + +struct mouse_info +{ + uint32_t type; + uint32_t button; + uint32_t x; + uint32_t y; + uint32_t ts; + uint32_t id; +}; + +#define CMD_MOUSE_SET_NOTIFY 0 /* arg is shmid, in the shm, a sem point is given */ + +#endif \ No newline at end of file diff --git a/bsp/qemu-vexpress-a53/drivers/drv_sdio.c b/bsp/qemu-vexpress-a53/drivers/drv_sdio.c new file mode 100644 index 0000000000..d44ee46f91 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_sdio.c @@ -0,0 +1,469 @@ +#include +#include +#include +#include + +#include +#include + +#include "board.h" +#include "drv_sdio.h" + +#ifdef RT_USING_SDIO + +#define MMC_BASE_ADDR (0x10005000) + +#define PL180_POWER (0x00) +#define PL180_CLOCK (0x04) +#define PL180_ARGUMENT (0x08) +#define PL180_COMMAND (0x0c) +#define PL180_RESPCMD (0x10) +#define PL180_RESP0 (0x14) +#define PL180_RESP1 (0x18) +#define PL180_RESP2 (0x1c) +#define PL180_RESP3 (0x20) +#define PL180_DATA_TIMER (0x24) +#define PL180_DATA_LENGTH (0x28) +#define PL180_DATA_CTRL (0x2c) +#define PL180_DATA_CNT (0x30) +#define PL180_STATUS (0x34) +#define PL180_CLEAR (0x38) +#define PL180_MASK0 (0x3c) +#define PL180_MASK1 (0x40) +#define PL180_SELECT (0x44) +#define PL180_FIFO_CNT (0x48) +#define PL180_FIFO (0x80) + +#define PL180_RSP_NONE (0 << 0) +#define PL180_RSP_PRESENT (1 << 0) +#define PL180_RSP_136BIT (1 << 1) +#define PL180_RSP_CRC (1 << 2) + +#define PL180_CMD_WAITRESP (1 << 6) +#define PL180_CMD_LONGRSP (1 << 7) +#define PL180_CMD_WAITINT (1 << 8) +#define PL180_CMD_WAITPEND (1 << 9) +#define PL180_CMD_ENABLE (1 << 10) + +#define PL180_STAT_CMD_CRC_FAIL (1 << 0) +#define PL180_STAT_DAT_CRC_FAIL (1 << 1) +#define PL180_STAT_CMD_TIME_OUT (1 << 2) +#define PL180_STAT_DAT_TIME_OUT (1 << 3) +#define PL180_STAT_TX_UNDERRUN (1 << 4) +#define PL180_STAT_RX_OVERRUN (1 << 5) +#define PL180_STAT_CMD_RESP_END (1 << 6) +#define PL180_STAT_CMD_SENT (1 << 7) +#define PL180_STAT_DAT_END (1 << 8) +#define PL180_STAT_DAT_BLK_END (1 << 10) +#define PL180_STAT_CMD_ACT (1 << 11) +#define PL180_STAT_TX_ACT (1 << 12) +#define PL180_STAT_RX_ACT (1 << 13) +#define PL180_STAT_TX_FIFO_HALF (1 << 14) +#define PL180_STAT_RX_FIFO_HALF (1 << 15) +#define PL180_STAT_TX_FIFO_FULL (1 << 16) +#define PL180_STAT_RX_FIFO_FULL (1 << 17) +#define PL180_STAT_TX_FIFO_ZERO (1 << 18) +#define PL180_STAT_RX_DAT_ZERO (1 << 19) +#define PL180_STAT_TX_DAT_AVL (1 << 20) +#define PL180_STAT_RX_FIFO_AVL (1 << 21) + +#define PL180_CLR_CMD_CRC_FAIL (1 << 0) +#define PL180_CLR_DAT_CRC_FAIL (1 << 1) +#define PL180_CLR_CMD_TIMEOUT (1 << 2) +#define PL180_CLR_DAT_TIMEOUT (1 << 3) +#define PL180_CLR_TX_UNDERRUN (1 << 4) +#define PL180_CLR_RX_OVERRUN (1 << 5) +#define PL180_CLR_CMD_RESP_END (1 << 6) +#define PL180_CLR_CMD_SENT (1 << 7) +#define PL180_CLR_DAT_END (1 << 8) +#define PL180_CLR_DAT_BLK_END (1 << 10) + +#define DBG_TAG "drv.sdio" +#define DBG_LVL DBG_INFO +#include "rtdbg.h" + +struct sdhci_pl180_pdata_t +{ + rt_size_t virt; +}; + +static inline rt_uint32_t read32(rt_size_t addr) +{ + return( *((volatile rt_uint32_t *)(addr)) ); +} + +static inline void write32(rt_size_t addr, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr)) = value; +} + +static rt_err_t pl180_transfer_command(struct sdhci_pl180_pdata_t * pdat, struct sdhci_cmd_t * cmd) +{ + rt_uint32_t cmdidx; + rt_uint32_t status; + rt_err_t ret = RT_EOK; + + if(read32(pdat->virt + PL180_COMMAND) & PL180_CMD_ENABLE) + write32(pdat->virt + PL180_COMMAND, 0x0); + + cmdidx = (cmd->cmdidx & 0xff) | PL180_CMD_ENABLE; + if(cmd->resptype) + { + cmdidx |= PL180_CMD_WAITRESP; + if(cmd->resptype & PL180_RSP_136BIT) + cmdidx |= PL180_CMD_LONGRSP; + } + + write32(pdat->virt + PL180_ARGUMENT, cmd->cmdarg); + write32(pdat->virt + PL180_COMMAND, cmdidx); + + do { + status = read32(pdat->virt + PL180_STATUS); + } while(!(status & (PL180_STAT_CMD_SENT | PL180_STAT_CMD_RESP_END | PL180_STAT_CMD_TIME_OUT | PL180_STAT_CMD_CRC_FAIL))); + LOG_D("mmc status done!"); + + if(cmd->resptype & PL180_RSP_PRESENT) + { + cmd->response[0] = read32(pdat->virt + PL180_RESP0); + if(cmd->resptype & PL180_RSP_136BIT) + { + LOG_D("136bit response"); + cmd->response[1] = read32(pdat->virt + PL180_RESP1); + cmd->response[2] = read32(pdat->virt + PL180_RESP2); + cmd->response[3] = read32(pdat->virt + PL180_RESP3); + } + } + + if(status & PL180_STAT_CMD_TIME_OUT) + { + ret = -RT_ETIMEOUT; + } + else if ((status & PL180_STAT_CMD_CRC_FAIL) && (cmd->resptype & PL180_RSP_CRC)) + { + ret = -RT_ERROR; + } + + write32(pdat->virt + PL180_CLEAR, (PL180_CLR_CMD_SENT | PL180_CLR_CMD_RESP_END | PL180_CLR_CMD_TIMEOUT | PL180_CLR_CMD_CRC_FAIL)); + return ret; +} + +static rt_err_t read_bytes(struct sdhci_pl180_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) +{ + rt_uint32_t * tmp = buf; + rt_uint32_t count = blkcount * blksize; + rt_uint32_t status, err; + + status = read32(pdat->virt + PL180_STATUS); + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN); + while((!err) && (count >= sizeof(rt_uint32_t))) + { + if(status & PL180_STAT_RX_FIFO_AVL) + { + *(tmp) = read32(pdat->virt + PL180_FIFO); + tmp++; + count -= sizeof(rt_uint32_t); + } + status = read32(pdat->virt + PL180_STATUS); + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN); + } + + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN); + while(!err) + { + status = read32(pdat->virt + PL180_STATUS); + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN); + } + + if(status & PL180_STAT_DAT_TIME_OUT) + return -RT_ERROR; + else if (status & PL180_STAT_DAT_CRC_FAIL) + return -RT_ERROR; + else if (status & PL180_STAT_RX_OVERRUN) + return -RT_ERROR; + write32(pdat->virt + PL180_CLEAR, 0x1DC007FF); + + if(count) + return -RT_ERROR; + + return RT_EOK; +} + +static rt_err_t write_bytes(struct sdhci_pl180_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) +{ + rt_uint32_t * tmp = buf; + rt_uint32_t count = blkcount * blksize; + rt_uint32_t status, err; + int i; + + status = read32(pdat->virt + PL180_STATUS); + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT); + while(!err && count) + { + if(status & PL180_STAT_TX_FIFO_HALF) + { + if(count >= 8 * sizeof(rt_uint32_t)) + { + for(i = 0; i < 8; i++) + write32(pdat->virt + PL180_FIFO, *(tmp + i)); + tmp += 8; + count -= 8 * sizeof(rt_uint32_t); + } + else + { + while(count >= sizeof(rt_uint32_t)) + { + write32(pdat->virt + PL180_FIFO, *tmp); + tmp++; + count -= sizeof(rt_uint32_t); + } + } + } + status = read32(pdat->virt + PL180_STATUS); + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT); + } + + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END); + while(!err) + { + status = read32(pdat->virt + PL180_STATUS); + err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END); + } + + if(status & PL180_STAT_DAT_TIME_OUT) + return -RT_ERROR; + else if (status & PL180_STAT_DAT_CRC_FAIL) + return -RT_ERROR; + write32(pdat->virt + PL180_CLEAR, 0x1DC007FF); + + if(count) + return -RT_ERROR; + return RT_EOK; +} + +static rt_err_t pl180_transfer_data(struct sdhci_pl180_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_uint32_t blksz_bits = dat->blksz - 1; + rt_uint32_t dctrl = (blksz_bits << 4) | (0x1 << 0) | (0x1 << 14); + rt_err_t ret = -RT_ERROR; + + write32(pdat->virt + PL180_DATA_TIMER, 0xffff); + write32(pdat->virt + PL180_DATA_LENGTH, dlen); + + if(dat->flag & DATA_DIR_READ) + { + dctrl |= (0x1 << 1); + write32(pdat->virt + PL180_DATA_CTRL, dctrl); + ret = pl180_transfer_command(pdat, cmd); + if (ret < 0) return ret; + ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); + } + else if(dat->flag & DATA_DIR_WRITE) + { + ret = pl180_transfer_command(pdat, cmd); + if (ret < 0) return ret; + write32(pdat->virt + PL180_DATA_CTRL, dctrl); + ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); + } + + return ret; +} + +static rt_err_t sdhci_pl180_detect(struct sdhci_t * sdhci) +{ + return RT_EOK; +} + +static rt_err_t sdhci_pl180_setwidth(struct sdhci_t * sdhci, rt_uint32_t width) +{ + return RT_EOK; +} + +static rt_err_t sdhci_pl180_setclock(struct sdhci_t * sdhci, rt_uint32_t clock) +{ + rt_uint32_t temp = 0; + struct sdhci_pl180_pdata_t * pdat = (struct sdhci_pl180_pdata_t *)sdhci->priv; + + if(clock) + { + temp = read32(pdat->virt + PL180_CLOCK) | (0x1 << 8); + (void)temp; // skip warning + write32(pdat->virt + PL180_CLOCK, 0x100); + } + else + { + //write32(pdat->virt + PL180_CLOCK, read32(pdat->virt + PL180_CLOCK) & (~(0x1 << 8))); + } + return RT_EOK; +} + +static rt_err_t sdhci_pl180_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat) +{ + struct sdhci_pl180_pdata_t * pdat = (struct sdhci_pl180_pdata_t *)sdhci->priv; + + if(!dat) + return pl180_transfer_command(pdat, cmd); + + return pl180_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; + if (req->cmd->flags & RESP_MASK) + { + cmd.resptype = PL180_RSP_PRESENT; + if (resp_type(req->cmd) == RESP_R2) + cmd.resptype |= PL180_RSP_136BIT; + } + else + cmd.resptype = 0; + + 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_pl180_transfer(sdhci, &cmd, &dat); + } + else + { + req->cmd->err = sdhci_pl180_transfer(sdhci, &cmd, RT_NULL); + } + + LOG_D("cmdarg:%d", cmd.cmdarg); + LOG_D("cmdidx:%d", cmd.cmdidx); + + LOG_D("[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x", cmd.response[0], cmd.response[1], cmd.response[2], cmd.response[3]); + 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; + if (req->stop->flags & RESP_MASK) + { + stop.resptype = PL180_RSP_PRESENT; + if (resp_type(req->stop) == RESP_R2) + stop.resptype |= PL180_RSP_136BIT; + } + else + stop.resptype = 0; + + req->stop->err = sdhci_pl180_transfer(sdhci, &stop, RT_NULL); + } + + mmcsd_req_complete(host); +} + +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_pl180_setclock(sdhci, io_cfg->clock); + sdhci_pl180_setwidth(sdhci, io_cfg->bus_width); + LOG_D("clock:%d bus_width:%d", io_cfg->clock, io_cfg->bus_width); +} + +static const struct rt_mmcsd_host_ops ops = +{ + mmc_request_send, + mmc_set_iocfg, + RT_NULL, + RT_NULL, +}; + +int pl180_init(void) +{ + rt_size_t virt; + rt_uint32_t id; + struct rt_mmcsd_host * host = RT_NULL; + struct sdhci_pl180_pdata_t * pdat = RT_NULL; + struct sdhci_t * sdhci = RT_NULL; + + host = mmcsd_alloc_host(); + if (!host) + { + LOG_E("alloc host failed"); + goto err; + } + + sdhci = rt_malloc(sizeof(struct sdhci_t)); + if (!sdhci) + { + LOG_E("alloc sdhci failed"); + goto err; + } + rt_memset(sdhci, 0, sizeof(struct sdhci_t)); + + virt = (rt_size_t)rt_ioremap((void*)MMC_BASE_ADDR, 0x1000); + + id = (((read32((virt + 0xfec)) & 0xff) << 24) | + ((read32((virt + 0xfe8)) & 0xff) << 16) | + ((read32((virt + 0xfe4)) & 0xff) << 8) | + ((read32((virt + 0xfe0)) & 0xff) << 0)); + + LOG_D("id=0x%08x", id); + if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x181) + { + LOG_E("check id failed"); + goto err; + } + + pdat = (struct sdhci_pl180_pdata_t *)rt_malloc(sizeof(struct sdhci_pl180_pdata_t)); + RT_ASSERT(pdat != RT_NULL); + + pdat->virt = (rt_size_t)virt; + + sdhci->name = "sd0"; + sdhci->voltages = VDD_33_34; + sdhci->width = MMCSD_BUSWIDTH_4; + sdhci->clock = 26 * 1000 * 1000; + sdhci->removeable = RT_TRUE; + sdhci->detect = sdhci_pl180_detect; + sdhci->setwidth = sdhci_pl180_setwidth; + sdhci->setclock = sdhci_pl180_setclock; + sdhci->transfer = sdhci_pl180_transfer; + sdhci->priv = pdat; + write32(pdat->virt + PL180_POWER, 0xbf); + + 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 = 4096; + + host->private_data = sdhci; + + mmcsd_change(host); + + return RT_EOK; + +err: + if(host) rt_free(host); + if(sdhci) rt_free(sdhci); + + return -RT_EIO; +} +INIT_DEVICE_EXPORT(pl180_init); + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_sdio.h b/bsp/qemu-vexpress-a53/drivers/drv_sdio.h new file mode 100644 index 0000000000..8b7adfec59 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_sdio.h @@ -0,0 +1,47 @@ +#ifndef __DRV_SDIO_H__ +#define __DRV_SDIO_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct sdhci_cmd_t +{ + rt_uint32_t cmdidx; + rt_uint32_t cmdarg; + rt_uint32_t resptype; + 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; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_smc911x.c b/bsp/qemu-vexpress-a53/drivers/drv_smc911x.c new file mode 100644 index 0000000000..b9807a5b6a --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_smc911x.c @@ -0,0 +1,561 @@ +#if 1 +#include +#include +#include +#include +#include +#include + +#include "mmu.h" +#include "drv_smc911x.h" + +#define MAX_ADDR_LEN 6 +#define SMC911X_EMAC_DEVICE(eth) (struct eth_device_smc911x*)(eth) + +#define DRIVERNAME "EMAC" + +#define DBG_LVL DBG_LOG +#define DBG_TAG "EMAC" +#include + +struct eth_device_smc911x +{ + /* inherit from Ethernet device */ + struct eth_device parent; + /* interface address info. */ + rt_uint8_t enetaddr[MAX_ADDR_LEN]; /* MAC address */ + + size_t iobase; + uint32_t irqno; +}; +static struct eth_device_smc911x _emac; + +int udelay(int value) +{ + return 0; +} + +int mdelay(int value) +{ + return 0; +} + +#if defined (CONFIG_SMC911X_32_BIT) +rt_inline uint32_t smc911x_reg_read(struct eth_device_smc911x *dev, uint32_t offset) +{ + return *(volatile uint32_t*)(dev->iobase + offset); +} + +rt_inline void smc911x_reg_write(struct eth_device_smc911x *dev, uint32_t offset, uint32_t val) +{ + *(volatile uint32_t*)(dev->iobase + offset) = val; +} + +#elif defined (CONFIG_SMC911X_16_BIT) +rt_inline uint32_t smc911x_reg_read(struct eth_device_smc911x *dev, uint32_t offset) +{ + volatile uint16_t *addr_16 = (uint16_t *)(dev->iobase + offset); + return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); +} + +rt_inline void smc911x_reg_write(struct eth_device_smc911x *dev, uint32_t offset, uint32_t val) +{ + *(volatile uint16_t *)(dev->iobase + offset) = (uint16_t)val; + *(volatile uint16_t *)(dev->iobase + offset + 2) = (uint16_t)(val >> 16); +} +#else +#error "SMC911X: undefined bus width" +#endif /* CONFIG_SMC911X_16_BIT */ + +struct chip_id +{ + uint16_t id; + char *name; +}; + +static const struct chip_id chip_ids[] = +{ + { CHIP_89218,"LAN89218" }, + { CHIP_9115, "LAN9115" }, + { CHIP_9116, "LAN9116" }, + { CHIP_9117, "LAN9117" }, + { CHIP_9118, "LAN9118" }, + { CHIP_9211, "LAN9211" }, + { CHIP_9215, "LAN9215" }, + { CHIP_9216, "LAN9216" }, + { CHIP_9217, "LAN9217" }, + { CHIP_9218, "LAN9218" }, + { CHIP_9220, "LAN9220" }, + { CHIP_9221, "LAN9221" }, + { 0, RT_NULL }, +}; + +static uint32_t smc911x_get_mac_csr(struct eth_device_smc911x *dev, uint8_t reg) +{ + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; + + smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); + + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; + + return smc911x_reg_read(dev, MAC_CSR_DATA); +} + +static void smc911x_set_mac_csr(struct eth_device_smc911x *dev, uint8_t reg, uint32_t data) +{ + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; + + smc911x_reg_write(dev, MAC_CSR_DATA, data); + smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); + + while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; +} + +static int smc911x_detect_chip(struct eth_device_smc911x *dev) +{ + unsigned long val, i; + + val = smc911x_reg_read(dev, BYTE_TEST); + if (val == 0xffffffff) + { + /* Special case -- no chip present */ + return -1; + } + else if (val != 0x87654321) + { + LOG_E("Invalid chip endian 0x%08lx\n", val); + return -1; + } + + val = smc911x_reg_read(dev, ID_REV) >> 16; + for (i = 0; chip_ids[i].id != 0; i++) + { + if (chip_ids[i].id == val) break; + } + + if (!chip_ids[i].id) + { + rt_kprintf(DRIVERNAME ": Unknown chip ID %04lx\n", val); + return -1; + } + + return 0; +} + +static void smc911x_reset(struct eth_device_smc911x *dev) +{ + int timeout; + + /* + * Take out of PM setting first + * Device is already wake up if PMT_CTRL_READY bit is set + */ + if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) + { + /* Write to the bytetest will take out of powerdown */ + smc911x_reg_write(dev, BYTE_TEST, 0x0); + + timeout = 10; + + while (timeout-- && !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY)) + udelay(10); + + if (timeout < 0) + { + rt_kprintf(DRIVERNAME + ": timeout waiting for PM restore\n"); + return; + } + } + + /* Disable interrupts */ + smc911x_reg_write(dev, INT_EN, 0); + smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST); + + timeout = 1000; + while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY) + udelay(10); + + if (timeout < 0) + { + rt_kprintf(DRIVERNAME ": reset timeout\n"); + return; + } + + /* Reset the FIFO level and flow control settings */ + smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN); + smc911x_reg_write(dev, AFC_CFG, 0x0050287F); + + /* Set to LED outputs */ + smc911x_reg_write(dev, GPIO_CFG, 0x70070000); +} + +static void smc911x_handle_mac_address(struct eth_device_smc911x *dev) +{ + unsigned long addrh, addrl; + uint8_t *m = dev->enetaddr; + + addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24); + addrh = m[4] | (m[5] << 8); + + smc911x_set_mac_csr(dev, ADDRL, addrl); + smc911x_set_mac_csr(dev, ADDRH, addrh); +} + +static int smc911x_eth_phy_read(struct eth_device_smc911x *dev, + uint8_t phy, uint8_t reg, uint16_t *val) +{ + while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) ; + + smc911x_set_mac_csr(dev, MII_ACC, phy << 11 | reg << 6 | MII_ACC_MII_BUSY); + + while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) ; + + *val = smc911x_get_mac_csr(dev, MII_DATA); + + return 0; +} + +static int smc911x_eth_phy_write(struct eth_device_smc911x *dev, + uint8_t phy, uint8_t reg, uint16_t val) +{ + while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) + ; + + smc911x_set_mac_csr(dev, MII_DATA, val); + smc911x_set_mac_csr(dev, MII_ACC, + phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE); + + while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) + ; + return 0; +} + +static int smc911x_phy_reset(struct eth_device_smc911x *dev) +{ + uint32_t reg; + + reg = smc911x_reg_read(dev, PMT_CTRL); + reg &= ~0xfffff030; + reg |= PMT_CTRL_PHY_RST; + smc911x_reg_write(dev, PMT_CTRL, reg); + + mdelay(100); + + return 0; +} + +static void smc911x_phy_configure(struct eth_device_smc911x *dev) +{ + int timeout; + uint16_t status; + + smc911x_phy_reset(dev); + + smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_RESET); + mdelay(1); + smc911x_eth_phy_write(dev, 1, MII_ADVERTISE, 0x01e1); + smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); + + timeout = 5000; + do + { + mdelay(1); + if ((timeout--) == 0) + goto err_out; + + if (smc911x_eth_phy_read(dev, 1, MII_BMSR, &status) != 0) + goto err_out; + } + while (!(status & BMSR_LSTATUS)); + + return; + +err_out: + rt_kprintf(DRIVERNAME ": autonegotiation timed out\n"); +} + +static void smc911x_enable(struct eth_device_smc911x *dev) +{ + /* Enable TX */ + smc911x_reg_write(dev, HW_CFG, 8 << 16 | HW_CFG_SF); + + smc911x_reg_write(dev, GPT_CFG, GPT_CFG_TIMER_EN | 10000); + + smc911x_reg_write(dev, TX_CFG, TX_CFG_TX_ON); + + /* no padding to start of packets */ + smc911x_reg_write(dev, RX_CFG, 0); + + smc911x_set_mac_csr(dev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | + MAC_CR_HBDIS); +} + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +/* wrapper for smc911x_eth_phy_read */ +static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad, + int reg) +{ + uint16_t val = 0; + struct eth_device_smc911x *dev = eth_get_dev_by_name(bus->name); + if (dev) + { + int retval = smc911x_eth_phy_read(dev, phy, reg, &val); + if (retval < 0) + return retval; + return val; + } + return -ENODEV; +} + +/* wrapper for smc911x_eth_phy_write */ +static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad, + int reg, uint16_t val) +{ + struct eth_device_smc911x *dev = eth_get_dev_by_name(bus->name); + if (dev) + return smc911x_eth_phy_write(dev, phy, reg, val); + return -ENODEV; +} +#endif + +static void smc911x_isr(int vector, void *param) +{ + uint32_t status; + struct eth_device_smc911x *emac; + + emac = SMC911X_EMAC_DEVICE(param); + + status = smc911x_reg_read(emac, INT_STS); + + if (status & INT_STS_RSFL) + { + eth_device_ready(&emac->parent); + } + smc911x_reg_write(emac, INT_STS, status); + + return ; +} + +static rt_err_t smc911x_emac_init(rt_device_t dev) +{ + // uint32_t value; + struct eth_device_smc911x *emac; + + emac = SMC911X_EMAC_DEVICE(dev); + RT_ASSERT(emac != RT_NULL); + + smc911x_reset(emac); + + /* Configure the PHY, initialize the link state */ + smc911x_phy_configure(emac); + smc911x_handle_mac_address(emac); + + /* Turn on Tx + Rx */ + smc911x_enable(emac); + + /* Interrupt on every received packet */ + smc911x_reg_write(emac, FIFO_INT, 0x01 << 8); + smc911x_reg_write(emac, INT_EN, INT_EN_RDFL_EN | INT_EN_RSFL_EN); + + /* enable interrupt */ + smc911x_reg_write(emac, INT_CFG, INT_CFG_IRQ_EN | INT_CFG_IRQ_POL | INT_CFG_IRQ_TYPE); + + rt_hw_interrupt_install(emac->irqno, smc911x_isr, emac, "smc911x"); + rt_hw_interrupt_umask(emac->irqno); + + return RT_EOK; +} + +static rt_err_t smc911x_emac_control(rt_device_t dev, int cmd, void *args) +{ + struct eth_device_smc911x *emac; + + emac = SMC911X_EMAC_DEVICE(dev); + RT_ASSERT(emac != RT_NULL); + + switch(cmd) + { + case NIOCTL_GADDR: + /* get MAC address */ + if(args) rt_memcpy(args, emac->enetaddr, 6); + else return -RT_ERROR; + break; + + default : + break; + } + return RT_EOK; +} + +/* Ethernet device interface */ +/* transmit packet. */ +static uint8_t tx_buf[2048]; +rt_err_t smc911x_emac_tx(rt_device_t dev, struct pbuf* p) +{ + struct eth_device_smc911x *emac; + + uint32_t *data; + uint32_t tmplen; + uint32_t status; + uint32_t length; + + emac = SMC911X_EMAC_DEVICE(dev); + RT_ASSERT(emac != RT_NULL); + + /* copy pbuf to a whole ETH frame */ + pbuf_copy_partial(p, tx_buf, p->tot_len, 0); + + /* send it out */ + data = (uint32_t*)tx_buf; + length = p->tot_len; + + smc911x_reg_write(emac, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length); + smc911x_reg_write(emac, TX_DATA_FIFO, length); + + tmplen = (length + 3) / 4; + while (tmplen--) + { + smc911x_reg_write(emac, TX_DATA_FIFO, *data++); + } + + /* wait for transmission */ + while (!((smc911x_reg_read(emac, TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16)); + + /* get status. Ignore 'no carrier' error, it has no meaning for + * full duplex operation + */ + status = smc911x_reg_read(emac, TX_STATUS_FIFO) & + (TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL | + TX_STS_MANY_DEFER | TX_STS_UNDERRUN); + + if (!status) return 0; + + LOG_E("failed to send packet: %s%s%s%s%s", + status & TX_STS_LOC ? "TX_STS_LOC " : "", + status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "", + status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "", + status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "", + status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : ""); + + return -RT_EIO; +} + +/* reception packet. */ +struct pbuf *smc911x_emac_rx(rt_device_t dev) +{ + struct pbuf* p = RT_NULL; + struct eth_device_smc911x *emac; + + emac = SMC911X_EMAC_DEVICE(dev); + RT_ASSERT(emac != RT_NULL); + + /* take the emac buffer to the pbuf */ + if ((smc911x_reg_read(emac, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) + { + uint32_t status; + uint32_t pktlen, tmplen; + + status = smc911x_reg_read(emac, RX_STATUS_FIFO); + + /* get frame length */ + pktlen = (status & RX_STS_PKT_LEN) >> 16; + + smc911x_reg_write(emac, RX_CFG, 0); + + tmplen = (pktlen + 3) / 4; + + /* allocate pbuf */ + p = pbuf_alloc(PBUF_RAW, tmplen * 4, PBUF_RAM); + if (p) + { + uint32_t *data = (uint32_t *)p->payload; + while (tmplen--) + { + *data++ = smc911x_reg_read(emac, RX_DATA_FIFO); + } + } + + if (status & RX_STS_ES) + { + rt_kprintf(DRIVERNAME ": dropped bad packet. Status: 0x%08x\n", status); + } + } + + return p; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops smc911x_emac_ops = +{ + smc911x_emac_init, + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + smc911x_emac_control +}; +#endif + +int smc911x_emac_hw_init(void) +{ + rt_memset(&_emac, 0x0, sizeof(_emac)); + + _emac.iobase = (size_t)rt_ioremap((void*)VEXPRESS_ETH_BASE, 0x1000); + _emac.irqno = IRQ_VEXPRESS_A9_ETH; + + if (smc911x_detect_chip(&_emac)) + { + rt_kprintf("no smc911x network interface found!\n"); + return -1; + } + + /* set INT CFG */ + smc911x_reg_write(&_emac, INT_CFG, INT_CFG_IRQ_POL | INT_CFG_IRQ_TYPE); + + /* test MAC address */ + _emac.enetaddr[0] = AUTOMAC0; + _emac.enetaddr[1] = AUTOMAC1; + _emac.enetaddr[2] = AUTOMAC2; + _emac.enetaddr[3] = AUTOMAC3; + _emac.enetaddr[4] = AUTOMAC4; + _emac.enetaddr[5] = AUTOMAC5; + +#ifdef RT_USING_DEVICE_OPS + _emac.parent.parent.ops = &smc911x_emac_ops; +#else + _emac.parent.parent.init = smc911x_emac_init; + _emac.parent.parent.open = RT_NULL; + _emac.parent.parent.close = RT_NULL; + _emac.parent.parent.read = RT_NULL; + _emac.parent.parent.write = RT_NULL; + _emac.parent.parent.control = smc911x_emac_control; +#endif + _emac.parent.parent.user_data = RT_NULL; + _emac.parent.eth_rx = smc911x_emac_rx; + _emac.parent.eth_tx = smc911x_emac_tx; + + /* register ETH device */ + eth_device_init(&(_emac.parent), "e0"); + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + { + int retval; + struct mii_dev *mdiodev = mdio_alloc(); + if (!mdiodev) + return -ENOMEM; + strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); + mdiodev->read = smc911x_miiphy_read; + mdiodev->write = smc911x_miiphy_write; + + retval = mdio_register(mdiodev); + if (retval < 0) + return retval; + } +#endif + + eth_device_linkchange(&_emac.parent, RT_TRUE); + return 0; +} +INIT_APP_EXPORT(smc911x_emac_hw_init); +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_smc911x.h b/bsp/qemu-vexpress-a53/drivers/drv_smc911x.h new file mode 100644 index 0000000000..abaa24f9fd --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_smc911x.h @@ -0,0 +1,402 @@ +/* + * SMSC LAN9[12]1[567] Network driver + * + * (c) 2007 Pengutronix, Sascha Hauer + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SMC911X_H_ +#define _SMC911X_H_ + +#include + +#define CONFIG_SMC911X_32_BIT + +/* Below are the register offsets and bit definitions + * of the Lan911x memory space + */ +#define RX_DATA_FIFO 0x00 + +#define TX_DATA_FIFO 0x20 +#define TX_CMD_A_INT_ON_COMP 0x80000000 +#define TX_CMD_A_INT_BUF_END_ALGN 0x03000000 +#define TX_CMD_A_INT_4_BYTE_ALGN 0x00000000 +#define TX_CMD_A_INT_16_BYTE_ALGN 0x01000000 +#define TX_CMD_A_INT_32_BYTE_ALGN 0x02000000 +#define TX_CMD_A_INT_DATA_OFFSET 0x001F0000 +#define TX_CMD_A_INT_FIRST_SEG 0x00002000 +#define TX_CMD_A_INT_LAST_SEG 0x00001000 +#define TX_CMD_A_BUF_SIZE 0x000007FF +#define TX_CMD_B_PKT_TAG 0xFFFF0000 +#define TX_CMD_B_ADD_CRC_DISABLE 0x00002000 +#define TX_CMD_B_DISABLE_PADDING 0x00001000 +#define TX_CMD_B_PKT_BYTE_LENGTH 0x000007FF + +#define RX_STATUS_FIFO 0x40 +#define RX_STS_PKT_LEN 0x3FFF0000 +#define RX_STS_ES 0x00008000 +#define RX_STS_BCST 0x00002000 +#define RX_STS_LEN_ERR 0x00001000 +#define RX_STS_RUNT_ERR 0x00000800 +#define RX_STS_MCAST 0x00000400 +#define RX_STS_TOO_LONG 0x00000080 +#define RX_STS_COLL 0x00000040 +#define RX_STS_ETH_TYPE 0x00000020 +#define RX_STS_WDOG_TMT 0x00000010 +#define RX_STS_MII_ERR 0x00000008 +#define RX_STS_DRIBBLING 0x00000004 +#define RX_STS_CRC_ERR 0x00000002 +#define RX_STATUS_FIFO_PEEK 0x44 +#define TX_STATUS_FIFO 0x48 +#define TX_STS_TAG 0xFFFF0000 +#define TX_STS_ES 0x00008000 +#define TX_STS_LOC 0x00000800 +#define TX_STS_NO_CARR 0x00000400 +#define TX_STS_LATE_COLL 0x00000200 +#define TX_STS_MANY_COLL 0x00000100 +#define TX_STS_COLL_CNT 0x00000078 +#define TX_STS_MANY_DEFER 0x00000004 +#define TX_STS_UNDERRUN 0x00000002 +#define TX_STS_DEFERRED 0x00000001 +#define TX_STATUS_FIFO_PEEK 0x4C +#define ID_REV 0x50 +#define ID_REV_CHIP_ID 0xFFFF0000 /* RO */ +#define ID_REV_REV_ID 0x0000FFFF /* RO */ + +#define INT_CFG 0x54 +#define INT_CFG_INT_DEAS 0xFF000000 /* R/W */ +#define INT_CFG_INT_DEAS_CLR 0x00004000 +#define INT_CFG_INT_DEAS_STS 0x00002000 +#define INT_CFG_IRQ_INT 0x00001000 /* RO */ +#define INT_CFG_IRQ_EN 0x00000100 /* R/W */ +/* R/W Not Affected by SW Reset */ +#define INT_CFG_IRQ_POL 0x00000010 +/* R/W Not Affected by SW Reset */ +#define INT_CFG_IRQ_TYPE 0x00000001 + +#define INT_STS 0x58 +#define INT_STS_SW_INT 0x80000000 /* R/WC */ +#define INT_STS_TXSTOP_INT 0x02000000 /* R/WC */ +#define INT_STS_RXSTOP_INT 0x01000000 /* R/WC */ +#define INT_STS_RXDFH_INT 0x00800000 /* R/WC */ +#define INT_STS_RXDF_INT 0x00400000 /* R/WC */ +#define INT_STS_TX_IOC 0x00200000 /* R/WC */ +#define INT_STS_RXD_INT 0x00100000 /* R/WC */ +#define INT_STS_GPT_INT 0x00080000 /* R/WC */ +#define INT_STS_PHY_INT 0x00040000 /* RO */ +#define INT_STS_PME_INT 0x00020000 /* R/WC */ +#define INT_STS_TXSO 0x00010000 /* R/WC */ +#define INT_STS_RWT 0x00008000 /* R/WC */ +#define INT_STS_RXE 0x00004000 /* R/WC */ +#define INT_STS_TXE 0x00002000 /* R/WC */ +/*#define INT_STS_ERX 0x00001000*/ /* R/WC */ +#define INT_STS_TDFU 0x00000800 /* R/WC */ +#define INT_STS_TDFO 0x00000400 /* R/WC */ +#define INT_STS_TDFA 0x00000200 /* R/WC */ +#define INT_STS_TSFF 0x00000100 /* R/WC */ +#define INT_STS_TSFL 0x00000080 /* R/WC */ +/*#define INT_STS_RXDF 0x00000040*/ /* R/WC */ +#define INT_STS_RDFO 0x00000040 /* R/WC */ +#define INT_STS_RDFL 0x00000020 /* R/WC */ +#define INT_STS_RSFF 0x00000010 /* R/WC */ +#define INT_STS_RSFL 0x00000008 /* R/WC */ +#define INT_STS_GPIO2_INT 0x00000004 /* R/WC */ +#define INT_STS_GPIO1_INT 0x00000002 /* R/WC */ +#define INT_STS_GPIO0_INT 0x00000001 /* R/WC */ +#define INT_EN 0x5C +#define INT_EN_SW_INT_EN 0x80000000 /* R/W */ +#define INT_EN_TXSTOP_INT_EN 0x02000000 /* R/W */ +#define INT_EN_RXSTOP_INT_EN 0x01000000 /* R/W */ +#define INT_EN_RXDFH_INT_EN 0x00800000 /* R/W */ +/*#define INT_EN_RXDF_INT_EN 0x00400000*/ /* R/W */ +#define INT_EN_TIOC_INT_EN 0x00200000 /* R/W */ +#define INT_EN_RXD_INT_EN 0x00100000 /* R/W */ +#define INT_EN_GPT_INT_EN 0x00080000 /* R/W */ +#define INT_EN_PHY_INT_EN 0x00040000 /* R/W */ +#define INT_EN_PME_INT_EN 0x00020000 /* R/W */ +#define INT_EN_TXSO_EN 0x00010000 /* R/W */ +#define INT_EN_RWT_EN 0x00008000 /* R/W */ +#define INT_EN_RXE_EN 0x00004000 /* R/W */ +#define INT_EN_TXE_EN 0x00002000 /* R/W */ +/*#define INT_EN_ERX_EN 0x00001000*/ /* R/W */ +#define INT_EN_TDFU_EN 0x00000800 /* R/W */ +#define INT_EN_TDFO_EN 0x00000400 /* R/W */ +#define INT_EN_TDFA_EN 0x00000200 /* R/W */ +#define INT_EN_TSFF_EN 0x00000100 /* R/W */ +#define INT_EN_TSFL_EN 0x00000080 /* R/W */ +/*#define INT_EN_RXDF_EN 0x00000040*/ /* R/W */ +#define INT_EN_RDFO_EN 0x00000040 /* R/W */ +#define INT_EN_RDFL_EN 0x00000020 /* R/W */ +#define INT_EN_RSFF_EN 0x00000010 /* R/W */ +#define INT_EN_RSFL_EN 0x00000008 /* R/W */ +#define INT_EN_GPIO2_INT 0x00000004 /* R/W */ +#define INT_EN_GPIO1_INT 0x00000002 /* R/W */ +#define INT_EN_GPIO0_INT 0x00000001 /* R/W */ + +#define BYTE_TEST 0x64 +#define FIFO_INT 0x68 +#define FIFO_INT_TX_AVAIL_LEVEL 0xFF000000 /* R/W */ +#define FIFO_INT_TX_STS_LEVEL 0x00FF0000 /* R/W */ +#define FIFO_INT_RX_AVAIL_LEVEL 0x0000FF00 /* R/W */ +#define FIFO_INT_RX_STS_LEVEL 0x000000FF /* R/W */ + +#define RX_CFG 0x6C +#define RX_CFG_RX_END_ALGN 0xC0000000 /* R/W */ +#define RX_CFG_RX_END_ALGN4 0x00000000 /* R/W */ +#define RX_CFG_RX_END_ALGN16 0x40000000 /* R/W */ +#define RX_CFG_RX_END_ALGN32 0x80000000 /* R/W */ +#define RX_CFG_RX_DMA_CNT 0x0FFF0000 /* R/W */ +#define RX_CFG_RX_DUMP 0x00008000 /* R/W */ +#define RX_CFG_RXDOFF 0x00001F00 /* R/W */ +/*#define RX_CFG_RXBAD 0x00000001*/ /* R/W */ + +#define TX_CFG 0x70 +/*#define TX_CFG_TX_DMA_LVL 0xE0000000*/ /* R/W */ +/* R/W Self Clearing */ +/*#define TX_CFG_TX_DMA_CNT 0x0FFF0000*/ +#define TX_CFG_TXS_DUMP 0x00008000 /* Self Clearing */ +#define TX_CFG_TXD_DUMP 0x00004000 /* Self Clearing */ +#define TX_CFG_TXSAO 0x00000004 /* R/W */ +#define TX_CFG_TX_ON 0x00000002 /* R/W */ +#define TX_CFG_STOP_TX 0x00000001 /* Self Clearing */ + +#define HW_CFG 0x74 +#define HW_CFG_TTM 0x00200000 /* R/W */ +#define HW_CFG_SF 0x00100000 /* R/W */ +#define HW_CFG_TX_FIF_SZ 0x000F0000 /* R/W */ +#define HW_CFG_TR 0x00003000 /* R/W */ +#define HW_CFG_PHY_CLK_SEL 0x00000060 /* R/W */ +#define HW_CFG_PHY_CLK_SEL_INT_PHY 0x00000000 /* R/W */ +#define HW_CFG_PHY_CLK_SEL_EXT_PHY 0x00000020 /* R/W */ +#define HW_CFG_PHY_CLK_SEL_CLK_DIS 0x00000040 /* R/W */ +#define HW_CFG_SMI_SEL 0x00000010 /* R/W */ +#define HW_CFG_EXT_PHY_DET 0x00000008 /* RO */ +#define HW_CFG_EXT_PHY_EN 0x00000004 /* R/W */ +#define HW_CFG_32_16_BIT_MODE 0x00000004 /* RO */ +#define HW_CFG_SRST_TO 0x00000002 /* RO */ +#define HW_CFG_SRST 0x00000001 /* Self Clearing */ + +#define RX_DP_CTRL 0x78 +#define RX_DP_CTRL_RX_FFWD 0x80000000 /* R/W */ +#define RX_DP_CTRL_FFWD_BUSY 0x80000000 /* RO */ + +#define RX_FIFO_INF 0x7C +#define RX_FIFO_INF_RXSUSED 0x00FF0000 /* RO */ +#define RX_FIFO_INF_RXDUSED 0x0000FFFF /* RO */ + +#define TX_FIFO_INF 0x80 +#define TX_FIFO_INF_TSUSED 0x00FF0000 /* RO */ +#define TX_FIFO_INF_TDFREE 0x0000FFFF /* RO */ + +#define PMT_CTRL 0x84 +#define PMT_CTRL_PM_MODE 0x00003000 /* Self Clearing */ +#define PMT_CTRL_PHY_RST 0x00000400 /* Self Clearing */ +#define PMT_CTRL_WOL_EN 0x00000200 /* R/W */ +#define PMT_CTRL_ED_EN 0x00000100 /* R/W */ +/* R/W Not Affected by SW Reset */ +#define PMT_CTRL_PME_TYPE 0x00000040 +#define PMT_CTRL_WUPS 0x00000030 /* R/WC */ +#define PMT_CTRL_WUPS_NOWAKE 0x00000000 /* R/WC */ +#define PMT_CTRL_WUPS_ED 0x00000010 /* R/WC */ +#define PMT_CTRL_WUPS_WOL 0x00000020 /* R/WC */ +#define PMT_CTRL_WUPS_MULTI 0x00000030 /* R/WC */ +#define PMT_CTRL_PME_IND 0x00000008 /* R/W */ +#define PMT_CTRL_PME_POL 0x00000004 /* R/W */ +/* R/W Not Affected by SW Reset */ +#define PMT_CTRL_PME_EN 0x00000002 +#define PMT_CTRL_READY 0x00000001 /* RO */ + +#define GPIO_CFG 0x88 +#define GPIO_CFG_LED3_EN 0x40000000 /* R/W */ +#define GPIO_CFG_LED2_EN 0x20000000 /* R/W */ +#define GPIO_CFG_LED1_EN 0x10000000 /* R/W */ +#define GPIO_CFG_GPIO2_INT_POL 0x04000000 /* R/W */ +#define GPIO_CFG_GPIO1_INT_POL 0x02000000 /* R/W */ +#define GPIO_CFG_GPIO0_INT_POL 0x01000000 /* R/W */ +#define GPIO_CFG_EEPR_EN 0x00700000 /* R/W */ +#define GPIO_CFG_GPIOBUF2 0x00040000 /* R/W */ +#define GPIO_CFG_GPIOBUF1 0x00020000 /* R/W */ +#define GPIO_CFG_GPIOBUF0 0x00010000 /* R/W */ +#define GPIO_CFG_GPIODIR2 0x00000400 /* R/W */ +#define GPIO_CFG_GPIODIR1 0x00000200 /* R/W */ +#define GPIO_CFG_GPIODIR0 0x00000100 /* R/W */ +#define GPIO_CFG_GPIOD4 0x00000010 /* R/W */ +#define GPIO_CFG_GPIOD3 0x00000008 /* R/W */ +#define GPIO_CFG_GPIOD2 0x00000004 /* R/W */ +#define GPIO_CFG_GPIOD1 0x00000002 /* R/W */ +#define GPIO_CFG_GPIOD0 0x00000001 /* R/W */ + +#define GPT_CFG 0x8C +#define GPT_CFG_TIMER_EN 0x20000000 /* R/W */ +#define GPT_CFG_GPT_LOAD 0x0000FFFF /* R/W */ + +#define GPT_CNT 0x90 +#define GPT_CNT_GPT_CNT 0x0000FFFF /* RO */ + +#define ENDIAN 0x98 +#define FREE_RUN 0x9C +#define RX_DROP 0xA0 +#define MAC_CSR_CMD 0xA4 +#define MAC_CSR_CMD_CSR_BUSY 0x80000000 /* Self Clearing */ +#define MAC_CSR_CMD_R_NOT_W 0x40000000 /* R/W */ +#define MAC_CSR_CMD_CSR_ADDR 0x000000FF /* R/W */ + +#define MAC_CSR_DATA 0xA8 +#define AFC_CFG 0xAC +#define AFC_CFG_AFC_HI 0x00FF0000 /* R/W */ +#define AFC_CFG_AFC_LO 0x0000FF00 /* R/W */ +#define AFC_CFG_BACK_DUR 0x000000F0 /* R/W */ +#define AFC_CFG_FCMULT 0x00000008 /* R/W */ +#define AFC_CFG_FCBRD 0x00000004 /* R/W */ +#define AFC_CFG_FCADD 0x00000002 /* R/W */ +#define AFC_CFG_FCANY 0x00000001 /* R/W */ + +#define E2P_CMD 0xB0 +#define E2P_CMD_EPC_BUSY 0x80000000 /* Self Clearing */ +#define E2P_CMD_EPC_CMD 0x70000000 /* R/W */ +#define E2P_CMD_EPC_CMD_READ 0x00000000 /* R/W */ +#define E2P_CMD_EPC_CMD_EWDS 0x10000000 /* R/W */ +#define E2P_CMD_EPC_CMD_EWEN 0x20000000 /* R/W */ +#define E2P_CMD_EPC_CMD_WRITE 0x30000000 /* R/W */ +#define E2P_CMD_EPC_CMD_WRAL 0x40000000 /* R/W */ +#define E2P_CMD_EPC_CMD_ERASE 0x50000000 /* R/W */ +#define E2P_CMD_EPC_CMD_ERAL 0x60000000 /* R/W */ +#define E2P_CMD_EPC_CMD_RELOAD 0x70000000 /* R/W */ +#define E2P_CMD_EPC_TIMEOUT 0x00000200 /* RO */ +#define E2P_CMD_MAC_ADDR_LOADED 0x00000100 /* RO */ +#define E2P_CMD_EPC_ADDR 0x000000FF /* R/W */ + +#define E2P_DATA 0xB4 +#define E2P_DATA_EEPROM_DATA 0x000000FF /* R/W */ +/* end of LAN register offsets and bit definitions */ + +/* MAC Control and Status registers */ +#define MAC_CR 0x01 /* R/W */ + +/* MAC_CR - MAC Control Register */ +#define MAC_CR_RXALL 0x80000000 +/* TODO: delete this bit? It is not described in the data sheet. */ +#define MAC_CR_HBDIS 0x10000000 +#define MAC_CR_RCVOWN 0x00800000 +#define MAC_CR_LOOPBK 0x00200000 +#define MAC_CR_FDPX 0x00100000 +#define MAC_CR_MCPAS 0x00080000 +#define MAC_CR_PRMS 0x00040000 +#define MAC_CR_INVFILT 0x00020000 +#define MAC_CR_PASSBAD 0x00010000 +#define MAC_CR_HFILT 0x00008000 +#define MAC_CR_HPFILT 0x00002000 +#define MAC_CR_LCOLL 0x00001000 +#define MAC_CR_BCAST 0x00000800 +#define MAC_CR_DISRTY 0x00000400 +#define MAC_CR_PADSTR 0x00000100 +#define MAC_CR_BOLMT_MASK 0x000000C0 +#define MAC_CR_DFCHK 0x00000020 +#define MAC_CR_TXEN 0x00000008 +#define MAC_CR_RXEN 0x00000004 + +#define ADDRH 0x02 /* R/W mask 0x0000FFFFUL */ +#define ADDRL 0x03 /* R/W mask 0xFFFFFFFFUL */ +#define HASHH 0x04 /* R/W */ +#define HASHL 0x05 /* R/W */ + +#define MII_ACC 0x06 /* R/W */ +#define MII_ACC_PHY_ADDR 0x0000F800 +#define MII_ACC_MIIRINDA 0x000007C0 +#define MII_ACC_MII_WRITE 0x00000002 +#define MII_ACC_MII_BUSY 0x00000001 + +#define MII_DATA 0x07 /* R/W mask 0x0000FFFFUL */ + +#define FLOW 0x08 /* R/W */ +#define FLOW_FCPT 0xFFFF0000 +#define FLOW_FCPASS 0x00000004 +#define FLOW_FCEN 0x00000002 +#define FLOW_FCBSY 0x00000001 + +#define VLAN1 0x09 /* R/W mask 0x0000FFFFUL */ +#define VLAN1_VTI1 0x0000ffff + +#define VLAN2 0x0A /* R/W mask 0x0000FFFFUL */ +#define VLAN2_VTI2 0x0000ffff + +#define WUFF 0x0B /* WO */ + +#define WUCSR 0x0C /* R/W */ +#define WUCSR_GUE 0x00000200 +#define WUCSR_WUFR 0x00000040 +#define WUCSR_MPR 0x00000020 +#define WUCSR_WAKE_EN 0x00000004 +#define WUCSR_MPEN 0x00000002 + +/* Chip ID values */ +#define CHIP_89218 0x218a +#define CHIP_9115 0x115 +#define CHIP_9116 0x116 +#define CHIP_9117 0x117 +#define CHIP_9118 0x118 +#define CHIP_9211 0x9211 +#define CHIP_9215 0x115a +#define CHIP_9216 0x116a +#define CHIP_9217 0x117a +#define CHIP_9218 0x118a +#define CHIP_9220 0x9220 +#define CHIP_9221 0x9221 + + +/* Generic MII registers. */ + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_CTRL1000 0x09 /* 1000BASE-T control */ +#define MII_STAT1000 0x0a /* 1000BASE-T status */ +#define MII_ESTATUS 0x0f /* Extended Status */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x00c0 /* Unused... */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ +#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_timer.c b/bsp/qemu-vexpress-a53/drivers/drv_timer.c new file mode 100644 index 0000000000..8dcc6e2c3e --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_timer.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-22 Jesven first version + */ + +#include +#include +#include + +#include "mmu.h" +#include "board.h" + +#define TIMER01_HW_BASE_PHY 0x10011000 +#define TIMER23_HW_BASE_PHY 0x10012000 + +void* timer01_hw_base; +void* timer23_hw_base; + +#define TIMER01_HW_BASE timer01_hw_base +#define TIMER23_HW_BASE timer23_hw_base + +#define TIMER_LOAD(hw_base) __REG32(hw_base + 0x00) +#define TIMER_VALUE(hw_base) __REG32(hw_base + 0x04) +#define TIMER_CTRL(hw_base) __REG32(hw_base + 0x08) +#define TIMER_CTRL_ONESHOT (1 << 0) +#define TIMER_CTRL_32BIT (1 << 1) +#define TIMER_CTRL_DIV1 (0 << 2) +#define TIMER_CTRL_DIV16 (1 << 2) +#define TIMER_CTRL_DIV256 (2 << 2) +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ +#define TIMER_CTRL_PERIODIC (1 << 6) +#define TIMER_CTRL_ENABLE (1 << 7) + +#define TIMER_INTCLR(hw_base) __REG32(hw_base + 0x0c) +#define TIMER_RIS(hw_base) __REG32(hw_base + 0x10) +#define TIMER_MIS(hw_base) __REG32(hw_base + 0x14) +#define TIMER_BGLOAD(hw_base) __REG32(hw_base + 0x18) + +#define TIMER_LOAD(hw_base) __REG32(hw_base + 0x00) +#define TIMER_VALUE(hw_base) __REG32(hw_base + 0x04) +#define TIMER_CTRL(hw_base) __REG32(hw_base + 0x08) +#define TIMER_CTRL_ONESHOT (1 << 0) +#define TIMER_CTRL_32BIT (1 << 1) +#define TIMER_CTRL_DIV1 (0 << 2) +#define TIMER_CTRL_DIV16 (1 << 2) +#define TIMER_CTRL_DIV256 (2 << 2) +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ +#define TIMER_CTRL_PERIODIC (1 << 6) +#define TIMER_CTRL_ENABLE (1 << 7) + +#define TIMER_INTCLR(hw_base) __REG32(hw_base + 0x0c) +#define TIMER_RIS(hw_base) __REG32(hw_base + 0x10) +#define TIMER_MIS(hw_base) __REG32(hw_base + 0x14) +#define TIMER_BGLOAD(hw_base) __REG32(hw_base + 0x18) + +void* sys_ctrl; +#define SYS_CTRL __REG32(sys_ctrl) +void* timer_hw_base; +#define TIMER_HW_BASE timer_hw_base + +static void rt_hw_timer_isr(int vector, void *param) +{ + rt_tick_increase(); + /* clear interrupt */ + TIMER_INTCLR(TIMER_HW_BASE) = 0x01; +} + +int rt_hw_timer_init(void) +{ + rt_uint32_t val; + + sys_ctrl = (void*)rt_ioremap((void*)REALVIEW_SCTL_BASE, 0x1000); + timer_hw_base = (void*)rt_ioremap((void*)REALVIEW_TIMER2_3_BASE, 0x1000); + + SYS_CTRL |= REALVIEW_REFCLK; + + /* Setup Timer0 for generating irq */ + val = TIMER_CTRL(TIMER_HW_BASE); + val &= ~TIMER_CTRL_ENABLE; + val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); + TIMER_CTRL(TIMER_HW_BASE) = val; + + TIMER_LOAD(TIMER_HW_BASE) = 1000000/RT_TICK_PER_SECOND; + + /* enable timer */ + TIMER_CTRL(TIMER_HW_BASE) |= TIMER_CTRL_ENABLE; + + rt_hw_interrupt_install(IRQ_PBA8_TIMER2_3, rt_hw_timer_isr, RT_NULL, "tick"); + rt_hw_interrupt_umask(IRQ_PBA8_TIMER2_3); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_timer_init); + +void timer_init(int timer, unsigned int preload) +{ + uint32_t val; + + if (timer == 0) + { + timer01_hw_base = (void*)rt_ioremap((void*)TIMER01_HW_BASE_PHY, 0x1000); + /* Setup Timer0 for generating irq */ + val = TIMER_CTRL(TIMER01_HW_BASE); + val &= ~TIMER_CTRL_ENABLE; + val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); + TIMER_CTRL(TIMER01_HW_BASE) = val; + + TIMER_LOAD(TIMER01_HW_BASE) = preload; + + /* enable timer */ + TIMER_CTRL(TIMER01_HW_BASE) |= TIMER_CTRL_ENABLE; + } + else + { + timer23_hw_base = (void*)rt_ioremap((void*)TIMER23_HW_BASE_PHY, 0x1000); + /* Setup Timer1 for generating irq */ + val = TIMER_CTRL(TIMER23_HW_BASE); + val &= ~TIMER_CTRL_ENABLE; + val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); + TIMER_CTRL(TIMER23_HW_BASE) = val; + + TIMER_LOAD(TIMER23_HW_BASE) = preload; + + /* enable timer */ + TIMER_CTRL(TIMER23_HW_BASE) |= TIMER_CTRL_ENABLE; + } +} + +void timer_clear_pending(int timer) +{ + if (timer == 0) + { + TIMER_INTCLR(TIMER01_HW_BASE) = 0x01; + } + else + { + TIMER_INTCLR(TIMER23_HW_BASE) = 0x01; + } +} diff --git a/bsp/qemu-vexpress-a53/drivers/drv_timer.h b/bsp/qemu-vexpress-a53/drivers/drv_timer.h new file mode 100644 index 0000000000..718f5d43cf --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/drv_timer.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-22 Jesven first version + */ + +#ifndef DRV_TIMER_H__ +#define DRV_TIMER_H__ + +void timer_init(int timer, unsigned int preload); +void timer_clear_pending(int timer); + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/realview.h b/bsp/qemu-vexpress-a53/drivers/realview.h new file mode 100644 index 0000000000..d63df40f45 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/realview.h @@ -0,0 +1,331 @@ +#ifndef __AM33XX_H__ +#define __AM33XX_H__ + +#define __REG32(x) (*((volatile unsigned int *)(x))) +#define __REG16(x) (*((volatile unsigned short *)(x))) + +/* + * Peripheral addresses + */ +#define REALVIEW_UART0_BASE 0x10009000 /* UART 0 */ +#define REALVIEW_UART1_BASE 0x1000A000 /* UART 1 */ +#define REALVIEW_UART2_BASE 0x1000B000 /* UART 2 */ +#define REALVIEW_UART3_BASE 0x1000C000 /* UART 3 */ +#define REALVIEW_SSP_BASE 0x1000D000 /* Synchronous Serial Port */ +#define REALVIEW_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */ +#define REALVIEW_WATCHDOG_BASE 0x10010000 /* watchdog interface */ +#define REALVIEW_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */ +#define REALVIEW_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */ +#define REALVIEW_GPIO0_BASE 0x10013000 /* GPIO port 0 */ +#define REALVIEW_RTC_BASE 0x10017000 /* Real Time Clock */ +#define REALVIEW_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */ +#define REALVIEW_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */ +#define REALVIEW_SCTL_BASE 0x10001000 /* System Controller */ +#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */ +#define REALVIEW_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */ +#define REALVIEW_DMC_BASE 0x100E0000 /* DMC configuration */ +#define REALVIEW_SMC_BASE 0x100E1000 /* SMC configuration */ +#define REALVIEW_CAN_BASE 0x100E2000 /* CAN bus */ +#define REALVIEW_GIC_CPU_BASE 0x1E000100 /* Generic interrupt controller CPU interface */ +#define REALVIEW_FLASH0_BASE 0x40000000 +#define REALVIEW_FLASH0_SIZE SZ_64M +#define REALVIEW_FLASH1_BASE 0x44000000 +#define REALVIEW_FLASH1_SIZE SZ_64M + +#define VEXPRESS_SRAM_BASE 0x48000000 + +#define REALVIEW_ETH_BASE 0x4E000000 /* Ethernet */ +#define VEXPRESS_ETH_BASE 0x4E000000 /* Ethernet */ + +#define REALVIEW_USB_BASE 0x4F000000 /* USB */ +#define REALVIEW_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */ +#define REALVIEW_LT_BASE 0xC0000000 /* Logic Tile expansion */ +#define REALVIEW_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */ +#define REALVIEW_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */ + +#define REALVIEW_SYS_PLD_CTRL1 0x74 + +/* + * PCI regions + */ +#define REALVIEW_PCI_BASE 0x90040000 /* PCI-X Unit base */ +#define REALVIEW_PCI_IO_BASE 0x90050000 /* IO Region on AHB */ +#define REALVIEW_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */ + +#define REALVIEW_PCI_BASE_SIZE 0x10000 /* 16 Kb */ +#define REALVIEW_PCI_IO_SIZE 0x1000 /* 4 Kb */ +#define REALVIEW_PCI_MEM_SIZE 0x20000000 /* 512 MB */ + +/* + * Memory definitions + */ +#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)... */ +#define REALVIEW_BOOT_ROM_HI 0x30000000 +#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */ +#define REALVIEW_BOOT_ROM_SIZE SZ_64M + +#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */ +#define REALVIEW_SSRAM_SIZE SZ_2M + +/* + * SDRAM + */ +#define REALVIEW_SDRAM_BASE 0x00000000 + +/* + * Logic expansion modules + * + */ +#define IRQ_PBA8_GIC_START 32 + +/* + * PB-A8 on-board gic irq sources + */ +#define IRQ_PBA8_WATCHDOG (IRQ_PBA8_GIC_START + 0) /* Watchdog timer */ +#define IRQ_PBA8_SOFT (IRQ_PBA8_GIC_START + 1) /* Software interrupt */ +#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 2) /* Timer 0/1 (default timer) */ +#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 3) /* Timer 2/3 */ +#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 4) /* Timer 2/3 */ +#define IRQ_VEXPRESS_A9_RTC (IRQ_PBA8_GIC_START + 4) + +#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 5) /* UART 0 on development chip */ +#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 6) /* UART 1 on development chip */ +#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 7) /* UART 2 on development chip */ +#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 8) /* UART 3 on development chip */ + +#define IRQ_VEXPRESS_A9_KBD (IRQ_PBA8_GIC_START + 12) +#define IRQ_VEXPRESS_A9_MOUSE (IRQ_PBA8_GIC_START + 13) +#define IRQ_VEXPRESS_A9_CLCD (IRQ_PBA8_GIC_START + 14) +#define IRQ_VEXPRESS_A9_ETH (IRQ_PBA8_GIC_START + 15) + +/* 9 reserved */ +#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11) /* Synchronous Serial Port */ +#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16) /* Smart Card Interface */ +#define IRQ_PBA8_MMCI0A (IRQ_PBA8_GIC_START + 17) /* Multimedia Card 0A */ +#define IRQ_PBA8_MMCI0B (IRQ_PBA8_GIC_START + 18) /* Multimedia Card 0B */ +#define IRQ_PBA8_AACI (IRQ_PBA8_GIC_START + 19) /* Audio Codec */ +#define IRQ_PBA8_KMI0 (IRQ_PBA8_GIC_START + 20) /* Keyboard/Mouse port 0 */ +#define IRQ_PBA8_KMI1 (IRQ_PBA8_GIC_START + 21) /* Keyboard/Mouse port 1 */ +#define IRQ_PBA8_CHARLCD (IRQ_PBA8_GIC_START + 22) /* Character LCD */ +#define IRQ_PBA8_CLCD (IRQ_PBA8_GIC_START + 23) /* CLCD controller */ +#define IRQ_PBA8_DMAC (IRQ_PBA8_GIC_START + 24) /* DMA controller */ +#define IRQ_PBA8_PWRFAIL (IRQ_PBA8_GIC_START + 25) /* Power failure */ +#define IRQ_PBA8_PISMO (IRQ_PBA8_GIC_START + 26) /* PISMO interface */ +#define IRQ_PBA8_DoC (IRQ_PBA8_GIC_START + 27) /* Disk on Chip memory controller */ +#define IRQ_PBA8_ETH (IRQ_PBA8_GIC_START + 28) /* Ethernet controller */ +#define IRQ_PBA8_USB (IRQ_PBA8_GIC_START + 29) /* USB controller */ +#define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */ +#define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */ + +#define IRQ_PBA8_PMU (IRQ_PBA8_GIC_START + 47) /* Cortex-A8 PMU */ + +/* ... */ +#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50) +#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51) +#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52) +#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53) + +#define IRQ_PBA8_SMC -1 +#define IRQ_PBA8_SCTL -1 + +#define NR_GIC_PBA8 1 + +/* + * Only define NR_IRQS if less than NR_IRQS_PBA8 + */ +#define NR_IRQS_PBA8 (IRQ_PBA8_GIC_START + 64) + +/* ------------------------------------------------------------------------ + * RealView Registers + * ------------------------------------------------------------------------ + * + */ +#define REALVIEW_SYS_ID_OFFSET 0x00 +#define REALVIEW_SYS_SW_OFFSET 0x04 +#define REALVIEW_SYS_LED_OFFSET 0x08 +#define REALVIEW_SYS_OSC0_OFFSET 0x0C + +#define REALVIEW_SYS_OSC1_OFFSET 0x10 +#define REALVIEW_SYS_OSC2_OFFSET 0x14 +#define REALVIEW_SYS_OSC3_OFFSET 0x18 +#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */ + +#define REALVIEW_SYS_LOCK_OFFSET 0x20 +#define REALVIEW_SYS_100HZ_OFFSET 0x24 +#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28 +#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C +#define REALVIEW_SYS_FLAGS_OFFSET 0x30 +#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30 +#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34 +#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38 +#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38 +#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C +#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 +#define REALVIEW_SYS_PCICTL_OFFSET 0x44 +#define REALVIEW_SYS_MCI_OFFSET 0x48 +#define REALVIEW_SYS_FLASH_OFFSET 0x4C +#define REALVIEW_SYS_CLCD_OFFSET 0x50 +#define REALVIEW_SYS_CLCDSER_OFFSET 0x54 +#define REALVIEW_SYS_BOOTCS_OFFSET 0x58 +#define REALVIEW_SYS_24MHz_OFFSET 0x5C +#define REALVIEW_SYS_MISC_OFFSET 0x60 +#define REALVIEW_SYS_IOSEL_OFFSET 0x70 +#define REALVIEW_SYS_PROCID_OFFSET 0x84 +#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0 +#define REALVIEW_SYS_TEST_OSC1_OFFSET 0xC4 +#define REALVIEW_SYS_TEST_OSC2_OFFSET 0xC8 +#define REALVIEW_SYS_TEST_OSC3_OFFSET 0xCC +#define REALVIEW_SYS_TEST_OSC4_OFFSET 0xD0 + +#define REALVIEW_SYS_BASE 0x10000000 +#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET) +#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET) +#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET) +#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET) +#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET) + +#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET) +#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET) +#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET) +#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET) +#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET) +#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET) +#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET) +#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET) +#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET) +#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET) +#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET) +#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET) +#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET) +#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET) +#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET) +#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET) +#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET) +#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET) +#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET) +#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET) +#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET) +#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET) +#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET) +#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET) +#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) +#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) + +#define REALVIEW_SYS_CTRL_LED (1 << 0) + +/* ------------------------------------------------------------------------ + * RealView control registers + * ------------------------------------------------------------------------ + */ + +/* + * REALVIEW_IDFIELD + * + * 31:24 = manufacturer (0x41 = ARM) + * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus) + * 15:12 = FPGA (0x3 = XVC600 or XVC600E) + * 11:4 = build value + * 3:0 = revision number (0x1 = rev B (AHB)) + */ + +/* + * REALVIEW_SYS_LOCK + * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, + * SYS_CLD, SYS_BOOTCS + */ +#define REALVIEW_SYS_LOCK_LOCKED (1 << 16) +#define REALVIEW_SYS_LOCKVAL 0xA05F +#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ + +/* + * REALVIEW_SYS_FLASH + */ +#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */ + +/* + * REALVIEW_INTREG + * - used to acknowledge and control MMCI and UART interrupts + */ +#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */ +#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */ +#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */ +/* write 1 to acknowledge and clear */ +#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */ +#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */ + +/* + * LED settings, bits [7:0] + */ +#define REALVIEW_SYS_LED0 (1 << 0) +#define REALVIEW_SYS_LED1 (1 << 1) +#define REALVIEW_SYS_LED2 (1 << 2) +#define REALVIEW_SYS_LED3 (1 << 3) +#define REALVIEW_SYS_LED4 (1 << 4) +#define REALVIEW_SYS_LED5 (1 << 5) +#define REALVIEW_SYS_LED6 (1 << 6) +#define REALVIEW_SYS_LED7 (1 << 7) + +#define ALL_LEDS 0xFF + +#define LED_BANK REALVIEW_SYS_LED + +/* + * Control registers + */ +#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */ +#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */ +#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */ +#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ + +/* + * Clean base - dummy + * + */ +#define CLEAN_BASE REALVIEW_BOOT_ROM_HI + +/* + * System controller bit assignment + */ +#define REALVIEW_REFCLK 0 +#define REALVIEW_TIMCLK 1 + +#define REALVIEW_TIMER1_EnSel 15 +#define REALVIEW_TIMER2_EnSel 17 +#define REALVIEW_TIMER3_EnSel 19 +#define REALVIEW_TIMER4_EnSel 21 + +struct rt_hw_register +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; + unsigned long ORIG_r0; +}; + +#include +#include + +/* Interrupt Control Interface */ +#define ARM_GIC_CPU_BASE 0x1E000000 + +/* number of interrupts on board */ +#define ARM_GIC_NR_IRQS 96 +/* only one GIC available */ +#define ARM_GIC_MAX_NR 1 + +#endif + diff --git a/bsp/qemu-vexpress-a53/drivers/rt_lcd.h b/bsp/qemu-vexpress-a53/drivers/rt_lcd.h new file mode 100644 index 0000000000..e496a871da --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/rt_lcd.h @@ -0,0 +1,59 @@ +#ifndef RT_LCD_H__ +#define RT_LCD_H__ + + +/* ioctls + 0x46 is 'F' */ +#define FBIOGET_VSCREENINFO 0x4600 +#define FBIOPUT_VSCREENINFO 0x4601 +#define FBIOGET_FSCREENINFO 0x4602 +#define FBIOGETCMAP 0x4604 +#define FBIOPUTCMAP 0x4605 +#define FBIOPAN_DISPLAY 0x4606 +#define FBIO_CURSOR 0x4608 +/* #define FBIOGET_MONITORSPEC 0x460C */ +/* #define FBIOPUT_MONITORSPEC 0x460D */ +/* #define FBIOSWITCH_MONIBIT 0x460E */ +#define FBIOGET_CON2FBMAP 0x460F +#define FBIOPUT_CON2FBMAP 0x4610 +#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */ +#define FBIOGET_VBLANK 0x4612 +#define FBIO_ALLOC 0x4613 +#define FBIO_FREE 0x4614 +#define FBIOGET_GLYPH 0x4615 +#define FBIOGET_HWCINFO 0x4616 +#define FBIOPUT_MODEINFO 0x4617 +#define FBIOGET_DISPINFO 0x4618 +#define FBIO_WAITFORVSYNC 0x4620 + +struct fb_bitfield +{ + uint32_t offset; /* beginning of bitfield */ + uint32_t length; /* length of bitfield */ + uint32_t msb_right; /* != 0 : Most significant bit is */ + /* right */ +}; + +struct fb_var_screeninfo +{ + uint32_t xres; + uint32_t yres; + + uint32_t bits_per_pixel; + + struct fb_bitfield red; /* bitfield in fb mem if true color, */ + struct fb_bitfield green; /* else only length is significant */ + struct fb_bitfield blue; + struct fb_bitfield transp; /* transparency */ +}; + +struct fb_fix_screeninfo +{ + char id[16]; + unsigned long smem_start; + uint32_t smem_len; + + uint32_t line_length; +}; + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/secondary_cpu.c b/bsp/qemu-vexpress-a53/drivers/secondary_cpu.c new file mode 100644 index 0000000000..b455beb53a --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/secondary_cpu.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-22 Jesven first version + */ + +#include +#include +#include + +#include "board.h" +#include "gic.h" +#include "drv_timer.h" + +#ifdef RT_USING_SMP +#include + +#ifdef RT_USING_USERSPACE +#include +#endif + +static void rt_hw_timer2_isr(int vector, void *param) +{ + rt_tick_increase(); + /* clear interrupt */ + timer_clear_pending(0); +} + +void rt_hw_secondary_cpu_up(void) +{ + volatile void **plat_boot_reg = (volatile void **)0x10000034; + char *entry = (char *)rt_secondary_cpu_entry; + +#ifdef RT_USING_USERSPACE + plat_boot_reg = (volatile void **)rt_hw_mmu_map(&mmu_info, 0, (void *)plat_boot_reg, 0x1000, MMU_MAP_K_RW); + if (!plat_boot_reg) + { + /* failed */ + return; + } + entry += PV_OFFSET; +#endif + *plat_boot_reg-- = (void *)(size_t)-1; + *plat_boot_reg = (void *)entry; + rt_hw_dsb(); + rt_hw_ipi_send(0, 1 << 1); +} + +/* Interface */ +void rt_hw_secondary_cpu_bsp_start(void) +{ + rt_hw_vector_init(); + + rt_hw_spin_lock(&_cpus_lock); + + arm_gic_cpu_init(0, 0); + arm_gic_set_cpu(0, IRQ_PBA8_TIMER0_1, 0x2); + + timer_init(0, 10000); + rt_hw_interrupt_install(IRQ_PBA8_TIMER0_1, rt_hw_timer2_isr, RT_NULL, "tick"); + rt_hw_interrupt_umask(IRQ_PBA8_TIMER0_1); + + rt_system_scheduler_start(); +} + +void rt_hw_secondary_cpu_idle_exec(void) +{ + asm volatile ("wfe":::"memory", "cc"); +} + +#endif diff --git a/bsp/qemu-vexpress-a53/drivers/serial.c b/bsp/qemu-vexpress-a53/drivers/serial.c new file mode 100644 index 0000000000..bf54cee6e3 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/serial.c @@ -0,0 +1,187 @@ +/* + * serial.c UART driver + * + * COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd + * + * This file is part of RT-Thread (http://www.rt-thread.org) + * Maintainer: bernard.xiong + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-03-30 Bernard the first verion + */ + +#include +#include + +#include "serial.h" +#include "board.h" +#include "mmu.h" + +struct hw_uart_device +{ + rt_size_t hw_base; + rt_size_t irqno; +}; + +#define UART_DR(base) __REG32(base + 0x00) +#define UART_FR(base) __REG32(base + 0x18) +#define UART_CR(base) __REG32(base + 0x30) +#define UART_IMSC(base) __REG32(base + 0x38) +#define UART_ICR(base) __REG32(base + 0x44) + +#define UARTFR_RXFE 0x10 +#define UARTFR_TXFF 0x20 +#define UARTIMSC_RXIM 0x10 +#define UARTIMSC_TXIM 0x20 +#define UARTICR_RXIC 0x10 +#define UARTICR_TXIC 0x20 + +static void rt_hw_uart_isr(int irqno, void *param) +{ + struct rt_serial_device *serial = (struct rt_serial_device *)param; + + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); +} + +static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + return RT_EOK; +} + +static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM; + break; + + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM; + rt_hw_interrupt_umask(uart->irqno); + break; + } + + return RT_EOK; +} + +static int uart_putc(struct rt_serial_device *serial, char c) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + while (UART_FR(uart->hw_base) & UARTFR_TXFF); + UART_DR(uart->hw_base) = c; + + return 1; +} + +static int uart_getc(struct rt_serial_device *serial) +{ + int ch; + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + ch = -1; + if (!(UART_FR(uart->hw_base) & UARTFR_RXFE)) + { + ch = UART_DR(uart->hw_base) & 0xff; + } + + return ch; +} + +static const struct rt_uart_ops _uart_ops = +{ + uart_configure, + uart_control, + uart_putc, + uart_getc, +}; + +#ifdef RT_USING_UART0 +/* UART device driver structure */ +static struct hw_uart_device _uart0_device = +{ + REALVIEW_UART0_BASE, + IRQ_PBA8_UART0, +}; +static struct rt_serial_device _serial0; +#endif + +#ifdef RT_USING_UART1 +/* UART1 device driver structure */ +static struct hw_uart_device _uart1_device = +{ + REALVIEW_UART1_BASE, + IRQ_PBA8_UART1, +}; +static struct rt_serial_device _serial1; +#endif + +int rt_hw_uart_init(void) +{ + struct hw_uart_device *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + +#ifdef RT_USING_UART0 + _uart0_device.hw_base = (rt_size_t)rt_ioremap((void*)_uart0_device.hw_base, 0x1000); + uart = &_uart0_device; + + _serial0.ops = &_uart_ops; + _serial0.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&_serial0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0"); + /* enable Rx and Tx of UART */ + UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); +#endif + +#ifdef RT_USING_UART1 + _uart1_device.hw_base = (rt_size_t)rt_ioremap((void*)_uart1_device.hw_base, 0x1000); + uart = &_uart1_device; + _serial1.ops = &_uart_ops; + _serial1.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&_serial1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); + /* enable Rx and Tx of UART */ + UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial1, "uart1"); +#endif + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_uart_init); diff --git a/bsp/qemu-vexpress-a53/drivers/serial.h b/bsp/qemu-vexpress-a53/drivers/serial.h new file mode 100644 index 0000000000..52e6f07ea3 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/serial.h @@ -0,0 +1,39 @@ +/* + * UART driver + * + * COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd + * + * This file is part of RT-Thread (http://www.rt-thread.org) + * Maintainer: bernard.xiong + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-03-30 Bernard the first verion + */ + +#ifndef __UART_H__ +#define __UART_H__ + +#include + +int rt_hw_uart_init(void); + +#endif + + diff --git a/bsp/qemu-vexpress-a53/drivers/vexpress_a9.h b/bsp/qemu-vexpress-a53/drivers/vexpress_a9.h new file mode 100644 index 0000000000..86ab590932 --- /dev/null +++ b/bsp/qemu-vexpress-a53/drivers/vexpress_a9.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-03-22 quanzhao first version + */ + +#ifndef __VEXPRESS_A9_H__ +#define __VEXPRESS_A9_H__ + +/* for 'rt_inline' */ +#include +/* SOC-relative definitions */ +#include "realview.h" + +/* the maximum entries of the exception table */ +#define MAX_HANDLERS NR_IRQS_PBA8 + +/* the basic constants and interfaces needed by gic */ +rt_inline rt_uint64_t platform_get_gic_dist_base(void) +{ + return REALVIEW_GIC_DIST_BASE; +} + +rt_inline rt_uint64_t platform_get_gic_cpu_base(void) +{ + return REALVIEW_GIC_CPU_BASE; +} + +#define GIC_IRQ_START 0 + +#define GIC_ACK_INTID_MASK 0x000003ff + +#endif /* __VEXPRESS_A9_H__ */ diff --git a/bsp/qemu-vexpress-a53/link.lds b/bsp/qemu-vexpress-a53/link.lds new file mode 100644 index 0000000000..d21ab041db --- /dev/null +++ b/bsp/qemu-vexpress-a53/link.lds @@ -0,0 +1,109 @@ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +SECTIONS +{ + /*. = 0x60080000; */ + . = 0xffff000000080000; + + __text_start = .; + .text : + { + KEEP(*(.text.entrypoint)) + KEEP(*(.vectors)) + *(.text) + *(.text.*) + + /* section information for utest */ + . = ALIGN(4); + __rt_utest_tc_tab_start = .; + KEEP(*(UtestTcTab)) + __rt_utest_tc_tab_end = .; + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* section information for initialization */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + } =0 + __text_end = .; + + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } + + __rodata_start = .; + .rodata : { *(.rodata) *(.rodata.*) } + __rodata_end = .; + + . = ALIGN(4); + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } + + . = ALIGN(8); + __data_start = .; + .data : + { + *(.data) + *(.data.*) + } + __data_end = .; + + . = ALIGN(8); + __bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + } + . = ALIGN(4); + __bss_end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + __data_size = SIZEOF(.data); + __bss_size = SIZEOF(.bss); + + _end = .; +} diff --git a/bsp/qemu-vexpress-a53/makefile.targets b/bsp/qemu-vexpress-a53/makefile.targets new file mode 100644 index 0000000000..a00129bd90 --- /dev/null +++ b/bsp/qemu-vexpress-a53/makefile.targets @@ -0,0 +1,4 @@ +clean2: + -$(RM) $(CC_DEPS)$(C++_DEPS)$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS) + -$(RM) $(OBJS) *.elf + -@echo ' ' \ No newline at end of file diff --git a/bsp/qemu-vexpress-a53/qemu-dbg.sh b/bsp/qemu-vexpress-a53/qemu-dbg.sh new file mode 100755 index 0000000000..3c79dfe607 --- /dev/null +++ b/bsp/qemu-vexpress-a53/qemu-dbg.sh @@ -0,0 +1,6 @@ +if [ ! -f "sd.bin" ]; then +dd if=/dev/zero of=sd.bin bs=1024 count=65536 +fi + +qemu-system-aarch64 -cpu cortex-a53 -M vexpress-a9 -kernel rtthread.bin -nographic -sd sd.bin -S -s + diff --git a/bsp/qemu-vexpress-a53/qemu-nographic.sh b/bsp/qemu-vexpress-a53/qemu-nographic.sh new file mode 100755 index 0000000000..9eda5342ca --- /dev/null +++ b/bsp/qemu-vexpress-a53/qemu-nographic.sh @@ -0,0 +1,5 @@ +if [ ! -f "sd.bin" ]; then +dd if=/dev/zero of=sd.bin bs=1024 count=65536 +fi + +qemu-system-aarch64 -cpu cortex-a53 -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -nographic -sd sd.bin diff --git a/bsp/qemu-vexpress-a53/qemu.sh b/bsp/qemu-vexpress-a53/qemu.sh new file mode 100755 index 0000000000..f97c57cad2 --- /dev/null +++ b/bsp/qemu-vexpress-a53/qemu.sh @@ -0,0 +1,5 @@ +if [ ! -f "sd.bin" ]; then +dd if=/dev/zero of=sd.bin bs=1024 count=65536 +fi + +qemu-system-aarch64 -cpu cortex-a53 -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -serial stdio -sd sd.bin diff --git a/bsp/qemu-vexpress-a53/rtconfig.h b/bsp/qemu-vexpress-a53/rtconfig.h new file mode 100644 index 0000000000..c23bd4a36e --- /dev/null +++ b/bsp/qemu-vexpress-a53/rtconfig.h @@ -0,0 +1,292 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_USING_SMART +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 8192 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 8192 +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE +#define RT_USING_SIGNALS + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +#define RT_USING_SMALL_MEM +#define RT_USING_MEMTRACE +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_DEVICE_OPS +#define RT_USING_INTERRUPT_INFO +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart0" +#define RT_VER_NUM 0x50000 +#define ARCH_CPU_64BIT +#define RT_USING_CACHE +#define ARCH_ARM_MMU +#define RT_USING_USERSPACE +#define KERNEL_VADDR_START 0xffff000000000000 +#define PV_OFFSET 0x1000060000000 +#define ARCH_ARMV8 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 8192 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + + +/* Command shell */ + +#define RT_USING_FINSH +#define RT_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 10 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 256 +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 8 +#define DFS_FD_MAX 32 +#define RT_USING_DFS_ELMFAT + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +#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_MAX_LFN 255 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 +#define RT_DFS_ELM_REENTRANT +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_ROMFS +#define RT_USING_DFS_RAMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 256 +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS +#define RT_USING_PIN +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_MTD_NOR +#define RT_USING_MTD_NAND +#define RT_MTD_NAND_DEBUG +#define RT_USING_RTC +#define RT_USING_SOFT_RTC +#define RT_USING_SDIO +#define RT_SDIO_STACK_SIZE 512 +#define RT_SDIO_THREAD_PRIORITY 15 +#define RT_MMCSD_STACK_SIZE 8192 +#define RT_MMCSD_THREAD_PREORITY 22 +#define RT_MMCSD_MAX_PARTITION 16 +#define RT_USING_SPI +#define RT_USING_SPI_MSD +#define RT_USING_SFUD +#define RT_SFUD_USING_SFDP +#define RT_SFUD_USING_FLASH_INFO_TABLE +#define RT_SFUD_SPI_MAX_HZ 50000000 +#define RT_USING_WDT + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_MUSL +#define RT_USING_POSIX +#define RT_USING_POSIX_MMAP +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_USING_POSIX_CLOCKTIME + +/* Network */ + +/* Socket abstraction layer */ + +#define RT_USING_SAL + +/* protocol stack implement */ + +#define SAL_USING_LWIP +#define SAL_USING_POSIX + +/* 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_LWIP202 +#define RT_LWIP_MEM_ALIGNMENT 4 +#define RT_LWIP_IGMP +#define RT_LWIP_ICMP +#define RT_LWIP_DNS + +/* Static IPv4 Address */ + +#define RT_LWIP_IPADDR "10.0.2.100" +#define RT_LWIP_GWADDR "10.0.2.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 8192 +#define RT_LWIP_ETHTHREAD_PRIORITY 12 +#define RT_LWIP_ETHTHREAD_STACKSIZE 8192 +#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 */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define RT_LWP_SHM_MAX_NR 64 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + + +/* games: games run on RT-Thread console */ + + +/* Privated Packages of RealThread */ + + +/* Network Utilities */ + +#define SOC_VEXPRESS_A53 +#define RT_USING_UART0 +#define RT_USING_UART1 +#define BSP_DRV_CLCD +#define BSP_LCD_WIDTH 640 +#define BSP_LCD_HEIGHT 480 +#define BSP_DRV_EMAC + +#endif diff --git a/bsp/qemu-vexpress-a53/rtconfig.py b/bsp/qemu-vexpress-a53/rtconfig.py new file mode 100644 index 0000000000..431d06a14a --- /dev/null +++ b/bsp/qemu-vexpress-a53/rtconfig.py @@ -0,0 +1,70 @@ +import os + +import uuid +def get_mac_address(): + mac=uuid.UUID(int = uuid.getnode()).hex[-12:] + return "#define AUTOMAC".join([str(int(e/2) + 1) + ' 0x' + mac[e:e+2] + '\n' for e in range(5,11,2)]) + +header = ''' +#ifndef __MAC_AUTO_GENERATE_H__ +#define __MAC_AUTO_GENERATE_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* mac configure file for RT-Thread qemu */ + +#define AUTOMAC0 0x52 +#define AUTOMAC1 0x54 +#define AUTOMAC2 0x00 +#define AUTOMAC''' + +end = ''' +#endif +''' + +automac_h_fn = os.path.join(os.path.dirname(__file__), 'drivers', 'automac.h') +with open(automac_h_fn, 'w') as f: + f.write(header + get_mac_address() + end) + +# toolchains options +ARCH ='aarch64' +CPU ='cortex-a' +CROSS_TOOL = 'gcc' +PLATFORM = 'gcc' +EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin' +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = os.getenv('RTT_CC_PREFIX') or 'arm-none-eabi-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + STRIP = PREFIX + 'strip' + CFPFLAGS = ' ' + AFPFLAGS = ' ' + DEVICE = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' + + CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall' + CFLAGS = DEVICE + CFPFLAGS + ' -Wall -std=gnu99' + AFLAGS = ' -c' + AFPFLAGS + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc' + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + CXXFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -Os' + CXXFLAGS += ' -Os' + CXXFLAGS += ' -Woverloaded-virtual -fno-exceptions -fno-rtti' + +DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c index 3da827f526..b57edb0e5c 100644 --- a/components/dfs/src/dfs.c +++ b/components/dfs/src/dfs.c @@ -814,17 +814,17 @@ static int lsofp(int pid) else if (fd->fnode->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device"); else rt_kprintf("%-8.8s ", "unknown"); rt_kprintf("%6d ", fd->fnode->ref_count); - rt_kprintf("%04x 0x%.8x ", fd->magic, (int)fd->fnode); + rt_kprintf("%04x 0x%.8x ", fd->magic, (int)(size_t)fd->fnode); if(fd->fnode == RT_NULL) { - rt_kprintf("0x%.8x 0x%.8x ", (int)0x00000000, (int)fd); + rt_kprintf("0x%.8x 0x%.8x ", (int)0x00000000, (int)(size_t)fd); } else { - rt_kprintf("0x%.8x 0x%.8x ", (int)(fd->fnode->data), (int)fd); + rt_kprintf("0x%.8x 0x%.8x ", (int)(size_t)(fd->fnode->data), (int)(size_t)fd); } - + if (fd->fnode->path) { rt_kprintf("%s \n", fd->fnode->path); diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c index 3b3405af92..276d7219d3 100644 --- a/components/drivers/serial/serial.c +++ b/components/drivers/serial/serial.c @@ -1122,7 +1122,7 @@ static rt_err_t rt_serial_control(struct rt_device *dev, break; case TCFLSH: { - int queue = (int)args; + int queue = (int)(size_t)args; _tc_flush(serial, queue); } diff --git a/components/libc/aio/posix_aio.c b/components/libc/aio/posix_aio.c index 3eb7634495..8894f817c0 100644 --- a/components/libc/aio/posix_aio.c +++ b/components/libc/aio/posix_aio.c @@ -457,7 +457,7 @@ int lio_listio(int mode, struct aiocb * const list[], int nent, int aio_system_init(void) { - aio_queue = rt_workqueue_create("aio", 2048, RT_THREAD_PRIORITY_MAX/2); + aio_queue = rt_workqueue_create("aio", 8192, RT_THREAD_PRIORITY_MAX/2); RT_ASSERT(aio_queue != NULL); return 0; diff --git a/components/libc/termios/posix_termios.c b/components/libc/termios/posix_termios.c index 9c736c3184..7051ac54c2 100644 --- a/components/libc/termios/posix_termios.c +++ b/components/libc/termios/posix_termios.c @@ -95,12 +95,12 @@ int tcsendbreak(int fd, int dur) int tcflush(int fd, int queue) { - return ioctl(fd, TCFLSH, (void*)queue); + return ioctl(fd, TCFLSH, (void*)(size_t)queue); } int tcflow(int fd, int action) { - return ioctl(fd, TCXONC, (void*)action); + return ioctl(fd, TCXONC, (void*)(size_t)action); } /** diff --git a/components/lwp/SConscript b/components/lwp/SConscript index 40f0ce7842..ddf585aa5f 100644 --- a/components/lwp/SConscript +++ b/components/lwp/SConscript @@ -5,7 +5,7 @@ cwd = GetCurrentDir() src = [] CPPPATH = [cwd] -support_arch = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7", "arm926", "cortex-a"],"risc-v": ["virt64"]} +support_arch = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7", "arm926", "cortex-a"],"aarch64":["cortex-a"],"risc-v": ["virt64"]} platform_file = {'armcc': 'rvds.S', 'gcc': 'gcc.S', 'iar': 'iar.S'} if GetDepend('LWP_UNIX98_PTY'): diff --git a/components/lwp/arch/aarch64/common/reloc.c b/components/lwp/arch/aarch64/common/reloc.c new file mode 100644 index 0000000000..2ad00c9d01 --- /dev/null +++ b/components/lwp/arch/aarch64/common/reloc.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#ifdef RT_USING_USERSPACE +#include +#include +#endif + +#define Elf_Word Elf64_Word +#define Elf_Addr Elf64_Addr +#define Elf_Half Elf64_Half +#define Elf_Ehdr Elf64_Ehdr #define Elf_Phdr Elf64_Phdr +#define Elf_Shdr Elf64_Shdr + +typedef struct +{ + Elf_Word st_name; + Elf_Addr st_value; + Elf_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf_Half st_shndx; +} Elf_sym; + +void lwp_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf_sym *dynsym) +{ +} diff --git a/components/lwp/arch/aarch64/cortex-a/arch_user_space_init.c b/components/lwp/arch/aarch64/cortex-a/arch_user_space_init.c new file mode 100644 index 0000000000..a8e2ce93d4 --- /dev/null +++ b/components/lwp/arch/aarch64/cortex-a/arch_user_space_init.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven first version + */ + +#include +#include + +#ifdef RT_USING_USERSPACE + +#include +#include +#include +#include +#include + +extern size_t MMUTable[]; + +int arch_user_space_init(struct rt_lwp *lwp) +{ + size_t *mmu_table; + + mmu_table = (size_t*)rt_pages_alloc(0); + if (!mmu_table) + { + return -1; + } + + lwp->end_heap = USER_HEAP_VADDR; + memset(mmu_table, 0, ARCH_PAGE_SIZE); + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE); + rt_hw_mmu_map_init(&lwp->mmu_info, (void*)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table, PV_OFFSET); + + return 0; +} + +void *arch_kernel_mmu_table_get(void) +{ + return (void*)NULL; +} + +void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors) +{ +} + +void arch_user_space_vtable_free(struct rt_lwp *lwp) +{ + if (lwp && lwp->mmu_info.vtable) + { + rt_pages_free(lwp->mmu_info.vtable, 0); + } +} +#endif diff --git a/components/lwp/arch/aarch64/cortex-a/arch_user_stack.c b/components/lwp/arch/aarch64/cortex-a/arch_user_stack.c new file mode 100644 index 0000000000..767e75292c --- /dev/null +++ b/components/lwp/arch/aarch64/cortex-a/arch_user_stack.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-11-18 Jesven first version + */ + +#include +#include + +#ifdef RT_USING_USERSPACE + +#include +#include +#include +#include +#include + +int arch_expand_user_stack(void *addr) +{ + int ret = 0; + size_t stack_addr = (size_t)addr; + + stack_addr &= ~ARCH_PAGE_MASK; + if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND)) + { + void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0); + + if (map || lwp_user_accessable(addr, 1)) + { + ret = 1; + } + } + return ret; +} +#endif diff --git a/components/lwp/arch/aarch64/cortex-a/lwp_arch.h b/components/lwp/arch/aarch64/cortex-a/lwp_arch.h new file mode 100644 index 0000000000..06e3cfd77a --- /dev/null +++ b/components/lwp/arch/aarch64/cortex-a/lwp_arch.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven first version + */ + +#ifndef LWP_ARCH_H__ +#define LWP_ARCH_H__ + +#include + +#ifdef RT_USING_USERSPACE + +#define USER_VADDR_TOP 0x0001000000000000UL +#define USER_HEAP_VEND 0x0000ffffB0000000UL +#define USER_HEAP_VADDR 0x0000ffff80000000UL +#define USER_STACK_VSTART 0x0000ffff70000000UL +#define USER_STACK_VEND USER_HEAP_VADDR +#define LDSO_LOAD_VADDR 0x60000000UL +#define USER_VADDR_START 0x00200000UL +#define USER_LOAD_VADDR USER_VADDR_START + +#ifdef __cplusplus +extern "C" { +#endif + +int arch_user_space_init(struct rt_lwp *lwp); +void arch_user_space_vtable_free(struct rt_lwp *lwp); +void *arch_kernel_mmu_table_get(void); +void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors); +int arch_expand_user_stack(void *addr); + +unsigned long ffz(unsigned long x); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /*LWP_ARCH_H__*/ diff --git a/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S b/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S new file mode 100644 index 0000000000..32425d4141 --- /dev/null +++ b/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven first version + */ + +#include "rtconfig.h" + +#include "asm-fpu.h" + +/********************* + * SPSR BIT * + *********************/ + +#define SPSR_Mode(v) ((v) << 0) +#define SPSR_A64 (0 << 4) +#define SPSR_RESEVRED_5 (0 << 5) +#define SPSR_FIQ_MASKED(v) ((v) << 6) +#define SPSR_IRQ_MASKED(v) ((v) << 7) +#define SPSR_SERROR_MASKED(v) ((v) << 8) +#define SPSR_D_MASKED(v) ((v) << 9) +#define SPSR_RESEVRED_10_19 (0 << 10) +#define SPSR_IL(v) ((v) << 20) +#define SPSR_SS(v) ((v) << 21) +#define SPSR_RESEVRED_22_27 (0 << 22) +#define SPSR_V(v) ((v) << 28) +#define SPSR_C(v) ((v) << 29) +#define SPSR_Z(v) ((v) << 30) +#define SPSR_N(v) ((v) << 31) + +/********************* + * CONTEXT_OFFSET * + *********************/ + +#define CONTEXT_OFFSET_ELR_EL1 0x0 +#define CONTEXT_OFFSET_SPSR_EL1 0x8 +#define CONTEXT_OFFSET_SP_EL0 0x10 +#define CONTEXT_OFFSET_X30 0x18 +#define CONTEXT_OFFSET_FPCR 0x20 +#define CONTEXT_OFFSET_FPSR 0x28 +#define CONTEXT_OFFSET_X28 0x30 +#define CONTEXT_OFFSET_X29 0x38 +#define CONTEXT_OFFSET_X26 0x40 +#define CONTEXT_OFFSET_X27 0x48 +#define CONTEXT_OFFSET_X24 0x50 +#define CONTEXT_OFFSET_X25 0x58 +#define CONTEXT_OFFSET_X22 0x60 +#define CONTEXT_OFFSET_X23 0x68 +#define CONTEXT_OFFSET_X20 0x70 +#define CONTEXT_OFFSET_X21 0x78 +#define CONTEXT_OFFSET_X18 0x80 +#define CONTEXT_OFFSET_X19 0x88 +#define CONTEXT_OFFSET_X16 0x90 +#define CONTEXT_OFFSET_X17 0x98 +#define CONTEXT_OFFSET_X14 0xa0 +#define CONTEXT_OFFSET_X15 0xa8 +#define CONTEXT_OFFSET_X12 0xb0 +#define CONTEXT_OFFSET_X13 0xb8 +#define CONTEXT_OFFSET_X10 0xc0 +#define CONTEXT_OFFSET_X11 0xc8 +#define CONTEXT_OFFSET_X8 0xd0 +#define CONTEXT_OFFSET_X9 0xd8 +#define CONTEXT_OFFSET_X6 0xe0 +#define CONTEXT_OFFSET_X7 0xe8 +#define CONTEXT_OFFSET_X4 0xf0 +#define CONTEXT_OFFSET_X5 0xf8 +#define CONTEXT_OFFSET_X2 0x100 +#define CONTEXT_OFFSET_X3 0x108 +#define CONTEXT_OFFSET_X0 0x110 +#define CONTEXT_OFFSET_X1 0x118 + +#define CONTEXT_OFFSET_Q15 0x120 +#define CONTEXT_OFFSET_Q14 0x130 +#define CONTEXT_OFFSET_Q13 0x140 +#define CONTEXT_OFFSET_Q12 0x150 +#define CONTEXT_OFFSET_Q11 0x160 +#define CONTEXT_OFFSET_Q10 0x170 +#define CONTEXT_OFFSET_Q9 0x180 +#define CONTEXT_OFFSET_Q8 0x190 +#define CONTEXT_OFFSET_Q7 0x1a0 +#define CONTEXT_OFFSET_Q6 0x1b0 +#define CONTEXT_OFFSET_Q5 0x1c0 +#define CONTEXT_OFFSET_Q4 0x1d0 +#define CONTEXT_OFFSET_Q3 0x1e0 +#define CONTEXT_OFFSET_Q2 0x1f0 +#define CONTEXT_OFFSET_Q1 0x200 +#define CONTEXT_OFFSET_Q0 0x210 + +#define CONTEXT_FPU_SIZE 0x100 +#define CONTEXT_SIZE 0x220 + +/**************************************************/ + +.text + +/* + * void lwp_user_entry(args, text, data, kstack); + */ +.global lwp_user_entry +.type lwp_user_entry, % function +lwp_user_entry: + mov sp, x3 + mov x4, #(SPSR_Mode(0) | SPSR_A64) + ldr x3, =0x0000ffff80000000 + msr daifset, #3 + dsb sy + mrs x30, sp_el0 + msr spsr_el1, x4 + msr elr_el1, x1 + eret + +.global set_user_context +set_user_context: + sub x2, x0, #0x10 + adr x0, lwp_thread_return + ldr x1, [x0] + str x1, [x2] + ldr x1, [x0, #4] + str x1, [x2, #4] + ldr x1, [x0, #8] + str x1, [x2, #8] + ic ialluis + dsb sy + msr sp_el0, x2 + ret +/* +void lwp_set_thread_context(void *exit_addr, void *new_thread_stack, void *user_stack, void **thread_sp); +*/ +.global lwp_set_thread_context +lwp_set_thread_context: + sub x1, x1, #CONTEXT_SIZE + str x2, [x1, #CONTEXT_OFFSET_SP_EL0] + sub x1, x1, #CONTEXT_SIZE + str xzr, [x1, #CONTEXT_OFFSET_X0] /* new thread return 0 */ + mov x4, #((3 << 6) | 0x4 | 0x1) /* el1h, disable interrupt */ + str x4, [x1, #CONTEXT_OFFSET_SPSR_EL1] + str x0, [x1, #CONTEXT_OFFSET_ELR_EL1] + str x1, [x3] + ret + +.global lwp_get_user_sp +lwp_get_user_sp: + mrs x0, sp_el0 + ret + +.global sys_fork +.global sys_vfork +.global sys_fork_exit +sys_fork: +sys_vfork: + bl _sys_fork +sys_fork_exit: + b svc_exit + +.global sys_clone +.global sys_clone_exit +sys_clone: + bl _sys_clone +sys_clone_exit: + b svc_exit + +/* +void lwp_exec_user(void *args, void *kernel_stack, void *user_entry) +*/ +.global lwp_exec_user +lwp_exec_user: + mov sp, x1 + mov x4, #(SPSR_Mode(0) | SPSR_A64) + ldr x3, =0x0000ffff80000000 + msr daifset, #3 + msr spsr_el1, x4 + msr elr_el1, x2 + eret + +/* + * void SVC_Handler(regs); + */ +.global SVC_Handler +.type SVC_Handler, % function +SVC_Handler: + /* x0 is initial sp */ + mov sp, x0 + + msr daifclr, #3 /* enable interrupt */ + + bl rt_thread_self + bl lwp_user_setting_save + + ldp x8, x9, [sp, #(CONTEXT_OFFSET_X8)] + uxtb x0, w8 + cmp x0, #0xfe + beq lwp_signal_quit + bl lwp_get_sys_api + cmp x0, xzr + mov x30, x0 + beq svc_exit + ldp x0, x1, [sp, #(CONTEXT_OFFSET_X0)] + ldp x2, x3, [sp, #(CONTEXT_OFFSET_X2)] + ldp x4, x5, [sp, #(CONTEXT_OFFSET_X4)] + ldp x6, x7, [sp, #(CONTEXT_OFFSET_X6)] + blr x30 +svc_exit: + msr daifset, #3 + + ldp x2, x3, [sp], #0x10 /* SPSR and ELR. */ + msr spsr_el1, x3 + msr elr_el1, x2 + + ldp x29, x30, [sp], #0x10 + msr sp_el0, x29 + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + add sp, sp, #0x40 + RESTORE_FPU sp + +.global ret_to_user +ret_to_user: + SAVE_FPU sp + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x4, x5, [sp, #-0x10]! + stp x6, x7, [sp, #-0x10]! + stp x8, x9, [sp, #-0x10]! + mrs x0, fpcr + mrs x1, fpsr + stp x0, x1, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + + bl lwp_signal_check + cmp x0, xzr + + ldp x29, x30, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + msr fpcr, x0 + msr fpsr, x1 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp + + bne user_do_signal + eret + +.global lwp_check_exit +lwp_check_exit: + SAVE_FPU sp + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x4, x5, [sp, #-0x10]! + stp x6, x7, [sp, #-0x10]! + mrs x0, fpcr + mrs x1, fpsr + stp x0, x1, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + + bl lwp_check_exit_request + cmp x0, xzr + bne 1f + ldp x29, x30, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + msr fpcr, x0 + msr fpsr, x1 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp + + br x30 +1: + mov x0, xzr + b sys_exit + +lwp_signal_quit: + msr daifset, #3 +/* + drop stack data +*/ + add sp, sp, #CONTEXT_SIZE + bl lwp_signal_restore + /* x0 is user_ctx : ori sp, pc, cpsr */ + ldr x1, [x0] + ldr x2, [x0, #8] + ldr x3, [x0, #10] + msr spsr_el1, x3 + msr elr_el1, x2 + msr sp_el0, x1 + + msr spsel, #0 + + ldp x29, x30, [sp], #0x10 + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp + + msr spsel, #1 + + b ret_to_user + +user_do_signal: + msr spsel, #0 + SAVE_FPU sp + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x4, x5, [sp, #-0x10]! + stp x6, x7, [sp, #-0x10]! + stp x8, x9, [sp, #-0x10]! + stp x10, x11, [sp, #-0x10]! + stp x12, x13, [sp, #-0x10]! + stp x14, x15, [sp, #-0x10]! + stp x16, x17, [sp, #-0x10]! + stp x18, x19, [sp, #-0x10]! + stp x20, x21, [sp, #-0x10]! + stp x22, x23, [sp, #-0x10]! + stp x24, x25, [sp, #-0x10]! + stp x26, x27, [sp, #-0x10]! + stp x28, x29, [sp, #-0x10]! + mrs x28, fpcr + mrs x29, fpsr + stp x28, x29, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + + sub sp, sp, #0x10 + adr x0, lwp_sigreturn + ldr w1, [x0] + str w1, [sp] + ldr w1, [x0, #4] + str w1, [sp, #4] + ic ialluis + dsb sy + + mov x9, sp + add x0, sp, #0x10 /* lwp_sigreturn */ + + msr spsel, #1 + + mrs x1, elr_el1 + mrs x2, spsr_el1 + bl lwp_signal_backup + /* x0 is signal */ + mov x8, x0 + bl lwp_sighandler_get + adds x1, x0, xzr + mov x0, x8 + bne 1f + mov x1, x9 +1: + msr elr_el1, x1 + mov x30, x9 + eret + +lwp_sigreturn: + mov x8, #0xfe + svc #0 + +lwp_thread_return: + mov x0, xzr + mov x8, #0x01 + svc #0 + +.globl rt_cpu_get_thread_idr +rt_cpu_get_thread_idr: + mrs x0, tpidr_el0 + ret + +.global lwp_set_thread_area +lwp_set_thread_area: +.globl rt_cpu_set_thread_idr +rt_cpu_set_thread_idr: + msr tpidr_el0, x0 + ret diff --git a/components/lwp/arch/arm/cortex-a/arch_user_space_init.c b/components/lwp/arch/arm/cortex-a/arch_user_space_init.c index cf6c518056..5577f6a6c9 100644 --- a/components/lwp/arch/arm/cortex-a/arch_user_space_init.c +++ b/components/lwp/arch/arm/cortex-a/arch_user_space_init.c @@ -35,7 +35,7 @@ int arch_user_space_init(struct rt_lwp *lwp) memcpy(mmu_table + (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT), MMUTable + (KERNEL_VADDR_START >> ARCH_SECTION_SHIFT), ARCH_PAGE_SIZE); memset(mmu_table, 0, 3 * ARCH_PAGE_SIZE); rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, 4 * ARCH_PAGE_SIZE); - rt_hw_mmu_map_init(&lwp->mmu_info, (void*)USER_VADDR_START, KERNEL_VADDR_START - USER_VADDR_START, mmu_table, PV_OFFSET); + rt_hw_mmu_map_init(&lwp->mmu_info, (void*)USER_VADDR_START, USER_VADDR_TOP - USER_VADDR_START, mmu_table, PV_OFFSET); return 0; } diff --git a/components/lwp/arch/arm/cortex-a/lwp_arch.h b/components/lwp/arch/arm/cortex-a/lwp_arch.h index 0757b9e58c..efae56651c 100644 --- a/components/lwp/arch/arm/cortex-a/lwp_arch.h +++ b/components/lwp/arch/arm/cortex-a/lwp_arch.h @@ -14,6 +14,7 @@ #ifdef RT_USING_USERSPACE +#define USER_VADDR_TOP 0xC0000000UL #define USER_HEAP_VEND 0xB0000000UL #define USER_HEAP_VADDR 0x80000000UL #define USER_STACK_VSTART 0x70000000UL diff --git a/components/lwp/arch/arm/cortex-a/lwp_gcc.S b/components/lwp/arch/arm/cortex-a/lwp_gcc.S index 452adb7c94..2c0d78abc1 100644 --- a/components/lwp/arch/arm/cortex-a/lwp_gcc.S +++ b/components/lwp/arch/arm/cortex-a/lwp_gcc.S @@ -134,8 +134,14 @@ vector_swi: push {lr} mrs lr, spsr push {r4, r5, lr} + cpsie i + push {r0 - r3, r12} + + bl rt_thread_self + bl lwp_user_setting_save + and r0, r7, #0xff cmp r0, #0xfe beq lwp_signal_quit @@ -146,6 +152,7 @@ vector_swi: bl lwp_get_sys_api cmp r0, #0 /* r0 = api */ mov lr, r0 + pop {r0 - r3, r12} beq svc_exit blx lr diff --git a/components/lwp/arch/risc-v/virt64/lwp_arch.h b/components/lwp/arch/risc-v/virt64/lwp_arch.h index f2142167b6..a0266c46d6 100644 --- a/components/lwp/arch/risc-v/virt64/lwp_arch.h +++ b/components/lwp/arch/risc-v/virt64/lwp_arch.h @@ -14,6 +14,7 @@ #ifdef RT_USING_USERSPACE +#define USER_VADDR_TOP 0x150000000UL #define USER_HEAP_VADDR 0x300000000UL #define USER_STACK_VSTART 0x270000000UL #define USER_STACK_VEND USER_HEAP_VADDR diff --git a/components/lwp/lwp.c b/components/lwp/lwp.c index 9bba06fd7c..fe4dc80665 100644 --- a/components/lwp/lwp.c +++ b/components/lwp/lwp.c @@ -64,21 +64,21 @@ uint32_t *lwp_get_kernel_sp(void) #ifdef RT_USING_USERSPACE struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char **envp) { - int size = sizeof(int) * 5; /* store argc, argv, envp, aux, NULL */ + int size = sizeof(size_t) * 5; /* store argc, argv, envp, aux, NULL */ int *args; char *str; char *str_k; char **new_argve; int i; int len; - int *args_k; + size_t *args_k; struct process_aux *aux; for (i = 0; i < argc; i++) { size += (rt_strlen(argv[i]) + 1); } - size += (sizeof(int) * argc); + size += (sizeof(size_t) * argc); i = 0; if (envp) @@ -86,7 +86,7 @@ struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char while (envp[i] != 0) { size += (rt_strlen(envp[i]) + 1); - size += sizeof(int); + size += sizeof(size_t); i++; } } @@ -100,18 +100,18 @@ struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char } /* args = (int *)lwp_map_user(lwp, 0, size); */ - args = (int *)lwp_map_user(lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE), size, 0); + args = (int *)lwp_map_user(lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE), size, 0); if (args == RT_NULL) { return RT_NULL; } - args_k = (int *)rt_hw_mmu_v2p(&lwp->mmu_info, args); - args_k = (int *)((size_t)args_k - PV_OFFSET); + args_k = (size_t *)rt_hw_mmu_v2p(&lwp->mmu_info, args); + args_k = (size_t *)((size_t)args_k - PV_OFFSET); /* argc, argv[], 0, envp[], 0 , aux[] */ - str = (char *)((size_t)args + (argc + 2 + i + 1 + AUX_ARRAY_ITEMS_NR * 2 + 1) * sizeof(int)); - str_k = (char *)((size_t)args_k + (argc + 2 + i + 1 + AUX_ARRAY_ITEMS_NR * 2 + 1) * sizeof(int)); + str = (char *)((size_t)args + (argc + 2 + i + 1 + AUX_ARRAY_ITEMS_NR * 2 + 1) * sizeof(size_t)); + str_k = (char *)((size_t)args_k + (argc + 2 + i + 1 + AUX_ARRAY_ITEMS_NR * 2 + 1) * sizeof(size_t)); new_argve = (char **)&args_k[1]; args_k[0] = argc; @@ -148,7 +148,7 @@ struct process_aux *lwp_argscopy(struct rt_lwp *lwp, int argc, char **argv, char /* aux */ aux = (struct process_aux *)(new_argve + i); aux->item[0].key = AT_EXECFN; - aux->item[0].value = (uint32_t)(size_t)new_argve[0]; + aux->item[0].value = (size_t)(size_t)new_argve[0]; i += AUX_ARRAY_ITEMS_NR * 2; new_argve[i] = 0; @@ -282,22 +282,6 @@ static size_t load_fread(void *ptr, size_t size, size_t nmemb, int fd) return read_block; } -#ifdef ARCH_CPU_64BIT -#define Elf_Word Elf64_Word -#define Elf_Addr Elf64_Addr -#define Elf_Half Elf64_Half -#define Elf_Ehdr Elf64_Ehdr -#define Elf_Phdr Elf64_Phdr -#define Elf_Shdr Elf64_Shdr -#else -#define Elf_Word Elf32_Word -#define Elf_Addr Elf32_Addr -#define Elf_Half Elf32_Half -#define Elf_Ehdr Elf32_Ehdr -#define Elf_Phdr Elf32_Phdr -#define Elf_Shdr Elf32_Shdr -#endif - typedef struct { Elf_Word st_name; @@ -526,7 +510,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str { return -RT_ERROR; } - va = (uint8_t *)lwp_map_user(lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE * 2), process_header_size, 0); + va = (uint8_t *)lwp_map_user(lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE * 2), process_header_size, 0); if (!va) { return -RT_ERROR; @@ -561,7 +545,7 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str #ifdef RT_USING_USERSPACE uint8_t *krandom; - random = (uint8_t *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE - sizeof(char[16])); + random = (uint8_t *)(USER_VADDR_TOP - ARCH_PAGE_SIZE - sizeof(char[16])); krandom = (uint8_t *)rt_hw_mmu_v2p(m_info, random); krandom = (uint8_t *)krandom - PV_OFFSET; @@ -570,13 +554,13 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str random = (uint8_t *)(process_header + process_header_size); rt_memcpy(random, &random_value, sizeof random_value); #endif - aux->item[2].value = (uint32_t)(size_t)random; + aux->item[2].value = (size_t)random; } aux->item[3].key = AT_PHDR; #ifdef RT_USING_USERSPACE - aux->item[3].value = (uint32_t)(size_t)va; + aux->item[3].value = (size_t)va; #else - aux->item[3].value = (uint32_t)(size_t)process_header; + aux->item[3].value = (size_t)process_header; #endif aux->item[4].key = AT_PHNUM; aux->item[4].value = eheader.e_phnum; @@ -1090,7 +1074,7 @@ pid_t lwp_execve(char *filename, int argc, char **argv, char **envp) if (result == 1) { /* dynmaic */ - lwp_unmap_user(lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE)); + lwp_unmap_user(lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE)); result = load_ldso(lwp, filename, argv, envp); } if (result == RT_EOK) @@ -1160,3 +1144,43 @@ pid_t exec(char *filename, int argc, char **argv) return lwp_execve(filename, argc, argv, 0); } #endif + +void lwp_user_setting_save(rt_thread_t thread) +{ + if (thread) + { + thread->thread_idr = rt_cpu_get_thread_idr(); + } +} + +void lwp_user_setting_restore(rt_thread_t thread) +{ + if (!thread) + { + return; + } + rt_cpu_set_thread_idr(thread->thread_idr); + +#ifdef RT_USING_GDBSERVER + { + struct rt_lwp *l = (struct rt_lwp *)thread->lwp; + + set_process_id((uint32_t)(size_t)l); + if (l && l->debug) + { + uint32_t step_type = 0; + + step_type = gdb_get_step_type(); + + if ((step_type == 2) || (thread->step_exec && (step_type == 1))) + { + arch_activate_step(); + } + else + { + arch_deactivate_step(); + } + } + } +#endif +} diff --git a/components/lwp/lwp.h b/components/lwp/lwp.h index 2b540e0899..f19faeb4dd 100644 --- a/components/lwp/lwp.h +++ b/components/lwp/lwp.h @@ -32,6 +32,7 @@ #include "mmu.h" #include "page.h" +#include "lwp_arch.h" #endif #ifdef __cplusplus @@ -129,6 +130,8 @@ size_t lwp_user_strlen(const char *s, int *err); #ifdef RT_USING_USERSPACE void lwp_mmu_switch(struct rt_thread *thread); #endif +void lwp_user_setting_save(rt_thread_t thread); +void lwp_user_setting_restore(rt_thread_t thread); #ifdef RT_USING_USERSPACE struct __pthread { @@ -222,8 +225,8 @@ struct __pthread { struct process_aux_item { - uint32_t key; - uint32_t value; + size_t key; + size_t value; }; struct process_aux diff --git a/components/lwp/lwp_elf.h b/components/lwp/lwp_elf.h index aae6c79d2e..e4817fe6f9 100644 --- a/components/lwp/lwp_elf.h +++ b/components/lwp/lwp_elf.h @@ -11,17 +11,37 @@ #define LWP_ELF_H__ #include +#include #ifdef __cplusplus extern "C" { #endif +#ifdef ARCH_CPU_64BIT +#define elfhdr elf64_hdr +#define elf_phdr elf64_phdr +#define elf_shdr elf64_shdr +#define elf_note elf64_note +#define elf_addr_t Elf64_Off +#define Elf_Word Elf64_Word +#define Elf_Addr Elf64_Addr +#define Elf_Half Elf64_Half +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Phdr Elf64_Phdr +#define Elf_Shdr Elf64_Shdr +#else #define elfhdr elf32_hdr #define elf_phdr elf32_phdr #define elf_shdr elf32_shdr #define elf_note elf32_note #define elf_addr_t Elf32_Off -#define Elf_Half Elf32_Half +#define Elf_Word Elf32_Word +#define Elf_Addr Elf32_Addr +#define Elf_Half Elf32_Half +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Phdr Elf32_Phdr +#define Elf_Shdr Elf32_Shdr +#endif /* Type for a 16-bit quantity. */ typedef uint16_t Elf32_Half; diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 33242ea5ba..d24c00aded 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -2126,7 +2126,7 @@ int sys_execve(const char *path, char *const argv[], char *const envp[]) if (ret == 1) { /* dynamic */ - lwp_unmap_user(new_lwp, (void *)(KERNEL_VADDR_START - ARCH_PAGE_SIZE)); + lwp_unmap_user(new_lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE)); ret = load_ldso(new_lwp, (char *)path, args_info.argv, args_info.envp); } if (ret == RT_EOK) diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c index dff16c5bd7..72626d5e82 100644 --- a/components/lwp/lwp_user_mm.c +++ b/components/lwp/lwp_user_mm.c @@ -43,22 +43,6 @@ void lwp_mmu_switch(struct rt_thread *thread) { l = (struct rt_lwp *)thread->lwp; new_mmu_table = (void *)((char *)l->mmu_info.vtable + l->mmu_info.pv_off); -#ifdef LWP_DEBUG - { - int i = 0; - size_t *p = l->mmu_info.vtable; - - rt_kprintf("vtable = 0x%p\n", l->mmu_info.vtable); - for (i = 0; i < 0x1000; i++) - { - rt_kprintf("0x%08x ", *p++); - if ((i & 0xf) == 0xf) - { - rt_kprintf("\n"); - } - } - } -#endif } else { @@ -68,29 +52,8 @@ void lwp_mmu_switch(struct rt_thread *thread) pre_mmu_table = mmu_table_get(); if (pre_mmu_table != new_mmu_table) { -#ifdef RT_USING_GDBSERVER - set_process_id((uint32_t)(size_t)l); -#endif switch_mmu(new_mmu_table); } - rt_cpu_set_thread_idr(thread->thread_idr); -#ifdef RT_USING_GDBSERVER - if (l && l->debug) - { - uint32_t step_type = 0; - - step_type = gdb_get_step_type(); - - if ((step_type == 2) || (thread->step_exec && (step_type == 1))) - { - arch_activate_step(); - } - else - { - arch_deactivate_step(); - } - } -#endif } static void unmap_range(struct rt_lwp *lwp, void *addr, size_t size, int pa_need_free) @@ -438,11 +401,11 @@ size_t lwp_get_from_user(void *dst, void *src, size_t size) return 0; } #else - if (src >= (void *)KERNEL_VADDR_START) + if (src >= (void *)USER_VADDR_TOP) { return 0; } - if ((void *)((char *)src + size) > (void *)KERNEL_VADDR_START) + if ((void *)((char *)src + size) > (void *)USER_VADDR_TOP) { return 0; } @@ -464,11 +427,11 @@ size_t lwp_put_to_user(void *dst, void *src, size_t size) rt_mmu_info *m_info = RT_NULL; /* check dst */ - if (dst >= (void *)KERNEL_VADDR_START) + if (dst >= (void *)USER_VADDR_TOP) { return 0; } - if ((void *)((char *)dst + size) > (void *)KERNEL_VADDR_START) + if ((void *)((char *)dst + size) > (void *)USER_VADDR_TOP) { return 0; } @@ -506,11 +469,11 @@ int lwp_user_accessable(void *addr, size_t size) return 0; } #else - if (addr_start >= (void *)KERNEL_VADDR_START) + if (addr_start >= (void *)USER_VADDR_TOP) { return 0; } - if (addr_end > (void *)KERNEL_VADDR_START) + if (addr_end > (void *)USER_VADDR_TOP) { return 0; } diff --git a/components/net/lwip-2.0.2/src/arch/sys_arch.c b/components/net/lwip-2.0.2/src/arch/sys_arch.c index 827dcd154b..479fd9608a 100644 --- a/components/net/lwip-2.0.2/src/arch/sys_arch.c +++ b/components/net/lwip-2.0.2/src/arch/sys_arch.c @@ -321,7 +321,7 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) */ int sys_sem_valid(sys_sem_t *sem) { - return (int)(*sem); + return (int)(size_t)(*sem); } #endif @@ -397,7 +397,7 @@ void sys_mutex_free(sys_mutex_t *mutex) */ int sys_mutex_valid(sys_mutex_t *mutex) { - return (int)(*mutex); + return (int)(size_t)(*mutex); } #endif @@ -555,7 +555,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) */ int sys_mbox_valid(sys_mbox_t *mbox) { - return (int)(*mbox); + return (int)(size_t)(*mbox); } #endif diff --git a/components/net/sal_socket/dfs_net/dfs_net.c b/components/net/sal_socket/dfs_net/dfs_net.c index f8c4b4a91f..6c0b731641 100644 --- a/components/net/sal_socket/dfs_net/dfs_net.c +++ b/components/net/sal_socket/dfs_net/dfs_net.c @@ -27,28 +27,28 @@ int dfs_net_getsocket(int fd) if (_dfs_fd == NULL) return -1; if (_dfs_fd->fnode->type != FT_SOCKET) socket = -1; - else socket = (int)_dfs_fd->fnode->data; + else socket = (int)(size_t)_dfs_fd->fnode->data; return socket; } static int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args) { - int socket = (int) file->fnode->data; + int socket = (int)(size_t)file->fnode->data; return sal_ioctlsocket(socket, cmd, args); } static int dfs_net_read(struct dfs_fd* file, void *buf, size_t count) { - int socket = (int) file->fnode->data; + int socket = (int)(size_t)file->fnode->data; return sal_recvfrom(socket, buf, count, 0, NULL, NULL); } static int dfs_net_write(struct dfs_fd *file, const void *buf, size_t count) { - int socket = (int) file->fnode->data; + int socket = (int)(size_t)file->fnode->data; return sal_sendto(socket, buf, count, 0, NULL, 0); } @@ -60,7 +60,7 @@ static int dfs_net_close(struct dfs_fd* file) if (file->fnode->ref_count == 1) { - socket = (int) file->fnode->data; + socket = (int)(size_t)file->fnode->data; ret = sal_closesocket(socket); } return ret; diff --git a/components/net/sal_socket/impl/af_inet_lwip.c b/components/net/sal_socket/impl/af_inet_lwip.c index 29fb84e027..4dac99c00c 100644 --- a/components/net/sal_socket/impl/af_inet_lwip.c +++ b/components/net/sal_socket/impl/af_inet_lwip.c @@ -165,7 +165,7 @@ static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len if (event) { - rt_wqueue_wakeup(&sock->wait_head, (void*) event); + rt_wqueue_wakeup(&sock->wait_head, (void*)(size_t)event); } } #endif /* SAL_USING_POSIX */ @@ -229,7 +229,7 @@ int inet_ioctlsocket(int socket, long cmd, void *arg) { case F_GETFL: case F_SETFL: - return lwip_fcntl(socket, cmd, (int) arg); + return lwip_fcntl(socket, cmd, (int)(size_t)arg); default: return lwip_ioctl(socket, cmd, arg); @@ -243,13 +243,13 @@ static int inet_poll(struct dfs_fd *file, struct rt_pollreq *req) struct lwip_sock *sock; struct sal_socket *sal_sock; - sal_sock = sal_get_socket((int) file->fnode->data); + sal_sock = sal_get_socket((int)(size_t)file->fnode->data); if(!sal_sock) { return -1; } - sock = lwip_tryget_socket((int)sal_sock->user_data); + sock = lwip_tryget_socket((int)(size_t)sal_sock->user_data); if (sock != NULL) { rt_base_t level; diff --git a/components/net/sal_socket/socket/net_sockets.c b/components/net/sal_socket/socket/net_sockets.c index 9f97d75cfb..9bc7edf699 100644 --- a/components/net/sal_socket/socket/net_sockets.c +++ b/components/net/sal_socket/socket/net_sockets.c @@ -62,7 +62,7 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen) d->pos = 0; /* set socket to the data of dfs_fd */ - d->fnode->data = (void *) new_socket; + d->fnode->data = (void *)(size_t)new_socket; return fd; } @@ -243,7 +243,7 @@ int socket(int domain, int type, int protocol) d->pos = 0; /* set socket to the data of dfs_fd */ - d->fnode->data = (void *) socket; + d->fnode->data = (void *)(size_t)socket; } else { diff --git a/components/net/sal_socket/src/sal_socket.c b/components/net/sal_socket/src/sal_socket.c index c57271ca71..431798442b 100644 --- a/components/net/sal_socket/src/sal_socket.c +++ b/components/net/sal_socket/src/sal_socket.c @@ -570,7 +570,7 @@ int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen) /* check the network interface socket operations */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, accept); - new_socket = pf->skt_ops->accept((int) sock->user_data, addr, addrlen); + new_socket = pf->skt_ops->accept((int)(size_t)sock->user_data, addr, addrlen); if (new_socket != -1) { int retval; @@ -598,7 +598,7 @@ int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen) } /* socket structure user_data used to store the acquired new socket */ - new_sock->user_data = (void *) new_socket; + new_sock->user_data = (void *)(size_t)new_socket; return new_sal_socket; } @@ -664,13 +664,13 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen) return -1; } sock->netdev = new_netdev; - sock->user_data = (void *) new_socket; + sock->user_data = (void *)(size_t)new_socket; } } /* check and get protocol families by the network interface device */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind); - return pf->skt_ops->bind((int) sock->user_data, name, namelen); + return pf->skt_ops->bind((int)(size_t)sock->user_data, name, namelen); } int sal_shutdown(int socket, int how) @@ -686,7 +686,7 @@ int sal_shutdown(int socket, int how) /* check the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, shutdown); - if (pf->skt_ops->shutdown((int) sock->user_data, how) == 0) + if (pf->skt_ops->shutdown((int)(size_t)sock->user_data, how) == 0) { #ifdef SAL_USING_TLS if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket)) @@ -719,7 +719,7 @@ int sal_getpeername(int socket, struct sockaddr *name, socklen_t *namelen) /* check the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, getpeername); - return pf->skt_ops->getpeername((int) sock->user_data, name, namelen); + return pf->skt_ops->getpeername((int)(size_t)sock->user_data, name, namelen); } int sal_getsockname(int socket, struct sockaddr *name, socklen_t *namelen) @@ -733,7 +733,7 @@ int sal_getsockname(int socket, struct sockaddr *name, socklen_t *namelen) /* check the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, getsockname); - return pf->skt_ops->getsockname((int) sock->user_data, name, namelen); + return pf->skt_ops->getsockname((int)(size_t)sock->user_data, name, namelen); } int sal_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen) @@ -747,7 +747,7 @@ int sal_getsockopt(int socket, int level, int optname, void *optval, socklen_t * /* check the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, getsockopt); - return pf->skt_ops->getsockopt((int) sock->user_data, level, optname, optval, optlen); + return pf->skt_ops->getsockopt((int)(size_t)sock->user_data, level, optname, optval, optlen); } int sal_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen) @@ -793,7 +793,7 @@ int sal_setsockopt(int socket, int level, int optname, const void *optval, sockl return pf->skt_ops->setsockopt((int) sock->user_data, level, optname, optval, optlen); } #else - return pf->skt_ops->setsockopt((int) sock->user_data, level, optname, optval, optlen); + return pf->skt_ops->setsockopt((int)(size_t)sock->user_data, level, optname, optval, optlen); #endif /* SAL_USING_TLS */ } @@ -811,7 +811,7 @@ int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen) /* check the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, connect); - ret = pf->skt_ops->connect((int) sock->user_data, name, namelen); + ret = pf->skt_ops->connect((int)(size_t)sock->user_data, name, namelen); #ifdef SAL_USING_TLS if (ret >= 0 && SAL_SOCKOPS_PROTO_TLS_VALID(sock, connect)) { @@ -838,7 +838,7 @@ int sal_listen(int socket, int backlog) /* check the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, listen); - return pf->skt_ops->listen((int) sock->user_data, backlog); + return pf->skt_ops->listen((int)(size_t)sock->user_data, backlog); } int sal_recvfrom(int socket, void *mem, size_t len, int flags, @@ -868,10 +868,10 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags, } else { - return pf->skt_ops->recvfrom((int) sock->user_data, mem, len, flags, from, fromlen); + return pf->skt_ops->recvfrom((int)(size_t)sock->user_data, mem, len, flags, from, fromlen); } #else - return pf->skt_ops->recvfrom((int) sock->user_data, mem, len, flags, from, fromlen); + return pf->skt_ops->recvfrom((int)(size_t)sock->user_data, mem, len, flags, from, fromlen); #endif } @@ -905,7 +905,7 @@ int sal_sendto(int socket, const void *dataptr, size_t size, int flags, return pf->skt_ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen); } #else - return pf->skt_ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen); + return pf->skt_ops->sendto((int)(size_t)sock->user_data, dataptr, size, flags, to, tolen); #endif } @@ -957,7 +957,7 @@ int sal_socket(int domain, int type, int protocol) } } #endif - sock->user_data = (void *) proto_socket; + sock->user_data = (void *)(size_t)proto_socket; return sock->socket; } socket_delete(socket); @@ -977,7 +977,7 @@ int sal_closesocket(int socket) /* valid the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, socket); - if (pf->skt_ops->closesocket((int) sock->user_data) == 0) + if (pf->skt_ops->closesocket((int)(size_t)sock->user_data) == 0) { #ifdef SAL_USING_TLS if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket)) @@ -1012,7 +1012,7 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) /* check the network interface socket opreation */ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, ioctlsocket); - return pf->skt_ops->ioctlsocket((int) sock->user_data, cmd, arg); + return pf->skt_ops->ioctlsocket((int)(size_t)sock->user_data, cmd, arg); } #ifdef SAL_USING_POSIX @@ -1020,7 +1020,7 @@ int sal_poll(struct dfs_fd *file, struct rt_pollreq *req) { struct sal_socket *sock; struct sal_proto_family *pf; - int socket = (int) file->fnode->data; + int socket = (int)(size_t)file->fnode->data; /* get the socket object by socket descriptor */ SAL_SOCKET_OBJ_GET(sock, socket); diff --git a/include/rtdef.h b/include/rtdef.h index e5f398a386..a479349c62 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -610,7 +610,13 @@ struct rt_wakeup }; #define _LWP_NSIG 64 + +#ifdef ARCH_CPU_64BIT +#define _LWP_NSIG_BPW 64 +#else #define _LWP_NSIG_BPW 32 +#endif + #define _LWP_NSIG_WORDS (_LWP_NSIG / _LWP_NSIG_BPW) typedef void (*lwp_sighandler_t)(int); diff --git a/libcpu/aarch64/common/armv8.h b/libcpu/aarch64/common/armv8.h index 4350890544..b92db355cd 100644 --- a/libcpu/aarch64/common/armv8.h +++ b/libcpu/aarch64/common/armv8.h @@ -14,47 +14,51 @@ /* the exception stack without VFP registers */ struct rt_hw_exp_stack { - unsigned long long pc; - unsigned long long spsr; - unsigned long long x30; - unsigned long long xz; - unsigned long long x28; - unsigned long long x29; - unsigned long long x26; - unsigned long long x27; - unsigned long long x24; - unsigned long long x25; - unsigned long long x22; - unsigned long long x23; - unsigned long long x20; - unsigned long long x21; - unsigned long long x18; - unsigned long long x19; - unsigned long long x16; - unsigned long long x17; - unsigned long long x14; - unsigned long long x15; - unsigned long long x12; - unsigned long long x13; - unsigned long long x10; - unsigned long long x11; - unsigned long long x8; - unsigned long long x9; - unsigned long long x6; - unsigned long long x7; - unsigned long long x4; - unsigned long long x5; - unsigned long long x2; - unsigned long long x3; - unsigned long long x0; - unsigned long long x1; + unsigned long pc; + unsigned long spsr; + unsigned long sp_el0; + unsigned long x30; + unsigned long fpcr; + unsigned long fpsr; + unsigned long x28; + unsigned long x29; + unsigned long x26; + unsigned long x27; + unsigned long x24; + unsigned long x25; + unsigned long x22; + unsigned long x23; + unsigned long x20; + unsigned long x21; + unsigned long x18; + unsigned long x19; + unsigned long x16; + unsigned long x17; + unsigned long x14; + unsigned long x15; + unsigned long x12; + unsigned long x13; + unsigned long x10; + unsigned long x11; + unsigned long x8; + unsigned long x9; + unsigned long x6; + unsigned long x7; + unsigned long x4; + unsigned long x5; + unsigned long x2; + unsigned long x3; + unsigned long x0; + unsigned long x1; + + unsigned long long fpu[16]; }; -#define SP_ELx ( ( unsigned long long ) 0x01 ) -#define SP_EL0 ( ( unsigned long long ) 0x00 ) -#define PSTATE_EL1 ( ( unsigned long long ) 0x04 ) -#define PSTATE_EL2 ( ( unsigned long long ) 0x08 ) -#define PSTATE_EL3 ( ( unsigned long long ) 0x0c ) +#define SP_ELx ( ( unsigned long ) 0x01 ) +#define SP_EL0 ( ( unsigned long ) 0x00 ) +#define PSTATE_EL1 ( ( unsigned long ) 0x04 ) +#define PSTATE_EL2 ( ( unsigned long ) 0x08 ) +#define PSTATE_EL3 ( ( unsigned long ) 0x0c ) rt_ubase_t rt_hw_get_current_el(void); void rt_hw_set_elx_env(void); diff --git a/libcpu/aarch64/common/asm-fpu.h b/libcpu/aarch64/common/asm-fpu.h new file mode 100644 index 0000000000..8ac4ab9bd8 --- /dev/null +++ b/libcpu/aarch64/common/asm-fpu.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven the first version + */ + +.macro SAVE_FPU, reg + STR Q0, [\reg, #-0x10]! + STR Q1, [\reg, #-0x10]! + STR Q2, [\reg, #-0x10]! + STR Q3, [\reg, #-0x10]! + STR Q4, [\reg, #-0x10]! + STR Q5, [\reg, #-0x10]! + STR Q6, [\reg, #-0x10]! + STR Q7, [\reg, #-0x10]! + STR Q8, [\reg, #-0x10]! + STR Q9, [\reg, #-0x10]! + STR Q10, [\reg, #-0x10]! + STR Q11, [\reg, #-0x10]! + STR Q12, [\reg, #-0x10]! + STR Q13, [\reg, #-0x10]! + STR Q14, [\reg, #-0x10]! + STR Q15, [\reg, #-0x10]! +.endm +.macro RESTORE_FPU, reg + LDR Q15, [\reg], #0x10 + LDR Q14, [\reg], #0x10 + LDR Q13, [\reg], #0x10 + LDR Q12, [\reg], #0x10 + LDR Q11, [\reg], #0x10 + LDR Q10, [\reg], #0x10 + LDR Q9, [\reg], #0x10 + LDR Q8, [\reg], #0x10 + LDR Q7, [\reg], #0x10 + LDR Q6, [\reg], #0x10 + LDR Q5, [\reg], #0x10 + LDR Q4, [\reg], #0x10 + LDR Q3, [\reg], #0x10 + LDR Q2, [\reg], #0x10 + LDR Q1, [\reg], #0x10 + LDR Q0, [\reg], #0x10 +.endm diff --git a/libcpu/aarch64/common/cache.S b/libcpu/aarch64/common/cache.S index 7f295a2b02..bd8504e9ff 100644 --- a/libcpu/aarch64/common/cache.S +++ b/libcpu/aarch64/common/cache.S @@ -127,7 +127,59 @@ __asm_flush_dcache_range: /* x2 <- minimal cache line size in cache system */ sub x3, x2, #1 bic x0, x0, x3 -1: dc civac, x0 /* clean & invalidate data or unified cache */ + +1: dc civac, x0 /* clean & invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret + +/* void __asm_invalidate_dcache_range(start, end) + * + * invalidate data cache in the range + * + * x0: start address + * x1: end address + */ +.globl __asm_invalidate_dcache_range +__asm_invalidate_dcache_range: + mrs x3, ctr_el0 + lsr x3, x3, #16 + and x3, x3, #0xf + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 + +1: dc ivac, x0 /* invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret + +/* void __asm_invalidate_icache_range(start, end) + * + * invalidate icache in the range + * + * x0: start address + * x1: end address + */ +.globl __asm_invalidate_icache_range +__asm_invalidate_icache_range: + mrs x3, ctr_el0 + and x3, x3, #0xf + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 + +1: ic ivau, x0 /* invalidate instruction or unified cache */ add x0, x0, x2 cmp x0, x1 b.lo 1b @@ -148,4 +200,4 @@ __asm_invalidate_icache_all: .globl __asm_flush_l3_cache __asm_flush_l3_cache: mov x0, #0 /* return status as success */ - ret \ No newline at end of file + ret diff --git a/libcpu/aarch64/common/cache_ops.c b/libcpu/aarch64/common/cache_ops.c new file mode 100644 index 0000000000..018f0be4a4 --- /dev/null +++ b/libcpu/aarch64/common/cache_ops.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-29 quanzhao the first version + */ +#include +#include + +void __asm_invalidate_icache_all(void); +void __asm_flush_dcache_all(void); +void __asm_flush_dcache_range(unsigned long start, unsigned long end); +void __asm_invalidate_dcache_range(unsigned long start, unsigned long end); +void __asm_invalidate_icache_range(unsigned long start, unsigned long end); +void __asm_invalidate_dcache_all(void); +void __asm_invalidate_icache_all(void); + +rt_inline rt_uint32_t rt_cpu_icache_line_size(void) +{ + return 0; +} + +rt_inline rt_uint32_t rt_cpu_dcache_line_size(void) +{ + return 0; +} + +void rt_hw_cpu_icache_invalidate(void *addr, int size) +{ + __asm_invalidate_icache_range((unsigned long)addr, (unsigned long)addr + size); +} + +void rt_hw_cpu_dcache_invalidate(void *addr, int size) +{ + __asm_invalidate_dcache_range((unsigned long)addr, (unsigned long)addr + size); +} + +void rt_hw_cpu_dcache_clean(void *addr, int size) +{ + __asm_flush_dcache_range((unsigned long)addr, (unsigned long)addr + size); +} + +void rt_hw_cpu_dcache_clean_and_invalidate(void *addr, int size) +{ + __asm_flush_dcache_range((unsigned long)addr, (unsigned long)addr + size); +} + +void rt_hw_cpu_icache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_INVALIDATE) + { + rt_hw_cpu_icache_invalidate(addr, size); + } +} + +void rt_hw_cpu_dcache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_FLUSH) + { + rt_hw_cpu_dcache_clean(addr, size); + } + else if (ops == RT_HW_CACHE_INVALIDATE) + { + rt_hw_cpu_dcache_invalidate(addr, size); + } +} + +rt_base_t rt_hw_cpu_icache_status(void) +{ + return 0; +} + +rt_base_t rt_hw_cpu_dcache_status(void) +{ + return 0; +} + +#ifdef RT_USING_LWP +#define ICACHE (1<<0) +#define DCACHE (1<<1) +#define BCACHE (ICACHE|DCACHE) + +int sys_cacheflush(void *addr, int size, int cache) +{ + if ((size_t)addr < KERNEL_VADDR_START && (size_t)addr + size <= KERNEL_VADDR_START) + { + if ((cache & DCACHE) != 0) + { + rt_hw_cpu_dcache_clean_and_invalidate(addr, size); + } + if ((cache & ICACHE) != 0) + { + rt_hw_cpu_icache_invalidate(addr, size); + } + return 0; + } + return -1; +} +#endif diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S index 934db7ed84..d924b920a6 100644 --- a/libcpu/aarch64/common/context_gcc.S +++ b/libcpu/aarch64/common/context_gcc.S @@ -1,217 +1,197 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes - * 2018-10-06 ZhaoXiaowei the first version + * 2021-05-18 Jesven the first version */ +#include "asm-fpu.h" + /* *enable gtimer */ .globl rt_hw_gtimer_enable rt_hw_gtimer_enable: - MOV X0,#1 - MSR CNTP_CTL_EL0,X0 - RET + MOV X0,#1 + MSR CNTP_CTL_EL0,X0 + RET /* *set gtimer CNTP_TVAL_EL0 value */ .globl rt_hw_set_gtimer_val rt_hw_set_gtimer_val: - MSR CNTP_TVAL_EL0,X0 - RET + MSR CNTP_TVAL_EL0,X0 + RET /* *get gtimer CNTP_TVAL_EL0 value */ .globl rt_hw_get_gtimer_val rt_hw_get_gtimer_val: - MRS X0,CNTP_TVAL_EL0 - RET + MRS X0,CNTP_TVAL_EL0 + RET .globl rt_hw_get_cntpct_val rt_hw_get_cntpct_val: - MRS X0, CNTPCT_EL0 - RET + MRS X0, CNTPCT_EL0 + RET /* *get gtimer frq value */ .globl rt_hw_get_gtimer_frq rt_hw_get_gtimer_frq: - MRS X0,CNTFRQ_EL0 - RET + MRS X0,CNTFRQ_EL0 + RET .macro SAVE_CONTEXT - - /* Switch to use the EL0 stack pointer. */ - MSR SPSEL, #0 - /* Save the entire context. */ - STP X0, X1, [SP, #-0x10]! - STP X2, X3, [SP, #-0x10]! - STP X4, X5, [SP, #-0x10]! - STP X6, X7, [SP, #-0x10]! - STP X8, X9, [SP, #-0x10]! - STP X10, X11, [SP, #-0x10]! - STP X12, X13, [SP, #-0x10]! - STP X14, X15, [SP, #-0x10]! - STP X16, X17, [SP, #-0x10]! - STP X18, X19, [SP, #-0x10]! - STP X20, X21, [SP, #-0x10]! - STP X22, X23, [SP, #-0x10]! - STP X24, X25, [SP, #-0x10]! - STP X26, X27, [SP, #-0x10]! - STP X28, X29, [SP, #-0x10]! - STP X30, XZR, [SP, #-0x10]! - - MRS X0, CurrentEL - CMP X0, 0xc - B.EQ 3f - CMP X0, 0x8 - B.EQ 2f - CMP X0, 0x4 - B.EQ 1f - B . -3: - MRS X3, SPSR_EL3 - /* Save the ELR. */ - MRS X2, ELR_EL3 - B 0f -2: - MRS X3, SPSR_EL2 - /* Save the ELR. */ - MRS X2, ELR_EL2 - B 0f -1: - MRS X3, SPSR_EL1 - MRS X2, ELR_EL1 - B 0f -0: - - STP X2, X3, [SP, #-0x10]! - - MOV X0, SP /* Move SP into X0 for saving. */ - - /* Switch to use the ELx stack pointer. */ - MSR SPSEL, #1 - - .endm - -.macro SAVE_CONTEXT_T - - /* Switch to use the EL0 stack pointer. */ - MSR SPSEL, #0 - + SAVE_FPU SP + STP X0, X1, [SP, #-0x10]! + STP X2, X3, [SP, #-0x10]! + STP X4, X5, [SP, #-0x10]! + STP X6, X7, [SP, #-0x10]! + STP X8, X9, [SP, #-0x10]! + STP X10, X11, [SP, #-0x10]! + STP X12, X13, [SP, #-0x10]! + STP X14, X15, [SP, #-0x10]! + STP X16, X17, [SP, #-0x10]! + STP X18, X19, [SP, #-0x10]! + STP X20, X21, [SP, #-0x10]! + STP X22, X23, [SP, #-0x10]! + STP X24, X25, [SP, #-0x10]! + STP X26, X27, [SP, #-0x10]! + STP X28, X29, [SP, #-0x10]! + MRS X28, FPCR + MRS X29, FPSR + STP X28, X29, [SP, #-0x10]! + MRS X29, SP_EL0 + STP X29, X30, [SP, #-0x10]! + + MRS X3, SPSR_EL1 + MRS X2, ELR_EL1 + + STP X2, X3, [SP, #-0x10]! + + MOV X0, SP /* Move SP into X0 for saving. */ +.endm + +.macro SAVE_CONTEXT_FROM_EL1 /* Save the entire context. */ - STP X0, X1, [SP, #-0x10]! - STP X2, X3, [SP, #-0x10]! - STP X4, X5, [SP, #-0x10]! - STP X6, X7, [SP, #-0x10]! - STP X8, X9, [SP, #-0x10]! - STP X10, X11, [SP, #-0x10]! - STP X12, X13, [SP, #-0x10]! - STP X14, X15, [SP, #-0x10]! - STP X16, X17, [SP, #-0x10]! - STP X18, X19, [SP, #-0x10]! - STP X20, X21, [SP, #-0x10]! - STP X22, X23, [SP, #-0x10]! - STP X24, X25, [SP, #-0x10]! - STP X26, X27, [SP, #-0x10]! - STP X28, X29, [SP, #-0x10]! - STP X30, XZR, [SP, #-0x10]! - - MRS X0, CurrentEL - CMP X0, 0xc - B.EQ 3f - CMP X0, 0x8 - B.EQ 2f - CMP X0, 0x4 - B.EQ 1f - B . -3: - MRS X3, SPSR_EL3 - MOV X2, X30 - B 0f -2: - MRS X3, SPSR_EL2 - MOV X2, X30 - B 0f -1: - MRS X3, SPSR_EL1 - MOV X2, X30 - B 0f -0: - - STP X2, X3, [SP, #-0x10]! - - MOV X0, SP /* Move SP into X0 for saving. */ - - /* Switch to use the ELx stack pointer. */ - MSR SPSEL, #1 - - .endm + SAVE_FPU SP + STP X0, X1, [SP, #-0x10]! + STP X2, X3, [SP, #-0x10]! + STP X4, X5, [SP, #-0x10]! + STP X6, X7, [SP, #-0x10]! + STP X8, X9, [SP, #-0x10]! + STP X10, X11, [SP, #-0x10]! + STP X12, X13, [SP, #-0x10]! + STP X14, X15, [SP, #-0x10]! + STP X16, X17, [SP, #-0x10]! + STP X18, X19, [SP, #-0x10]! + STP X20, X21, [SP, #-0x10]! + STP X22, X23, [SP, #-0x10]! + STP X24, X25, [SP, #-0x10]! + STP X26, X27, [SP, #-0x10]! + STP X28, X29, [SP, #-0x10]! + MRS X28, FPCR + MRS X29, FPSR + STP X28, X29, [SP, #-0x10]! + MRS X29, SP_EL0 + STP X29, X30, [SP, #-0x10]! + + MOV X3, #((3 << 6) | 0x4 | 0x1) /* el1h, disable interrupt */ + MOV X2, X30 + + STP X2, X3, [SP, #-0x10]! +.endm .macro RESTORE_CONTEXT - - /* Switch to use the EL0 stack pointer. */ - MSR SPSEL, #0 - /* Set the SP to point to the stack of the task being restored. */ - MOV SP, X0 - - LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ - - MRS X0, CurrentEL - CMP X0, 0xc - B.EQ 3f - CMP X0, 0x8 - B.EQ 2f - CMP X0, 0x4 - B.EQ 1f - B . -3: - MSR SPSR_EL3, X3 - MSR ELR_EL3, X2 - B 0f -2: - MSR SPSR_EL2, X3 - MSR ELR_EL2, X2 - B 0f -1: - MSR SPSR_EL1, X3 - MSR ELR_EL1, X2 - B 0f -0: - - LDP X30, XZR, [SP], #0x10 - LDP X28, X29, [SP], #0x10 - LDP X26, X27, [SP], #0x10 - LDP X24, X25, [SP], #0x10 - LDP X22, X23, [SP], #0x10 - LDP X20, X21, [SP], #0x10 - LDP X18, X19, [SP], #0x10 - LDP X16, X17, [SP], #0x10 - LDP X14, X15, [SP], #0x10 - LDP X12, X13, [SP], #0x10 - LDP X10, X11, [SP], #0x10 - LDP X8, X9, [SP], #0x10 - LDP X6, X7, [SP], #0x10 - LDP X4, X5, [SP], #0x10 - LDP X2, X3, [SP], #0x10 - LDP X0, X1, [SP], #0x10 - - /* Switch to use the ELx stack pointer. _RB_ Might not be required. */ - MSR SPSEL, #1 + MOV SP, X0 + + BL lwp_check_exit + + BL rt_thread_self + MOV X8, X0 + BL lwp_mmu_switch + MOV X0, X8 + BL lwp_user_setting_restore + + LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ + + TST X3, #0x1f + MSR SPSR_EL1, X3 + MSR ELR_EL1, X2 + + LDP X29, X30, [SP], #0x10 + MSR SP_EL0, X29 + LDP X28, X29, [SP], #0x10 + MSR FPCR, X28 + MSR FPSR, X29 + LDP X28, X29, [SP], #0x10 + LDP X26, X27, [SP], #0x10 + LDP X24, X25, [SP], #0x10 + LDP X22, X23, [SP], #0x10 + LDP X20, X21, [SP], #0x10 + LDP X18, X19, [SP], #0x10 + LDP X16, X17, [SP], #0x10 + LDP X14, X15, [SP], #0x10 + LDP X12, X13, [SP], #0x10 + LDP X10, X11, [SP], #0x10 + LDP X8, X9, [SP], #0x10 + LDP X6, X7, [SP], #0x10 + LDP X4, X5, [SP], #0x10 + LDP X2, X3, [SP], #0x10 + LDP X0, X1, [SP], #0x10 + RESTORE_FPU SP + + BEQ ret_to_user ERET +.endm + +.macro RESTORE_CONTEXT_WITHOUT_MMU_SWITCH + /* the SP is already ok */ + BL lwp_check_exit + + LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ + + TST X3, #0x1f + MSR SPSR_EL1, X3 + MSR ELR_EL1, X2 + + LDP X29, X30, [SP], #0x10 + MSR SP_EL0, X29 + LDP X28, X29, [SP], #0x10 + MSR FPCR, X28 + MSR FPSR, X29 + LDP X28, X29, [SP], #0x10 + LDP X26, X27, [SP], #0x10 + LDP X24, X25, [SP], #0x10 + LDP X22, X23, [SP], #0x10 + LDP X20, X21, [SP], #0x10 + LDP X18, X19, [SP], #0x10 + LDP X16, X17, [SP], #0x10 + LDP X14, X15, [SP], #0x10 + LDP X12, X13, [SP], #0x10 + LDP X10, X11, [SP], #0x10 + LDP X8, X9, [SP], #0x10 + LDP X6, X7, [SP], #0x10 + LDP X4, X5, [SP], #0x10 + LDP X2, X3, [SP], #0x10 + LDP X0, X1, [SP], #0x10 + RESTORE_FPU SP + + BEQ ret_to_user - .endm + ERET +.endm .text /* @@ -219,9 +199,9 @@ rt_hw_get_gtimer_frq: */ .globl rt_hw_interrupt_disable rt_hw_interrupt_disable: - MRS X0, DAIF - MSR DAIFSet, #3 - DSB SY + MRS X0, DAIF + MSR DAIFSet, #3 + DSB SY RET /* @@ -230,39 +210,38 @@ rt_hw_interrupt_disable: .globl rt_hw_interrupt_enable rt_hw_interrupt_enable: DSB SY - MOV X1, #0xC0 - ANDS X0, X0, X1 - B.NE rt_hw_interrupt_enable_exit - MSR DAIFClr, #3 -rt_hw_interrupt_enable_exit: + AND X0, X0, #0xc0 + MRS X1, DAIF + BIC X1, X1, #0xc0 + ORR X0, X0, X1 + MSR DAIF, X0 RET /* * void rt_hw_context_switch_to(rt_ubase_t to); - * r0 --> to + * X0 --> to sp */ .globl rt_hw_context_switch_to rt_hw_context_switch_to: - LDR X0, [X0] + LDR X0, [X0] RESTORE_CONTEXT .text /* * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); - * r0 --> from - * r1 --> to + * X0 --> from sp + * X1 --> to sp + * X2 --> to thread */ .globl rt_hw_context_switch rt_hw_context_switch: - MOV X8,X0 - MOV X9,X1 + SAVE_CONTEXT_FROM_EL1 + + MOV X2, SP + STR X2, [X0] // store sp in preempted tasks TCB + LDR X0, [X1] // get new task stack pointer - SAVE_CONTEXT_T - - STR X0, [X8] // store sp in preempted tasks TCB - LDR X0, [X9] // get new task stack pointer - RESTORE_CONTEXT /* @@ -273,17 +252,17 @@ rt_hw_context_switch: .globl rt_interrupt_to_thread .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: - ADR X2, rt_thread_switch_interrupt_flag - LDR X3, [X2] - CMP X3, #1 - B.EQ _reswitch - ADR X4, rt_interrupt_from_thread // set rt_interrupt_from_thread - MOV X3, #1 // set rt_thread_switch_interrupt_flag to 1 - STR X0, [X4] - STR X3, [X2] + ADR X2, rt_thread_switch_interrupt_flag + LDR X3, [X2] + CMP X3, #1 + B.EQ _reswitch + ADR X4, rt_interrupt_from_thread // set rt_interrupt_from_thread + MOV X3, #1 // set rt_thread_switch_interrupt_flag to 1 + STR X0, [X4] + STR X3, [X2] _reswitch: - ADR X2, rt_interrupt_to_thread // set rt_interrupt_to_thread - STR X1, [X2] + ADR X2, rt_interrupt_to_thread // set rt_interrupt_to_thread + STR X1, [X2] RET .text @@ -294,9 +273,9 @@ _reswitch: .globl vector_fiq vector_fiq: SAVE_CONTEXT - STP X0, X1, [SP, #-0x10]! + STP X0, X1, [SP, #-0x10]! BL rt_hw_trap_fiq - LDP X0, X1, [SP], #0x10 + LDP X0, X1, [SP], #0x10 RESTORE_CONTEXT .globl rt_interrupt_enter @@ -312,20 +291,23 @@ vector_fiq: .globl vector_irq vector_irq: SAVE_CONTEXT - STP X0, X1, [SP, #-0x10]! + STP X0, X1, [SP, #-0x10]! /* X0 is thread sp */ + + BL rt_thread_self + BL lwp_user_setting_save BL rt_interrupt_enter BL rt_hw_trap_irq BL rt_interrupt_leave - - LDP X0, X1, [SP], #0x10 + + LDP X0, X1, [SP], #0x10 // if rt_thread_switch_interrupt_flag set, jump to // rt_hw_context_switch_interrupt_do and don't return - ADR X1, rt_thread_switch_interrupt_flag + ADR X1, rt_thread_switch_interrupt_flag LDR X2, [X1] CMP X2, #1 - B.NE vector_irq_exit + B.NE vector_irq_exit MOV X2, #0 // clear flag STR X2, [X1] @@ -337,15 +319,53 @@ vector_irq: ADR x3, rt_interrupt_to_thread LDR X4, [X3] LDR x0, [X4] // get new task's stack pointer - -vector_irq_exit: + RESTORE_CONTEXT +vector_irq_exit: + MOV SP, X0 + RESTORE_CONTEXT_WITHOUT_MMU_SWITCH + // ------------------------------------------------- - .align 8 - .globl vector_error -vector_error: + .globl vector_exception +vector_exception: SAVE_CONTEXT - BL rt_hw_trap_error - B . + STP X0, X1, [SP, #-0x10]! + BL rt_hw_trap_exception + LDP X0, X1, [SP], #0x10 + MOV SP, X0 + RESTORE_CONTEXT_WITHOUT_MMU_SWITCH + + .globl vector_serror +vector_serror: + SAVE_CONTEXT + STP X0, X1, [SP, #-0x10]! + BL rt_hw_trap_serror + b . + +.global switch_mmu +switch_mmu: + MSR TTBR0_EL1, X0 + MRS X1, TCR_EL1 + CMP X0, XZR + ORR X1, X1, #(1 << 7) + BEQ 1f + BIC X1, X1, #(1 << 7) +1: + MSR TCR_EL1, X1 + DSB SY + ISB + TLBI VMALLE1 + DSB SY + ISB + IC IALLUIS + DSB SY + ISB + RET + +.global mmu_table_get +mmu_table_get: + MRS X0, TTBR0_EL1 + RET + diff --git a/libcpu/aarch64/common/cpu_gcc.S b/libcpu/aarch64/common/cpu_gcc.S index b8c8b8768c..5e26871492 100644 --- a/libcpu/aarch64/common/cpu_gcc.S +++ b/libcpu/aarch64/common/cpu_gcc.S @@ -55,7 +55,6 @@ rt_hw_set_current_vbar: 0: RET - .globl rt_hw_set_elx_env rt_hw_set_elx_env: MRS X1, CurrentEL @@ -80,3 +79,22 @@ rt_hw_set_elx_env: B 0f 0: RET + +.global rt_cpu_vector_set_base +rt_cpu_vector_set_base: + MSR VBAR_EL1,X0 + RET + + +.global ffz +ffz: + mvn x1, x0 + clz x0, x1 + mov x1, #0x3f + sub x0, x1, x0 + ret + +.global rt_clz +rt_clz: + clz x0, x0 + ret diff --git a/libcpu/aarch64/common/cpuport.h b/libcpu/aarch64/common/cpuport.h new file mode 100644 index 0000000000..213d95b13f --- /dev/null +++ b/libcpu/aarch64/common/cpuport.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#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/exception.c b/libcpu/aarch64/common/exception.c new file mode 100644 index 0000000000..dadf2da5e7 --- /dev/null +++ b/libcpu/aarch64/common/exception.c @@ -0,0 +1,227 @@ +#include "rtthread.h" + +static void data_abort(unsigned long far, unsigned long iss) +{ + rt_kprintf("fault addr = 0x%016lx\n", far); + if (iss & 0x40) { + rt_kprintf("abort caused by write instruction\n"); + } else { + rt_kprintf("abort caused by read instruction\n"); + } + switch (iss & 0x3f) { + case 0b000000: + rt_kprintf("Address size fault, zeroth level of translation or translation table base register\n"); + break; + + case 0b000001: + rt_kprintf("Address size fault, first level\n"); + break; + + case 0b000010: + rt_kprintf("Address size fault, second level\n"); + break; + + case 0b000011: + rt_kprintf("Address size fault, third level\n"); + break; + + case 0b000100: + rt_kprintf("Translation fault, zeroth level\n"); + break; + + case 0b000101: + rt_kprintf("Translation fault, first level\n"); + break; + + case 0b000110: + rt_kprintf("Translation fault, second level\n"); + break; + + case 0b000111: + rt_kprintf("Translation fault, third level\n"); + break; + + case 0b001001: + rt_kprintf("Access flag fault, first level\n"); + break; + + case 0b001010: + rt_kprintf("Access flag fault, second level\n"); + break; + + case 0b001011: + rt_kprintf("Access flag fault, third level\n"); + break; + + case 0b001101: + rt_kprintf("Permission fault, first level\n"); + break; + + case 0b001110: + rt_kprintf("Permission fault, second level\n"); + break; + + case 0b001111: + rt_kprintf("Permission fault, third level\n"); + break; + + case 0b010000: + rt_kprintf("Synchronous external abort, not on translation table walk\n"); + break; + + case 0b011000: + rt_kprintf("Synchronous parity or ECC error on memory access, not on translation table walk\n"); + break; + + case 0b010100: + rt_kprintf("Synchronous external abort on translation table walk, zeroth level\n"); + break; + + case 0b010101: + rt_kprintf("Synchronous external abort on translation table walk, first level\n"); + break; + + case 0b010110: + rt_kprintf("Synchronous external abort on translation table walk, second level\n"); + break; + + case 0b010111: + rt_kprintf("Synchronous external abort on translation table walk, third level\n"); + break; + + case 0b011100: + rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, zeroth level\n"); + break; + + case 0b011101: + rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, first level\n"); + break; + + case 0b011110: + rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, second level\n"); + break; + + case 0b011111: + rt_kprintf("Synchronous parity or ECC error on memory access on translation table walk, third level\n"); + break; + + case 0b100001: + rt_kprintf("Alignment fault\n"); + break; + + case 0b110000: + rt_kprintf("TLB conflict abort\n"); + break; + + case 0b110100: + rt_kprintf("IMPLEMENTATION DEFINED fault (Lockdown fault)\n"); + break; + + case 0b110101: + rt_kprintf("IMPLEMENTATION DEFINED fault (Unsupported Exclusive access fault)\n"); + break; + + case 0b111101: + rt_kprintf("Section Domain Fault, used only for faults reported in the PAR_EL1\n"); + break; + + case 0b111110: + rt_kprintf("Page Domain Fault, used only for faults reported in the PAR_EL1\n"); + break; + + default: + rt_kprintf("unknow abort\n"); + break; + } +} + +void process_exception(unsigned long esr, unsigned long epc) +{ + rt_uint8_t ec; + rt_uint32_t iss; + unsigned long fault_addr; + rt_kprintf("\nexception info:\n"); + ec = (unsigned char)((esr >> 26) & 0x3fU); + iss = (unsigned int )(esr & 0x00ffffffU); + rt_kprintf("esr.EC :0x%02x\n", ec); + rt_kprintf("esr.IL :0x%02x\n", (unsigned char)((esr >> 25) & 0x01U)); + rt_kprintf("esr.ISS:0x%08x\n", iss); + rt_kprintf("epc :0x%016p\n", (void *)epc); + switch (ec) { + case 0x00: + rt_kprintf("Exceptions with an unknow reason\n"); + break; + + case 0x01: + rt_kprintf("Exceptions from an WFI or WFE instruction\n"); + break; + + case 0x03: + rt_kprintf("Exceptions from an MCR or MRC access to CP15 from AArch32\n"); + break; + + case 0x04: + rt_kprintf("Exceptions from an MCRR or MRRC access to CP15 from AArch32\n"); + break; + + case 0x05: + rt_kprintf("Exceptions from an MCR or MRC access to CP14 from AArch32\n"); + break; + + case 0x06: + rt_kprintf("Exceptions from an LDC or STC access to CP14 from AArch32\n"); + break; + + case 0x07: + rt_kprintf("Exceptions from Access to Advanced SIMD or floating-point registers\n"); + break; + + case 0x08: + rt_kprintf("Exceptions from an MRC (or VMRS) access to CP10 from AArch32\n"); + break; + + case 0x0c: + rt_kprintf("Exceptions from an MCRR or MRRC access to CP14 from AArch32\n"); + break; + + case 0x0e: + rt_kprintf("Exceptions that occur because ther value of PSTATE.IL is 1\n"); + break; + + case 0x11: + rt_kprintf("SVC call from AArch32 state\n"); + break; + + case 0x15: + rt_kprintf("SVC call from AArch64 state\n"); + break; + + case 0x20: + rt_kprintf("Instruction abort from lower exception level\n"); + break; + + case 0x21: + rt_kprintf("Instruction abort from current exception level\n"); + break; + + case 0x22: + rt_kprintf("PC alignment fault\n"); + break; + + case 0x24: + rt_kprintf("Data abort from a lower Exception level\n"); + __asm__ volatile ("mrs %0, far_el1":"=r"(fault_addr)); + data_abort(fault_addr, iss); + break; + + case 0x25: + rt_kprintf("Data abort\n"); + __asm__ volatile ("mrs %0, far_el1":"=r"(fault_addr)); + data_abort(fault_addr, iss); + break; + + default: + rt_kprintf("Other error\n"); + break; + } +} diff --git a/libcpu/aarch64/common/gic.c b/libcpu/aarch64/common/gic.c new file mode 100644 index 0000000000..7c3150635d --- /dev/null +++ b/libcpu/aarch64/common/gic.c @@ -0,0 +1,516 @@ +/* + * 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 "gic.h" +#include "cp15.h" + +struct arm_gic +{ + rt_uint64_t offset; /* the first interrupt index in the vector table */ + + rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ + rt_uint64_t cpu_hw_base; /* the base addrees of the gic cpu interface */ +}; + +/* 'ARM_GIC_MAX_NR' is the number of cores */ +static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; + +/** Macro to access the Generic Interrupt Controller Interface (GICC) +*/ +#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00U) +#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04U) +#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08U) +#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0cU) +#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10U) +#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14U) +#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18U) +#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFCU) + +/** Macro to access the Generic Interrupt Controller Distributor (GICD) +*/ +#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) +#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004U) +#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380U + ((n)/32U) * 4U) +#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400U + ((n)/4U) * 4U) +#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800U + ((n)/4U) * 4U) +#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U) +#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00U) +#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U) +#define GIC_DIST_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U) +#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8U) + +static unsigned int _gic_max_irq; + +int arm_gic_get_active_irq(rt_uint64_t index) +{ + int irq; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base); + irq += _gic_table[index].offset; + return irq; +} + +void arm_gic_ack(rt_uint64_t index, int irq) +{ + rt_uint64_t mask = 1U << (irq % 32U); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; +} + +void arm_gic_mask(rt_uint64_t index, int irq) +{ + rt_uint64_t mask = 1U << (irq % 32U); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +void arm_gic_umask(rt_uint64_t index, int irq) +{ + rt_uint64_t mask = 1U << (irq % 32U); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; +} + +rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq) +{ + rt_uint64_t pend; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + /* No CPU identification offered */ + if (pend != 0U) + { + pend = 1U; + } + else + { + pend = 0U; + } + } + + return (pend); +} + +void arm_gic_set_pending_irq(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1U << (irq % 32U); + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + /* Forward the interrupt to the CPU interface that requested it */ + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000U); + } +} + +void arm_gic_clear_pending_irq(rt_uint64_t index, int irq) +{ + rt_uint64_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + mask = 1U << (irq % 32U); + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } + else + { + mask = 1U << ((irq % 4U) * 8U); + GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config) +{ + rt_uint64_t icfgr; + rt_uint64_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq); + shift = (irq % 16U) << 1U; + + icfgr &= (~(3U << shift)); + icfgr |= (config << shift); + + GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr; +} + +rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> ((irq % 16U) >> 1U)); +} + +void arm_gic_clear_active(rt_uint64_t index, int irq) +{ + rt_uint64_t mask = 1U << (irq % 32U); + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; +} + +/* Set up the cpu mask for the specific interrupt */ +void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask) +{ + rt_uint64_t old_tgt; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); + + old_tgt &= ~(0x0FFUL << ((irq % 4U)*8U)); + old_tgt |= cpumask << ((irq % 4U)*8U); + + GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; +} + +rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; +} + +void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority) +{ + rt_uint64_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq); + mask &= ~(0xFFUL << ((irq % 4U) * 8U)); + mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U)); + GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask; +} + +rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; +} + +void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + /* set priority mask */ + GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base) = priority & 0xFFUL; +} + +rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base); +} + +void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point) +{ + GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base) = binary_point & 0x7U; +} + +rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index) +{ + return GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base); +} + +rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq) +{ + rt_uint64_t pending; + rt_uint64_t active; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + + return ((active << 1U) | pending); +} + +void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_uint64_t filter_list) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = + ((filter_list & 0x3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (irq & 0x0FUL); +} + +rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); +} + +rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_IIDR(_gic_table[index].cpu_hw_base); +} + +void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group) +{ + uint32_t igroupr; + uint32_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(group <= 1U); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq); + shift = (irq % 32U); + igroupr &= (~(1U << shift)); + igroupr |= ((group & 0x1U) << shift); + + GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr; +} + +rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; +} + +int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start) +{ + unsigned int gic_type, i; + rt_uint64_t cpumask = 1U << 0U; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + _gic_table[index].dist_hw_base = dist_base; + _gic_table[index].offset = irq_start; + + /* Find out how many interrupts are supported. */ + gic_type = GIC_DIST_TYPE(dist_base); + _gic_max_irq = ((gic_type & 0x1fU) + 1U) * 32U; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (_gic_max_irq > 1020U) + { + _gic_max_irq = 1020U; + } + if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ + { + _gic_max_irq = ARM_GIC_NR_IRQS; + } + + cpumask |= cpumask << 8U; + cpumask |= cpumask << 16U; + cpumask |= cpumask << 24U; + + GIC_DIST_CTRL(dist_base) = 0x0U; + + /* Set all global interrupts to be level triggered, active low. */ + for (i = 32U; i < _gic_max_irq; i += 16U) + { + GIC_DIST_CONFIG(dist_base, i) = 0x0U; + } + + /* Set all global interrupts to this CPU only. */ + for (i = 32U; i < _gic_max_irq; i += 4U) + { + GIC_DIST_TARGET(dist_base, i) = cpumask; + } + + /* Set priority on all interrupts. */ + for (i = 0U; i < _gic_max_irq; i += 4U) + { + GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0U; + } + + /* Disable all interrupts. */ + for (i = 0U; i < _gic_max_irq; i += 32U) + { + GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffffU; + } + + /* All interrupts defaults to IGROUP1(IRQ). */ + /* + for (i = 0; i < _gic_max_irq; i += 32) + { + GIC_DIST_IGROUP(dist_base, i) = 0xffffffffU; + } + */ + for (i = 0U; i < _gic_max_irq; i += 32U) + { + GIC_DIST_IGROUP(dist_base, i) = 0U; + } + + /* 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..4cdcb44028 --- /dev/null +++ b/libcpu/aarch64/common/gic.h @@ -0,0 +1,62 @@ +/* + * 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 + +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 b114ba7678..0000000000 --- a/libcpu/aarch64/common/gic/SConscript +++ /dev/null @@ -1,24 +0,0 @@ -# RT-Thread building script for component - -from building import * - -cwd = GetCurrentDir() -CPPPATH = [cwd] - -gic400_group = Split(''' -gic_pl400.c -''') - -gic500_group = Split(''' -gic_pl500.c -''') - -src = () -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_pl400.c b/libcpu/aarch64/common/gic/gic_pl400.c deleted file mode 100644 index 1f4d868636..0000000000 --- a/libcpu/aarch64/common/gic/gic_pl400.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2006-2018, 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 fa20846ea2..0000000000 --- a/libcpu/aarch64/common/gic/gic_pl400.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2006-2018, 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/cortex-a53/interrupt.c b/libcpu/aarch64/common/interrupt.c similarity index 37% rename from libcpu/aarch64/cortex-a53/interrupt.c rename to libcpu/aarch64/common/interrupt.c index a412ca1953..eea5f06635 100644 --- a/libcpu/aarch64/cortex-a53/interrupt.c +++ b/libcpu/aarch64/common/interrupt.c @@ -1,25 +1,32 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2018, 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 + * 2013-07-06 Bernard first version + * 2018-11-22 Jesven add smp support */ #include -#include #include - -#include "cp15.h" -#include "armv8.h" #include "interrupt.h" +#include "gic.h" -#define MAX_HANDLERS 72 +/* 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 void rt_cpu_vector_set_base(unsigned int addr); +extern int system_vectors; #ifdef RT_USING_SMP #define rt_interrupt_nest rt_cpu_self()->irq_nest @@ -27,20 +34,7 @@ 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 -} - +#ifdef SOC_BCM283x static void default_isr_handler(int vector, void *param) { #ifdef RT_USING_SMP @@ -49,13 +43,25 @@ static void default_isr_handler(int vector, void *param) rt_kprintf("unhandled irq: %d\n",vector); #endif } +#endif + +void rt_hw_vector_init(void) +{ + rt_cpu_vector_set_base((unsigned long)&system_vectors); +} /** * This function will initialize hardware interrupt */ void rt_hw_interrupt_init(void) { +#ifdef SOC_BCM283x rt_uint32_t index; + /* initialize vector table */ + rt_hw_vector_init(); + + /* initialize exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); /* mask all of interrupts */ IRQ_DISABLE_BASIC = 0x000000ff; @@ -64,7 +70,7 @@ void rt_hw_interrupt_init(void) for (index = 0; index < MAX_HANDLERS; index ++) { isr_table[index].handler = default_isr_handler; - isr_table[index].param = NULL; + 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; @@ -76,6 +82,31 @@ void rt_hw_interrupt_init(void) 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 */ +#ifdef RT_USING_USERSPACE + gic_dist_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_dist_base(), 0x2000, MMU_MAP_K_DEVICE); + gic_cpu_base = (rt_uint64_t)rt_hw_mmu_map(&mmu_info, 0, (void*)platform_get_gic_cpu_base(), 0x1000, MMU_MAP_K_DEVICE); +#else + gic_dist_base = platform_get_gic_dist_base(); + gic_cpu_base = platform_get_gic_cpu_base(); +#endif + + gic_irq_start = GIC_IRQ_START; + + arm_gic_dist_init(0, gic_dist_base, gic_irq_start); + arm_gic_cpu_init(0, gic_cpu_base); +#endif } /** @@ -84,11 +115,12 @@ void rt_hw_interrupt_init(void) */ void rt_hw_interrupt_mask(int vector) { +#ifdef SOC_BCM283x if (vector < 32) { IRQ_DISABLE1 = (1 << vector); } - else if (vector<64) + else if (vector < 64) { vector = vector % 32; IRQ_DISABLE2 = (1 << vector); @@ -98,6 +130,9 @@ void rt_hw_interrupt_mask(int vector) vector = vector - 64; IRQ_DISABLE_BASIC = (1 << vector); } +#else + arm_gic_mask(0, vector); +#endif } /** @@ -106,7 +141,8 @@ void rt_hw_interrupt_mask(int vector) */ void rt_hw_interrupt_umask(int vector) { - if (vector < 32) +#ifdef SOC_BCM283x +if (vector < 32) { IRQ_ENABLE1 = (1 << vector); } @@ -120,6 +156,176 @@ void rt_hw_interrupt_umask(int vector) 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) +{ +#ifndef SOC_BCM283x + 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) +{ +#ifndef SOC_BCM283x + 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) +{ + arm_gic_set_cpu(0, vector, cpu_mask); +} + +/** + * 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) +{ + return arm_gic_get_target_cpu(0, vector); +} + +/** + * 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) +{ + arm_gic_set_configuration(0, vector, mode); +} + +/** + * 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) +{ + return arm_gic_get_configuration(0, vector); +} + +/** + * This function set interrupt pending flag. + * @param vector: the interrupt number + */ +void rt_hw_interrupt_set_pending(int vector) +{ + arm_gic_set_pending_irq(0, vector); +} + +/** + * 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) +{ + return arm_gic_get_pending_irq(0, vector); +} + +/** + * This function clear interrupt pending flag. + * @param vector: the interrupt number + */ +void rt_hw_interrupt_clear_pending(int vector) +{ + arm_gic_clear_pending_irq(0, vector); +} + +/** + * 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) +{ + arm_gic_set_priority(0, vector, priority); +} + +/** + * This function get interrupt priority. + * @param vector: the interrupt number + * @return interrupt priority value + */ +unsigned int rt_hw_interrupt_get_priority(int vector) +{ + return arm_gic_get_priority(0, vector); +} + +/** + * This function set priority masking threshold. + * @param priority: priority masking threshold + */ +void rt_hw_interrupt_set_priority_mask(unsigned int priority) +{ + arm_gic_set_interface_prior_mask(0, priority); +} + +/** + * This function get priority masking threshold. + * @param none + * @return priority masking threshold + */ +unsigned int rt_hw_interrupt_get_priority_mask(void) +{ + return arm_gic_get_interface_prior_mask(0); +} + +/** + * 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) +{ + int status; + + if (bits < 8) + { + arm_gic_set_binary_point(0, (7 - bits)); + status = 0; + } + else + { + status = -1; + } + + return (status); +} + +/** + * 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) +{ + unsigned int bp; + + bp = arm_gic_get_binary_point(0) & 0x07; + + return (7 - bp); } /** @@ -153,31 +359,13 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, #ifdef RT_USING_SMP void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) { - __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(); + arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0); } -#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/common/interrupt.h b/libcpu/aarch64/common/interrupt.h new file mode 100644 index 0000000000..1c4199c61b --- /dev/null +++ b/libcpu/aarch64/common/interrupt.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006-2018, 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/common/mmu.c b/libcpu/aarch64/common/mmu.c index b799143084..8ba903d526 100644 --- a/libcpu/aarch64/common/mmu.c +++ b/libcpu/aarch64/common/mmu.c @@ -1,47 +1,62 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2020-02-20 bigmagic first version + * Date Author Notes + * 2012-01-10 bernard porting to AM1808 */ -#include -#include -#include - -#define TTBR_CNP 1 - -typedef unsigned long int uint64_t; -static unsigned long main_tbl[512 * 20] __attribute__((aligned (4096))); - -#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) +#include +#include +#include -#define PMD_TYPE_SECT (1 << 0) +#include "cp15.h" +#include "mmu.h" -#define PMD_TYPE_TABLE (3 << 0) +#ifdef RT_USING_USERSPACE +#include "page.h" +#endif -#define PTE_TYPE_PAGE (3 << 0) +#define MMU_LEVEL_MASK 0x1ffUL +#define MMU_LEVEL_SHIFT 9 +#define MMU_ADDRESS_BITS 39 +#define MMU_ADDRESS_MASK 0x0000fffffffff000UL +#define MMU_ATTRIB_MASK 0xfff0000000000ffcUL -#define BITS_PER_VA 39 +#define MMU_TYPE_MASK 3UL +#define MMU_TYPE_USED 1UL +#define MMU_TYPE_BLOCK 1UL +#define MMU_TYPE_TABLE 3UL +#define MMU_TYPE_PAGE 3UL -/* Granule size of 4KB is being used */ -#define GRANULE_SIZE_SHIFT 12 -#define GRANULE_SIZE (1 << GRANULE_SIZE_SHIFT) -#define XLAT_ADDR_MASK ((1UL << BITS_PER_VA) - GRANULE_SIZE) +#define MMU_TBL_BLOCK_2M_LEVEL 2 +#define MMU_TBL_PAGE_4k_LEVEL 3 +#define MMU_TBL_LEVEL_NR 4 -#define PMD_TYPE_MASK (3 << 0) +void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr); -int free_idx = 1; +struct page_table +{ + unsigned long page[512]; +}; -void __asm_invalidate_icache_all(void); -void __asm_flush_dcache_all(void); -int __asm_flush_l3_cache(void); -void __asm_flush_dcache_range(unsigned long long start, unsigned long long end); -void __asm_invalidate_dcache_all(void); -void __asm_invalidate_icache_all(void); +static struct page_table *__init_page_array; +static unsigned long __page_off = 0UL; +unsigned long get_free_page(void) +{ + if (!__init_page_array) + { + __init_page_array = (struct page_table *)(((unsigned long)HEAP_BEGIN + ARCH_PAGE_MASK) & ~(ARCH_PAGE_MASK)); + } + __page_off++; + if (__init_page_array + __page_off > (struct page_table *)HEAP_END) + { + return 0; + } + return (unsigned long)(__init_page_array[__page_off - 1].page); +} void mmu_memset(char *dst, char v, size_t len) { @@ -51,148 +66,291 @@ void mmu_memset(char *dst, char v, size_t len) } } -static unsigned long __page_off = 0; -static unsigned long get_free_page(void) +static int _map_single_page_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr) { - __page_off += 512; - return (unsigned long)(main_tbl + __page_off); -} - + int level; + unsigned long* cur_lv_tbl = lv0_tbl; + unsigned long page; + unsigned long off; + int level_shift = MMU_ADDRESS_BITS; -static inline unsigned int get_sctlr(void) -{ - unsigned int val; - asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc"); - return val; + if (va & ARCH_SECTION_MASK) + { + return MMU_MAP_ERROR_VANOTALIGN; + } + if (pa & ARCH_SECTION_MASK) + { + return MMU_MAP_ERROR_PANOTALIGN; + } + for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; level++) + { + off = (va >> level_shift); + off &= MMU_LEVEL_MASK; + if (!(cur_lv_tbl[off] & MMU_TYPE_USED)) + { + page = get_free_page(); + if (!page) + { + return MMU_MAP_ERROR_NOPAGE; + } + mmu_memset((char *)page, 0, ARCH_PAGE_SIZE); + cur_lv_tbl[off] = page | MMU_TYPE_TABLE; + } + page = cur_lv_tbl[off]; + if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) + { + //is block! error! + return MMU_MAP_ERROR_CONFLICT; + } + cur_lv_tbl = (unsigned long*)(page & MMU_ADDRESS_MASK); + level_shift -= MMU_LEVEL_SHIFT; + } + attr &= MMU_ATTRIB_MASK; + pa |= (attr | MMU_TYPE_BLOCK); //block + off = (va >> ARCH_SECTION_SHIFT); + off &= MMU_LEVEL_MASK; + cur_lv_tbl[off] = pa; + return 0; } -static inline void set_sctlr(unsigned int val) +int armv8_init_map_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long count, unsigned long attr) { - asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc"); - asm volatile("isb"); + unsigned long i; + int ret; + + if (va & ARCH_SECTION_MASK) + { + return -1; + } + if (pa & ARCH_SECTION_MASK) + { + return -1; + } + for (i = 0; i < count; i++) + { + ret = _map_single_page_2M(lv0_tbl, va, pa, attr); + va += ARCH_SECTION_SIZE; + pa += ARCH_SECTION_SIZE; + if (ret != 0) + { + return ret; + } + } + return 0; } -void mmu_init(void) +static int _kenrel_map_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr) { - unsigned long val64; - unsigned long val32; + int level; + unsigned long* cur_lv_tbl = lv0_tbl; + unsigned long page; + unsigned long off; + int level_shift = MMU_ADDRESS_BITS; - val64 = 0x007f6eUL; - __asm__ volatile("msr MAIR_EL1, %0\n dsb sy\n"::"r"(val64)); - __asm__ volatile("mrs %0, MAIR_EL1\n dsb sy\n":"=r"(val64)); + if (va & ARCH_SECTION_MASK) + { + return MMU_MAP_ERROR_VANOTALIGN; + } + if (pa & ARCH_SECTION_MASK) + { + return MMU_MAP_ERROR_PANOTALIGN; + } + for (level = 0; level < MMU_TBL_BLOCK_2M_LEVEL; level++) + { + off = (va >> level_shift); + off &= MMU_LEVEL_MASK; + if (!(cur_lv_tbl[off] & MMU_TYPE_USED)) + { + page = (unsigned long)rt_pages_alloc(0); + if (!page) + { + return MMU_MAP_ERROR_NOPAGE; + } + rt_memset((char *)page, 0, ARCH_PAGE_SIZE); + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)page, ARCH_PAGE_SIZE); + cur_lv_tbl[off] = (page + PV_OFFSET) | MMU_TYPE_TABLE; + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *)); + } + else + { + page = cur_lv_tbl[off]; + page &= MMU_ADDRESS_MASK; + /* page to va */ + page -= PV_OFFSET; + rt_page_ref_inc((void *)page, 0); + } + page = cur_lv_tbl[off]; + if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) + { + //is block! error! + return MMU_MAP_ERROR_CONFLICT; + } + cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK); + cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET); + level_shift -= MMU_LEVEL_SHIFT; + } + attr &= MMU_ATTRIB_MASK; + pa |= (attr | MMU_TYPE_BLOCK); //block + off = (va >> ARCH_SECTION_SHIFT); + off &= MMU_LEVEL_MASK; + cur_lv_tbl[off] = pa; + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *)); + return 0; +} - //TCR_EL1 - val32 = (16UL << 0)//48bit - | (0x0UL << 6) - | (0x0UL << 7) - | (0x3UL << 8) - | (0x3UL << 10)//Inner Shareable - | (0x2UL << 12) - | (0x0UL << 14)//4K - | (0x0UL << 16) - | (0x0UL << 22) - | (0x1UL << 23) - | (0x2UL << 30) - | (0x1UL << 32) - | (0x0UL << 35) - | (0x0UL << 36) - | (0x0UL << 37) - | (0x0UL << 38); - __asm__ volatile("msr TCR_EL1, %0\n"::"r"(val32)); - __asm__ volatile("mrs %0, TCR_EL1\n":"=r"(val32)); - - __asm__ volatile("msr TTBR0_EL1, %0\n dsb sy\n"::"r"(main_tbl)); - __asm__ volatile("mrs %0, TTBR0_EL1\n dsb sy\n":"=r"(val64)); - - mmu_memset((char *)main_tbl, 0, 4096); -} - -void mmu_enable(void) +struct mmu_level_info { - unsigned long val64; - unsigned long val32; + unsigned long *pos; + void *page; +}; - __asm__ volatile("mrs %0, SCTLR_EL1\n":"=r"(val64)); - val64 &= ~0x1000; //disable I - __asm__ volatile("dmb sy\n msr SCTLR_EL1, %0\n isb sy\n"::"r"(val64)); +static void _kenrel_unmap_4K(unsigned long* lv0_tbl, void* v_addr) +{ + int level; + unsigned long va = (unsigned long)v_addr; + unsigned long* cur_lv_tbl = lv0_tbl; + unsigned long page; + unsigned long off; + struct mmu_level_info level_info[4]; + int ref; + int level_shift = MMU_ADDRESS_BITS; + unsigned long *pos; - __asm__ volatile("IC IALLUIS\n dsb sy\n isb sy\n"); - __asm__ volatile("tlbi vmalle1\n dsb sy\n isb sy\n"); + rt_memset(level_info, 0 , sizeof level_info); + for (level = 0; level < MMU_TBL_LEVEL_NR; level++) + { + off = (va >> level_shift); + off &= MMU_LEVEL_MASK; + page = cur_lv_tbl[off]; + if (!(page & MMU_TYPE_USED)) + { + break; + } + if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) + { + break; + } + level_info[level].pos = cur_lv_tbl + off; + cur_lv_tbl = (unsigned long*)(page & MMU_ADDRESS_MASK); + cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET); + level_info[level].page = cur_lv_tbl; + level_shift -= MMU_LEVEL_SHIFT; + } - //SCTLR_EL1, turn on mmu - __asm__ volatile("mrs %0, SCTLR_EL1\n":"=r"(val32)); - val32 |= 0x1005; //enable mmu, I C M - __asm__ volatile("dmb sy\n msr SCTLR_EL1, %0\nisb sy\n"::"r"(val32)); - rt_hw_icache_enable(); - rt_hw_dcache_enable(); + level = MMU_TBL_PAGE_4k_LEVEL; + pos = level_info[level].pos; + if (pos) + { + *pos = RT_NULL; + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, pos, sizeof(void *)); + } + level--; + while (level >= 0) + { + pos = level_info[level].pos; + if (pos) + { + void *cur_page = level_info[level].page; + ref = rt_page_ref_get(cur_page, 0); + if (ref == 1) + { + *pos = RT_NULL; + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, pos, sizeof(void *)); + } + rt_pages_free(cur_page, 0); + } + level--; + } + asm volatile("tlbi vae1, %0\ndsb sy"::"r"(v_addr):"memory"); + return; } -static int map_single_page_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr) +static int _kenrel_map_4K(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr) { + int ret = 0; int level; unsigned long* cur_lv_tbl = lv0_tbl; unsigned long page; unsigned long off; - int level_shift = 39; + int level_shift = MMU_ADDRESS_BITS; - if (va & (0x200000UL - 1)) + if (va & ARCH_PAGE_MASK) { return MMU_MAP_ERROR_VANOTALIGN; } - if (pa & (0x200000UL - 1)) + if (pa & ARCH_PAGE_MASK) { return MMU_MAP_ERROR_PANOTALIGN; } - for (level = 0; level < 2; level++) + for (level = 0; level < MMU_TBL_PAGE_4k_LEVEL; level++) { off = (va >> level_shift); off &= MMU_LEVEL_MASK; - if ((cur_lv_tbl[off] & 1) == 0) + if (!(cur_lv_tbl[off] & MMU_TYPE_USED)) { - page = get_free_page(); - if (!page) + page = (unsigned long)rt_pages_alloc(0); + if (!page) { - return MMU_MAP_ERROR_NOPAGE; + ret = MMU_MAP_ERROR_NOPAGE; + goto err; } - mmu_memset((char *)page, 0, 4096); - cur_lv_tbl[off] = page | 0x3UL; + rt_memset((void *)page, 0, ARCH_PAGE_SIZE); + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)page, ARCH_PAGE_SIZE); + cur_lv_tbl[off] = (page + PV_OFFSET) | MMU_TYPE_TABLE; + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *)); + } + else + { + page = cur_lv_tbl[off]; + page &= MMU_ADDRESS_MASK; + /* page to va */ + page -= PV_OFFSET; + rt_page_ref_inc((void *)page, 0); } page = cur_lv_tbl[off]; - if (!(page & 0x2)) + if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) { //is block! error! - return MMU_MAP_ERROR_CONFLICT; + ret = MMU_MAP_ERROR_CONFLICT; + goto err; } - cur_lv_tbl = (unsigned long*)(page & 0x0000fffffffff000UL); - level_shift -= 9; + cur_lv_tbl = (unsigned long *)(page & MMU_ADDRESS_MASK); + cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET); + level_shift -= MMU_LEVEL_SHIFT; } - attr &= 0xfff0000000000ffcUL; - pa |= (attr | 0x1UL); //block - off = (va >> 21); + //now is level page + attr &= MMU_ATTRIB_MASK; + pa |= (attr | MMU_TYPE_PAGE); //page + off = (va >> ARCH_PAGE_SHIFT); off &= MMU_LEVEL_MASK; - cur_lv_tbl[off] = pa; - return 0; + cur_lv_tbl[off] = pa; //page + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cur_lv_tbl + off, sizeof(void *)); + return ret; +err: + _kenrel_unmap_4K(lv0_tbl, (void *)va); + return ret; } -int armv8_map_2M(unsigned long va, unsigned long pa, int count, unsigned long attr) +int kernel_map_fixed(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long count, unsigned long attr) { - int i; + unsigned long i; int ret; + unsigned long _attr = MMU_MAP_CUSTOM(MMU_AP_KAUN, attr); - if (va & (0x200000 - 1)) + if (va & ARCH_SECTION_MASK) { return -1; } - if (pa & (0x200000 - 1)) + if (pa & ARCH_SECTION_MASK) { return -1; } for (i = 0; i < count; i++) { - ret = map_single_page_2M((unsigned long *)main_tbl, va, pa, attr); - va += 0x200000; - pa += 0x200000; + ret = _kenrel_map_2M(lv0_tbl, va, pa, _attr); + va += ARCH_SECTION_SIZE; + pa += ARCH_SECTION_SIZE; if (ret != 0) { return ret; @@ -201,167 +359,551 @@ int armv8_map_2M(unsigned long va, unsigned long pa, int count, unsigned long at return 0; } -static void set_table(uint64_t *pt, uint64_t *table_addr) +/************ setting el1 mmu register************** + MAIR_EL1 + index 0 : memory outer writeback, write/read alloc + index 1 : memory nocache + index 2 : device nGnRnE + *****************************************************/ +void mmu_tcr_init(void *tbl0, void *tbl1) +{ + unsigned long val64; + + val64 = 0x00447fUL; + __asm__ volatile("msr MAIR_EL1, %0\n dsb sy\n"::"r"(val64)); + + //TCR_EL1 + val64 = (16UL << 0) //t0sz 48bit + | (0x0UL << 6) //reserved + | (0x0UL << 7) //epd0 + | (0x3UL << 8) //t0 wb cacheable + | (0x3UL << 10) //inner shareable + | (0x2UL << 12) //t0 outer shareable + | (0x0UL << 14) //t0 4K + | (16UL << 16) //t1sz 48bit + | (0x0UL << 22) //define asid use ttbr0.asid + | (0x0UL << 23) //epd1 + | (0x3UL << 24) //t1 inner wb cacheable + | (0x3UL << 26) //t1 outer wb cacheable + | (0x2UL << 28) //t1 outer shareable + | (0x2UL << 30) //t1 4k + | (0x1UL << 32) //001b 64GB PA + | (0x0UL << 35) //reserved + | (0x1UL << 36) //as: 0:8bit 1:16bit + | (0x0UL << 37) //tbi0 + | (0x0UL << 38); //tbi1 + __asm__ volatile("msr TCR_EL1, %0\n"::"r"(val64)); +} + +/* dump 2nd level page table */ +void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) { - uint64_t val; - val = (0x3UL | (uint64_t)table_addr); - *pt = val; } -void mmu_memset2(unsigned char *dst, char v, int len) +void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) { - while (len--) +} + +volatile unsigned long MMUTable[512] __attribute__((aligned(4*1024))); +void rt_hw_mmu_setmtt(unsigned long vaddrStart, + unsigned long vaddrEnd, + unsigned long paddrStart, + unsigned long attr) +{ + unsigned long count; + + if (vaddrStart & ARCH_SECTION_MASK) { - *dst++ = v; + return; + } + if (paddrStart & ARCH_SECTION_MASK) + { + return; + } + if (vaddrStart > vaddrEnd) + { + return; + } + count = vaddrEnd + 1; + if (count & ARCH_SECTION_MASK) + { + return; } + count -= vaddrStart; + if (count == 0) + { + return; + } + count >>= ARCH_SECTION_SHIFT; + kernel_map_fixed((unsigned long *)MMUTable, vaddrStart, paddrStart, count, attr); } -static uint64_t *create_table(void) +static void kernel_mmu_switch(unsigned long tbl) { - uint64_t *new_table = (uint64_t *)((unsigned char *)&main_tbl[0] + free_idx * 4096); //+ free_idx * GRANULE_SIZE; - /* Mark all entries as invalid */ - mmu_memset2((unsigned char *)new_table, 0, 4096); - free_idx++; - return new_table; + tbl += PV_OFFSET; + __asm__ volatile("msr TTBR1_EL1, %0\n dsb sy\nisb"::"r"(tbl):"memory"); + __asm__ volatile("tlbi vmalle1\n dsb sy\nisb":::"memory"); + __asm__ volatile("ic ialluis\n dsb sy\nisb":::"memory"); } -static int pte_type(uint64_t *pte) +void rt_hw_mmu_setup(struct mem_desc *mdesc, int desc_nr) +{ + /* set page table */ + for(; desc_nr > 0; desc_nr--) + { + rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, + mdesc->paddr_start, mdesc->attr); + mdesc++; + } + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)MMUTable, sizeof MMUTable); + kernel_mmu_switch((unsigned long)MMUTable); +} + +/* + mem map + */ +int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off) { - return *pte & PMD_TYPE_MASK; + rt_base_t level; + size_t va_s, va_e; + + if (!mmu_info || !vtable) + { + return -1; + } + + va_s = (size_t)v_address; + va_e = (size_t)v_address + size - 1; + + if ( va_e < va_s) + { + return -1; + } + + va_s >>= ARCH_SECTION_SHIFT; + va_e >>= ARCH_SECTION_SHIFT; + + if (va_s == 0) + { + return -1; + } + + level = rt_hw_interrupt_disable(); + + mmu_info->vtable = vtable; + mmu_info->vstart = va_s; + mmu_info->vend = va_e; + mmu_info->pv_off = pv_off; + + rt_hw_interrupt_enable(level); + + return 0; } -static int level2shift(int level) +int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size) { - /* Page is 12 bits wide, every level translates 9 bits */ - return (12 + 9 * (3 - level)); + return 0; } -static uint64_t *get_level_table(uint64_t *pte) +static size_t find_vaddr(rt_mmu_info *mmu_info, int pages) { - uint64_t *table = (uint64_t *)(*pte & XLAT_ADDR_MASK); - - if (pte_type(pte) != PMD_TYPE_TABLE) + size_t loop_pages; + size_t va; + size_t find_va = 0; + int n = 0; + size_t i; + + if (!pages) { - table = create_table(); - set_table(pte, table); + return 0; } - return table; + + if (!mmu_info) + { + return 0; + } + + loop_pages = mmu_info->vend - mmu_info->vstart + 1; + loop_pages <<= (ARCH_SECTION_SHIFT - ARCH_PAGE_SHIFT); + va = mmu_info->vstart; + va <<= ARCH_SECTION_SHIFT; + for (i = 0; i < loop_pages; i++, va += ARCH_PAGE_SIZE) + { + if (_rt_hw_mmu_v2p(mmu_info, (void *)va)) + { + n = 0; + find_va = 0; + continue; + } + if (!find_va) + { + find_va = va; + } + n++; + if (n >= pages) + { + return find_va; + } + } + return 0; } -static void map_region(uint64_t virt, uint64_t phys, uint64_t size, uint64_t attr) +#ifdef RT_USING_USERSPACE +static int check_vaddr(rt_mmu_info *mmu_info, void *va, int pages) { - uint64_t block_size = 0; - uint64_t block_shift = 0; - uint64_t *pte; - uint64_t idx = 0; - uint64_t addr = 0; - uint64_t *table = 0; - int level = 0; + size_t loop_va; - addr = virt; - while (size) + if (!pages) { - table = &main_tbl[0]; - for (level = 0; level < 4; level++) - { - block_shift = level2shift(level); - idx = addr >> block_shift; - idx = idx%512; - block_size = (uint64_t)(1L << block_shift); - pte = table + idx; + return -1; + } - if (size >= block_size && IS_ALIGNED(addr, block_size)) - { - attr &= 0xfff0000000000ffcUL; - if(level != 3) - { - *pte = phys | (attr | 0x1UL); - } - else - { - *pte = phys | (attr | 0x3UL); - } - addr += block_size; - phys += block_size; - size -= block_size; - break; - } - table = get_level_table(pte); + if (!mmu_info) + { + return -1; + } + + loop_va = ((size_t)va >> ARCH_SECTION_SHIFT); + if (loop_va < mmu_info->vstart || loop_va > mmu_info->vend) + { + return -1; + } + loop_va += ((pages << ARCH_PAGE_SHIFT) >> ARCH_SECTION_SHIFT); + if (loop_va < mmu_info->vstart || loop_va > mmu_info->vend + 1) + { + return -1; + } + + loop_va = (size_t)va & ~ARCH_PAGE_MASK; + while (pages--) + { + if (_rt_hw_mmu_v2p(mmu_info, (void *)loop_va)) + { + return -1; } + loop_va += ARCH_PAGE_SIZE; } + return 0; } +#endif -void armv8_map(unsigned long va, unsigned long pa, unsigned long size, unsigned long attr) +static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t npages) { - map_region(va, pa, size, attr); + size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; + + if (!mmu_info || !mmu_info->vtable) + { + return; + } + + while (npages--) + { + _kenrel_unmap_4K(mmu_info->vtable, (void *)loop_va); + loop_va += ARCH_PAGE_SIZE; + } } -void rt_hw_dcache_enable(void) +static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void* v_addr, void* p_addr, size_t npages, size_t attr) { - if (!(get_sctlr() & CR_M)) + size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; + size_t loop_pa = (size_t)p_addr & ~ARCH_PAGE_MASK; + + if (!mmu_info) + { + return -1; + } + + while (npages--) + { + _kenrel_map_4K(mmu_info->vtable, loop_va, loop_pa, attr); + loop_va += ARCH_PAGE_SIZE; + loop_pa += ARCH_PAGE_SIZE; + } + return 0; +} + +static void rt_hw_cpu_tlb_invalidate(void) +{ + __asm__ volatile("tlbi vmalle1\n dsb sy\n isb sy\n"); +} + +#ifdef RT_USING_USERSPACE +void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr) +{ + size_t pa_s, pa_e; + size_t vaddr; + int pages; + int ret; + + if (!size) + { + return 0; + } + pa_s = (size_t)p_addr; + pa_e = (size_t)p_addr + size - 1; + pa_s >>= ARCH_PAGE_SHIFT; + pa_e >>= ARCH_PAGE_SHIFT; + pages = pa_e - pa_s + 1; + if (v_addr) { - rt_kprintf("please init mmu!\n"); + vaddr = (size_t)v_addr; + pa_s = (size_t)p_addr; + if ((vaddr & ARCH_PAGE_MASK) != (pa_s & ARCH_PAGE_MASK)) + { + return 0; + } + vaddr &= ~ARCH_PAGE_MASK; + if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0) + { + return 0; + } } else { - set_sctlr(get_sctlr() | CR_C); + vaddr = find_vaddr(mmu_info, pages); + } + if (vaddr) { + ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr); + if (ret == 0) + { + rt_hw_cpu_tlb_invalidate(); + return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK)); + } + } + return 0; +} +#else +void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr) +{ + size_t pa_s, pa_e; + size_t vaddr; + int pages; + int ret; + + pa_s = (size_t)p_addr; + pa_e = (size_t)p_addr + size - 1; + pa_s >>= ARCH_PAGE_SHIFT; + pa_e >>= ARCH_PAGE_SHIFT; + pages = pa_e - pa_s + 1; + vaddr = find_vaddr(mmu_info, pages); + if (vaddr) { + ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr); + if (ret == 0) + { + rt_hw_cpu_tlb_invalidate(); + return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK)); + } } + return 0; } +#endif -void rt_hw_dcache_flush_all(void) +#ifdef RT_USING_USERSPACE +static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void* v_addr, size_t npages, size_t attr) { + size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK; + size_t loop_pa; + + if (!mmu_info) + { + return -1; + } + + while (npages--) + { + loop_pa = (size_t)rt_pages_alloc(0); + if (!loop_pa) + { + goto err; + } + loop_pa += mmu_info->pv_off; + _kenrel_map_4K(mmu_info->vtable, loop_va, loop_pa, attr); + loop_va += ARCH_PAGE_SIZE; + } + return 0; +err: + { + /* error, unmap and quit */ + int i; + void *va, *pa; + + va = (void*)((size_t)v_addr & ~ARCH_PAGE_MASK); + for (i = 0; i < npages; i++) + { + pa = rt_hw_mmu_v2p(mmu_info, va); + pa = (void*)((char*)pa - mmu_info->pv_off); + rt_pages_free(pa, 0); + va = (void*)((char*)va + ARCH_PAGE_SIZE); + } + + __rt_hw_mmu_unmap(mmu_info, v_addr, npages); + return -1; + } +} + +void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr) +{ + size_t vaddr; + size_t offset; + int pages; int ret; - __asm_flush_dcache_all(); - ret = __asm_flush_l3_cache(); - if (ret) + if (!size) + { + return 0; + } + offset = (size_t)v_addr & ARCH_PAGE_MASK; + size += (offset + ARCH_PAGE_SIZE - 1); + pages = (size >> ARCH_PAGE_SHIFT); + if (v_addr) { - rt_kprintf("flushing dcache returns 0x%x\n", ret); + vaddr = (size_t)v_addr; + vaddr &= ~ARCH_PAGE_MASK; + if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0) + { + return 0; + } } else { - rt_kprintf("flushing dcache successfully.\n"); + vaddr = find_vaddr(mmu_info, pages); + } + if (vaddr) { + ret = __rt_hw_mmu_map_auto(mmu_info, (void*)vaddr, pages, attr); + if (ret == 0) + { + rt_hw_cpu_tlb_invalidate(); + return (void*)((char*)vaddr + offset); + } } + return 0; } +#endif -void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size) +void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size) { - __asm_flush_dcache_range(start_addr, start_addr + size); + size_t va_s, va_e; + int pages; + + va_s = (size_t)v_addr; + va_e = (size_t)v_addr + size - 1; + va_s >>= ARCH_PAGE_SHIFT; + va_e >>= ARCH_PAGE_SHIFT; + pages = va_e - va_s + 1; + __rt_hw_mmu_unmap(mmu_info, v_addr, pages); + rt_hw_cpu_tlb_invalidate(); } -void rt_hw_dcache_invalidate_range(unsigned long start_addr,unsigned long size) + +#ifdef RT_USING_USERSPACE +void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr) { - __asm_flush_dcache_range(start_addr, start_addr + size); + void *ret; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr); + rt_hw_interrupt_enable(level); + return ret; } -void rt_hw_dcache_invalidate_all(void) +void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr) { - __asm_invalidate_dcache_all(); + void *ret; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr); + rt_hw_interrupt_enable(level); + return ret; } +#endif -void rt_hw_dcache_disable(void) +void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size) { - /* if cache isn't enabled no need to disable */ - if(!(get_sctlr() & CR_C)) - { - rt_kprintf("need enable cache!\n"); - return; - } - set_sctlr(get_sctlr() & ~CR_C); + rt_base_t level; + + level = rt_hw_interrupt_disable(); + _rt_hw_mmu_unmap(mmu_info, v_addr, size); + rt_hw_interrupt_enable(level); } -//icache -void rt_hw_icache_enable(void) +void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr) { - __asm_invalidate_icache_all(); - set_sctlr(get_sctlr() | CR_I); + int level; + unsigned long va = (unsigned long)v_addr; + unsigned long pa; + unsigned long* cur_lv_tbl; + unsigned long page; + unsigned long off; + unsigned long off_addr; + int level_shift = MMU_ADDRESS_BITS; + + if (!mmu_info) + { + return (void*)0; + } + cur_lv_tbl = mmu_info->vtable; + for (level = 0; level < MMU_TBL_PAGE_4k_LEVEL; level++) + { + off = (va >> level_shift); + off &= MMU_LEVEL_MASK; + if (!(cur_lv_tbl[off] & MMU_TYPE_USED)) + { + return (void *)0; + } + page = cur_lv_tbl[off]; + if ((page & MMU_TYPE_MASK) == MMU_TYPE_BLOCK) + { + off_addr = va & ((1UL << level_shift) - 1); + pa = (page & MMU_ADDRESS_MASK); + pa += off_addr; + return (void *)pa; + } + cur_lv_tbl = (unsigned long*)(page & MMU_ADDRESS_MASK); + cur_lv_tbl = (unsigned long *)((unsigned long)cur_lv_tbl - PV_OFFSET); + level_shift -= MMU_LEVEL_SHIFT; + } + //now is level MMU_TBL_PAGE_4k_LEVEL + off = (va >> ARCH_PAGE_SHIFT); + off &= MMU_LEVEL_MASK; + page = cur_lv_tbl[off]; + if (!(page & MMU_TYPE_USED)) + { + return (void *)0; + } + pa = (page & MMU_ADDRESS_MASK); + pa += (va & ARCH_PAGE_MASK); + return (void *)pa; } -void rt_hw_icache_invalidate_all(void) +void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr) { - __asm_invalidate_icache_all(); + void *ret; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + ret = _rt_hw_mmu_v2p(mmu_info, v_addr); + rt_hw_interrupt_enable(level); + return ret; } -void rt_hw_icache_disable(void) +#ifdef RT_USING_USERSPACE +void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1, unsigned long size, unsigned long pv_off) { - set_sctlr(get_sctlr() & ~CR_I); -} \ No newline at end of file + int ret; + unsigned long va = KERNEL_VADDR_START; + unsigned long count = (size + ARCH_SECTION_MASK) >> ARCH_SECTION_SHIFT; + unsigned long normal_attr = MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM); + + ret = armv8_init_map_2M(tbl1 , va, va + pv_off, count, normal_attr); + if (ret != 0) + { + while (1); + } + ret = armv8_init_map_2M(tbl0, va + pv_off, va + pv_off, count, normal_attr); + if (ret != 0) + { + while (1); + } +} +#endif diff --git a/libcpu/aarch64/common/mmu.h b/libcpu/aarch64/common/mmu.h index 6a66472c79..abc159e521 100644 --- a/libcpu/aarch64/common/mmu.h +++ b/libcpu/aarch64/common/mmu.h @@ -1,78 +1,136 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2020-02-20 bigmagic first version + * Date Author Notes + * 2021-05-12 RT-Thread the first version */ +#ifndef __MMU_H_ +#define __MMU_H_ -#ifndef __MMU_H__ -#define __MMU_H__ +#include -/* - * CR1 bits (CP#15 CR1) - */ -#define CR_M (1 << 0) /* MMU enable */ -#define CR_A (1 << 1) /* Alignment abort enable */ -#define CR_C (1 << 2) /* Dcache enable */ -#define CR_W (1 << 3) /* Write buffer enable */ -#define CR_P (1 << 4) /* 32-bit exception handler */ -#define CR_D (1 << 5) /* 32-bit data address range */ -#define CR_L (1 << 6) /* Implementation defined */ -#define CR_B (1 << 7) /* Big endian */ -#define CR_S (1 << 8) /* System MMU protection */ -#define CR_R (1 << 9) /* ROM MMU protection */ -#define CR_F (1 << 10) /* Implementation defined */ -#define CR_Z (1 << 11) /* Implementation defined */ -#define CR_I (1 << 12) /* Icache enable */ -#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ -#define CR_RR (1 << 14) /* Round Robin cache replacement */ -#define CR_L4 (1 << 15) /* LDR pc can set T bit */ -#define CR_DT (1 << 16) -#define CR_IT (1 << 18) -#define CR_ST (1 << 19) -#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ -#define CR_U (1 << 22) /* Unaligned access operation */ -#define CR_XP (1 << 23) /* Extended page tables */ -#define CR_VE (1 << 24) /* Vectored interrupts */ -#define CR_EE (1 << 25) /* Exception (Big) Endian */ -#define CR_TRE (1 << 28) /* TEX remap enable */ -#define CR_AFE (1 << 29) /* Access flag enable */ -#define CR_TE (1 << 30) /* Thumb exception enable */ +/* normal memory wra mapping type */ +#define NORMAL_MEM 0 +/* normal nocache memory mapping type */ +#define NORMAL_NOCACHE_MEM 1 +/* device mapping type */ +#define DEVICE_MEM 2 -#define MMU_LEVEL_MASK 0x1ffUL -#define MMU_MAP_ERROR_VANOTALIGN -1 -#define MMU_MAP_ERROR_PANOTALIGN -2 -#define MMU_MAP_ERROR_NOPAGE -3 -#define MMU_MAP_ERROR_CONFLICT -4 +struct mem_desc +{ + unsigned long vaddr_start; + unsigned long vaddr_end; + unsigned long paddr_start; + unsigned long attr; +}; -#define MEM_ATTR_MEMORY ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x1UL << 2)) -#define MEM_ATTR_IO ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x2UL << 2)) +#define MMU_AF_SHIFT 10 +#define MMU_SHARED_SHIFT 8 +#define MMU_AP_SHIFT 6 +#define MMU_MA_SHIFT 2 -#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000) +#define MMU_AP_KAUN 0UL /* kernel r/w, user none */ +#define MMU_AP_KAUA 1UL /* kernel r/w, user r/w */ +#define MMU_AP_KRUN 2UL /* kernel r, user none */ +#define MMU_AP_KRUR 3UL /* kernel r, user r */ -void mmu_init(void); +#define MMU_MAP_K_RO (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KRUN << MMU_AP_SHIFT) |\ + (NORMAL_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_K_RWCB (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KAUN << MMU_AP_SHIFT) |\ + (NORMAL_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_K_RW (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KAUN << MMU_AP_SHIFT) |\ + (NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_K_DEVICE (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KAUN << MMU_AP_SHIFT) |\ + (DEVICE_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_U_RO (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KRUR << MMU_AP_SHIFT) |\ + (NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_U_RWCB (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KAUA << MMU_AP_SHIFT) |\ + (NORMAL_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_U_RW (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KAUA << MMU_AP_SHIFT) |\ + (NORMAL_NOCACHE_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_U_DEVICE (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + (MMU_AP_KAUA << MMU_AP_SHIFT) |\ + (DEVICE_MEM << MMU_MA_SHIFT)\ + ) +#define MMU_MAP_CUSTOM(ap, mtype) (\ + (0x1UL << MMU_AF_SHIFT) |\ + (0x2UL << MMU_SHARED_SHIFT) |\ + ((ap) << MMU_AP_SHIFT) |\ + ((mtype) << MMU_MA_SHIFT)\ + ) -void mmu_enable(void); +#define ARCH_SECTION_SHIFT 21 +#define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT) +#define ARCH_SECTION_MASK (ARCH_SECTION_SIZE - 1) +#define ARCH_PAGE_SHIFT 12 +#define ARCH_PAGE_SIZE (1 << ARCH_PAGE_SHIFT) +#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1) +#define ARCH_PAGE_TBL_SHIFT 12 +#define ARCH_PAGE_TBL_SIZE (1 << ARCH_PAGE_TBL_SHIFT) +#define ARCH_PAGE_TBL_MASK (ARCH_PAGE_TBL_SIZE - 1) + +#define ARCH_ADDRESS_WIDTH_BITS 64 + +#define MMU_MAP_ERROR_VANOTALIGN -1 +#define MMU_MAP_ERROR_PANOTALIGN -2 +#define MMU_MAP_ERROR_NOPAGE -3 +#define MMU_MAP_ERROR_CONFLICT -4 -int armv8_map_2M(unsigned long va, unsigned long pa, int count, unsigned long attr); +typedef struct +{ + size_t *vtable; + size_t vstart; + size_t vend; + size_t pv_off; +} rt_mmu_info; -void armv8_map(unsigned long va, unsigned long pa, unsigned long size, unsigned long attr); +void rt_hw_mmu_setup_early(unsigned long *tbl0, unsigned long *tbl1, unsigned long size, unsigned long pv_off); +void rt_hw_mmu_setup(struct mem_desc *mdesc, int desc_nr); -//dcache -void rt_hw_dcache_enable(void); -void rt_hw_dcache_flush_all(void); -void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size); -void rt_hw_dcache_invalidate_range(unsigned long start_addr,unsigned long size); -void rt_hw_dcache_invalidate_all(void); -void rt_hw_dcache_disable(void); +int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off); +int rt_hw_mmu_ioremap_init(rt_mmu_info *mmu_info, void* v_address, size_t size); -//icache -void rt_hw_icache_enable(void); -void rt_hw_icache_invalidate_all(void); -void rt_hw_icache_disable(void); +#ifdef RT_USING_USERSPACE +void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr); +void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr); +#else +void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr); +#endif +void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size); +void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr); -#endif /*__MMU_H__*/ +#endif diff --git a/libcpu/aarch64/common/page.c b/libcpu/aarch64/common/page.c new file mode 100644 index 0000000000..d3c3779f81 --- /dev/null +++ b/libcpu/aarch64/common/page.c @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-11-01 Jesven The first version + */ +#include + +#include +#include + +#ifdef RT_USING_USERSPACE + +#include +#include + +#define ARCH_PAGE_LIST_SIZE (ARCH_ADDRESS_WIDTH_BITS - ARCH_PAGE_SHIFT) + +#define DBG_TAG "PAGE" +#define DBG_LVL DBG_WARNING +#include + +struct page +{ + struct page *next; /* same level next */ + struct page *pre; /* same level pre */ + uint32_t size_bits; /* if is ARCH_ADDRESS_WIDTH_BITS, means not free */ + int ref_cnt; /* page group ref count */ +}; + +static struct page* page_start; +static void* page_addr; +static size_t page_nr; + +static struct page *page_list[ARCH_PAGE_LIST_SIZE]; + +RT_WEAK int rt_clz(size_t n) +{ + int bits = sizeof(size_t) * 8; + + n |= (n >> 1); + n |= (n >> 2); + n |= (n >> 4); + n |= (n >> 8); + n |= (n >> 16); + +#ifdef ARCH_CPU_64BIT + n |= (n >> 32); + + n = (n & 0x5555555555555555UL) + ((n >> 1) & 0x5555555555555555UL); + n = (n & 0x3333333333333333UL) + ((n >> 2) & 0x3333333333333333UL); + n = (n & 0x0707070707070707UL) + ((n >> 4) & 0x0707070707070707UL); + n = (n & 0x000f000f000f000fUL) + ((n >> 8) & 0x000f000f000f000fUL); + n = (n & 0x0000001f0000001fUL) + ((n >> 16) & 0x0000001f0000001fUL); + n = (n & 0x000000000000003fUL) + ((n >> 32) & 0x000000000000003fUL); +#else + n = (n & 0x55555555UL) + ((n >> 1) & 0x55555555UL); + n = (n & 0x33333333UL) + ((n >> 2) & 0x33333333UL); + n = (n & 0x07070707UL) + ((n >> 4) & 0x07070707UL); + n = (n & 0x000f000fUL) + ((n >> 8) & 0x000f000fUL); + n = (n & 0x0000001fUL) + ((n >> 16) & 0x0000001fUL); +#endif + return bits - n; +} + +RT_WEAK int rt_ctz(size_t n) +{ + int ret = sizeof(size_t) * 8; + + if (n) + { + ret -= (rt_clz(n ^ (n - 1)) + 1); + } + return ret; +} + +size_t rt_page_bits(size_t size) +{ + int bit = sizeof(size_t) * 8 - rt_clz(size) - 1; + + if ((size ^ (1UL << bit)) != 0) + { + bit++; + } + bit -= ARCH_PAGE_SHIFT; + if (bit < 0) + { + bit = 0; + } + return bit; +} + +static struct page * addr_to_page(void *addr) +{ + size_t off; + + if (addr < page_addr) + { + return 0; + } + off = (size_t)((char*)addr - (char*)page_addr); + off >>= ARCH_PAGE_SHIFT; + if (off >= page_nr) + { + return 0; + } + return &page_start[off]; +} + +static void* page_to_addr(struct page* p) +{ + if (!p) + { + return 0; + } + return (void*)((char*)page_addr + ((p - page_start) << ARCH_PAGE_SHIFT)); +} + +static inline struct page *buddy_get(struct page *p, uint32_t size_bits) +{ + size_t addr; + + addr = (size_t)page_to_addr(p); + addr ^= (1UL << (size_bits + ARCH_PAGE_SHIFT)); + return addr_to_page((void*)addr); +} + +static void page_remove(struct page *p, uint32_t size_bits) +{ + if (p->pre) + { + p->pre->next = p->next; + } + else + { + page_list[size_bits] = p->next; + } + + if (p->next) + { + p->next->pre = p->pre; + } + + p->size_bits = ARCH_ADDRESS_WIDTH_BITS; +} + +static void page_insert(struct page *p, uint32_t size_bits) +{ + p->next = page_list[size_bits]; + if (p->next) + { + p->next->pre = p; + } + p->pre = 0; + page_list[size_bits] = p; + p->size_bits = size_bits; +} + +static void _pages_ref_inc(struct page *p, uint32_t size_bits) +{ + struct page *page_head; + int idx; + + /* find page group head */ + idx = p - page_start; + if (idx < 0 || idx >= page_nr) + { + return; + } + idx = idx & ~((1UL << size_bits) - 1); + + page_head = page_start + idx; + page_head->ref_cnt++; +} + +static int _pages_ref_get(struct page *p, uint32_t size_bits) +{ + struct page *page_head; + int idx; + + /* find page group head */ + idx = p - page_start; + if (idx < 0 || idx >= page_nr) + { + return 0; + } + idx = idx & ~((1UL << size_bits) - 1); + + page_head = page_start + idx; + return page_head->ref_cnt; +} + +static int _pages_free(struct page *p, uint32_t size_bits) +{ + uint32_t level = size_bits; + uint32_t high = ARCH_ADDRESS_WIDTH_BITS - size_bits - 1; + struct page *buddy; + + RT_ASSERT(p->ref_cnt > 0); + RT_ASSERT(p->size_bits == ARCH_ADDRESS_WIDTH_BITS); + + p->ref_cnt--; + if (p->ref_cnt != 0) + { + return 0; + } + + while (level < high) + { + buddy = buddy_get(p, level); + if (buddy && buddy->size_bits == level) + { + page_remove(buddy, level); + p = (p < buddy) ? p : buddy; + level++; + } + else + { + break; + } + } + page_insert(p, level); + return 1; +} + +static struct page *_pages_alloc(uint32_t size_bits) +{ + struct page *p; + + if (page_list[size_bits]) + { + p = page_list[size_bits]; + page_remove(p, size_bits); + } + else + { + uint32_t level; + uint32_t high = ARCH_ADDRESS_WIDTH_BITS - size_bits - 1; + + for (level = size_bits + 1; level <= high; level++) + { + if (page_list[level]) + { + break; + } + } + if (level == high + 1) + { + return 0; + } + + p = page_list[level]; + page_remove(p, level); + while (level > size_bits) + { + page_insert(p, level - 1); + p = buddy_get(p, level - 1); + level--; + } + } + p->size_bits = ARCH_ADDRESS_WIDTH_BITS; + p->ref_cnt = 1; + return p; +} + +int rt_page_ref_get(void *addr, uint32_t size_bits) +{ + struct page *p; + rt_base_t level; + int ref; + + p = addr_to_page(addr); + level = rt_hw_interrupt_disable(); + ref = _pages_ref_get(p, size_bits); + rt_hw_interrupt_enable(level); + return ref; +} + +void rt_page_ref_inc(void *addr, uint32_t size_bits) +{ + struct page *p; + rt_base_t level; + + p = addr_to_page(addr); + level = rt_hw_interrupt_disable(); + _pages_ref_inc(p, size_bits); + rt_hw_interrupt_enable(level); +} + +void *rt_pages_alloc(uint32_t size_bits) +{ + struct page *p; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + p = _pages_alloc(size_bits); + rt_hw_interrupt_enable(level); + return page_to_addr(p); +} + +int rt_pages_free(void *addr, uint32_t size_bits) +{ + struct page *p; + int real_free = 0; + + p = addr_to_page(addr); + if (p) + { + rt_base_t level; + level = rt_hw_interrupt_disable(); + real_free = _pages_free(p, size_bits); + rt_hw_interrupt_enable(level); + } + return real_free; +} + +void list_page(void) +{ + int i; + size_t total = 0; + + rt_base_t level; + level = rt_hw_interrupt_disable(); + + for (i = 0; i < ARCH_PAGE_LIST_SIZE; i++) + { + struct page *p = page_list[i]; + + rt_kprintf("level %d ", i); + + while (p) + { + total += (1UL << i); + rt_kprintf("[0x%08p]", page_to_addr(p)); + p = p->next; + } + rt_kprintf("\n"); + } + rt_hw_interrupt_enable(level); + rt_kprintf("free pages is %08x\n", total); + rt_kprintf("-------------------------------\n"); +} +MSH_CMD_EXPORT(list_page, show page info); + +void rt_page_get_info(size_t *total_nr, size_t *free_nr) +{ + int i; + size_t total_free = 0; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + for (i = 0; i < ARCH_PAGE_LIST_SIZE; i++) + { + struct page *p = page_list[i]; + + while (p) + { + total_free += (1UL << i); + p = p->next; + } + } + rt_hw_interrupt_enable(level); + *total_nr = page_nr; + *free_nr = total_free; +} + +void rt_page_init(rt_region_t reg) +{ + int i; + + LOG_D("split 0x%08x 0x%08x\n", reg.start, reg.end); + + reg.start += ARCH_PAGE_MASK; + reg.start &= ~ARCH_PAGE_MASK; + + reg.end &= ~ARCH_PAGE_MASK; + + { + int nr = ARCH_PAGE_SIZE / sizeof(struct page); + int total = (reg.end - reg.start) >> ARCH_PAGE_SHIFT; + int mnr = (total + nr) / (nr + 1); + + LOG_D("nr = 0x%08x\n", nr); + LOG_D("total = 0x%08x\n", total); + LOG_D("mnr = 0x%08x\n", mnr); + + RT_ASSERT(mnr < total); + + page_start = (struct page*)reg.start; + reg.start += (mnr << ARCH_PAGE_SHIFT); + page_addr = (void*)reg.start; + page_nr = (reg.end - reg.start) >> ARCH_PAGE_SHIFT; + } + + LOG_D("align 0x%08x 0x%08x\n", reg.start, reg.end); + + /* init free list */ + for (i = 0; i < ARCH_PAGE_LIST_SIZE; i++) + { + page_list[i] = 0; + } + + /* add pages to free list */ + while (reg.start != reg.end) + { + struct page *p; + int align_bits; + int size_bits; + + size_bits = ARCH_ADDRESS_WIDTH_BITS - 1 - rt_clz(reg.end - reg.start); + align_bits = rt_ctz(reg.start); + if (align_bits < size_bits) + { + size_bits = align_bits; + } + p = addr_to_page((void*)reg.start); + p->size_bits = ARCH_ADDRESS_WIDTH_BITS; + p->ref_cnt = 1; + _pages_free(p, size_bits - ARCH_PAGE_SHIFT); + reg.start += (1UL << size_bits); + } +} +#endif diff --git a/libcpu/aarch64/common/page.h b/libcpu/aarch64/common/page.h new file mode 100644 index 0000000000..8b65299d91 --- /dev/null +++ b/libcpu/aarch64/common/page.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-11-01 Jesven The first version + */ + +#ifndef __PAGE_H__ +#define __PAGE_H__ + +#ifdef RT_USING_USERSPACE + +typedef struct tag_region +{ + size_t start; + size_t end; +} rt_region_t; + +void rt_page_init(rt_region_t reg); + +void *rt_pages_alloc(uint32_t size_bits); + +void rt_page_ref_inc(void *addr, uint32_t size_bits); + +int rt_page_ref_get(void *addr, uint32_t size_bits); + +int rt_pages_free(void *addr, uint32_t size_bits); + +void rt_pageinfo_dump(void); + +size_t rt_page_bits(size_t size); + +void rt_page_get_info(size_t *total_nr, size_t *free_nr); + +#endif + +#endif /*__PAGE_H__*/ diff --git a/libcpu/aarch64/cortex-a53/stack.c b/libcpu/aarch64/common/stack.c similarity index 43% rename from libcpu/aarch64/cortex-a53/stack.c rename to libcpu/aarch64/common/stack.c index 68222c2c67..571d392091 100644 --- a/libcpu/aarch64/cortex-a53/stack.c +++ b/libcpu/aarch64/common/stack.c @@ -1,21 +1,18 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * 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 + * 2021-05-12 RT-Thread init */ #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) +#define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_ELx) /** * This function will initialize thread stack @@ -31,20 +28,52 @@ 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 ) 0; /* Q0 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q0 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q1 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q1 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q2 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q2 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q3 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q3 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q4 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q4 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q5 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q5 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q6 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q6 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q7 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q7 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q8 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q8 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q9 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q9 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q10 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q10 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q11 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q11 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q12 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q12 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q13 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q13 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q14 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q14 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q15 */ + *(--stk) = ( rt_ubase_t ) 0; /* Q15 */ + + *(--stk) = ( rt_ubase_t ) 1; /* 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 ) 3; /* X3 */ + *(--stk) = ( rt_ubase_t ) 2; /* X2 */ + *(--stk) = ( rt_ubase_t ) 5; /* X5 */ + *(--stk) = ( rt_ubase_t ) 4; /* X4 */ + *(--stk) = ( rt_ubase_t ) 7; /* X7 */ + *(--stk) = ( rt_ubase_t ) 6; /* X6 */ + *(--stk) = ( rt_ubase_t ) 9; /* X9 */ + *(--stk) = ( rt_ubase_t ) 8; /* X8 */ *(--stk) = ( rt_ubase_t ) 11; /* X11 */ *(--stk) = ( rt_ubase_t ) 10; /* X10 */ *(--stk) = ( rt_ubase_t ) 13; /* X13 */ @@ -65,23 +94,12 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, *(--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 ) 0; /* FPSR */ + *(--stk) = ( rt_ubase_t ) 0; /* FPCR */ *(--stk) = ( rt_ubase_t ) texit; /* X30 - procedure call link register. */ + *(--stk) = ( rt_ubase_t ) 0; /* sp_el0 */ - 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) = INITIAL_SPSR_EL1; *(--stk) = ( rt_ubase_t ) tentry; /* Exception return address. */ diff --git a/libcpu/aarch64/common/startup_gcc.S b/libcpu/aarch64/common/startup_gcc.S index ea4268148c..9674b57d57 100644 --- a/libcpu/aarch64/common/startup_gcc.S +++ b/libcpu/aarch64/common/startup_gcc.S @@ -11,3 +11,8 @@ .section ".start", "ax" Reset_Handler: nop + +.text +.weak SVC_Handler +SVC_Handler: + ret diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c new file mode 100644 index 0000000000..d55e7dace0 --- /dev/null +++ b/libcpu/aarch64/common/trap.c @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2006-2018, 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 "interrupt.h" + +void rt_unwind(struct rt_hw_exp_stack *regs, int pc_adj) +{ +} + +#ifdef RT_USING_FINSH +extern long list_thread(void); +#endif + +#ifdef RT_USING_LWP +#include +#include + +#ifdef LWP_USING_CORE_DUMP +#include +#endif + +void sys_exit(int value); +void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info) +{ + uint32_t mode = regs->spsr; + + if ((mode & 0x1f) == 0x00) + { + rt_kprintf("%s! pc = 0x%08x\n", info, regs->pc - pc_adj); +#ifdef LWP_USING_CORE_DUMP + lwp_core_dump(regs, pc_adj); +#endif + sys_exit(-1); + } +} + +int check_user_stack(unsigned long esr, struct rt_hw_exp_stack *regs) +{ + unsigned char ec; + void *dfar; + int ret = 0; + + ec = (unsigned char)((esr >> 26) & 0x3fU); + switch (ec) + { + case 0x20: + case 0x21: + case 0x24: + asm volatile ("mrs %0, far_el1":"=r"(dfar)); + if (arch_expand_user_stack(dfar)) + { + ret = 1; + } + break; + default: + break; + } + return ret; +} +#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("SP_EL0:0x%16.16p\n", (void *)regs->sp_el0); + rt_kprintf("SPSR :0x%16.16p\n", (void *)regs->spsr); + rt_kprintf("EPC :0x%16.16p\n", (void *)regs->pc); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) +{ +#ifdef RT_USING_LWP +#ifdef RT_USING_GDBSERVER + if (check_debug_event(regs, 4)) + { + return; + } +#endif + check_user_fault(regs, 4, "User prefetch abort"); +#endif + rt_unwind(regs, 4); + rt_kprintf("prefetch abort:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +void rt_hw_trap_irq(void) +{ +#ifdef SOC_BCM283x + extern rt_uint8_t core_timer_flag; + 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; + + if(core_timer_flag != 0) + { + uint32_t cpu_id = rt_hw_cpu_id(); + uint32_t int_source = CORE_IRQSOURCE(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); + } + } + } + } + + /* 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); +} + +void process_exception(unsigned long esr, unsigned long epc); +void SVC_Handler(struct rt_hw_exp_stack *regs); +void rt_hw_trap_exception(struct rt_hw_exp_stack *regs) +{ + unsigned long esr; + unsigned char ec; + + asm volatile ("mrs %0, esr_el1":"=r"(esr)); + ec = (unsigned char)((esr >> 26) & 0x3fU); + + if (ec == 0x15) /* is 64bit syscall ? */ + { + SVC_Handler(regs); + /* never return here */ + } + + if (check_user_stack(esr, regs)) + { + return; + } + + process_exception(esr, regs->pc); + rt_hw_show_register(regs); + rt_kprintf("current: %s\n", rt_thread_self()->name); + check_user_fault(regs, 0, "user fault"); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +void rt_hw_trap_serror(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("SError\n"); + rt_hw_show_register(regs); + rt_kprintf("current: %s\n", rt_thread_self()->name); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} diff --git a/libcpu/aarch64/common/vector_gcc.S b/libcpu/aarch64/common/vector_gcc.S index fc88cce7f8..b8a03b002e 100644 --- a/libcpu/aarch64/common/vector_gcc.S +++ b/libcpu/aarch64/common/vector_gcc.S @@ -10,7 +10,7 @@ .text .globl system_vectors -.globl vector_error +.globl vector_exception .globl vector_irq .globl vector_fiq @@ -20,42 +20,40 @@ system_vectors: .org VBAR // Exception from CurrentEL (EL1) with SP_EL0 (SPSEL=1) .org (VBAR + 0x00 + 0) - B vector_error // Synchronous + B vector_serror // Synchronous .org (VBAR + 0x80 + 0) - B vector_irq // IRQ/vIRQ + B vector_serror // IRQ/vIRQ .org (VBAR + 0x100 + 0) - B vector_fiq // FIQ/vFIQ + B vector_serror // FIQ/vFIQ .org (VBAR + 0x180 + 0) - B vector_error // Error/vError + B vector_serror // Error/vError // Exception from CurrentEL (EL1) with SP_ELn .org (VBAR + 0x200 + 0) - B vector_error // Synchronous + B vector_exception // Synchronous .org (VBAR + 0x280 + 0) B vector_irq // IRQ/vIRQ .org (VBAR + 0x300 + 0) B vector_fiq // FIQ/vFIQ .org (VBAR + 0x380 + 0) - B vector_error + B vector_serror // Exception from lower EL, aarch64 .org (VBAR + 0x400 + 0) - B vector_error + B vector_exception .org (VBAR + 0x480 + 0) - B vector_error + B vector_irq .org (VBAR + 0x500 + 0) - B vector_error + B vector_fiq .org (VBAR + 0x580 + 0) - B vector_error + B vector_serror // Exception from lower EL, aarch32 .org (VBAR + 0x600 + 0) - B vector_error + B vector_serror .org (VBAR + 0x680 + 0) - B vector_error + B vector_serror .org (VBAR + 0x700 + 0) - B vector_error + B vector_serror .org (VBAR + 0x780 + 0) - B vector_error - .org (VBAR + 0x800 + 0) - B vector_error + B vector_serror diff --git a/libcpu/aarch64/cortex-a53/SConscript b/libcpu/aarch64/cortex-a/SConscript similarity index 100% rename from libcpu/aarch64/cortex-a53/SConscript rename to libcpu/aarch64/cortex-a/SConscript diff --git a/libcpu/aarch64/cortex-a72/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S similarity index 72% rename from libcpu/aarch64/cortex-a72/entry_point.S rename to libcpu/aarch64/cortex-a/entry_point.S index 6d2c69226b..89f29341ec 100644 --- a/libcpu/aarch64/cortex-a72/entry_point.S +++ b/libcpu/aarch64/cortex-a/entry_point.S @@ -7,19 +7,20 @@ * 2020-01-15 bigmagic the first version */ -.section ".text.entrypoint" +#include "rtconfig.h" +.section ".text.entrypoint","ax" .set EL1_stack, __el1_stack -.global _start +.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: +__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 + 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 @@ -35,7 +36,7 @@ _start: // ldr x2, =EL1_stack // mov sp, x2 - ldr x1, =_start + adr x1, __start // set up EL1 mrs x0, CurrentEL // CurrentEL Register. bit 2, 3. Others reserved @@ -50,15 +51,18 @@ _start: 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 + 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: +.L__not_in_el3: cmp x0, #4 // 0x04 0100 EL1 beq .L__in_el1 // EL1 -> 5: + mrs x0, hcr_el2 + bic x0, x0, #0xff + msr hcr_el2, x0 // in EL2 msr sp_el1, x1 // Set sp of EL1 to _start @@ -79,23 +83,20 @@ _start: 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: + ldr x9, =PV_OFFSET 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 + add x1, x1, x9 ldr w2, =__bss_size .L__clean_bss_loop: @@ -106,6 +107,56 @@ _start: // jump to C code, should not return .L__jump_to_entry: - bl entry - // for failsafe, halt this core too - b .L__current_cpu_idle + + bl get_free_page + mov x21, x0 + bl get_free_page + mov x20, x0 + + mov x1, x21 + bl mmu_tcr_init + + mov x0, x20 + mov x1, x21 + + msr ttbr0_el1, x0 + msr ttbr1_el1, x1 + dsb sy + + ldr x2, =0x40000000 //1G + mov x3, x9 + bl rt_hw_mmu_setup_early + + ldr x30, =after_mmu_enable + + mrs x1, sctlr_el1 + bic x1, x1, #(3 << 3) /* dis SA, SA0 */ + bic x1, x1, #(1 << 1) /* dis A */ + orr x1, x1, #(1 << 12) /* I */ + orr x1, x1, #(1 << 2) /* C */ + orr x1, x1, #(1 << 0) /* M */ + msr sctlr_el1, x1 + dsb sy + isb sy + ic ialluis + dsb sy + isb sy + tlbi vmalle1 + dsb sy + isb sy + ret + +after_mmu_enable: + // disable ttbr0 + mrs x0, tcr_el1 + orr x0, x0, #(1 << 7) + msr tcr_el1, x0 + msr ttbr0_el1, xzr + dsb sy + + mov x0, #1 + msr spsel, x0 + adr x1, __start + mov sp, x1 // sp_el1 set to _start + + b rtthread_startup diff --git a/libcpu/aarch64/cortex-a53/entry_point.S b/libcpu/aarch64/cortex-a53/entry_point.S deleted file mode 100644 index 6d2c69226b..0000000000 --- a/libcpu/aarch64/cortex-a53/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-a53/interrupt.h b/libcpu/aarch64/cortex-a53/interrupt.h deleted file mode 100644 index 8e741ed4e6..0000000000 --- a/libcpu/aarch64/cortex-a53/interrupt.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2006-2020, 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 - -#include "raspi.h" - -#define INT_IRQ 0x00 -#define INT_FIQ 0x01 - -void rt_hw_interrupt_init(void); -void rt_hw_interrupt_mask(int vector); -void rt_hw_interrupt_umask(int vector); - -rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, const char *name); - -#endif diff --git a/libcpu/aarch64/cortex-a53/trap.c b/libcpu/aarch64/cortex-a53/trap.c deleted file mode 100644 index 41d4d620f6..0000000000 --- a/libcpu/aarch64/cortex-a53/trap.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2006-2020, 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; -#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("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); -#ifdef RT_USING_FINSH - 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[]; - 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; - } - - /* 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); - } - } -} - -void rt_hw_trap_fiq(void) -{ - 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); - } - } -} diff --git a/libcpu/aarch64/cortex-a72/interrupt.c b/libcpu/aarch64/cortex-a72/interrupt.c deleted file mode 100644 index 3b689dceb3..0000000000 --- a/libcpu/aarch64/cortex-a72/interrupt.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2006-2020, 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 0d2d4867c7..0000000000 --- a/libcpu/aarch64/cortex-a72/interrupt.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2006-2020, 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/stack.c b/libcpu/aarch64/cortex-a72/stack.c deleted file mode 100644 index 68222c2c67..0000000000 --- a/libcpu/aarch64/cortex-a72/stack.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2006-2019, 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-a72/trap.c b/libcpu/aarch64/cortex-a72/trap.c deleted file mode 100644 index d93aa18fd6..0000000000 --- a/libcpu/aarch64/cortex-a72/trap.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2006-2020, 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; -#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("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); -#ifdef RT_USING_FINSH - 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) -{ -} diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S index 7fa3a26a88..9c9d990d16 100644 --- a/libcpu/arm/cortex-a/context_gcc.S +++ b/libcpu/arm/cortex-a/context_gcc.S @@ -45,13 +45,18 @@ rt_hw_context_switch_to: #ifdef RT_USING_SMP mov r0, r1 bl rt_cpus_lock_status_restore + bl rt_thread_self + bl lwp_user_setting_restore #else + bl rt_thread_self #ifdef RT_USING_USERSPACE - ldr r1, =rt_current_thread - ldr r0, [r1] + mov r4, r0 bl lwp_mmu_switch + mov r0, r4 #endif + bl lwp_user_setting_restore #endif /*RT_USING_SMP*/ + b rt_hw_context_switch_exit .section .bss.share.isr @@ -101,13 +106,18 @@ rt_hw_context_switch: #ifdef RT_USING_SMP mov r0, r2 bl rt_cpus_lock_status_restore + bl rt_thread_self + bl lwp_user_setting_restore #else + bl rt_thread_self #ifdef RT_USING_USERSPACE - ldr r1, =rt_current_thread - ldr r0, [r1] + mov r4, r0 bl lwp_mmu_switch + mov r0, r4 #endif + bl lwp_user_setting_restore #endif /*RT_USING_SMP*/ + b rt_hw_context_switch_exit /* diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 94e0b9f567..3d0ecadd40 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -361,6 +361,11 @@ vector_irq: cps #Mode_SVC mov sp, r8 +#ifdef RT_USING_LWP + bl rt_thread_self + bl lwp_user_setting_save +#endif + bl rt_interrupt_enter bl rt_hw_trap_irq bl rt_interrupt_leave @@ -373,6 +378,11 @@ vector_irq: #else stmfd sp!, {r0-r12,lr} +#ifdef RT_USING_LWP + bl rt_thread_self + bl lwp_user_setting_save +#endif + bl rt_interrupt_enter bl rt_hw_trap_irq bl rt_interrupt_leave @@ -462,11 +472,13 @@ rt_hw_context_switch_interrupt_do: ldr r6, [r6] ldr sp, [r6] /* get new task's stack pointer */ + bl rt_thread_self #ifdef RT_USING_USERSPACE - ldr r1, =rt_current_thread - ldr r0, [r1] + mov r4, r0 bl lwp_mmu_switch + mov r0, r4 #endif + bl lwp_user_setting_restore #ifdef RT_USING_FPU /* fpu context */ diff --git a/src/kservice.c b/src/kservice.c index 234f9c2c16..7b35b903c3 100644 --- a/src/kservice.c +++ b/src/kservice.c @@ -819,7 +819,7 @@ rt_int32_t rt_vsnprintf(char *buf, #ifdef RT_PRINTF_LONGLONG unsigned long long num; #else - rt_uint32_t num; + long num; #endif int i, len; char *str, *end, c; @@ -1041,7 +1041,7 @@ rt_int32_t rt_vsnprintf(char *buf, if (qualifier == 'l') #endif { - num = va_arg(args, rt_uint32_t); + num = va_arg(args, long); if (flags & SIGN) num = (rt_int32_t)num; } else if (qualifier == 'h') @@ -1051,7 +1051,7 @@ rt_int32_t rt_vsnprintf(char *buf, } else { - num = va_arg(args, rt_uint32_t); + num = va_arg(args, long); if (flags & SIGN) num = (rt_int32_t)num; } #ifdef RT_PRINTF_PRECISION diff --git a/src/scheduler.c b/src/scheduler.c index 41c1b167d0..c6f675c1b1 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -47,6 +47,10 @@ struct rt_thread *rt_current_thread; rt_uint8_t rt_current_priority; #endif /*RT_USING_SMP*/ +#ifdef RT_USING_LWP +void lwp_user_setting_save(rt_thread_t thread); +#endif + #ifdef RT_USING_HOOK static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to); @@ -373,6 +377,9 @@ void rt_schedule(void) _rt_scheduler_stack_check(to_thread); #endif +#ifdef RT_USING_LWP + lwp_user_setting_save(current_thread); +#endif rt_hw_context_switch((rt_ubase_t)¤t_thread->sp, (rt_ubase_t)&to_thread->sp, to_thread); } @@ -482,6 +489,9 @@ void rt_schedule(void) { extern void rt_thread_handle_sig(rt_bool_t clean_state); +#ifdef RT_USING_LWP + lwp_user_setting_save(from_thread); +#endif rt_hw_context_switch((rt_ubase_t)&from_thread->sp, (rt_ubase_t)&to_thread->sp); -- Gitee From a22d1e7c6b1983b90edc890fe89cdcf6d0094fbf Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Mon, 24 May 2021 13:47:20 +0800 Subject: [PATCH 2/4] add raspi4-64 smart support --- bsp/qemu-vexpress-a53/.config | 689 ----------------- bsp/qemu-vexpress-a53/.cproject | 175 ----- bsp/qemu-vexpress-a53/.gitignore | 45 -- bsp/qemu-vexpress-a53/.project | 54 -- bsp/qemu-vexpress-a53/Kconfig | 31 - bsp/qemu-vexpress-a53/README.md | 105 --- bsp/qemu-vexpress-a53/SConstruct | 43 -- bsp/qemu-vexpress-a53/applications/.config | 631 ---------------- bsp/qemu-vexpress-a53/applications/SConscript | 11 - bsp/qemu-vexpress-a53/applications/lcd_init.c | 19 - bsp/qemu-vexpress-a53/applications/main.c | 16 - bsp/qemu-vexpress-a53/applications/mnt.c | 29 - bsp/qemu-vexpress-a53/drivers/Kconfig | 30 - bsp/qemu-vexpress-a53/drivers/SConscript | 23 - .../drivers/audio/SConscript | 9 - .../drivers/audio/drv_ac97.c | 121 --- .../drivers/audio/drv_ac97.h | 63 -- .../drivers/audio/drv_pl041.c | 409 ---------- .../drivers/audio/drv_pl041.h | 237 ------ .../drivers/audio/drv_sound.c | 342 --------- .../drivers/audio/drv_sound.h | 15 - bsp/qemu-vexpress-a53/drivers/board.c | 93 --- bsp/qemu-vexpress-a53/drivers/board.h | 45 -- bsp/qemu-vexpress-a53/drivers/drv_clcd.c | 180 ----- bsp/qemu-vexpress-a53/drivers/drv_clcd.h | 16 - bsp/qemu-vexpress-a53/drivers/drv_keyboard.c | 474 ------------ bsp/qemu-vexpress-a53/drivers/drv_keyboard.h | 6 - bsp/qemu-vexpress-a53/drivers/drv_mouse.c | 300 -------- bsp/qemu-vexpress-a53/drivers/drv_mouse.h | 18 - bsp/qemu-vexpress-a53/drivers/drv_sdio.c | 469 ------------ bsp/qemu-vexpress-a53/drivers/drv_sdio.h | 47 -- bsp/qemu-vexpress-a53/drivers/drv_smc911x.c | 561 -------------- bsp/qemu-vexpress-a53/drivers/drv_smc911x.h | 402 ---------- bsp/qemu-vexpress-a53/drivers/drv_timer.c | 144 ---- bsp/qemu-vexpress-a53/drivers/drv_timer.h | 17 - bsp/qemu-vexpress-a53/drivers/realview.h | 331 --------- bsp/qemu-vexpress-a53/drivers/rt_lcd.h | 59 -- bsp/qemu-vexpress-a53/drivers/secondary_cpu.c | 75 -- bsp/qemu-vexpress-a53/drivers/serial.c | 187 ----- bsp/qemu-vexpress-a53/drivers/serial.h | 39 - bsp/qemu-vexpress-a53/drivers/vexpress_a9.h | 37 - bsp/qemu-vexpress-a53/link.lds | 109 --- bsp/qemu-vexpress-a53/makefile.targets | 4 - bsp/qemu-vexpress-a53/qemu-dbg.sh | 6 - bsp/qemu-vexpress-a53/qemu-nographic.sh | 5 - bsp/qemu-vexpress-a53/qemu.sh | 5 - bsp/qemu-vexpress-a53/rtconfig.h | 292 -------- bsp/qemu-vexpress-a53/rtconfig.py | 70 -- bsp/raspberry-pi/raspi4-64/.config | 330 ++++++++- bsp/raspberry-pi/raspi4-64/Kconfig | 6 +- bsp/raspberry-pi/raspi4-64/README.md | 125 ++-- bsp/raspberry-pi/raspi4-64/SConstruct | 17 +- .../raspi4-64/applications/main.c | 10 +- bsp/raspberry-pi/raspi4-64/applications/mnt.c | 28 + bsp/raspberry-pi/raspi4-64/driver/SConscript | 9 - bsp/raspberry-pi/raspi4-64/driver/board.c | 93 --- bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c | 118 --- bsp/raspberry-pi/raspi4-64/driver/drv_uart.c | 152 ---- bsp/raspberry-pi/raspi4-64/driver/raspi4.h | 29 - .../raspi4-64/{driver => drivers}/Kconfig | 35 + .../raspi4-64/drivers}/SConscript | 15 +- bsp/raspberry-pi/raspi4-64/drivers/board.c | 229 ++++++ .../raspi4-64/{driver => drivers}/board.h | 17 +- bsp/raspberry-pi/raspi4-64/drivers/drv_eth.c | 698 ++++++++++++++++++ bsp/raspberry-pi/raspi4-64/drivers/drv_eth.h | 224 ++++++ bsp/raspberry-pi/raspi4-64/drivers/drv_gpio.c | 440 +++++++++++ .../raspi4-64/{driver => drivers}/drv_gpio.h | 63 ++ bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.c | 309 ++++++++ bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.h | 27 + bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.c | 651 ++++++++++++++++ bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.h | 253 +++++++ bsp/raspberry-pi/raspi4-64/drivers/drv_spi.c | 296 ++++++++ bsp/raspberry-pi/raspi4-64/drivers/drv_spi.h | 87 +++ bsp/raspberry-pi/raspi4-64/drivers/drv_uart.c | 379 ++++++++++ .../raspi4-64/{driver => drivers}/drv_uart.h | 24 + bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.c | 135 ++++ bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.h | 25 + bsp/raspberry-pi/raspi4-64/drivers/mbox.c | 499 +++++++++++++ bsp/raspberry-pi/raspi4-64/drivers/mbox.h | 174 +++++ bsp/raspberry-pi/raspi4-64/drivers/raspi4.h | 189 +++++ bsp/raspberry-pi/raspi4-64/link.lds | 174 ++--- bsp/raspberry-pi/raspi4-64/rtconfig.h | 150 +++- bsp/raspberry-pi/raspi4-64/rtconfig.py | 49 +- components/lwp/lwp_user_mm.c | 15 +- 84 files changed, 5413 insertions(+), 7749 deletions(-) delete mode 100644 bsp/qemu-vexpress-a53/.config delete mode 100644 bsp/qemu-vexpress-a53/.cproject delete mode 100644 bsp/qemu-vexpress-a53/.gitignore delete mode 100644 bsp/qemu-vexpress-a53/.project delete mode 100644 bsp/qemu-vexpress-a53/Kconfig delete mode 100644 bsp/qemu-vexpress-a53/README.md delete mode 100644 bsp/qemu-vexpress-a53/SConstruct delete mode 100644 bsp/qemu-vexpress-a53/applications/.config delete mode 100644 bsp/qemu-vexpress-a53/applications/SConscript delete mode 100644 bsp/qemu-vexpress-a53/applications/lcd_init.c delete mode 100644 bsp/qemu-vexpress-a53/applications/main.c delete mode 100644 bsp/qemu-vexpress-a53/applications/mnt.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/Kconfig delete mode 100644 bsp/qemu-vexpress-a53/drivers/SConscript delete mode 100644 bsp/qemu-vexpress-a53/drivers/audio/SConscript delete mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/board.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/board.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_clcd.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_clcd.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_keyboard.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_keyboard.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_mouse.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_mouse.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_sdio.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_sdio.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_smc911x.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_smc911x.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_timer.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/drv_timer.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/realview.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/rt_lcd.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/secondary_cpu.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/serial.c delete mode 100644 bsp/qemu-vexpress-a53/drivers/serial.h delete mode 100644 bsp/qemu-vexpress-a53/drivers/vexpress_a9.h delete mode 100644 bsp/qemu-vexpress-a53/link.lds delete mode 100644 bsp/qemu-vexpress-a53/makefile.targets delete mode 100755 bsp/qemu-vexpress-a53/qemu-dbg.sh delete mode 100755 bsp/qemu-vexpress-a53/qemu-nographic.sh delete mode 100755 bsp/qemu-vexpress-a53/qemu.sh delete mode 100644 bsp/qemu-vexpress-a53/rtconfig.h delete mode 100644 bsp/qemu-vexpress-a53/rtconfig.py create mode 100644 bsp/raspberry-pi/raspi4-64/applications/mnt.c delete mode 100644 bsp/raspberry-pi/raspi4-64/driver/SConscript delete mode 100644 bsp/raspberry-pi/raspi4-64/driver/board.c delete mode 100644 bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c delete mode 100644 bsp/raspberry-pi/raspi4-64/driver/drv_uart.c delete mode 100644 bsp/raspberry-pi/raspi4-64/driver/raspi4.h rename bsp/raspberry-pi/raspi4-64/{driver => drivers}/Kconfig (70%) rename bsp/{qemu-vexpress-a53 => raspberry-pi/raspi4-64/drivers}/SConscript (49%) create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/board.c rename bsp/raspberry-pi/raspi4-64/{driver => drivers}/board.h (45%) create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_eth.c create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_eth.h create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_gpio.c rename bsp/raspberry-pi/raspi4-64/{driver => drivers}/drv_gpio.h (70%) create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.c create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.h create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.c create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.h create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_spi.c create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_spi.h create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_uart.c rename bsp/raspberry-pi/raspi4-64/{driver => drivers}/drv_uart.h (63%) create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.c create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.h create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/mbox.c create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/mbox.h create mode 100644 bsp/raspberry-pi/raspi4-64/drivers/raspi4.h diff --git a/bsp/qemu-vexpress-a53/.config b/bsp/qemu-vexpress-a53/.config deleted file mode 100644 index 62bc14309a..0000000000 --- a/bsp/qemu-vexpress-a53/.config +++ /dev/null @@ -1,689 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# RT-Thread Project Configuration -# - -# -# RT-Thread Kernel -# -CONFIG_RT_NAME_MAX=8 -# CONFIG_RT_USING_ARCH_DATA_TYPE is not set -CONFIG_RT_USING_SMART=y -# CONFIG_RT_USING_SMP is not set -CONFIG_RT_ALIGN_SIZE=4 -# CONFIG_RT_THREAD_PRIORITY_8 is not set -CONFIG_RT_THREAD_PRIORITY_32=y -# CONFIG_RT_THREAD_PRIORITY_256 is not set -CONFIG_RT_THREAD_PRIORITY_MAX=32 -CONFIG_RT_TICK_PER_SECOND=100 -CONFIG_RT_USING_OVERFLOW_CHECK=y -CONFIG_RT_USING_HOOK=y -CONFIG_RT_USING_IDLE_HOOK=y -CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=8192 -CONFIG_RT_USING_TIMER_SOFT=y -CONFIG_RT_TIMER_THREAD_PRIO=4 -CONFIG_RT_TIMER_THREAD_STACK_SIZE=8192 -CONFIG_RT_DEBUG=y -CONFIG_RT_DEBUG_COLOR=y -# CONFIG_RT_DEBUG_INIT_CONFIG is not set -# CONFIG_RT_DEBUG_THREAD_CONFIG is not set -# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set -# CONFIG_RT_DEBUG_IPC_CONFIG is not set -# CONFIG_RT_DEBUG_TIMER_CONFIG is not set -# CONFIG_RT_DEBUG_IRQ_CONFIG is not set -# CONFIG_RT_DEBUG_MEM_CONFIG is not set -# CONFIG_RT_DEBUG_SLAB_CONFIG is not set -# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set -# CONFIG_RT_DEBUG_MODULE_CONFIG is not set - -# -# Inter-Thread communication -# -CONFIG_RT_USING_SEMAPHORE=y -CONFIG_RT_USING_MUTEX=y -CONFIG_RT_USING_EVENT=y -CONFIG_RT_USING_MAILBOX=y -CONFIG_RT_USING_MESSAGEQUEUE=y -CONFIG_RT_USING_SIGNALS=y - -# -# Memory Management -# -CONFIG_RT_USING_MEMPOOL=y -CONFIG_RT_USING_MEMHEAP=y -# CONFIG_RT_USING_NOHEAP is not set -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_MEMTRACE=y -CONFIG_RT_USING_HEAP=y - -# -# Kernel Device Object -# -CONFIG_RT_USING_DEVICE=y -CONFIG_RT_USING_DEVICE_OPS=y -CONFIG_RT_USING_INTERRUPT_INFO=y -CONFIG_RT_USING_CONSOLE=y -CONFIG_RT_CONSOLEBUF_SIZE=256 -CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" -CONFIG_RT_VER_NUM=0x50000 -CONFIG_ARCH_CPU_64BIT=y -CONFIG_RT_USING_CACHE=y -# CONFIG_RT_USING_CPU_FFS is not set -# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set -CONFIG_ARCH_ARM_MMU=y -CONFIG_RT_USING_USERSPACE=y -CONFIG_KERNEL_VADDR_START=0xffff000000000000 -CONFIG_PV_OFFSET=0x1000060000000 -CONFIG_ARCH_ARMV8=y - -# -# RT-Thread Components -# -CONFIG_RT_USING_COMPONENTS_INIT=y -CONFIG_RT_USING_USER_MAIN=y -CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 -CONFIG_RT_MAIN_THREAD_PRIORITY=10 - -# -# C++ features -# -# CONFIG_RT_USING_CPLUSPLUS is not set - -# -# Command shell -# -CONFIG_RT_USING_FINSH=y -CONFIG_RT_USING_MSH=y -CONFIG_FINSH_THREAD_NAME="tshell" -CONFIG_FINSH_USING_HISTORY=y -CONFIG_FINSH_HISTORY_LINES=10 -CONFIG_FINSH_USING_SYMTAB=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=256 -# CONFIG_FINSH_USING_AUTH is not set -CONFIG_FINSH_ARG_MAX=10 - -# -# Device virtual file system -# -CONFIG_RT_USING_DFS=y -CONFIG_DFS_USING_WORKDIR=y -CONFIG_DFS_FILESYSTEMS_MAX=4 -CONFIG_DFS_FILESYSTEM_TYPES_MAX=8 -CONFIG_DFS_FD_MAX=32 -# CONFIG_RT_USING_DFS_MNTTABLE is not set -CONFIG_RT_USING_DFS_ELMFAT=y - -# -# 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_MAX_LFN=255 -CONFIG_RT_DFS_ELM_DRIVES=2 -CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 -# 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=y -# CONFIG_RT_USING_DFS_CROMFS is not set -CONFIG_RT_USING_DFS_RAMFS=y -# 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=y -CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 -CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 -CONFIG_RT_USING_SERIAL=y -CONFIG_RT_SERIAL_USING_DMA=y -CONFIG_RT_SERIAL_RB_BUFSZ=256 -# CONFIG_RT_USING_CAN is not set -# CONFIG_RT_USING_HWTIMER is not set -# CONFIG_RT_USING_CPUTIME is not set -CONFIG_RT_USING_I2C=y -# CONFIG_RT_I2C_DEBUG is not set -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_NULL=y -CONFIG_RT_USING_ZERO=y -CONFIG_RT_USING_RANDOM=y -# CONFIG_RT_USING_PWM is not set -CONFIG_RT_USING_MTD_NOR=y -CONFIG_RT_USING_MTD_NAND=y -CONFIG_RT_MTD_NAND_DEBUG=y -# CONFIG_RT_USING_PM is not set -CONFIG_RT_USING_RTC=y -# CONFIG_RT_USING_ALARM is not set -CONFIG_RT_USING_SOFT_RTC=y -CONFIG_RT_USING_SDIO=y -CONFIG_RT_SDIO_STACK_SIZE=512 -CONFIG_RT_SDIO_THREAD_PRIORITY=15 -CONFIG_RT_MMCSD_STACK_SIZE=8192 -CONFIG_RT_MMCSD_THREAD_PREORITY=22 -CONFIG_RT_MMCSD_MAX_PARTITION=16 -# CONFIG_RT_SDIO_DEBUG is not set -CONFIG_RT_USING_SPI=y -# CONFIG_RT_USING_QSPI is not set -CONFIG_RT_USING_SPI_MSD=y -CONFIG_RT_USING_SFUD=y -CONFIG_RT_SFUD_USING_SFDP=y -CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y -# CONFIG_RT_SFUD_USING_QSPI is not set -CONFIG_RT_SFUD_SPI_MAX_HZ=50000000 -# CONFIG_RT_DEBUG_SFUD is not set -# CONFIG_RT_USING_ENC28J60 is not set -# CONFIG_RT_USING_SPI_WIFI is not set -CONFIG_RT_USING_WDT=y -# CONFIG_RT_USING_AUDIO is not set -# CONFIG_RT_USING_SENSOR is not set -# CONFIG_RT_USING_TOUCH is not set -# CONFIG_RT_USING_HWCRYPTO is not set -# CONFIG_RT_USING_PULSE_ENCODER is not set -# CONFIG_RT_USING_INPUT_CAPTURE is not set -# CONFIG_RT_USING_WIFI is not set - -# -# Using USB -# -# CONFIG_RT_USING_USB_HOST is not set -# CONFIG_RT_USING_USB_DEVICE is not set - -# -# POSIX layer and C standard library -# -CONFIG_RT_USING_LIBC=y -# CONFIG_RT_USING_NEWLIB is not set -CONFIG_RT_USING_MUSL=y -# CONFIG_RT_USING_PTHREADS is not set -CONFIG_RT_USING_POSIX=y -CONFIG_RT_USING_POSIX_MMAP=y -CONFIG_RT_USING_POSIX_TERMIOS=y -# CONFIG_RT_USING_POSIX_GETLINE is not set -CONFIG_RT_USING_POSIX_AIO=y -CONFIG_RT_USING_POSIX_CLOCKTIME=y -# CONFIG_RT_USING_MODULE is not set - -# -# Network -# - -# -# Socket abstraction layer -# -CONFIG_RT_USING_SAL=y - -# -# protocol stack implement -# -CONFIG_SAL_USING_LWIP=y -CONFIG_SAL_USING_POSIX=y - -# -# Network interface device -# -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=y -# CONFIG_RT_USING_LWIP141 is not set -CONFIG_RT_USING_LWIP202=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 is not set - -# -# Static IPv4 Address -# -CONFIG_RT_LWIP_IPADDR="10.0.2.100" -CONFIG_RT_LWIP_GWADDR="10.0.2.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=8192 -# 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=8192 -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) -# -# CONFIG_RT_USING_VBUS is not set - -# -# Utilities -# -# CONFIG_RT_USING_RYM is not set -# CONFIG_RT_USING_ULOG is not set -# CONFIG_RT_USING_UTEST is not set -CONFIG_RT_USING_LWP=y -CONFIG_RT_LWP_MAX_NR=30 -CONFIG_LWP_TASK_STACK_SIZE=16384 -# CONFIG_RT_USING_GDBSERVER is not set -CONFIG_RT_CH_MSG_MAX_NR=1024 -CONFIG_RT_LWP_SHM_MAX_NR=64 -CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 -CONFIG_LWP_TID_MAX_NR=64 -# CONFIG_LWP_UNIX98_PTY is not set - -# -# RT-Thread online packages -# - -# -# 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 -# CONFIG_PKG_USING_MYMQTT is not set -# CONFIG_PKG_USING_KAWAII_MQTT is not set -# CONFIG_PKG_USING_BC28_MQTT is not set -# CONFIG_PKG_USING_WEBTERMINAL is not set -# CONFIG_PKG_USING_CJSON is not set -# CONFIG_PKG_USING_JSMN is not set -# CONFIG_PKG_USING_LIBMODBUS is not set -# CONFIG_PKG_USING_FREEMODBUS is not set -# CONFIG_PKG_USING_LJSON is not set -# CONFIG_PKG_USING_EZXML is not set -# CONFIG_PKG_USING_NANOPB is not set - -# -# Wi-Fi -# - -# -# Marvell WiFi -# -# CONFIG_PKG_USING_WLANMARVELL is not set - -# -# Wiced WiFi -# -# CONFIG_PKG_USING_WLAN_WICED is not set -# CONFIG_PKG_USING_RW007 is not set -# CONFIG_PKG_USING_COAP is not set -# CONFIG_PKG_USING_NOPOLL is not set -# CONFIG_PKG_USING_NETUTILS is not set -# CONFIG_PKG_USING_CMUX is not set -# CONFIG_PKG_USING_PPP_DEVICE is not set -# CONFIG_PKG_USING_AT_DEVICE is not set -# CONFIG_PKG_USING_ATSRV_SOCKET is not set -# CONFIG_PKG_USING_WIZNET is not set - -# -# IoT Cloud -# -# CONFIG_PKG_USING_ONENET is not set -# CONFIG_PKG_USING_GAGENT_CLOUD is not set -# CONFIG_PKG_USING_ALI_IOTKIT is not set -# CONFIG_PKG_USING_AZURE is not set -# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set -# CONFIG_PKG_USING_JIOT-C-SDK is not set -# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set -# CONFIG_PKG_USING_JOYLINK is not set -# CONFIG_PKG_USING_NIMBLE is not set -# CONFIG_PKG_USING_OTA_DOWNLOADER is not set -# CONFIG_PKG_USING_IPMSG is not set -# CONFIG_PKG_USING_LSSDP is not set -# CONFIG_PKG_USING_AIRKISS_OPEN is not set -# CONFIG_PKG_USING_LIBRWS is not set -# CONFIG_PKG_USING_TCPSERVER is not set -# CONFIG_PKG_USING_PROTOBUF_C is not set -# CONFIG_PKG_USING_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 -# CONFIG_PKG_USING_ABUP_FOTA is not set -# CONFIG_PKG_USING_LIBCURL2RTT is not set -# CONFIG_PKG_USING_CAPNP is not set -# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set -# CONFIG_PKG_USING_AGILE_TELNET is not set -# CONFIG_PKG_USING_NMEALIB is not set -# CONFIG_PKG_USING_AGILE_JSMN is not set -# CONFIG_PKG_USING_PDULIB is not set -# CONFIG_PKG_USING_BTSTACK is not set -# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set -# CONFIG_PKG_USING_WAYZ_IOTKIT is not set - -# -# security packages -# -# CONFIG_PKG_USING_MBEDTLS is not set -# CONFIG_PKG_USING_libsodium is not set -# CONFIG_PKG_USING_TINYCRYPT is not set -# CONFIG_PKG_USING_TFM is not set -# CONFIG_PKG_USING_YD_CRYPTO is not set - -# -# language packages -# -# CONFIG_PKG_USING_LUA is not set -# CONFIG_PKG_USING_JERRYSCRIPT is not set -# CONFIG_PKG_USING_MICROPYTHON is not set - -# -# multimedia packages -# -# CONFIG_PKG_USING_OPENMV is not set -# CONFIG_PKG_USING_MUPDF is not set -# CONFIG_PKG_USING_STEMWIN is not set -# CONFIG_PKG_USING_WAVPLAYER is not set -# CONFIG_PKG_USING_TJPGD is not set -# CONFIG_PKG_USING_HELIX is not set -# CONFIG_PKG_USING_AZUREGUIX is not set -# CONFIG_PKG_USING_TOUCHGFX2RTT is not set - -# -# tools packages -# -# CONFIG_PKG_USING_CMBACKTRACE is not set -# CONFIG_PKG_USING_EASYFLASH is not set -# CONFIG_PKG_USING_EASYLOGGER is not set -# CONFIG_PKG_USING_SYSTEMVIEW is not set -# CONFIG_PKG_USING_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 - -# -# system packages -# -# 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 -# CONFIG_PKG_USING_SQLITE is not set -# CONFIG_PKG_USING_RTI is not set -# CONFIG_PKG_USING_LITTLEVGL2RTT is not set -# 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_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 - -# -# 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_PPOOL is not set -# CONFIG_PKG_USING_OPENAMP is not set -# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set -# 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 -# CONFIG_PKG_USING_LPM is not set - -# -# peripheral libraries and drivers -# -# CONFIG_PKG_USING_SENSORS_DRIVERS is not set -# CONFIG_PKG_USING_REALTEK_AMEBA is not set -# CONFIG_PKG_USING_SHT2X is not set -# CONFIG_PKG_USING_SHT3X is not set -# CONFIG_PKG_USING_AS7341 is not set -# CONFIG_PKG_USING_STM32_SDIO is not set -# CONFIG_PKG_USING_ICM20608 is not set -# CONFIG_PKG_USING_U8G2 is not set -# CONFIG_PKG_USING_BUTTON is not set -# CONFIG_PKG_USING_PCF8574 is not set -# CONFIG_PKG_USING_SX12XX is not set -# CONFIG_PKG_USING_SIGNAL_LED is not set -# CONFIG_PKG_USING_LEDBLINK is not set -# CONFIG_PKG_USING_LITTLED is not set -# CONFIG_PKG_USING_LKDGUI is not set -# CONFIG_PKG_USING_NRF5X_SDK is not set -# CONFIG_PKG_USING_NRFX is not set -# CONFIG_PKG_USING_WM_LIBRARIES is not set -# CONFIG_PKG_USING_KENDRYTE_SDK is not set -# CONFIG_PKG_USING_INFRARED is not set -# CONFIG_PKG_USING_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 -# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set -# CONFIG_PKG_USING_AD7746 is not set -# CONFIG_PKG_USING_PCA9685 is not set -# CONFIG_PKG_USING_I2C_TOOLS is not set -# CONFIG_PKG_USING_NRF24L01 is not set -# CONFIG_PKG_USING_TOUCH_DRIVERS is not set -# CONFIG_PKG_USING_MAX17048 is not set -# CONFIG_PKG_USING_RPLIDAR is not set -# CONFIG_PKG_USING_AS608 is not set -# CONFIG_PKG_USING_RC522 is not set -# CONFIG_PKG_USING_WS2812B is not set -# CONFIG_PKG_USING_EMBARC_BSP is not set -# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set -# CONFIG_PKG_USING_MULTI_RTIMER is not set -# CONFIG_PKG_USING_MAX7219 is not set -# CONFIG_PKG_USING_BEEP is not set -# CONFIG_PKG_USING_EASYBLINK is not set -# CONFIG_PKG_USING_PMS_SERIES is not set -# CONFIG_PKG_USING_CAN_YMODEM is not set -# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set -# CONFIG_PKG_USING_QLED is not set -# CONFIG_PKG_USING_PAJ7620 is not set -# CONFIG_PKG_USING_AGILE_CONSOLE is not set -# CONFIG_PKG_USING_LD3320 is not set -# CONFIG_PKG_USING_WK2124 is not set -# CONFIG_PKG_USING_LY68L6400 is not set -# CONFIG_PKG_USING_DM9051 is not set -# CONFIG_PKG_USING_SSD1306 is not set -# CONFIG_PKG_USING_QKEY is not set -# CONFIG_PKG_USING_RS485 is not set -# CONFIG_PKG_USING_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 - -# -# 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_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_DSTR is not set -# CONFIG_PKG_USING_TINYFRAME is not set -# CONFIG_PKG_USING_KENDRYTE_DEMO is not set -# CONFIG_PKG_USING_DIGITALCTRL is not set -# CONFIG_PKG_USING_UPACKER is not set -# CONFIG_PKG_USING_UPARAM is not set - -# -# samples: kernel and components samples -# -# CONFIG_PKG_USING_KERNEL_SAMPLES is not set -# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set -# CONFIG_PKG_USING_NETWORK_SAMPLES is not set -# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set -# CONFIG_PKG_USING_HELLO is not set -# CONFIG_PKG_USING_VI is not set -# CONFIG_PKG_USING_KI 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_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 - -# -# games: games run on RT-Thread console -# -# 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_LWGPS is not set -# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set -# CONFIG_PKG_USING_STATE_MACHINE is not set - -# -# Privated Packages of RealThread -# -# CONFIG_PKG_USING_CODEC is not set -# CONFIG_PKG_USING_PLAYER is not set -# CONFIG_PKG_USING_MPLAYER is not set -# CONFIG_PKG_USING_PERSIMMON_SRC is not set -# CONFIG_PKG_USING_JS_PERSIMMON is not set -# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set - -# -# Network Utilities -# -# CONFIG_PKG_USING_MDNS is not set -# CONFIG_PKG_USING_UPNP is not set -# CONFIG_PKG_USING_WICED is not set -# CONFIG_PKG_USING_CLOUDSDK is not set -# CONFIG_PKG_USING_POWER_MANAGER is not set -# CONFIG_PKG_USING_RT_OTA is not set -# CONFIG_PKG_USING_RDBD_SRC is not set -# CONFIG_PKG_USING_RTINSIGHT is not set -# CONFIG_PKG_USING_SMARTCONFIG is not set -# CONFIG_PKG_USING_RTX is not set -# CONFIG_RT_USING_TESTCASE is not set -# CONFIG_PKG_USING_NGHTTP2 is not set -# CONFIG_PKG_USING_AVS is not set -# CONFIG_PKG_USING_ALI_LINKKIT is not set -# CONFIG_PKG_USING_STS is not set -# CONFIG_PKG_USING_DLMS is not set -# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set -# CONFIG_PKG_USING_ZBAR is not set -# CONFIG_PKG_USING_MCF is not set -# CONFIG_PKG_USING_URPC is not set -# CONFIG_PKG_USING_BSAL is not set -# CONFIG_PKG_USING_DCM is not set -# CONFIG_PKG_USING_EMQ is not set -# CONFIG_PKG_USING_CFGM is not set -# CONFIG_PKG_USING_RT_CMSIS_DAP is not set -# CONFIG_PKG_USING_SMODULE is not set -# CONFIG_PKG_USING_SNFD is not set -# CONFIG_PKG_USING_UDBD is not set -# CONFIG_PKG_USING_BENCHMARK is not set -# CONFIG_PKG_USING_UBJSON is not set -# CONFIG_PKG_USING_DATATYPE is not set -# CONFIG_PKG_USING_FASTFS is not set -CONFIG_SOC_VEXPRESS_A53=y -CONFIG_RT_USING_UART0=y -CONFIG_RT_USING_UART1=y -CONFIG_BSP_DRV_CLCD=y -CONFIG_BSP_LCD_WIDTH=640 -CONFIG_BSP_LCD_HEIGHT=480 -CONFIG_BSP_DRV_EMAC=y -# CONFIG_BSP_DRV_AUDIO is not set diff --git a/bsp/qemu-vexpress-a53/.cproject b/bsp/qemu-vexpress-a53/.cproject deleted file mode 100644 index 31c328ad90..0000000000 --- a/bsp/qemu-vexpress-a53/.cproject +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bsp/qemu-vexpress-a53/.gitignore b/bsp/qemu-vexpress-a53/.gitignore deleted file mode 100644 index 0ce2d51447..0000000000 --- a/bsp/qemu-vexpress-a53/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -*.pyc -*.map -*.dblite -*.elf -*.bin -*.hex -*.axf -*.exe -*.pdb -*.idb -*.ilk -*.old -build -Debug -documentation/html -packages/ -*~ -*.o -*.obj -*.out -*.bak -*.dep -*.lib -*.i -*.d -.DS_Stor* -.config 3 -.config 4 -.config 5 -Midea-X1 -*.uimg -GPATH -GRTAGS -GTAGS -.vscode -JLinkLog.txt -JLinkSettings.ini -DebugConfig/ -RTE/ -settings/ -*.uvguix* -cconfig.h -.settings -drivers/automac.h -romfs.c diff --git a/bsp/qemu-vexpress-a53/.project b/bsp/qemu-vexpress-a53/.project deleted file mode 100644 index e5f00228c0..0000000000 --- a/bsp/qemu-vexpress-a53/.project +++ /dev/null @@ -1,54 +0,0 @@ - - - qemu-vexpress-a9 - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.rttnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - - - rt-thread - 2 - virtual:/virtual - - - rt-thread/components - 2 - $%7BPARENT-2-PROJECT_LOC%7D/components - - - rt-thread/include - 2 - $%7BPARENT-2-PROJECT_LOC%7D/include - - - rt-thread/libcpu - 2 - $%7BPARENT-2-PROJECT_LOC%7D/libcpu - - - rt-thread/src - 2 - $%7BPARENT-2-PROJECT_LOC%7D/src - - - diff --git a/bsp/qemu-vexpress-a53/Kconfig b/bsp/qemu-vexpress-a53/Kconfig deleted file mode 100644 index 7c153bfe46..0000000000 --- a/bsp/qemu-vexpress-a53/Kconfig +++ /dev/null @@ -1,31 +0,0 @@ -mainmenu "RT-Thread Project Configuration" - -config BSP_DIR - string - option env="BSP_ROOT" - default "." - -config RTT_DIR - string - option env="RTT_ROOT" - default "../.." - -config PKGS_DIR - string - option env="PKGS_ROOT" - default "packages" - -source "$RTT_DIR/Kconfig" -source "$PKGS_DIR/Kconfig" - -config SOC_VEXPRESS_A53 - bool - select ARCH_ARMV8 - select ARCH_CPU_64BIT - select RT_USING_CACHE - select ARCH_ARM_MMU - select RT_USING_COMPONENTS_INIT - select RT_USING_USER_MAIN - default y - -source "$BSP_DIR/drivers/Kconfig" diff --git a/bsp/qemu-vexpress-a53/README.md b/bsp/qemu-vexpress-a53/README.md deleted file mode 100644 index 7ad3f30aa8..0000000000 --- a/bsp/qemu-vexpress-a53/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# QEMU/VExpress A9板级支持包说明 - -## 1. 简介 - -Versatile Express系统由ARM Ltd提供,作为CortexA9四核处理器的开发环境,硬件由uATX主板和CoreTile Express A9x4子板组成。有关该系统的详细信息,可以访问 [ARM官方页面][1] 。 - -Versatile Express的核心是一套FPGA的开发环境,Cortex-A芯片基于FPGA上的硬件逻辑,所以本身是不存在这么一款真实芯片。 - -QEMU/VExpress A9是QEMU模拟器针对ARM VExpress-A9 FPGA开发板进行软件模拟的指令级虚拟机。QEMU/VExpress因为是软件仿真模式,可以配置成多种模式,例如单核Cortex-A9,多核Cortex-A9,以及多核Cortex-A15等。同时也能够模拟出VExpress FPGA开发板上大多数的外设。 - -这份RT-Thread BSP是针对QEMU/VExpress-A9的一份移植,也并未在真实的VExpress FPGA开发板上运行过,主要是提供给开发者一定的便利,能够使用、验证一定的功能。对于真实FPGA开发板的执行情况,不做任何假设。 - -当前QEMU/VExpress-A9对应的硬件特性: - -| 硬件 | 描述 | -| -- | -- | -| CPU | ARM Cortex-A9(单核) | -| 主频 | NA | -| Memory | 128MB(0x60000000 - 0x68000000) | - -## 2. 编译说明 - -推荐使用[env工具][2],可以在console下进入到`bsp/qemu-vexpress-a9`目录中,运行以下命令: - - scons - -来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。在QEMU中一般使用elf方式来运行,所以只需要使用rtthread.elf文件即可。 - -**注:** RT-Thread/ENV中携带的工具版本是: - - gcc version 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496] - -如果在Linux下使用,请自行下载[GNU GCC工具链][3]。 - -## 3. 执行 - -当要执行编译好的RT-Thread时,在这个bsp目录下已经提供了运行脚本文件:qemu.bat/qemu.sh - -这个执行脚本默认把串口输出到stdio(即控制台)上,所以直接执行脚本后就可以输出结果了。 - -```text - \ | / -- RT - Thread Operating System - / | \ 3.0.4 build May 4 2018 - 2006 - 2018 Copyright by rt-thread team -SD card capacity 65536 KB -probe mmcsd block device! -hello rt-thread -msh /> -``` - -## 4. 支持情况 - -| 驱动 | 支持情况 | 备注 | -| ------ | ---- | :------: | -| UART | 支持 | UART0/1 | -| SD/MMC | 支持 | | -| CLCD | 支持 | | -| Key | 支持 | | -| Mouse | 支持 | | -| EMAC | 支持 | | - -### 4.1 使用VSCode编辑、编译、调试 - -在qemu-vexpress-a9中已经携带了部分vscode的配置,需要配合着env一起来使用。步骤包括: - -先使用env打开console,然后在console中切换都qemu-vexpress-a9 bsp的目录下, - -```bash -scons --target=vsc -s -``` - -更新vscode需要用到的C/C++头文件搜索路径信息(不是每次都需要更新,只有在使用了menuconfig重新配置了RT-Thread或更改了rtconfig.h头文件时才需要) - -然后在console下输入 - -```bash -code . -``` - -启动vscode。使用vscode,目前包含如下的一些功能: - -* 编译 `Ctrl+Shift+B` - 开启vscode内置终端,调用scons进行编译;如果有编译错误也会侦测问题,双击问题跳到指定代码文件、代码行; -* 包含执行`qemu`模拟器,`scons -c`进行目标文件清理的任务 -* `F5` 一键开启QEMU调试模式,并断点停留在`main`函数上;(需要更改下qemu-dbg.bat文件,在qemu-system-arm前加入`start`),即 - -```batch -@echo off -if exist sd.bin goto run -qemu-img create -f raw sd.bin 64M - -:run -start qemu-system-arm -M vexpress-a9 -kernel rtthread.elf -serial stdio -sd sd.bin -S -s -``` - -**已知问题** 如果在vscode的目录中额外添加了文件夹,会导致调试不能够启动。 - -## 5. 联系人信息 - -维护人:[bernard][4] - - [1]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.boards.express/index.html - [2]: https://www.rt-thread.org/page/download.html - [3]: https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q3-update/+download/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2 - [4]: https://github.com/BernardXiong diff --git a/bsp/qemu-vexpress-a53/SConstruct b/bsp/qemu-vexpress-a53/SConstruct deleted file mode 100644 index 266405fb6b..0000000000 --- a/bsp/qemu-vexpress-a53/SConstruct +++ /dev/null @@ -1,43 +0,0 @@ -import os -import sys -import rtconfig -import re - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = os.path.join(os.getcwd(), '..', '..') - -sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] -from building import * - -TARGET = 'rtthread.' + rtconfig.TARGET_EXT -TRACE_CONFIG = "" - -content = "" -with open("rtconfig.h") as f: - for line in f.readlines(): - if line.find("RT_BACKTRACE_FUNCTION_NAME") != -1: - for token in line.split(" "): - if re.match(r'RT_BACKTRACE_FUNCTION_NAME$', token, flags=0): - TRACE_CONFIG = " " - -DefaultEnvironment(tools=[]) -env = Environment(tools = ['mingw'], - AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS + TRACE_CONFIG, - CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS + TRACE_CONFIG, - CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS + TRACE_CONFIG, - AR = rtconfig.AR, ARFLAGS = '-rc', - LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) -env.PrependENVPath('PATH', rtconfig.EXEC_PATH) -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') - -# prepare building environment -objs = PrepareBuilding(env, RTT_ROOT) - -# make a building -DoBuilding(TARGET, objs) diff --git a/bsp/qemu-vexpress-a53/applications/.config b/bsp/qemu-vexpress-a53/applications/.config deleted file mode 100644 index a83891a3f5..0000000000 --- a/bsp/qemu-vexpress-a53/applications/.config +++ /dev/null @@ -1,631 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# RT-Thread Project Configuration -# - -# -# RT-Thread Kernel -# -CONFIG_RT_NAME_MAX=8 -# CONFIG_RT_USING_ARCH_DATA_TYPE is not set -CONFIG_RT_USING_SMART=y -CONFIG_RT_USING_SMP=y -CONFIG_RT_CPUS_NR=2 -CONFIG_RT_ALIGN_SIZE=4 -# CONFIG_RT_THREAD_PRIORITY_8 is not set -CONFIG_RT_THREAD_PRIORITY_32=y -# CONFIG_RT_THREAD_PRIORITY_256 is not set -CONFIG_RT_THREAD_PRIORITY_MAX=32 -CONFIG_RT_TICK_PER_SECOND=100 -CONFIG_RT_USING_OVERFLOW_CHECK=y -CONFIG_RT_USING_HOOK=y -CONFIG_RT_USING_IDLE_HOOK=y -CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=4096 -CONFIG_RT_USING_TIMER_SOFT=y -CONFIG_RT_TIMER_THREAD_PRIO=4 -CONFIG_RT_TIMER_THREAD_STACK_SIZE=1024 -CONFIG_RT_DEBUG=y -CONFIG_RT_DEBUG_COLOR=y -# CONFIG_RT_DEBUG_INIT_CONFIG is not set -# CONFIG_RT_DEBUG_THREAD_CONFIG is not set -# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set -# CONFIG_RT_DEBUG_IPC_CONFIG is not set -# CONFIG_RT_DEBUG_TIMER_CONFIG is not set -# CONFIG_RT_DEBUG_IRQ_CONFIG is not set -# CONFIG_RT_DEBUG_MEM_CONFIG is not set -# CONFIG_RT_DEBUG_SLAB_CONFIG is not set -# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set -# CONFIG_RT_DEBUG_MODULE_CONFIG is not set - -# -# Inter-Thread communication -# -CONFIG_RT_USING_SEMAPHORE=y -CONFIG_RT_USING_MUTEX=y -CONFIG_RT_USING_EVENT=y -CONFIG_RT_USING_MAILBOX=y -CONFIG_RT_USING_MESSAGEQUEUE=y -CONFIG_RT_USING_SIGNALS=y - -# -# Memory Management -# -CONFIG_RT_USING_MEMPOOL=y -CONFIG_RT_USING_MEMHEAP=y -# CONFIG_RT_USING_NOHEAP is not set -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_MEMTRACE=y -CONFIG_RT_USING_HEAP=y - -# -# Kernel Device Object -# -CONFIG_RT_USING_DEVICE=y -CONFIG_RT_USING_DEVICE_OPS=y -CONFIG_RT_USING_INTERRUPT_INFO=y -CONFIG_RT_USING_CONSOLE=y -CONFIG_RT_CONSOLEBUF_SIZE=256 -CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" -CONFIG_RT_VER_NUM=0x40003 -CONFIG_RT_USING_CACHE=y -# CONFIG_RT_USING_CPU_FFS is not set -# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set -CONFIG_ARCH_ARM=y -CONFIG_ARCH_ARM_MMU=y -CONFIG_RT_USING_USERSPACE=y -CONFIG_KERNEL_VADDR_START=0xc0000000 -CONFIG_PV_OFFSET=0xa0000000 -# CONFIG_RT_IOREMAP_LATE is not set -CONFIG_ARCH_ARM_CORTEX_A=y -CONFIG_ARCH_ARM_CORTEX_A9=y -CONFIG_RT_BACKTRACE_FUNCTION_NAME=y - -# -# RT-Thread Components -# -CONFIG_RT_USING_COMPONENTS_INIT=y -CONFIG_RT_USING_USER_MAIN=y -CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 -CONFIG_RT_MAIN_THREAD_PRIORITY=10 - -# -# C++ features -# -# CONFIG_RT_USING_CPLUSPLUS is not set - -# -# Command shell -# -CONFIG_RT_USING_FINSH=y -CONFIG_FINSH_THREAD_NAME="tshell" -CONFIG_FINSH_USING_HISTORY=y -CONFIG_FINSH_HISTORY_LINES=10 -CONFIG_FINSH_USING_SYMTAB=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=256 -# 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 - -# -# Device virtual file system -# -CONFIG_RT_USING_DFS=y -CONFIG_DFS_USING_WORKDIR=y -CONFIG_DFS_FILESYSTEMS_MAX=4 -CONFIG_DFS_FILESYSTEM_TYPES_MAX=8 -CONFIG_DFS_FD_MAX=32 -# CONFIG_RT_USING_DFS_MNTTABLE is not set -CONFIG_RT_USING_DFS_ELMFAT=y - -# -# 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_MAX_LFN=255 -CONFIG_RT_DFS_ELM_DRIVES=2 -CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 -# 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=y -# CONFIG_RT_USING_DFS_CROMFS is not set -CONFIG_RT_USING_DFS_RAMFS=y -# 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=y -CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 -CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 -CONFIG_RT_USING_SERIAL=y -CONFIG_RT_SERIAL_USING_DMA=y -CONFIG_RT_SERIAL_RB_BUFSZ=256 -# CONFIG_RT_USING_CAN is not set -# CONFIG_RT_USING_HWTIMER is not set -# CONFIG_RT_USING_CPUTIME is not set -CONFIG_RT_USING_I2C=y -# CONFIG_RT_I2C_DEBUG is not set -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_NULL is not set -CONFIG_RT_USING_RANDOM=y -# CONFIG_RT_USING_PWM is not set -CONFIG_RT_USING_MTD_NOR=y -CONFIG_RT_USING_MTD_NAND=y -CONFIG_RT_MTD_NAND_DEBUG=y -# CONFIG_RT_USING_PM is not set -CONFIG_RT_USING_RTC=y -# CONFIG_RT_USING_ALARM is not set -CONFIG_RT_USING_SOFT_RTC=y -CONFIG_RT_USING_SDIO=y -CONFIG_RT_SDIO_STACK_SIZE=512 -CONFIG_RT_SDIO_THREAD_PRIORITY=15 -CONFIG_RT_MMCSD_STACK_SIZE=1024 -CONFIG_RT_MMCSD_THREAD_PREORITY=22 -CONFIG_RT_MMCSD_MAX_PARTITION=16 -# CONFIG_RT_SDIO_DEBUG is not set -CONFIG_RT_USING_SPI=y -# CONFIG_RT_USING_QSPI is not set -CONFIG_RT_USING_SPI_MSD=y -CONFIG_RT_USING_SFUD=y -CONFIG_RT_SFUD_USING_SFDP=y -CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y -# CONFIG_RT_SFUD_USING_QSPI is not set -CONFIG_RT_SFUD_SPI_MAX_HZ=50000000 -# CONFIG_RT_DEBUG_SFUD is not set -# CONFIG_RT_USING_ENC28J60 is not set -# CONFIG_RT_USING_SPI_WIFI is not set -CONFIG_RT_USING_WDT=y -# CONFIG_RT_USING_AUDIO is not set -# CONFIG_RT_USING_SENSOR is not set -# CONFIG_RT_USING_TOUCH is not set -# CONFIG_RT_USING_HWCRYPTO is not set -# CONFIG_RT_USING_PULSE_ENCODER is not set -# CONFIG_RT_USING_INPUT_CAPTURE is not set -# CONFIG_RT_USING_WIFI is not set - -# -# Using USB -# -# CONFIG_RT_USING_USB_HOST is not set -# CONFIG_RT_USING_USB_DEVICE is not set - -# -# POSIX layer and C standard library -# -CONFIG_RT_USING_LIBC=y -# CONFIG_RT_USING_NEWLIB is not set -CONFIG_RT_USING_MUSL=y -# CONFIG_RT_USING_PTHREADS is not set -CONFIG_RT_USING_POSIX=y -CONFIG_RT_USING_POSIX_MMAP=y -CONFIG_RT_USING_POSIX_TERMIOS=y -# CONFIG_RT_USING_POSIX_GETLINE is not set -CONFIG_RT_USING_POSIX_AIO=y -# CONFIG_RT_USING_MODULE is not set - -# -# Network -# - -# -# Socket abstraction layer -# -CONFIG_RT_USING_SAL=y - -# -# protocol stack implement -# -CONFIG_SAL_USING_LWIP=y -CONFIG_SAL_USING_POSIX=y - -# -# Network interface device -# -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=y -# CONFIG_RT_USING_LWIP141 is not set -CONFIG_RT_USING_LWIP202=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 is not set -CONFIG_RT_LWIP_ICMP=y -# CONFIG_RT_LWIP_SNMP is not set -CONFIG_RT_LWIP_DNS=y -# CONFIG_RT_LWIP_DHCP is not set - -# -# Static IPv4 Address -# -CONFIG_RT_LWIP_IPADDR="10.0.2.100" -CONFIG_RT_LWIP_GWADDR="10.0.2.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=1024 -CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8 -CONFIG_RT_LWIP_REASSEMBLY_FRAG=y -CONFIG_LWIP_NETIF_STATUS_CALLBACK=1 -CONFIG_LWIP_NETIF_LINK_CALLBACK=1 -CONFIG_SO_REUSE=1 -CONFIG_LWIP_SO_RCVTIMEO=1 -CONFIG_LWIP_SO_SNDTIMEO=1 -CONFIG_LWIP_SO_RCVBUF=1 -CONFIG_LWIP_SO_LINGER=0 -# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=0 -# CONFIG_RT_LWIP_STATS is not set -# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set -CONFIG_RT_LWIP_USING_PING=y -# CONFIG_RT_LWIP_DEBUG is not set - -# -# AT commands -# -# CONFIG_RT_USING_AT is not set -# CONFIG_LWIP_USING_DHCPD is not set - -# -# VBUS(Virtual Software BUS) -# -# CONFIG_RT_USING_VBUS is not set - -# -# Utilities -# -# CONFIG_RT_USING_RYM is not set -# CONFIG_RT_USING_ULOG is not set -# CONFIG_RT_USING_UTEST is not set -CONFIG_RT_USING_LWP=y -CONFIG_RT_LWP_MAX_NR=30 -# CONFIG_RT_USING_GDBSERVER is not set -CONFIG_RT_CH_MSG_MAX_NR=1024 -CONFIG_RT_LWP_SHM_MAX_NR=64 -CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 - -# -# RT-Thread online packages -# - -# -# 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 -# CONFIG_PKG_USING_MYMQTT is not set -# CONFIG_PKG_USING_KAWAII_MQTT is not set -# CONFIG_PKG_USING_BC28_MQTT is not set -# CONFIG_PKG_USING_WEBTERMINAL is not set -# CONFIG_PKG_USING_CJSON is not set -# CONFIG_PKG_USING_JSMN is not set -# CONFIG_PKG_USING_LIBMODBUS is not set -# CONFIG_PKG_USING_FREEMODBUS is not set -# CONFIG_PKG_USING_LJSON is not set -# CONFIG_PKG_USING_EZXML is not set -# CONFIG_PKG_USING_NANOPB is not set - -# -# Wi-Fi -# - -# -# Marvell WiFi -# -# CONFIG_PKG_USING_WLANMARVELL is not set - -# -# Wiced WiFi -# -# CONFIG_PKG_USING_WLAN_WICED is not set -# CONFIG_PKG_USING_RW007 is not set -# CONFIG_PKG_USING_COAP is not set -# CONFIG_PKG_USING_NOPOLL is not set -# CONFIG_PKG_USING_NETUTILS is not set -# CONFIG_PKG_USING_CMUX is not set -# CONFIG_PKG_USING_PPP_DEVICE is not set -# CONFIG_PKG_USING_AT_DEVICE is not set -# CONFIG_PKG_USING_ATSRV_SOCKET is not set -# CONFIG_PKG_USING_WIZNET is not set - -# -# IoT Cloud -# -# CONFIG_PKG_USING_ONENET is not set -# CONFIG_PKG_USING_GAGENT_CLOUD is not set -# CONFIG_PKG_USING_ALI_IOTKIT is not set -# CONFIG_PKG_USING_AZURE is not set -# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set -# CONFIG_PKG_USING_JIOT-C-SDK is not set -# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set -# CONFIG_PKG_USING_JOYLINK is not set -# CONFIG_PKG_USING_NIMBLE is not set -# CONFIG_PKG_USING_OTA_DOWNLOADER is not set -# CONFIG_PKG_USING_IPMSG is not set -# CONFIG_PKG_USING_LSSDP is not set -# CONFIG_PKG_USING_AIRKISS_OPEN is not set -# CONFIG_PKG_USING_LIBRWS is not set -# CONFIG_PKG_USING_TCPSERVER is not set -# CONFIG_PKG_USING_PROTOBUF_C is not set -# CONFIG_PKG_USING_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 -# CONFIG_PKG_USING_ABUP_FOTA is not set -# CONFIG_PKG_USING_LIBCURL2RTT is not set -# CONFIG_PKG_USING_CAPNP is not set -# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set -# CONFIG_PKG_USING_AGILE_TELNET is not set -# CONFIG_PKG_USING_NMEALIB is not set -# CONFIG_PKG_USING_AGILE_JSMN is not set -# CONFIG_PKG_USING_PDULIB is not set -# CONFIG_PKG_USING_BTSTACK is not set -# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set -# CONFIG_PKG_USING_WAYZ_IOTKIT is not set - -# -# security packages -# -# CONFIG_PKG_USING_MBEDTLS is not set -# CONFIG_PKG_USING_libsodium is not set -# CONFIG_PKG_USING_TINYCRYPT is not set -# CONFIG_PKG_USING_TFM is not set -# CONFIG_PKG_USING_YD_CRYPTO is not set - -# -# language packages -# -# CONFIG_PKG_USING_LUA is not set -# CONFIG_PKG_USING_JERRYSCRIPT is not set -# CONFIG_PKG_USING_MICROPYTHON is not set - -# -# multimedia packages -# -# CONFIG_PKG_USING_OPENMV is not set -# CONFIG_PKG_USING_MUPDF is not set -# CONFIG_PKG_USING_STEMWIN is not set -# CONFIG_PKG_USING_WAVPLAYER is not set -# CONFIG_PKG_USING_TJPGD is not set -# CONFIG_PKG_USING_HELIX is not set -# CONFIG_PKG_USING_AZUREGUIX is not set -# CONFIG_PKG_USING_TOUCHGFX2RTT is not set - -# -# tools packages -# -# CONFIG_PKG_USING_CMBACKTRACE is not set -# CONFIG_PKG_USING_EASYFLASH is not set -# CONFIG_PKG_USING_EASYLOGGER is not set -# CONFIG_PKG_USING_SYSTEMVIEW is not set -# CONFIG_PKG_USING_RDB is not set -# CONFIG_PKG_USING_QRCODE is not set -# CONFIG_PKG_USING_ULOG_EASYFLASH 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 - -# -# system packages -# -# CONFIG_PKG_USING_GUIENGINE is not set -# CONFIG_PKG_USING_PERSIMMON 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 -# CONFIG_PKG_USING_SQLITE is not set -# CONFIG_PKG_USING_RTI is not set -# CONFIG_PKG_USING_LITTLEVGL2RTT is not set -# 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_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 - -# -# 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_PPOOL is not set -# CONFIG_PKG_USING_OPENAMP is not set - -# -# peripheral libraries and drivers -# -# CONFIG_PKG_USING_SENSORS_DRIVERS is not set -# CONFIG_PKG_USING_REALTEK_AMEBA is not set -# CONFIG_PKG_USING_SHT2X is not set -# CONFIG_PKG_USING_SHT3X is not set -# CONFIG_PKG_USING_STM32_SDIO is not set -# CONFIG_PKG_USING_ICM20608 is not set -# CONFIG_PKG_USING_U8G2 is not set -# CONFIG_PKG_USING_BUTTON is not set -# CONFIG_PKG_USING_PCF8574 is not set -# CONFIG_PKG_USING_SX12XX is not set -# CONFIG_PKG_USING_SIGNAL_LED is not set -# CONFIG_PKG_USING_LEDBLINK is not set -# CONFIG_PKG_USING_LITTLED is not set -# CONFIG_PKG_USING_LKDGUI is not set -# CONFIG_PKG_USING_NRF5X_SDK is not set -# CONFIG_PKG_USING_NRFX is not set -# CONFIG_PKG_USING_WM_LIBRARIES is not set -# CONFIG_PKG_USING_KENDRYTE_SDK is not set -# CONFIG_PKG_USING_INFRARED is not set -# CONFIG_PKG_USING_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 -# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set -# CONFIG_PKG_USING_AD7746 is not set -# CONFIG_PKG_USING_PCA9685 is not set -# CONFIG_PKG_USING_I2C_TOOLS is not set -# CONFIG_PKG_USING_NRF24L01 is not set -# CONFIG_PKG_USING_TOUCH_DRIVERS is not set -# CONFIG_PKG_USING_MAX17048 is not set -# CONFIG_PKG_USING_RPLIDAR is not set -# CONFIG_PKG_USING_AS608 is not set -# CONFIG_PKG_USING_RC522 is not set -# CONFIG_PKG_USING_WS2812B is not set -# CONFIG_PKG_USING_EMBARC_BSP is not set -# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set -# CONFIG_PKG_USING_MULTI_RTIMER is not set -# CONFIG_PKG_USING_MAX7219 is not set -# CONFIG_PKG_USING_BEEP is not set -# CONFIG_PKG_USING_EASYBLINK is not set -# CONFIG_PKG_USING_PMS_SERIES is not set -# CONFIG_PKG_USING_CAN_YMODEM is not set -# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set -# CONFIG_PKG_USING_QLED is not set -# CONFIG_PKG_USING_PAJ7620 is not set -# CONFIG_PKG_USING_AGILE_CONSOLE is not set -# CONFIG_PKG_USING_LD3320 is not set -# CONFIG_PKG_USING_WK2124 is not set -# CONFIG_PKG_USING_LY68L6400 is not set -# CONFIG_PKG_USING_DM9051 is not set -# CONFIG_PKG_USING_SSD1306 is not set -# CONFIG_PKG_USING_QKEY is not set -# CONFIG_PKG_USING_RS485 is not set -# CONFIG_PKG_USING_NES is not set -# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set -# CONFIG_PKG_USING_VDEVICE 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_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_DSTR is not set -# CONFIG_PKG_USING_TINYFRAME is not set -# CONFIG_PKG_USING_KENDRYTE_DEMO is not set -# CONFIG_PKG_USING_DIGITALCTRL is not set -# CONFIG_PKG_USING_UPACKER is not set -# CONFIG_PKG_USING_UPARAM is not set - -# -# samples: kernel and components samples -# -# CONFIG_PKG_USING_KERNEL_SAMPLES is not set -# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set -# CONFIG_PKG_USING_NETWORK_SAMPLES is not set -# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set -# CONFIG_PKG_USING_HELLO is not set -# CONFIG_PKG_USING_VI is not set -# CONFIG_PKG_USING_KI 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_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 - -# -# games: games run on RT-Thread console -# -# 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_LWGPS is not set -# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set -CONFIG_SOC_VEXPRESS_A9=y -CONFIG_RT_USING_UART0=y -CONFIG_RT_USING_UART1=y -CONFIG_BSP_DRV_CLCD=y -CONFIG_BSP_LCD_WIDTH=640 -CONFIG_BSP_LCD_HEIGHT=480 -CONFIG_BSP_DRV_EMAC=y -# CONFIG_BSP_DRV_AUDIO is not set diff --git a/bsp/qemu-vexpress-a53/applications/SConscript b/bsp/qemu-vexpress-a53/applications/SConscript deleted file mode 100644 index 89083a964a..0000000000 --- a/bsp/qemu-vexpress-a53/applications/SConscript +++ /dev/null @@ -1,11 +0,0 @@ -Import('RTT_ROOT') -Import('rtconfig') -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') -CPPPATH = [cwd] - -group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/qemu-vexpress-a53/applications/lcd_init.c b/bsp/qemu-vexpress-a53/applications/lcd_init.c deleted file mode 100644 index 6a870440a8..0000000000 --- a/bsp/qemu-vexpress-a53/applications/lcd_init.c +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#if defined(RT_USING_RTGUI) || defined(PKG_USING_GUIENGINE) - -#include -int lcd_init(void) -{ - struct rt_device *device; - device = rt_device_find("lcd"); - if (device) - { - rtgui_graphic_set_device(device); - } - - return 0; -} -INIT_APP_EXPORT(lcd_init); - -#endif diff --git a/bsp/qemu-vexpress-a53/applications/main.c b/bsp/qemu-vexpress-a53/applications/main.c deleted file mode 100644 index 9d5dfd21e7..0000000000 --- a/bsp/qemu-vexpress-a53/applications/main.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020/10/7 bernard the first version - */ -#include - -int main(void) -{ - printf("hello rt-thread\n"); - return 0; -} diff --git a/bsp/qemu-vexpress-a53/applications/mnt.c b/bsp/qemu-vexpress-a53/applications/mnt.c deleted file mode 100644 index 625f003c76..0000000000 --- a/bsp/qemu-vexpress-a53/applications/mnt.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#ifdef RT_USING_DFS -#include -#include - -int mnt_init(void) -{ - /* - if (dfs_mount(RT_NULL, "/", "rom", 0, &romfs_root) != 0) - { - rt_kprintf("Dir / mount failed!\n"); - return -1; - } - */ - - rt_thread_mdelay(200); - if (dfs_mount("sd0", "/", "elm", 0, NULL) != 0) - { - rt_kprintf("Dir / mount failed!\n"); - return -1; - } - - rt_kprintf("file system initialization done!\n"); - return 0; -} -INIT_ENV_EXPORT(mnt_init); -#endif - diff --git a/bsp/qemu-vexpress-a53/drivers/Kconfig b/bsp/qemu-vexpress-a53/drivers/Kconfig deleted file mode 100644 index ce3d2c3978..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/Kconfig +++ /dev/null @@ -1,30 +0,0 @@ -config RT_USING_UART0 - bool "Enable UART0" - default n - -config RT_USING_UART1 - bool "Enable UART1" - default y - -config BSP_DRV_CLCD - bool "CLCD driver" - default y - -if BSP_DRV_CLCD - config BSP_LCD_WIDTH - int "Width of LCD panel" - default 640 - - config BSP_LCD_HEIGHT - int "Height of LCD panel" - default 480 -endif - -config BSP_DRV_EMAC - bool "EMAC driver" - default y - -config BSP_DRV_AUDIO - bool "Audio driver" - select RT_USING_AUDIO - default n diff --git a/bsp/qemu-vexpress-a53/drivers/SConscript b/bsp/qemu-vexpress-a53/drivers/SConscript deleted file mode 100644 index 4f10c26217..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/SConscript +++ /dev/null @@ -1,23 +0,0 @@ -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') -list = os.listdir(cwd) -CPPPATH = [cwd] -objs = [] - -if not GetDepend('BSP_DRV_EMAC'): - SrcRemove(src, ['drv_smc911x.c']) - -if not GetDepend('BSP_DRV_CLCD'): - SrcRemove(src, ['drv_clcd.c']) - -group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) - -for d in list: - path = os.path.join(cwd, d) - if os.path.isfile(os.path.join(path, 'SConscript')): - objs = objs + SConscript(os.path.join(d, 'SConscript')) -objs = objs + group - -Return('objs') diff --git a/bsp/qemu-vexpress-a53/drivers/audio/SConscript b/bsp/qemu-vexpress-a53/drivers/audio/SConscript deleted file mode 100644 index 2118631608..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/audio/SConscript +++ /dev/null @@ -1,9 +0,0 @@ -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.S') -CPPPATH = [cwd] - -group = DefineGroup('drv_audio', src, depend = ['BSP_DRV_AUDIO'], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c b/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c deleted file mode 100644 index 46ea2e0fea..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * File : drv_ac97.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-25 RT-Thread the first version - */ - -#include -#include -#include "drv_pl041.h" -#include "drv_ac97.h" - -void ac97_reset(void) -{ - aaci_ac97_write(AC97_RESET, 0xFFFF); -} - -rt_err_t ac97_set_vol(int vol) -{ - rt_uint16_t tmp = vol | (vol << 8); - - if (vol < 0 || vol > 0x3f) - { - return -RT_ERROR; - } - - aaci_ac97_write(AC97_MASTER, tmp); - aaci_ac97_write(AC97_HEADPHONE, tmp); - aaci_ac97_write(AC97_MASTER_MONO, tmp); - aaci_ac97_write(AC97_PCM, tmp); - - return RT_EOK; -} - -int ac97_get_vol(void) -{ - rt_uint16_t v; - - v = aaci_ac97_read(AC97_MASTER); - if (v == (~0x0)) - { - v = 0; - } - return 0x3F & v; -} - -rt_err_t ac97_set_rate(int rate) -{ - if (rate < 0) - { - return -RT_ERROR; - } - aaci_ac97_write(AC97_PCM_FRONT_DAC_RATE, rate); - return 0; -} - -int ac97_get_rate(void) -{ - rt_uint16_t v; - - v = aaci_ac97_read(AC97_PCM_FRONT_DAC_RATE); - if (v == (~0x0)) - { - v = 0; - } - return v; -} - -#if 0 -#define AC97_DUMP(_v) rt_kprintf("%32s:addr:0x%08x data:0x%08x\n", #_v, (_v), (aaci_ac97_read(_v))) -int _ac97_reg_dump(int argc, char **argv) -{ - AC97_DUMP(AC97_RESET); - AC97_DUMP(AC97_MASTER); - AC97_DUMP(AC97_HEADPHONE); - AC97_DUMP(AC97_MASTER_MONO); - AC97_DUMP(AC97_MASTER_TONE); - AC97_DUMP(AC97_PC_BEEP); - AC97_DUMP(AC97_PHONE); - AC97_DUMP(AC97_MIC); - AC97_DUMP(AC97_LINE); - AC97_DUMP(AC97_CD); - AC97_DUMP(AC97_VIDEO); - AC97_DUMP(AC97_AUX); - AC97_DUMP(AC97_PCM); - AC97_DUMP(AC97_REC_SEL); - AC97_DUMP(AC97_REC_GAIN); - AC97_DUMP(AC97_REC_GAIN_MIC); - AC97_DUMP(AC97_GENERAL_PURPOSE); - AC97_DUMP(AC97_3D_CONTROL); - AC97_DUMP(AC97_INT_PAGING); - AC97_DUMP(AC97_POWERDOWN); - AC97_DUMP(AC97_PCM_FRONT_DAC_RATE); - AC97_DUMP(AC97_PCM_SURR_DAC_RATE); - AC97_DUMP(AC97_PCM_LFE_DAC_RATE); - AC97_DUMP(AC97_PCM_LR_ADC_RATE); - AC97_DUMP(AC97_PCM_MIC_ADC_RATE); - AC97_DUMP(AC97_DAC_SLOT_MAP); - AC97_DUMP(AC97_ADC_SLOT_MAP); - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(_ac97_reg_dump, __cmd_ac97_dump, ac97 dump reg.); - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h b/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h deleted file mode 100644 index 31d496024d..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/audio/drv_ac97.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * File : drv_ac97.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-25 RT-Thread the first version - */ - -#ifndef __DRV_AC97_H__ -#define __DRV_AC97_H__ - -/* Register offsets */ -#define AC97_RESET 0x00 -#define AC97_MASTER 0x02 -#define AC97_HEADPHONE 0x04 -#define AC97_MASTER_MONO 0x06 -#define AC97_MASTER_TONE 0x08 -#define AC97_PC_BEEP 0x0A //mixer volume -#define AC97_PHONE 0x0C -#define AC97_MIC 0x0E //qwert db -#define AC97_LINE 0x10 -#define AC97_CD 0x12 -#define AC97_VIDEO 0x14 -#define AC97_AUX 0x16 -#define AC97_PCM 0x18 -#define AC97_REC_SEL 0x1A //0 represent mic -#define AC97_REC_GAIN 0x1C -#define AC97_REC_GAIN_MIC 0x1E -#define AC97_GENERAL_PURPOSE 0x20 -#define AC97_3D_CONTROL 0x22 -#define AC97_INT_PAGING 0x24 //qwert -#define AC97_POWERDOWN 0x26 -#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */ -#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */ -#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */ -#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */ -#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */ -#define AC97_DAC_SLOT_MAP 0x6C -#define AC97_ADC_SLOT_MAP 0x6E - -void ac97_reset(void); -rt_err_t ac97_set_vol(int vol); -int ac97_get_vol(void); -rt_err_t ac97_set_rate(int rate); -int ac97_get_rate(void); - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c b/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c deleted file mode 100644 index 334e22f701..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * File : drv_pl041.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-25 RT-Thread the first version - */ - -#include -#include -#include "drv_pl041.h" -#include "drv_ac97.h" -#include "realview.h" - -#define DBG_TAG "PL041" -// #define DBG_LVL DBG_LOG -// #define DBG_LVL DBG_INFO -#define DBG_LVL DBG_WARNING -// #define DBG_LVL DBG_ERROR -#include - -#define FRAME_PERIOD_US (50) -#define PL041_CHANNEL_NUM (4) - -#define PL041_READ(_a) (*(volatile rt_uint32_t *)(_a)) -#define PL041_WRITE(_a, _v) (*(volatile rt_uint32_t *)(_a) = (_v)) - -struct pl041_irq_def -{ - pl041_irq_fun_t fun; - void *user_data; -}; - -static struct pl041_irq_def irq_tbl[PL041_CHANNEL_NUM]; - -static void aaci_pl041_delay(rt_uint32_t us) -{ - volatile int i; - - for (i = us * 10; i != 0; i--); -} - -static void aaci_ac97_select_codec(void) -{ - rt_uint32_t v, maincr; - - maincr = AACI_MAINCR_SCRA(0) | AACI_MAINCR_IE | AACI_MAINCR_SL1RXEN | \ - AACI_MAINCR_SL1TXEN | AACI_MAINCR_SL2RXEN | AACI_MAINCR_SL2TXEN; - - v = PL041_READ(&PL041->slfr); - if (v & AACI_SLFR_2RXV) - { - PL041_READ(&PL041->sl2rx); - } - if (v & AACI_SLFR_1RXV) - { - PL041_READ(&PL041->sl1rx); - } - - if (maincr != PL041_READ(&PL041->maincr)) - { - PL041_WRITE(&PL041->maincr, maincr); - aaci_pl041_delay(1); - } -} - -void aaci_ac97_write(rt_uint16_t reg, rt_uint16_t val) -{ - rt_uint32_t v, timeout; - - aaci_ac97_select_codec(); - - PL041_WRITE(&PL041->sl2tx, val << 4); - PL041_WRITE(&PL041->sl1tx, reg << 12); - - aaci_pl041_delay(FRAME_PERIOD_US); - - timeout = FRAME_PERIOD_US * 8; - do - { - aaci_pl041_delay(1); - v = PL041_READ(&PL041->slfr); - } - while ((v & (AACI_SLFR_1TXB | AACI_SLFR_2TXB)) && --timeout); - - if (v & (AACI_SLFR_1TXB | AACI_SLFR_2TXB)) - { - LOG_E("timeout waiting for write to complete"); - } -} - -rt_uint16_t aaci_ac97_read(rt_uint16_t reg) -{ - rt_uint32_t v, timeout, retries = 10; - - aaci_ac97_select_codec(); - - PL041_WRITE(&PL041->sl1tx, (reg << 12) | (1 << 19)); - aaci_pl041_delay(FRAME_PERIOD_US); - - timeout = FRAME_PERIOD_US * 8; - do - { - aaci_pl041_delay(1); - v = PL041_READ(&PL041->slfr); - } - while ((v & AACI_SLFR_1TXB) && --timeout); - - if (v & AACI_SLFR_1TXB) - { - LOG_E("timeout on slot 1 TX busy"); - v = ~0x0; - return v; - } - - aaci_pl041_delay(FRAME_PERIOD_US); - timeout = FRAME_PERIOD_US * 8; - do - { - aaci_pl041_delay(1); - v = PL041_READ(&PL041->slfr) & (AACI_SLFR_1RXV | AACI_SLFR_2RXV); - } - while ((v != (AACI_SLFR_1RXV | AACI_SLFR_2RXV)) && --timeout); - - if (v != (AACI_SLFR_1RXV | AACI_SLFR_2RXV)) - { - LOG_E("timeout on RX valid"); - v = ~0x0; - return v; - } - - do - { - v = PL041_READ(&PL041->sl1rx) >> 12; - if (v == reg) - { - v = PL041_READ(&PL041->sl2rx) >> 4; - break; - } - else if (--retries) - { - LOG_E("ac97 read back fail. retry"); - continue; - } - else - { - LOG_E("wrong ac97 register read back (%x != %x)", v, reg); - v = ~0x0; - } - } - while (retries); - - return v; -} - -int aaci_pl041_channel_disable(int channel) -{ - rt_uint32_t v; - void *p_rx, *p_tx; - - p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channel * 0x14); - p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channel * 0x14); - v = PL041_READ(p_rx); - v &= ~AACI_CR_EN; - PL041_WRITE(p_rx, v); - v = PL041_READ(p_tx); - v &= ~AACI_CR_EN; - PL041_WRITE(p_tx, v); - return 0; -} - -int aaci_pl041_channel_enable(int channel) -{ - rt_uint32_t v; - void *p_rx, *p_tx; - - p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channel * 0x14); - p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channel * 0x14); - v = PL041_READ(p_rx); - v |= AACI_CR_EN; - PL041_WRITE(p_rx, v); - v = PL041_READ(p_tx); - v |= AACI_CR_EN; - PL041_WRITE(p_tx, v); - return 0; -} - -int aaci_pl041_channel_read(int channel, rt_uint16_t *buff, int count) -{ - void *p_data, *p_status; - int i = 0; - - p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channel * 0x14); - p_data = (void *)((rt_uint32_t)(&(PL041->dr1[0])) + channel * 0x20); - for (i = 0; (!(PL041_READ(p_status) & AACI_SR_RXFE)) && (i < count); i++) - { - buff[i] = (rt_uint16_t)PL041_READ(p_data); - } - return i; -} - -int aaci_pl041_channel_write(int channel, rt_uint16_t *buff, int count) -{ - void *p_data, *p_status; - int i = 0; - - p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channel * 0x14); - p_data = (void *)((rt_uint32_t)(&(PL041->dr1[0])) + channel * 0x20); - for (i = 0; (!(PL041_READ(p_status) & AACI_SR_TXFF)) && (i < count); i++) - { - PL041_WRITE(p_data, buff[i]); - } - return i; -} - -int aaci_pl041_channel_cfg(int channel, pl041_cfg_t cgf) -{ - rt_uint32_t v; - void *p_rx, *p_tx; - - p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channel * 0x14); - p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channel * 0x14); - v = AACI_CR_FEN | AACI_CR_SZ16 | cgf->itype; - PL041_WRITE(p_rx, v); - v = AACI_CR_FEN | AACI_CR_SZ16 | cgf->otype; - PL041_WRITE(p_tx, v); - - ac97_set_vol(cgf->vol); - ac97_set_rate(cgf->rate); - - return 0; -} - -void aaci_pl041_irq_enable(int channel, rt_uint32_t vector) -{ - rt_uint32_t v; - void *p_irq; - - vector &= vector & 0x7f; - p_irq = (void *)((rt_uint32_t)(&PL041->iie1) + channel * 0x14); - v = PL041_READ(p_irq); - v |= vector; - PL041_WRITE(p_irq, v); -} - -void aaci_pl041_irq_disable(int channel, rt_uint32_t vector) -{ - rt_uint32_t v; - void *p_irq; - - vector &= vector & 0x7f; - p_irq = (void *)((rt_uint32_t)(&PL041->iie1) + channel * 0x14); - v = PL041_READ(p_irq); - v &= ~vector; - PL041_WRITE(p_irq, v); -} - -rt_err_t aaci_pl041_irq_register(int channel, pl041_irq_fun_t fun, void *user_data) -{ - if (channel < 0 || channel >= PL041_CHANNEL_NUM) - { - LOG_E("%s channel:%d err.", __FUNCTION__, channel); - return -RT_ERROR; - } - irq_tbl[channel].fun = fun; - irq_tbl[channel].user_data = user_data; - return RT_EOK; -} - -rt_err_t aaci_pl041_irq_unregister(int channel) -{ - if (channel < 0 || channel >= PL041_CHANNEL_NUM) - { - LOG_E("%s channel:%d err.", __FUNCTION__, channel); - return -RT_ERROR; - } - irq_tbl[channel].fun = RT_NULL; - irq_tbl[channel].user_data = RT_NULL; - return RT_EOK; -} - -static void aaci_pl041_irq_handle(int irqno, void *param) -{ - rt_uint32_t mask, channel, m; - struct pl041_irq_def *_irq = param; - void *p_status; - - mask = PL041_READ(&PL041->allints); - PL041_WRITE(&PL041->intclr, mask); - - for (channel = 0; (channel < PL041_CHANNEL_NUM) && (mask); channel++) - { - mask = mask >> 7; - m = mask & 0x7f; - if (m & AACI_ISR_ORINTR) - { - LOG_W("RX overrun on chan %d", channel); - } - - if (m & AACI_ISR_RXTOINTR) - { - LOG_W("RX timeout on chan %d", channel); - } - - if (mask & AACI_ISR_URINTR) - { - LOG_W("TX underrun on chan %d", channel); - } - - p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channel * 0x14); - if (_irq[channel].fun != RT_NULL) - { - _irq[channel].fun(PL041_READ(p_status), _irq[channel].user_data); - } - } -} - -rt_err_t aaci_pl041_init(void) -{ - rt_uint32_t i, maincr; - - maincr = AACI_MAINCR_SCRA(0) | AACI_MAINCR_IE | AACI_MAINCR_SL1RXEN | \ - AACI_MAINCR_SL1TXEN | AACI_MAINCR_SL2RXEN | AACI_MAINCR_SL2TXEN; - - for (i = 0; i < 4; i++) - { - void *base = (void *)((rt_uint32_t)(&PL041->rxcr1) + i * 0x14); - - PL041_WRITE(base + AACI_IE, 0); - PL041_WRITE(base + AACI_TXCR, 0); - PL041_WRITE(base + AACI_RXCR, 0); - } - - PL041_WRITE(&PL041->intclr, 0x1fff); - PL041_WRITE(&PL041->maincr, maincr); - - PL041_WRITE(&PL041->reset, 0); - aaci_pl041_delay(2); - PL041_WRITE(&PL041->reset, RESET_NRST); - - rt_hw_interrupt_install(43, aaci_pl041_irq_handle, &irq_tbl, "aaci_pl041"); - rt_hw_interrupt_umask(43); - - return 0; -} - -#if 0 -#define PL041_DUMP(_v) rt_kprintf("%32s:addr:0x%08x data:0x%08x\n", #_v, &(_v), (_v)) -int _aaci_pl041_reg_dump(int argc, char **argv) -{ - PL041_DUMP(PL041->rxcr1); - PL041_DUMP(PL041->txcr1); - PL041_DUMP(PL041->sr1); - PL041_DUMP(PL041->isr1); - PL041_DUMP(PL041->iie1); - PL041_DUMP(PL041->rxcr2); - PL041_DUMP(PL041->txcr2); - PL041_DUMP(PL041->sr2); - PL041_DUMP(PL041->isr2); - PL041_DUMP(PL041->iie2); - PL041_DUMP(PL041->rxcr3); - PL041_DUMP(PL041->txcr3); - PL041_DUMP(PL041->sr3); - PL041_DUMP(PL041->isr3); - PL041_DUMP(PL041->iie3); - PL041_DUMP(PL041->rxcr4); - PL041_DUMP(PL041->txcr4); - PL041_DUMP(PL041->sr4); - PL041_DUMP(PL041->isr4); - PL041_DUMP(PL041->iie4); - PL041_DUMP(PL041->sl1rx); - PL041_DUMP(PL041->sl1tx); - PL041_DUMP(PL041->sl2rx); - PL041_DUMP(PL041->sl2tx); - PL041_DUMP(PL041->sl12rx); - PL041_DUMP(PL041->sl12tx); - PL041_DUMP(PL041->slfr); - PL041_DUMP(PL041->slistat); - PL041_DUMP(PL041->slien); - PL041_DUMP(PL041->intclr); - PL041_DUMP(PL041->maincr); - PL041_DUMP(PL041->reset); - PL041_DUMP(PL041->sync); - PL041_DUMP(PL041->allints); - PL041_DUMP(PL041->mainfr); - PL041_DUMP(PL041->dr1[0]); - PL041_DUMP(PL041->dr2[0]); - PL041_DUMP(PL041->dr3[0]); - PL041_DUMP(PL041->dr4[0]); - return 0; -} -FINSH_FUNCTION_EXPORT_ALIAS(_aaci_pl041_reg_dump, __cmd_pl041_dump, aaci pl041 dump reg.); -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h b/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h deleted file mode 100644 index cd972b5bdd..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/audio/drv_pl041.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * File : drv_pl041.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-25 RT-Thread the first version - */ - -#ifndef __DRV_PL041_H__ -#define __DRV_PL041_H__ - -#define PL041_BASE_ADDR (0x10004000) - -/* offsets in CTRL_CH */ -#define AACI_RXCR 0x00 /* 29 bits Control Rx FIFO */ -#define AACI_TXCR 0x04 /* 17 bits Control Tx FIFO */ -#define AACI_SR 0x08 /* 12 bits Status */ -#define AACI_ISR 0x0C /* 7 bits Int Status */ -#define AACI_IE 0x10 /* 7 bits Int Enable */ - -/* both for AACI_RXCR and AACI_TXCR */ -#define AACI_CR_FEN (1 << 16) /* fifo enable */ -#define AACI_CR_COMPACT (1 << 15) /* compact mode */ -#define AACI_CR_SZ16 (0 << 13) /* 16 bits */ -#define AACI_CR_SZ18 (1 << 13) /* 18 bits */ -#define AACI_CR_SZ20 (2 << 13) /* 20 bits */ -#define AACI_CR_SZ12 (3 << 13) /* 12 bits */ -#define AACI_CR_SL12 (1 << 12) -#define AACI_CR_SL11 (1 << 11) -#define AACI_CR_SL10 (1 << 10) -#define AACI_CR_SL9 (1 << 9) -#define AACI_CR_SL8 (1 << 8) -#define AACI_CR_SL7 (1 << 7) -#define AACI_CR_SL6 (1 << 6) -#define AACI_CR_SL5 (1 << 5) -#define AACI_CR_SL4 (1 << 4) -#define AACI_CR_SL3 (1 << 3) -#define AACI_CR_SL2 (1 << 2) -#define AACI_CR_SL1 (1 << 1) -#define AACI_CR_EN (1 << 0) /* receive enable */ - -/* status register bits */ -#define AACI_SR_RXTOFE (1 << 11) /* rx timeout fifo empty */ -#define AACI_SR_TXTO (1 << 10) /* rx timeout fifo nonempty */ -#define AACI_SR_TXU (1 << 9) /* tx underrun */ -#define AACI_SR_RXO (1 << 8) /* rx overrun */ -#define AACI_SR_TXB (1 << 7) /* tx busy */ -#define AACI_SR_RXB (1 << 6) /* rx busy */ -#define AACI_SR_TXFF (1 << 5) /* tx fifo full */ -#define AACI_SR_RXFF (1 << 4) /* rx fifo full */ -#define AACI_SR_TXHE (1 << 3) /* tx fifo half empty */ -#define AACI_SR_RXHF (1 << 2) /* rx fifo half full */ -#define AACI_SR_TXFE (1 << 1) /* tx fifo empty */ -#define AACI_SR_RXFE (1 << 0) /* rx fifo empty */ - -#define AACI_ISR_RXTOFEINTR (1 << 6) /* rx fifo empty */ -#define AACI_ISR_URINTR (1 << 5) /* tx underflow */ -#define AACI_ISR_ORINTR (1 << 4) /* rx overflow */ -#define AACI_ISR_RXINTR (1 << 3) /* rx fifo */ -#define AACI_ISR_TXINTR (1 << 2) /* tx fifo intr */ -#define AACI_ISR_RXTOINTR (1 << 1) /* rx timeout */ -#define AACI_ISR_TXCINTR (1 << 0) /* tx complete */ - -/* interrupt enable */ -#define AACI_IE_RXTOIE (1 << 6) /*rx timeout interrupt enable*/ -#define AACI_IE_URIE (1 << 5) /*Transmit underrun interrupt enable*/ -#define AACI_IE_ORIE (1 << 4) /*Overrun receive interrupt enable*/ -#define AACI_IE_RXIE (1 << 3) /*Receive interrupt enable*/ -#define AACI_IE_TXIE (1 << 2) /*Transmit interrupt enable*/ -#define AACI_IE_RXTIE (1 << 1) /*Receive timeout interrupt enable*/ -#define AACI_IE_TXCIE (1 << 0) /*Transmit complete interrupt enable*/ - -/* interrupt status */ -#define AACI_ISR_RXTOFE (1 << 6) /* rx timeout fifo empty */ -#define AACI_ISR_UR (1 << 5) /* tx fifo underrun */ -#define AACI_ISR_OR (1 << 4) /* rx fifo overrun */ -#define AACI_ISR_RX (1 << 3) /* rx interrupt status */ -#define AACI_ISR_TX (1 << 2) /* tx interrupt status */ -#define AACI_ISR_RXTO (1 << 1) /* rx timeout */ -#define AACI_ISR_TXC (1 << 0) /* tx complete */ - -/* interrupt enable */ -#define AACI_IE_RXTOFE (1 << 6) /* rx timeout fifo empty */ -#define AACI_IE_UR (1 << 5) /* tx fifo underrun */ -#define AACI_IE_OR (1 << 4) /* rx fifo overrun */ -#define AACI_IE_RX (1 << 3) /* rx interrupt status */ -#define AACI_IE_TX (1 << 2) /* tx interrupt status */ -#define AACI_IE_RXTO (1 << 1) /* rx timeout */ -#define AACI_IE_TXC (1 << 0) /* tx complete */ - -/* slot flag register bits */ -#define AACI_SLFR_RWIS (1 << 13) /* raw wake-up interrupt status */ -#define AACI_SLFR_RGPIOINTR (1 << 12) /* raw gpio interrupt */ -#define AACI_SLFR_12TXE (1 << 11) /* slot 12 tx empty */ -#define AACI_SLFR_12RXV (1 << 10) /* slot 12 rx valid */ -#define AACI_SLFR_2TXE (1 << 9) /* slot 2 tx empty */ -#define AACI_SLFR_2RXV (1 << 8) /* slot 2 rx valid */ -#define AACI_SLFR_1TXE (1 << 7) /* slot 1 tx empty */ -#define AACI_SLFR_1RXV (1 << 6) /* slot 1 rx valid */ -#define AACI_SLFR_12TXB (1 << 5) /* slot 12 tx busy */ -#define AACI_SLFR_12RXB (1 << 4) /* slot 12 rx busy */ -#define AACI_SLFR_2TXB (1 << 3) /* slot 2 tx busy */ -#define AACI_SLFR_2RXB (1 << 2) /* slot 2 rx busy */ -#define AACI_SLFR_1TXB (1 << 1) /* slot 1 tx busy */ -#define AACI_SLFR_1RXB (1 << 0) /* slot 1 rx busy */ - -/* Interrupt clear register */ -#define AACI_ICLR_RXTOFEC4 (1 << 12) /* Receive timeout FIFO empty clear */ -#define AACI_ICLR_RXTOFEC3 (1 << 11) /* Receive timeout FIFO empty clear */ -#define AACI_ICLR_RXTOFEC2 (1 << 10) /* Receive timeout FIFO empty clear */ -#define AACI_ICLR_RXTOFEC1 (1 << 9) /* Receive timeout FIFO empty clear */ -#define AACI_ICLR_TXUEC4 (1 << 8) /* Transmit underrun error clear */ -#define AACI_ICLR_TXUEC3 (1 << 7) /* Transmit underrun error clear */ -#define AACI_ICLR_TXUEC2 (1 << 6) /* Transmit underrun error clear*/ -#define AACI_ICLR_TXUEC1 (1 << 5) /* Transmit underrun error clear */ -#define AACI_ICLR_RXOEC4 (1 << 4) /* Receive overrun error clear */ -#define AACI_ICLR_RXOEC3 (1 << 3) /* Receive overrun error clear */ -#define AACI_ICLR_RXOEC2 (1 << 2) /* Receive overrun error clear */ -#define AACI_ICLR_RXOEC1 (1 << 1) /* Receive overrun error clear */ -#define AACI_ICLR_WISC (1 << 0) /* Wake-up interrupt status clear */ - -/* Main control register bits AACI_MAINCR */ -#define AACI_MAINCR_SCRA(x) ((x) << 10) /* secondary codec reg access */ -#define AACI_MAINCR_DMAEN (1 << 9) /* dma enable */ -#define AACI_MAINCR_SL12TXEN (1 << 8) /* slot 12 transmit enable */ -#define AACI_MAINCR_SL12RXEN (1 << 7) /* slot 12 receive enable */ -#define AACI_MAINCR_SL2TXEN (1 << 6) /* slot 2 transmit enable */ -#define AACI_MAINCR_SL2RXEN (1 << 5) /* slot 2 receive enable */ -#define AACI_MAINCR_SL1TXEN (1 << 4) /* slot 1 transmit enable */ -#define AACI_MAINCR_SL1RXEN (1 << 3) /* slot 1 receive enable */ -#define AACI_MAINCR_LPM (1 << 2) /* low power mode */ -#define AACI_MAINCR_LOOPBK (1 << 1) /* loopback */ -#define AACI_MAINCR_IE (1 << 0) /* aaci interface enable */ - -/* Reset register bits. P65 */ -#define RESET_NRST (1 << 0) - -/* Sync register bits. P65 */ -#define SYNC_FORCE (1 << 0) - -/* Main flag register bits. P66 */ -#define MAINFR_TXB (1 << 1) /* transmit busy */ -#define MAINFR_RXB (1 << 0) /* receive busy */ - -#define PL041_CHANNEL_LEFT_DAC (0x1 << 3) -#define PL041_CHANNEL_RIGHT_DAC (0x1 << 3) -#define PL041_CHANNEL_LEFT_ADC (0x1 << 3) -#define PL041_CHANNEL_RIGHT_ADC (0x1 << 3) - -struct reg_pl041 -{ -volatile rt_uint32_t rxcr1; /* 0x000 */ -volatile rt_uint32_t txcr1; /* 0x004 */ -volatile rt_uint32_t sr1; /* 0x008 */ -volatile rt_uint32_t isr1; /* 0x00c */ -volatile rt_uint32_t iie1; /* 0x010 */ -volatile rt_uint32_t rxcr2; /* 0x014 */ -volatile rt_uint32_t txcr2; /* 0x018 */ -volatile rt_uint32_t sr2; /* 0x01c */ -volatile rt_uint32_t isr2; /* 0x020 */ -volatile rt_uint32_t iie2; /* 0x024 */ -volatile rt_uint32_t rxcr3; /* 0x028 */ -volatile rt_uint32_t txcr3; /* 0x02c */ -volatile rt_uint32_t sr3; /* 0x030 */ -volatile rt_uint32_t isr3; /* 0x034 */ -volatile rt_uint32_t iie3; /* 0x038 */ -volatile rt_uint32_t rxcr4; /* 0x03c */ -volatile rt_uint32_t txcr4; /* 0x040 */ -volatile rt_uint32_t sr4; /* 0x044 */ -volatile rt_uint32_t isr4; /* 0x048 */ -volatile rt_uint32_t iie4; /* 0x04c */ -volatile rt_uint32_t sl1rx; /* 0x050 */ -volatile rt_uint32_t sl1tx; /* 0x054 */ -volatile rt_uint32_t sl2rx; /* 0x058 */ -volatile rt_uint32_t sl2tx; /* 0x05c */ -volatile rt_uint32_t sl12rx; /* 0x060 */ -volatile rt_uint32_t sl12tx; /* 0x064 */ -volatile rt_uint32_t slfr; /* 0x068 */ -volatile rt_uint32_t slistat; /* 0x06c */ -volatile rt_uint32_t slien; /* 0x070 */ -volatile rt_uint32_t intclr; /* 0x074 */ -volatile rt_uint32_t maincr; /* 0x078 */ -volatile rt_uint32_t reset; /* 0x07c */ -volatile rt_uint32_t sync; /* 0x080 */ -volatile rt_uint32_t allints; /* 0x084 */ -volatile rt_uint32_t mainfr; /* 0x088 */ -volatile rt_uint32_t res08c; -volatile rt_uint32_t dr1[8]; /* 0x090 */ -volatile rt_uint32_t dr2[8]; /* 0x0b0 */ -volatile rt_uint32_t dr3[8]; /* 0x0d0 */ -volatile rt_uint32_t dr4[8]; /* 0x0f0 */ -}; - -typedef struct reg_pl041 *reg_pl041_t; - -#define PL041 ((reg_pl041_t)PL041_BASE_ADDR) - -struct pl041_cfg -{ - rt_uint32_t itype; - rt_uint32_t otype; - int vol; - int rate; -}; -typedef struct pl041_cfg *pl041_cfg_t; - -typedef void (*pl041_irq_fun_t)(rt_uint32_t status, void * user_data); - -rt_err_t aaci_pl041_init(void); -void aaci_ac97_write(rt_uint16_t reg, rt_uint16_t val); -rt_uint16_t aaci_ac97_read(rt_uint16_t reg); -int aaci_pl041_channel_cfg(int channel, pl041_cfg_t cfg); -int aaci_pl041_channel_write(int channel, rt_uint16_t *buff, int count); -int aaci_pl041_channel_read(int channel, rt_uint16_t *buff, int count); -int aaci_pl041_channel_enable(int channel); -int aaci_pl041_channel_disable(int channel); -rt_err_t aaci_pl041_irq_register(int channel, pl041_irq_fun_t fun, void *user_data); -rt_err_t aaci_pl041_irq_unregister(int channel); -void aaci_pl041_irq_disable(int channel, rt_uint32_t vector); -void aaci_pl041_irq_enable(int channel, rt_uint32_t vector); -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c b/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c deleted file mode 100644 index a2b46831b8..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Date Author Notes - * 2019-07-23 Zero-Free first implementation - */ - -#include -#include - -#include -#include -#include - -#define DBG_TAG "drv.sound" -#define DBG_LVL DBG_INFO -#include - -#define TX_FIFO_SIZE (3840) - -struct sound_device -{ - struct rt_audio_device audio; - struct rt_audio_configure replay_config; - rt_uint8_t *tx_fifo; - rt_uint8_t volume; -}; - -static struct sound_device snd_dev = {0}; - -static void rt_hw_aaci_isr(rt_uint32_t status, void *user_data) -{ - if (status & AACI_SR_TXHE) - { - rt_audio_tx_complete(&snd_dev.audio); - } -} - -static rt_err_t sound_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps) -{ - rt_err_t result = RT_EOK; - struct sound_device *snd_dev; - - RT_ASSERT(audio != RT_NULL); - snd_dev = (struct sound_device *)audio->parent.user_data; - - switch (caps->main_type) - { - case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */ - { - switch (caps->sub_type) - { - case AUDIO_TYPE_QUERY: - caps->udata.mask = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_MIXER; - break; - - default: - result = -RT_ERROR; - break; - } - - break; - } - - case AUDIO_TYPE_OUTPUT: /* Provide capabilities of OUTPUT unit */ - { - switch (caps->sub_type) - { - case AUDIO_DSP_PARAM: - caps->udata.config.samplerate = snd_dev->replay_config.samplerate; - caps->udata.config.channels = snd_dev->replay_config.channels; - caps->udata.config.samplebits = snd_dev->replay_config.samplebits; - break; - - case AUDIO_DSP_SAMPLERATE: - caps->udata.config.samplerate = snd_dev->replay_config.samplerate; - break; - - case AUDIO_DSP_CHANNELS: - caps->udata.config.channels = snd_dev->replay_config.channels; - break; - - case AUDIO_DSP_SAMPLEBITS: - caps->udata.config.samplebits = snd_dev->replay_config.samplebits; - break; - - default: - result = -RT_ERROR; - break; - } - - break; - } - - case AUDIO_TYPE_MIXER: /* report the Mixer Units */ - { - switch (caps->sub_type) - { - case AUDIO_MIXER_QUERY: - caps->udata.mask = AUDIO_MIXER_VOLUME; - break; - - case AUDIO_MIXER_VOLUME: - caps->udata.value = snd_dev->volume; - break; - - default: - result = -RT_ERROR; - break; - } - - break; - } - - default: - result = -RT_ERROR; - break; - } - - return result; -} - -static rt_err_t sound_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps) -{ - rt_err_t result = RT_EOK; - struct sound_device *snd_dev; - struct rt_audio_replay *replay; - - RT_ASSERT(audio != RT_NULL); - snd_dev = (struct sound_device *)audio->parent.user_data; - - switch (caps->main_type) - { - case AUDIO_TYPE_MIXER: - { - switch (caps->sub_type) - { - case AUDIO_MIXER_VOLUME: - { - rt_uint8_t volume = caps->udata.value; - - snd_dev->volume = volume; - ac97_set_vol(volume); - LOG_I("set volume %d", volume); - break; - } - - default: - result = -RT_ERROR; - break; - } - - break; - } - - case AUDIO_TYPE_OUTPUT: - { - switch (caps->sub_type) - { - case AUDIO_DSP_PARAM: - { - /* set samplerate */ - ac97_set_rate(caps->udata.config.samplerate); - - /* update buffer fifo informaition according samplerate */ - replay = snd_dev->audio.replay; - replay->buf_info.total_size = caps->udata.config.samplerate / 50 * 4; - replay->buf_info.block_size = replay->buf_info.total_size / 2; - - /* save configs */ - snd_dev->replay_config.samplerate = caps->udata.config.samplerate; - snd_dev->replay_config.channels = caps->udata.config.channels; - snd_dev->replay_config.samplebits = caps->udata.config.samplebits; - LOG_D("set samplerate %d", snd_dev->replay_config.samplerate); - break; - } - - case AUDIO_DSP_SAMPLERATE: - { - ac97_set_rate(caps->udata.config.samplerate); - - snd_dev->replay_config.samplerate = caps->udata.config.samplerate; - LOG_D("set samplerate %d", snd_dev->replay_config.samplerate); - break; - } - - case AUDIO_DSP_CHANNELS: - { - /* not support */ - snd_dev->replay_config.channels = caps->udata.config.channels; - LOG_D("set channels %d", snd_dev->replay_config.channels); - break; - } - - case AUDIO_DSP_SAMPLEBITS: - { - /* not support */ - snd_dev->replay_config.samplebits = caps->udata.config.samplebits; - break; - } - - default: - result = -RT_ERROR; - break; - } - - break; - } - - default: - break; - } - - return result; -} - -static rt_err_t sound_init(struct rt_audio_device *audio) -{ - rt_err_t result = RT_EOK; - struct sound_device *snd_dev; - struct pl041_cfg _cfg; - - RT_ASSERT(audio != RT_NULL); - snd_dev = (struct sound_device *)audio->parent.user_data; - - aaci_pl041_init(); - - _cfg.itype = PL041_CHANNEL_LEFT_ADC | PL041_CHANNEL_RIGHT_ADC; - _cfg.otype = PL041_CHANNEL_LEFT_DAC | PL041_CHANNEL_RIGHT_DAC; - _cfg.vol = snd_dev->volume; - _cfg.rate = snd_dev->replay_config.samplerate; - - ac97_reset(); - aaci_pl041_channel_cfg(0, &_cfg); - aaci_pl041_irq_register(0, rt_hw_aaci_isr, RT_NULL); - - return result; -} - -static rt_err_t sound_start(struct rt_audio_device *audio, int stream) -{ - RT_ASSERT(audio != RT_NULL); - - if (stream == AUDIO_STREAM_REPLAY) - { - LOG_D("open sound device"); - aaci_pl041_channel_enable(0); - aaci_pl041_irq_enable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); - } - - return RT_EOK; -} - -static rt_err_t sound_stop(struct rt_audio_device *audio, int stream) -{ - RT_ASSERT(audio != RT_NULL); - - if (stream == AUDIO_STREAM_REPLAY) - { - /* wait codec free */ - rt_thread_mdelay(100); - /* disable irq and channels 0 */ - aaci_pl041_irq_disable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); - aaci_pl041_channel_disable(0); - LOG_D("close sound device"); - } - - return RT_EOK; -} - -static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info) -{ - struct sound_device *snd_dev; - - RT_ASSERT(audio != RT_NULL); - snd_dev = (struct sound_device *)audio->parent.user_data; - - /** - * TX_FIFO - * +----------------+----------------+ - * | block1 | block2 | - * +----------------+----------------+ - * \ block_size / - */ - info->buffer = snd_dev->tx_fifo; - info->total_size = TX_FIFO_SIZE; - info->block_size = TX_FIFO_SIZE/2; - info->block_count = 2; -} - -static rt_size_t sound_transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size) -{ - RT_ASSERT(audio != RT_NULL); - - /* write data to channel_0 fifo */ - aaci_pl041_channel_write(0, (rt_uint16_t *)writeBuf, size >> 1); - - return size; -} - -static struct rt_audio_ops snd_ops = -{ - .getcaps = sound_getcaps, - .configure = sound_configure, - .init = sound_init, - .start = sound_start, - .stop = sound_stop, - .transmit = sound_transmit, - .buffer_info = sound_buffer_info, -}; - -int rt_hw_audio_init(void) -{ - rt_uint8_t *tx_fifo; - - if (snd_dev.tx_fifo) - return RT_EOK; - - tx_fifo = rt_malloc(TX_FIFO_SIZE); - if (tx_fifo == RT_NULL) - return -RT_ENOMEM; - rt_memset(tx_fifo, 0, TX_FIFO_SIZE); - snd_dev.tx_fifo = tx_fifo; - - /* init default configuration */ - { - snd_dev.replay_config.samplerate = 44100; - snd_dev.replay_config.channels = 2; - snd_dev.replay_config.samplebits = 16; - snd_dev.volume = 55; - } - - /* register sound device */ - snd_dev.audio.ops = &snd_ops; - rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev); - - return RT_EOK; -} - -INIT_DEVICE_EXPORT(rt_hw_audio_init); diff --git a/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h b/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h deleted file mode 100644 index 7cb47532be..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/audio/drv_sound.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Date Author Notes - * 2019-07-23 Zero-Free first implementation - */ - -#ifndef __DRV_SOUND_H__ -#define __DRV_SOUND_H__ - -int rt_hw_audio_init(void); - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/board.c b/bsp/qemu-vexpress-a53/drivers/board.c deleted file mode 100644 index fbe741a546..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/board.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-11-20 Bernard the first version - * 2018-11-22 Jesven add rt_hw_spin_lock - * add rt_hw_spin_unlock - * add smp ipi init - */ - -#include -#include - -#include "board.h" -#include "drv_timer.h" - -#include -#ifdef RT_USING_USERSPACE -#include -#include -#endif - -#ifdef RT_USING_USERSPACE -struct mem_desc platform_mem_desc[] = { - {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM} -}; -#else -struct mem_desc platform_mem_desc[] = { - {0x10000000, 0x50000000, 0x10000000, DEVICE_MEM}, - {0x60000000, 0x70000000, 0x60000000, NORMAL_MEM} -}; -#endif - -const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]); - -#define SYS_CTRL __REG32(REALVIEW_SCTL_BASE) - -extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); - -void idle_wfi(void) -{ - asm volatile ("wfi"); -} - -/** - * This function will initialize board - */ - -rt_mmu_info mmu_info; - -extern size_t MMUTable[]; - -#ifdef RT_USING_USERSPACE -rt_region_t init_page_region = { - PAGE_START, - PAGE_END, -}; -#endif - -void rt_hw_board_init(void) -{ -#ifdef RT_USING_USERSPACE - rt_page_init(init_page_region); - - rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size); - - rt_hw_mmu_map_init(&mmu_info, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET); - - arch_kuser_init(&mmu_info, (void*)0xffffffffffff0000); -#else - rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0); - rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000); -#endif - - /* initialize hardware interrupt */ - rt_hw_interrupt_init(); - - /* initialize system heap */ - rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); - - rt_components_board_init(); - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); - - rt_thread_idle_sethook(idle_wfi); - -#ifdef RT_USING_SMP - /* install IPI handle */ - rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler); -#endif -} diff --git a/bsp/qemu-vexpress-a53/drivers/board.h b/bsp/qemu-vexpress-a53/drivers/board.h deleted file mode 100644 index 003845f39d..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/board.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * File : board.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard the first version - */ - -#ifndef __BOARD_H__ -#define __BOARD_H__ - -#include -#include -#include "vexpress_a9.h" - -#include "mmu.h" -#include "ioremap.h" - -#if defined(__CC_ARM) -extern int Image$$RW_IRAM1$$ZI$$Limit; -#define HEAP_BEGIN ((void*)&Image$$RW_IRAM1$$ZI$$Limit) -#elif defined(__GNUC__) -extern int __bss_end; -#define HEAP_BEGIN ((void*)&__bss_end) -#endif - -#ifdef RT_USING_USERSPACE -#define HEAP_END ((size_t)KERNEL_VADDR_START + 16 * 1024 * 1024) -#define PAGE_START HEAP_END -#define PAGE_END ((size_t)KERNEL_VADDR_START + 128 * 1024 * 1024) -#else -#define HEAP_END ((size_t)0x60000000 + 64 * 1024 * 1024) -#endif - -void rt_hw_board_init(void); - -extern rt_mmu_info mmu_info; - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_clcd.c b/bsp/qemu-vexpress-a53/drivers/drv_clcd.c deleted file mode 100644 index e194be9da4..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_clcd.c +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include -#include - -#include -#include - -#include -#include - -#include "drv_clcd.h" -#include "rt_lcd.h" - -#define CLCD_WIDTH (BSP_LCD_WIDTH) -#define CLCD_HEIGHT (BSP_LCD_HEIGHT) - -#define CLCD_DEVICE(dev) (struct drv_clcd_device*)(dev) - -#define PL111_CR_EN 0x001 -#define PL111_CR_PWR 0x800 -#define PL111_IOBASE 0x10020000 -#define PL111_PALBASE (PL111_IOBASE + 0x200) - -typedef struct _PL111MMIO -{ - uint32_t volatile tim0; //0 - uint32_t volatile tim1; //4 - uint32_t volatile tim2; //8 - uint32_t volatile tim3; //c - uint32_t volatile upbase; //10 - uint32_t volatile f; //14 - uint32_t volatile control; //18 - uint32_t volatile g; //1c -} PL111MMIO; - -struct drv_clcd_device -{ - struct rt_device parent; - - int width; - int height; - - uint8_t *fb; - uint8_t *fb_virt; -}; -struct drv_clcd_device _lcd; - -static rt_err_t drv_clcd_init(struct rt_device *device) -{ - struct drv_clcd_device *lcd = CLCD_DEVICE(device); - - (void)lcd; /* nothing, right now */ - return RT_EOK; -} - -static rt_err_t drv_clcd_control(struct rt_device *device, int cmd, void *args) -{ - struct drv_clcd_device *lcd = CLCD_DEVICE(device); - - switch (cmd) - { - case RTGRAPHIC_CTRL_RECT_UPDATE: - { - struct rt_device_rect_info *info = (struct rt_device_rect_info*)args; - - (void)info; /* nothing, right now */ - rt_kprintf("update screen...\n"); - } - break; - - case RTGRAPHIC_CTRL_GET_INFO: - { - struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args; - - RT_ASSERT(info != RT_NULL); - info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; - info->bits_per_pixel= 16; - info->width = lcd->width; - info->height = lcd->height; - info->framebuffer = lcd->fb; - } - break; - - case FBIOGET_FSCREENINFO: - { -#ifdef RT_USING_USERSPACE - struct fb_fix_screeninfo *info = (struct fb_fix_screeninfo *)args; - strncpy(info->id, "lcd", sizeof(info->id)); - info->smem_len = lcd->width * lcd->height * 2; - info->smem_start = (size_t)lwp_map_user_phy(lwp_self(), RT_NULL, lcd->fb, - info->smem_len, 1); - info->line_length = lcd->width * 2; -#endif - } - break; - - case FBIOGET_VSCREENINFO: - { - struct fb_var_screeninfo *info = (struct fb_var_screeninfo *)args; - info->bits_per_pixel = 16; - info->xres = lcd->width; - info->yres = lcd->height; - } - break; - - case FBIOGET_DISPINFO: - break; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops clcd_ops = -{ - drv_clcd_init, - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - drv_clcd_control -}; -#endif - -int drv_clcd_hw_init(void) -{ - PL111MMIO *plio; - struct rt_device *device = &_lcd.parent; - - /* memset _lcd to zero */ - memset(&_lcd, 0x0, sizeof(_lcd)); - - _lcd.width = CLCD_WIDTH; - _lcd.height = CLCD_HEIGHT; - rt_kprintf("try to allocate fb... | w - %d, h - %d | ", _lcd.width, _lcd.height); -#ifdef RT_USING_USERSPACE - _lcd.fb_virt= rt_pages_alloc (rt_page_bits(_lcd.width * _lcd.height * 2)); - _lcd.fb = _lcd.fb_virt + PV_OFFSET; - rt_kprintf("done!\n"); - rt_kprintf("fb => 0x%08x\n", _lcd.fb); - if (_lcd.fb == NULL) - { - rt_kprintf("initialize frame buffer failed!\n"); - return -1; - } - - memset(_lcd.fb_virt, 0xff, _lcd.width * _lcd.height * 2); -#else - _lcd.fb = rt_malloc(_lcd.width * _lcd.height * 2); - if (_lcd.fb == NULL) - { - rt_kprintf("initialize frame buffer failed!\n"); - return -1; - } - - memset(_lcd.fb, 0xff, _lcd.width * _lcd.height * 2); -#endif - - plio = (PL111MMIO *)rt_ioremap((void*)PL111_IOBASE, 0x1000); - - plio->tim0 = 0x3F1F3C00 | ((CLCD_WIDTH / 16 - 1) << 2); - plio->tim1 = 0x080B6000 | (CLCD_HEIGHT - 1); - - plio->upbase = (uint32_t)(size_t)_lcd.fb; - /* 16-bit 565 color */ - plio->control = 0x1921 | (0x6 << 1); - - device->type = RT_Device_Class_Graphic; -#ifdef RT_USING_DEVICE_OPS - device->ops = &clcd_ops; -#else - device->init = drv_clcd_init; - device->control = drv_clcd_control; -#endif - - rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR); - - return 0; -} -INIT_DEVICE_EXPORT(drv_clcd_hw_init); diff --git a/bsp/qemu-vexpress-a53/drivers/drv_clcd.h b/bsp/qemu-vexpress-a53/drivers/drv_clcd.h deleted file mode 100644 index 4ed3136981..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_clcd.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef DRV_CLCD_H__ -#define DRV_CLCD_H__ - -#include - -#ifndef BSP_LCD_WIDTH -#define BSP_LCD_WIDTH 640 -#endif - -#ifndef BSP_LCD_HEIGHT -#define BSP_LCD_HEIGHT 480 -#endif - -int drv_clcd_hw_init(void); - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_keyboard.c b/bsp/qemu-vexpress-a53/drivers/drv_keyboard.c deleted file mode 100644 index 3f961b40ae..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_keyboard.c +++ /dev/null @@ -1,474 +0,0 @@ -#include -#include -#include - -#include "board.h" -#include "interrupt.h" -#include "drv_keyboard.h" - -#define DBG_LVL DBG_INFO -#include "rtdbg.h" - -#define KEYBOARD_ADDRESS (0x10006000) -#define KEYBOARD_IRQ_NUM (IRQ_VEXPRESS_A9_KBD) - -#ifdef PKG_USING_GUIENGINE - -#include -#include - -typedef rt_uint32_t virtual_addr_t; - -enum{ - KEYBOARD_CR = 0x00, - KEYBOARD_STAT = 0x04, - KEYBOARD_DATA = 0x08, - KEYBOARD_CLKDIV = 0x0c, - KEYBOARD_IIR = 0x10, -}; - -struct keyboard_pl050_pdata_t -{ - virtual_addr_t virt; - int irq; -}; - -enum decode_state { - DECODE_STATE_MAKE_CODE, - DECODE_STATE_BREAK_CODE, - DECODE_STATE_LONG_MAKE_CODE, - DECODE_STATE_LONG_BREAK_CODE -}; - -struct keymap { - rt_uint8_t data; - rt_uint32_t key; - rt_uint32_t unicode; - char *normal_key; -}; - -enum key_value_t { - KEY_BUTTON_UP, - KEY_BUTTON_DOWN, -}; - -enum { - KBD_LEFT_SHIFT = (0x1 << 0), - KBD_RIGHT_SHIFT = (0x1 << 1), - KBD_LEFT_CTRL = (0x1 << 2), - KBD_RIGHT_CTRL = (0x1 << 3), - KBD_CAPS_LOCK = (0x1 << 6), - KBD_NUM_LOCK = (0x1 << 7), - KBD_SCROLL_LOCK = (0x1 << 8), -}; - -static const struct keymap map[] = { - {0x1c, RTGUIK_a, 0, "a", }, - {0x32, RTGUIK_b, 0, "b", }, - {0x21, RTGUIK_c, 0, "c", }, - {0x23, RTGUIK_d, 0, "d", }, - {0x24, RTGUIK_e, 0, "e", }, - {0x2b, RTGUIK_f, 0, "f", }, - {0x34, RTGUIK_g, 0, "g", }, - {0x33, RTGUIK_h, 0, "h", }, - {0x43, RTGUIK_i, 0, "i", }, - {0x3b, RTGUIK_j, 0, "j", }, - {0x42, RTGUIK_k, 0, "k", }, - {0x4b, RTGUIK_l, 0, "l", }, - {0x3a, RTGUIK_m, 0, "m", }, - {0x31, RTGUIK_n, 0, "n", }, - {0x44, RTGUIK_o, 0, "o", }, - {0x4d, RTGUIK_p, 0, "p", }, - {0x15, RTGUIK_q, 0, "q", }, - {0x2d, RTGUIK_r, 0, "r", }, - {0x1b, RTGUIK_s, 0, "s", }, - {0x2c, RTGUIK_k, 0, "k", }, - {0x3c, RTGUIK_u, 0, "u", }, - {0x2a, RTGUIK_v, 0, "v", }, - {0x1d, RTGUIK_w, 0, "w", }, - {0x22, RTGUIK_x, 0, "x", }, - {0x35, RTGUIK_y, 0, "y", }, - {0x1a, RTGUIK_z, 0, "z", }, - - {0x45, RTGUIK_0, 0, "0", }, - {0x16, RTGUIK_1, 0, "1", }, - {0x1e, RTGUIK_2, 0, "2", }, - {0x26, RTGUIK_3, 0, "3", }, - {0x25, RTGUIK_4, 0, "4", }, - {0x2e, RTGUIK_5, 0, "5", }, - {0x36, RTGUIK_6, 0, "6", }, - {0x3d, RTGUIK_7, 0, "7", }, - {0x3e, RTGUIK_8, 0, "8", }, - {0x46, RTGUIK_9, 0, "9", }, - - {0x05, RTGUIK_F1, 0, "F1", }, - {0x06, RTGUIK_F2, 0, "F2", }, - {0x04, RTGUIK_F3, 0, "F3", }, - {0x0c, RTGUIK_F4, 0, "F4", }, - {0x03, RTGUIK_F5, 0, "F5", }, - {0x0b, RTGUIK_F6, 0, "F6", }, - {0x83, RTGUIK_F7, 0, "F7", }, - {0x0a, RTGUIK_F8, 0, "F8", }, - {0x01, RTGUIK_F9, 0, "F9", }, - {0x09, RTGUIK_F10, 0, "F10", }, - {0x78, RTGUIK_F11, 0, "F11", }, - {0x07, RTGUIK_F12, 0, "F12", }, - - {0x29, RTGUIK_SPACE, 0, "SPACE" }, - {0x71, RTGUIK_DELETE, 0, "DELETE" }, - {0x52, RTGUIK_QUOTE, 0, "'" }, - {0x55, RTGUIK_EQUALS, 0, "=" }, - {0x41, RTGUIK_COMMA, 0, "," }, - {0x4e, RTGUIK_MINUS, 0, "-" }, - // {0x49, RTGUIK_, 0, "." }, - {0x4a, RTGUIK_SLASH, 0, "/" }, - {0x4c, RTGUIK_SEMICOLON, 0, ";" }, - {0x54, RTGUIK_LEFTBRACKET, 0, "[" }, - {0x5d, RTGUIK_BACKSLASH, 0, "\\" }, - {0x5b, RTGUIK_RIGHTBRACKET, 0, "]"}, - {0x75, RTGUIK_UP, 0, "UP" }, - {0x72, RTGUIK_DOWN, 0, "DOWN" }, - {0x6b, RTGUIK_LEFT, 0, "LEFT" }, - {0x74, RTGUIK_RIGHT, 0, "RIGHT" }, - {0x0d, RTGUIK_TAB, 0, "TAB" }, - {0x76, RTGUIK_ESCAPE, 0, "ESC" }, - {0x37, RTGUIK_POWER, 0, "POWER" }, - {0x5a, RTGUIK_KP_ENTER, 0, "ENTER"}, - {0x66, RTGUIK_BACKSPACE, 0, "BACKSPACE"}, -}; - -rt_inline rt_uint8_t read8(uint32_t addr) -{ - return (*((volatile rt_uint8_t *)(addr))); -} - -rt_inline void write8(uint32_t addr, rt_uint8_t value) -{ - *((volatile rt_uint8_t *)(addr)) = value; -} - -rt_inline rt_uint32_t read32(uint32_t addr) -{ - return (*((volatile rt_uint32_t *)(addr))); -} - -rt_inline void write32(uint32_t addr, rt_uint32_t value) -{ - *((volatile rt_uint32_t *)(addr)) = value; -} - -rt_inline int kmi_write(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t value) -{ - int timeout = 1000; - - while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 6)) == 0 && timeout--); - - if(timeout) - { - write8(pdat->virt + KEYBOARD_DATA, value); - while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4)) == 0); - - if(read8(pdat->virt + KEYBOARD_DATA) == 0xfa) - return RT_TRUE; - } - return RT_FALSE; -} - -rt_inline int kmi_read(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t * value) -{ - if((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4))) - { - *value = read8(pdat->virt + KEYBOARD_DATA); - return RT_TRUE; - } - return RT_FALSE; -} - -static void keyboard_report_event(void * device, rt_uint32_t flag, rt_uint8_t data, enum key_value_t press) -{ - struct rtgui_event_kbd key_event; - rt_uint16_t i = 0, mod = 0, find_key = 0; - - for(i = 0; i < sizeof(map)/sizeof(map[0]); i++) - { - if (map[i].data == data) - { - LOG_D("KEY info:"); - if (flag & KBD_CAPS_LOCK) - { - LOG_D("CAPS:LOCK"); - } - else - { - LOG_D("CAPS:UNLOCK"); - } - - if (flag & KBD_LEFT_SHIFT) - { - mod |= RTGUI_KMOD_LSHIFT; - LOG_D("SHIFT:LEFT"); - } - else if (flag & KBD_RIGHT_SHIFT) - { - mod |= RTGUI_KMOD_RSHIFT; - LOG_D("SHIFT:RIGHT"); - } - else - { - LOG_D("SHIFT:NULL"); - } - - if (flag & KBD_LEFT_CTRL) - { - mod |= RTGUI_KMOD_LCTRL; - LOG_D("CTRL:LEFT"); - } - else if (flag & KBD_RIGHT_CTRL) - { - mod |= RTGUI_KMOD_RCTRL; - LOG_D("CTRL:RIGHT"); - } - else - { - LOG_D("CTRL:NULL"); - } - - LOG_D("flag:0x%08x value:0x%x key:%s status:%s", \ - flag, data, map[i].normal_key, press ==0 ? "UP" : "DOWN"); - find_key = 1; - break; - } - } - if (find_key == 0) - { - LOG_D("flag:0x%08x value:0x%x key:%s status:%s", \ - flag, data, "UNKNOWN", press ==0 ? "UP" : "DOWN"); - return; - } - - key_event.parent.sender = RT_NULL; - key_event.parent.type = RTGUI_EVENT_KBD; - key_event.type = (press == 0 ? RTGUI_KEYUP : RTGUI_KEYDOWN); - key_event.key = map[i].key; - key_event.mod = mod; - key_event.unicode = map[i].unicode; - rtgui_server_post_event(&key_event.parent, sizeof(key_event)); -} - -static void keyboard_pl050_interrupt(int irq, void *data) -{ - struct keyboard_pl050_pdata_t * pdat = (struct keyboard_pl050_pdata_t *)data; - static enum decode_state ds = DECODE_STATE_MAKE_CODE; - static rt_uint32_t kbd_flag = KBD_NUM_LOCK; - rt_uint8_t status, value; - - status = read8(pdat->virt + KEYBOARD_IIR); - - while(status & (1 << 0)) - { - value = read8(pdat->virt + KEYBOARD_DATA); - - switch(ds) - { - case DECODE_STATE_MAKE_CODE: - /* break code */ - if(value == 0xf0) - { - ds = DECODE_STATE_BREAK_CODE; - } - /* long make code */ - else if(value == 0xe0) - { - ds = DECODE_STATE_LONG_MAKE_CODE; - } - else - { - ds = DECODE_STATE_MAKE_CODE; - - /* left shift */ - if(value == 0x12) - { - kbd_flag |= KBD_LEFT_SHIFT; - } - /* right shift */ - else if(value == 0x59) - { - kbd_flag |= KBD_RIGHT_SHIFT; - } - /* left ctrl */ - else if(value == 0x14) - { - kbd_flag |= KBD_LEFT_CTRL; - } - /* caps lock */ - else if(value == 0x58) - { - if(kbd_flag & KBD_CAPS_LOCK) - kbd_flag &= ~KBD_CAPS_LOCK; - else - kbd_flag |= KBD_CAPS_LOCK; - } - /* scroll lock */ - else if(value == 0x7e) - { - if(kbd_flag & KBD_SCROLL_LOCK) - kbd_flag &= ~KBD_SCROLL_LOCK; - else - kbd_flag |= KBD_SCROLL_LOCK; - } - /* num lock */ - else if(value == 0x77) - { - if(kbd_flag & KBD_NUM_LOCK) - kbd_flag &= ~KBD_NUM_LOCK; - else - kbd_flag |= KBD_NUM_LOCK; - } - /* others */ - else - { - keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN); - } - } - break; - - case DECODE_STATE_BREAK_CODE: - if( (value != 0xf0) && (value != 0xe0)) - { - ds = DECODE_STATE_MAKE_CODE; - - /* left shift */ - if(value == 0x12) - { - kbd_flag &= ~KBD_LEFT_SHIFT; - } - /* right shift */ - else if(value == 0x59) - { - kbd_flag &= ~KBD_RIGHT_SHIFT; - } - /* left ctrl */ - else if(value == 0x14) - { - kbd_flag &= ~KBD_LEFT_CTRL; - } - /* others */ - else - { - keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP); - } - } - else - { - ds = DECODE_STATE_BREAK_CODE; - } - break; - - case DECODE_STATE_LONG_MAKE_CODE: - if( value != 0xf0 && value!= 0xe0) - { - ds = DECODE_STATE_MAKE_CODE; - - /* left ctrl */ - if(value == 0x14) - { - kbd_flag |= KBD_RIGHT_CTRL; - } - /* others */ - else - { - keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN); - } - } - else - { - ds = DECODE_STATE_LONG_BREAK_CODE; - } - break; - - case DECODE_STATE_LONG_BREAK_CODE: - if( (value != 0xf0) && (value != 0xe0)) - { - ds = DECODE_STATE_MAKE_CODE; - - /* left ctrl */ - if(value == 0x14) - { - kbd_flag &= ~KBD_RIGHT_CTRL; - } - /* others */ - else - { - keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP); - } - } - else - { - ds = DECODE_STATE_LONG_BREAK_CODE; - } - break; - - default: - ds = DECODE_STATE_MAKE_CODE; - break; - } - - status = read8(pdat->virt + KEYBOARD_IIR); - } -} - -int rt_hw_keyboard_init(void) -{ - rt_uint8_t value; - rt_uint32_t id; - struct keyboard_pl050_pdata_t *pdat; - virtual_addr_t virt; - int irq = KEYBOARD_IRQ_NUM; - - virt = (virtual_addr_t)rt_ioremap((void*)KEYBOARD_ADDRESS, 0x1000); - - id = (((read32(virt + 0xfec) & 0xff) << 24) | - ((read32(virt + 0xfe8) & 0xff) << 16) | - ((read32(virt + 0xfe4) & 0xff) << 8) | - ((read32(virt + 0xfe0) & 0xff) << 0)); - - if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050) - { - LOG_E("read id fail id:0x%08x", id); - return RT_ERROR; - } - - pdat = rt_malloc(sizeof(struct keyboard_pl050_pdata_t)); - if(!pdat) - { - LOG_E("malloc memory failed"); - return RT_ERROR; - } - rt_memset(pdat, 0, sizeof(struct keyboard_pl050_pdata_t)); - - pdat->virt = virt; - pdat->irq = irq; - - write8(pdat->virt + KEYBOARD_CLKDIV, 0); - write8(pdat->virt + KEYBOARD_CR, (1 << 2)); - kmi_read(pdat, &value); - kmi_write(pdat, 0xff); - kmi_read(pdat, &value); - kmi_write(pdat, 0xf3); - kmi_write(pdat, 0x2b); - kmi_write(pdat, 0xf0); - kmi_write(pdat, 0x02); - kmi_write(pdat, 0xfa); - kmi_write(pdat, 0xed); - kmi_write(pdat, 0x02); - write8(pdat->virt + KEYBOARD_CR, (1 << 2) | (1 << 4)); - - rt_hw_interrupt_install(irq, keyboard_pl050_interrupt, (void *)pdat, "keyboard"); - rt_hw_interrupt_umask(irq); - - return RT_EOK; -} -INIT_DEVICE_EXPORT(rt_hw_keyboard_init); - -#endif - diff --git a/bsp/qemu-vexpress-a53/drivers/drv_keyboard.h b/bsp/qemu-vexpress-a53/drivers/drv_keyboard.h deleted file mode 100644 index 6d5acb7427..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_keyboard.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __DEV_KEYBOARD_H__ -#define __DEV_KEYBOARD_H__ - -int rt_hw_keyboard_init(void); - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_mouse.c b/bsp/qemu-vexpress-a53/drivers/drv_mouse.c deleted file mode 100644 index d3244bcd29..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_mouse.c +++ /dev/null @@ -1,300 +0,0 @@ -#include -#include -#include - -#include "board.h" -#include "interrupt.h" -#include "drv_mouse.h" -#include "drv_clcd.h" - -#define DBG_TAG "drv.mouse" -#define DBG_LVL DBG_INFO -#include "rtdbg.h" - -#define MOUSE_ADDRESS (0x10007000) -#define MOUSE_IRQ_NUM (IRQ_VEXPRESS_A9_MOUSE) -#define MOUSE_XMAX (BSP_LCD_WIDTH) -#define MOUSE_YMAX (BSP_LCD_HEIGHT) - -#define MOUSE_BUTTON_LEFT (0x01) -#define MOUSE_BUTTON_RIGHT (0x02) -#define MOUSE_BUTTON_MIDDLE (0x04) -#define MOUSE_BUTTON_DOWN (0x10) -#define MOUSE_BUTTON_UP (0x20) -#define MOUSE_BUTTON_MOVE (0x40) -#define MOUSE_BUTTON_WHELL (0x80) - -#ifdef PKG_USING_GUIENGINE - -#include -#include - -typedef rt_uint32_t virtual_addr_t; - -enum { - MOUSE_CR = 0x00, - MOUSE_STAT = 0x04, - MOUSE_DATA = 0x08, - MOUSE_CLKDIV = 0x0c, - MOUSE_IIR = 0x10, -}; - -struct mouse_pl050_pdata_t { - virtual_addr_t virt; - int irq; - int xmax, ymax; - int xpos, ypos; - unsigned char packet[4]; - int index; - int obtn; - int type; -}; - -rt_inline rt_uint8_t read8(uint32_t addr) -{ - return (*((volatile rt_uint8_t *)(addr))); -} - -rt_inline void write8(uint32_t addr, rt_uint8_t value) -{ - *((volatile rt_uint8_t *)(addr)) = value; -} - -rt_inline rt_uint32_t read32(uint32_t addr) -{ - return (*((volatile rt_uint32_t *)(addr))); -} - -rt_inline void write32(uint32_t addr, rt_uint32_t value) -{ - *((volatile rt_uint32_t *)(addr)) = value; -} - -rt_inline int kmi_write(struct mouse_pl050_pdata_t * pdat, rt_uint8_t value) -{ - int timeout = 1000; - - while((read8(pdat->virt + MOUSE_STAT) & (1 << 6)) == 0 && timeout--); - - if(timeout) - { - write8(pdat->virt + MOUSE_DATA, value); - while((read8(pdat->virt + MOUSE_STAT) & (1 << 4)) == 0); - - if(read8(pdat->virt + MOUSE_DATA) == 0xfa) - return RT_TRUE; - } - return RT_FALSE; -} - -rt_inline int kmi_read(struct mouse_pl050_pdata_t * pdat, rt_uint8_t * value) -{ - if((read8(pdat->virt + MOUSE_STAT) & (1 << 4))) - { - *value = read8(pdat->virt + MOUSE_DATA); - return RT_TRUE; - } - return RT_FALSE; -} - -static rt_uint32_t emouse_id; - -void push_event_touch_move(int x, int y) -{ - struct rtgui_event_mouse emouse; - - emouse.parent.sender = RT_NULL; - emouse.wid = RT_NULL; - - emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN; - emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION; - emouse.x = x; - emouse.y = y; - emouse.ts = rt_tick_get(); - emouse.id = emouse_id; - - LOG_D("[line]:%d motion event id:%d x:%d y:%d", __LINE__, emouse.id, x, y); - rtgui_server_post_event(&emouse.parent, sizeof(emouse)); -} - -void push_event_touch_begin(int x, int y) -{ - struct rtgui_event_mouse emouse; - - emouse_id = rt_tick_get(); - - emouse.parent.sender = RT_NULL; - emouse.wid = RT_NULL; - - emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; - emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN; - emouse.x = x; - emouse.y = y; - emouse.ts = rt_tick_get(); - emouse.id = emouse_id; - LOG_D("[line]:%d down event id:%d x:%d y:%d", __LINE__, emouse.id, x, y); - rtgui_server_post_event(&emouse.parent, sizeof(emouse)); -} - -void push_event_touch_end(int x, int y) -{ - struct rtgui_event_mouse emouse; - - emouse.parent.sender = RT_NULL; - emouse.wid = RT_NULL; - - emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; - emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP; - emouse.x = x; - emouse.y = y; - emouse.ts = rt_tick_get(); - emouse.id = emouse_id; - - LOG_D("[line]:%d up event id:%d x:%d y:%d", __LINE__, emouse.id, x, y); - rtgui_server_post_event(&emouse.parent, sizeof(emouse)); -} - -static void mouse_pl050_interrupt(int irq, void * data) -{ - struct mouse_pl050_pdata_t * pdat = (struct mouse_pl050_pdata_t *)data; - int x, y, relx, rely, delta; - int btndown, btnup, btn; - int status = 0; - - status = read8(pdat->virt + MOUSE_IIR); - while(status & (1 << 0)) - { - pdat->packet[pdat->index] = read8(pdat->virt + MOUSE_DATA); - pdat->index = (pdat->index + 1) & 0x3; - - if(pdat->index == 0) - { - btn = pdat->packet[0] & 0x7; - btndown = (btn ^ pdat->obtn) & btn; - btnup = (btn ^ pdat->obtn) & pdat->obtn; - pdat->obtn = btn; - - if(pdat->packet[0] & 0x10) - relx = 0xffffff00 | pdat->packet[1]; - else - relx = pdat->packet[1]; - - if(pdat->packet[0] & 0x20) - rely = 0xffffff00 | pdat->packet[2]; - else - rely = pdat->packet[2]; - rely = -rely; - - delta = pdat->packet[3] & 0xf; - if(delta == 0xf) - delta = -1; - - if(relx != 0) - { - pdat->xpos = pdat->xpos + relx; - if(pdat->xpos < 0) - pdat->xpos = 0; - if(pdat->xpos > pdat->xmax - 1) - pdat->xpos = pdat->xmax - 1; - } - if(rely != 0) - { - pdat->ypos = pdat->ypos + rely; - if(pdat->ypos < 0) - pdat->ypos = 0; - if(pdat->ypos > pdat->ymax - 1) - pdat->ypos = pdat->ymax - 1; - } - x = pdat->xpos; - y = pdat->ypos; - - if((btn & (0x01 << 0)) && ((relx != 0) || (rely != 0))) - push_event_touch_move(x, y); - - if(btndown & (0x01 << 0)) - push_event_touch_begin(x, y); - - if(btnup & (0x01 << 0)) - push_event_touch_end(x, y); - } - - status = read8(pdat->virt + MOUSE_IIR); - } -} - -int rt_hw_mouse_init(void) -{ - rt_uint8_t value; - rt_uint32_t id; - struct mouse_pl050_pdata_t *pdat; - virtual_addr_t virt; - int irq = MOUSE_IRQ_NUM; - - virt = (virtual_addr_t)rt_ioremap((void*)MOUSE_ADDRESS, 0x1000); - - id = (((read32(virt + 0xfec) & 0xff) << 24) | - ((read32(virt + 0xfe8) & 0xff) << 16) | - ((read32(virt + 0xfe4) & 0xff) << 8) | - ((read32(virt + 0xfe0) & 0xff) << 0)); - - if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050) - { - LOG_E("read id fail id:0x%08x", id); - return RT_ERROR; - } - - pdat = rt_malloc(sizeof(struct mouse_pl050_pdata_t)); - if(!pdat) - { - LOG_E("malloc memory failed"); - return RT_ERROR; - } - rt_memset(pdat, 0, sizeof(struct mouse_pl050_pdata_t)); - - pdat->virt = virt; - pdat->irq = irq; - pdat->xmax = MOUSE_XMAX; - pdat->ymax = MOUSE_YMAX; - pdat->xpos = pdat->xmax / 2; - pdat->ypos = pdat->ymax / 2; - pdat->packet[0] = 0; - pdat->packet[1] = 0; - pdat->packet[2] = 0; - pdat->packet[3] = 0; - pdat->index = 0; - pdat->obtn = 0; - - write8(pdat->virt + MOUSE_CLKDIV, 0); - write8(pdat->virt + MOUSE_CR, (1 << 2)); - kmi_write(pdat, 0xff); - kmi_read(pdat, &value); - kmi_write(pdat, 0xf3); - kmi_write(pdat, 200); - kmi_write(pdat, 0xf3); - kmi_write(pdat, 100); - kmi_write(pdat, 0xf3); - kmi_write(pdat, 80); - kmi_write(pdat, 0xf2); - kmi_read(pdat, &value); - kmi_read(pdat, &value); - kmi_write(pdat, 0xf3); - kmi_write(pdat, 100); - kmi_write(pdat, 0xe8); - kmi_write(pdat, 0x02); - kmi_write(pdat, 0xe6); - kmi_write(pdat, 0xf4); - kmi_read(pdat, &value); - kmi_read(pdat, &value); - kmi_read(pdat, &value); - kmi_read(pdat, &value); - write8(pdat->virt + MOUSE_CR, (1 << 2) | (1 << 4)); - - rt_hw_interrupt_install(pdat->irq, mouse_pl050_interrupt, (void *)pdat, "mouse"); - rt_hw_interrupt_umask(pdat->irq); - - return RT_EOK; -} -INIT_DEVICE_EXPORT(rt_hw_mouse_init); - -#endif - diff --git a/bsp/qemu-vexpress-a53/drivers/drv_mouse.h b/bsp/qemu-vexpress-a53/drivers/drv_mouse.h deleted file mode 100644 index cfceabc00d..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_mouse.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __DRV_MOUSE_H__ -#define __DRV_MOUSE_H__ - -int rt_hw_mouse_init(void); - -struct mouse_info -{ - uint32_t type; - uint32_t button; - uint32_t x; - uint32_t y; - uint32_t ts; - uint32_t id; -}; - -#define CMD_MOUSE_SET_NOTIFY 0 /* arg is shmid, in the shm, a sem point is given */ - -#endif \ No newline at end of file diff --git a/bsp/qemu-vexpress-a53/drivers/drv_sdio.c b/bsp/qemu-vexpress-a53/drivers/drv_sdio.c deleted file mode 100644 index d44ee46f91..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_sdio.c +++ /dev/null @@ -1,469 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#include "board.h" -#include "drv_sdio.h" - -#ifdef RT_USING_SDIO - -#define MMC_BASE_ADDR (0x10005000) - -#define PL180_POWER (0x00) -#define PL180_CLOCK (0x04) -#define PL180_ARGUMENT (0x08) -#define PL180_COMMAND (0x0c) -#define PL180_RESPCMD (0x10) -#define PL180_RESP0 (0x14) -#define PL180_RESP1 (0x18) -#define PL180_RESP2 (0x1c) -#define PL180_RESP3 (0x20) -#define PL180_DATA_TIMER (0x24) -#define PL180_DATA_LENGTH (0x28) -#define PL180_DATA_CTRL (0x2c) -#define PL180_DATA_CNT (0x30) -#define PL180_STATUS (0x34) -#define PL180_CLEAR (0x38) -#define PL180_MASK0 (0x3c) -#define PL180_MASK1 (0x40) -#define PL180_SELECT (0x44) -#define PL180_FIFO_CNT (0x48) -#define PL180_FIFO (0x80) - -#define PL180_RSP_NONE (0 << 0) -#define PL180_RSP_PRESENT (1 << 0) -#define PL180_RSP_136BIT (1 << 1) -#define PL180_RSP_CRC (1 << 2) - -#define PL180_CMD_WAITRESP (1 << 6) -#define PL180_CMD_LONGRSP (1 << 7) -#define PL180_CMD_WAITINT (1 << 8) -#define PL180_CMD_WAITPEND (1 << 9) -#define PL180_CMD_ENABLE (1 << 10) - -#define PL180_STAT_CMD_CRC_FAIL (1 << 0) -#define PL180_STAT_DAT_CRC_FAIL (1 << 1) -#define PL180_STAT_CMD_TIME_OUT (1 << 2) -#define PL180_STAT_DAT_TIME_OUT (1 << 3) -#define PL180_STAT_TX_UNDERRUN (1 << 4) -#define PL180_STAT_RX_OVERRUN (1 << 5) -#define PL180_STAT_CMD_RESP_END (1 << 6) -#define PL180_STAT_CMD_SENT (1 << 7) -#define PL180_STAT_DAT_END (1 << 8) -#define PL180_STAT_DAT_BLK_END (1 << 10) -#define PL180_STAT_CMD_ACT (1 << 11) -#define PL180_STAT_TX_ACT (1 << 12) -#define PL180_STAT_RX_ACT (1 << 13) -#define PL180_STAT_TX_FIFO_HALF (1 << 14) -#define PL180_STAT_RX_FIFO_HALF (1 << 15) -#define PL180_STAT_TX_FIFO_FULL (1 << 16) -#define PL180_STAT_RX_FIFO_FULL (1 << 17) -#define PL180_STAT_TX_FIFO_ZERO (1 << 18) -#define PL180_STAT_RX_DAT_ZERO (1 << 19) -#define PL180_STAT_TX_DAT_AVL (1 << 20) -#define PL180_STAT_RX_FIFO_AVL (1 << 21) - -#define PL180_CLR_CMD_CRC_FAIL (1 << 0) -#define PL180_CLR_DAT_CRC_FAIL (1 << 1) -#define PL180_CLR_CMD_TIMEOUT (1 << 2) -#define PL180_CLR_DAT_TIMEOUT (1 << 3) -#define PL180_CLR_TX_UNDERRUN (1 << 4) -#define PL180_CLR_RX_OVERRUN (1 << 5) -#define PL180_CLR_CMD_RESP_END (1 << 6) -#define PL180_CLR_CMD_SENT (1 << 7) -#define PL180_CLR_DAT_END (1 << 8) -#define PL180_CLR_DAT_BLK_END (1 << 10) - -#define DBG_TAG "drv.sdio" -#define DBG_LVL DBG_INFO -#include "rtdbg.h" - -struct sdhci_pl180_pdata_t -{ - rt_size_t virt; -}; - -static inline rt_uint32_t read32(rt_size_t addr) -{ - return( *((volatile rt_uint32_t *)(addr)) ); -} - -static inline void write32(rt_size_t addr, rt_uint32_t value) -{ - *((volatile rt_uint32_t *)(addr)) = value; -} - -static rt_err_t pl180_transfer_command(struct sdhci_pl180_pdata_t * pdat, struct sdhci_cmd_t * cmd) -{ - rt_uint32_t cmdidx; - rt_uint32_t status; - rt_err_t ret = RT_EOK; - - if(read32(pdat->virt + PL180_COMMAND) & PL180_CMD_ENABLE) - write32(pdat->virt + PL180_COMMAND, 0x0); - - cmdidx = (cmd->cmdidx & 0xff) | PL180_CMD_ENABLE; - if(cmd->resptype) - { - cmdidx |= PL180_CMD_WAITRESP; - if(cmd->resptype & PL180_RSP_136BIT) - cmdidx |= PL180_CMD_LONGRSP; - } - - write32(pdat->virt + PL180_ARGUMENT, cmd->cmdarg); - write32(pdat->virt + PL180_COMMAND, cmdidx); - - do { - status = read32(pdat->virt + PL180_STATUS); - } while(!(status & (PL180_STAT_CMD_SENT | PL180_STAT_CMD_RESP_END | PL180_STAT_CMD_TIME_OUT | PL180_STAT_CMD_CRC_FAIL))); - LOG_D("mmc status done!"); - - if(cmd->resptype & PL180_RSP_PRESENT) - { - cmd->response[0] = read32(pdat->virt + PL180_RESP0); - if(cmd->resptype & PL180_RSP_136BIT) - { - LOG_D("136bit response"); - cmd->response[1] = read32(pdat->virt + PL180_RESP1); - cmd->response[2] = read32(pdat->virt + PL180_RESP2); - cmd->response[3] = read32(pdat->virt + PL180_RESP3); - } - } - - if(status & PL180_STAT_CMD_TIME_OUT) - { - ret = -RT_ETIMEOUT; - } - else if ((status & PL180_STAT_CMD_CRC_FAIL) && (cmd->resptype & PL180_RSP_CRC)) - { - ret = -RT_ERROR; - } - - write32(pdat->virt + PL180_CLEAR, (PL180_CLR_CMD_SENT | PL180_CLR_CMD_RESP_END | PL180_CLR_CMD_TIMEOUT | PL180_CLR_CMD_CRC_FAIL)); - return ret; -} - -static rt_err_t read_bytes(struct sdhci_pl180_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) -{ - rt_uint32_t * tmp = buf; - rt_uint32_t count = blkcount * blksize; - rt_uint32_t status, err; - - status = read32(pdat->virt + PL180_STATUS); - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN); - while((!err) && (count >= sizeof(rt_uint32_t))) - { - if(status & PL180_STAT_RX_FIFO_AVL) - { - *(tmp) = read32(pdat->virt + PL180_FIFO); - tmp++; - count -= sizeof(rt_uint32_t); - } - status = read32(pdat->virt + PL180_STATUS); - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN); - } - - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN); - while(!err) - { - status = read32(pdat->virt + PL180_STATUS); - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN); - } - - if(status & PL180_STAT_DAT_TIME_OUT) - return -RT_ERROR; - else if (status & PL180_STAT_DAT_CRC_FAIL) - return -RT_ERROR; - else if (status & PL180_STAT_RX_OVERRUN) - return -RT_ERROR; - write32(pdat->virt + PL180_CLEAR, 0x1DC007FF); - - if(count) - return -RT_ERROR; - - return RT_EOK; -} - -static rt_err_t write_bytes(struct sdhci_pl180_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) -{ - rt_uint32_t * tmp = buf; - rt_uint32_t count = blkcount * blksize; - rt_uint32_t status, err; - int i; - - status = read32(pdat->virt + PL180_STATUS); - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT); - while(!err && count) - { - if(status & PL180_STAT_TX_FIFO_HALF) - { - if(count >= 8 * sizeof(rt_uint32_t)) - { - for(i = 0; i < 8; i++) - write32(pdat->virt + PL180_FIFO, *(tmp + i)); - tmp += 8; - count -= 8 * sizeof(rt_uint32_t); - } - else - { - while(count >= sizeof(rt_uint32_t)) - { - write32(pdat->virt + PL180_FIFO, *tmp); - tmp++; - count -= sizeof(rt_uint32_t); - } - } - } - status = read32(pdat->virt + PL180_STATUS); - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT); - } - - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END); - while(!err) - { - status = read32(pdat->virt + PL180_STATUS); - err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END); - } - - if(status & PL180_STAT_DAT_TIME_OUT) - return -RT_ERROR; - else if (status & PL180_STAT_DAT_CRC_FAIL) - return -RT_ERROR; - write32(pdat->virt + PL180_CLEAR, 0x1DC007FF); - - if(count) - return -RT_ERROR; - return RT_EOK; -} - -static rt_err_t pl180_transfer_data(struct sdhci_pl180_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_uint32_t blksz_bits = dat->blksz - 1; - rt_uint32_t dctrl = (blksz_bits << 4) | (0x1 << 0) | (0x1 << 14); - rt_err_t ret = -RT_ERROR; - - write32(pdat->virt + PL180_DATA_TIMER, 0xffff); - write32(pdat->virt + PL180_DATA_LENGTH, dlen); - - if(dat->flag & DATA_DIR_READ) - { - dctrl |= (0x1 << 1); - write32(pdat->virt + PL180_DATA_CTRL, dctrl); - ret = pl180_transfer_command(pdat, cmd); - if (ret < 0) return ret; - ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); - } - else if(dat->flag & DATA_DIR_WRITE) - { - ret = pl180_transfer_command(pdat, cmd); - if (ret < 0) return ret; - write32(pdat->virt + PL180_DATA_CTRL, dctrl); - ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); - } - - return ret; -} - -static rt_err_t sdhci_pl180_detect(struct sdhci_t * sdhci) -{ - return RT_EOK; -} - -static rt_err_t sdhci_pl180_setwidth(struct sdhci_t * sdhci, rt_uint32_t width) -{ - return RT_EOK; -} - -static rt_err_t sdhci_pl180_setclock(struct sdhci_t * sdhci, rt_uint32_t clock) -{ - rt_uint32_t temp = 0; - struct sdhci_pl180_pdata_t * pdat = (struct sdhci_pl180_pdata_t *)sdhci->priv; - - if(clock) - { - temp = read32(pdat->virt + PL180_CLOCK) | (0x1 << 8); - (void)temp; // skip warning - write32(pdat->virt + PL180_CLOCK, 0x100); - } - else - { - //write32(pdat->virt + PL180_CLOCK, read32(pdat->virt + PL180_CLOCK) & (~(0x1 << 8))); - } - return RT_EOK; -} - -static rt_err_t sdhci_pl180_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat) -{ - struct sdhci_pl180_pdata_t * pdat = (struct sdhci_pl180_pdata_t *)sdhci->priv; - - if(!dat) - return pl180_transfer_command(pdat, cmd); - - return pl180_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; - if (req->cmd->flags & RESP_MASK) - { - cmd.resptype = PL180_RSP_PRESENT; - if (resp_type(req->cmd) == RESP_R2) - cmd.resptype |= PL180_RSP_136BIT; - } - else - cmd.resptype = 0; - - 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_pl180_transfer(sdhci, &cmd, &dat); - } - else - { - req->cmd->err = sdhci_pl180_transfer(sdhci, &cmd, RT_NULL); - } - - LOG_D("cmdarg:%d", cmd.cmdarg); - LOG_D("cmdidx:%d", cmd.cmdidx); - - LOG_D("[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x", cmd.response[0], cmd.response[1], cmd.response[2], cmd.response[3]); - 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; - if (req->stop->flags & RESP_MASK) - { - stop.resptype = PL180_RSP_PRESENT; - if (resp_type(req->stop) == RESP_R2) - stop.resptype |= PL180_RSP_136BIT; - } - else - stop.resptype = 0; - - req->stop->err = sdhci_pl180_transfer(sdhci, &stop, RT_NULL); - } - - mmcsd_req_complete(host); -} - -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_pl180_setclock(sdhci, io_cfg->clock); - sdhci_pl180_setwidth(sdhci, io_cfg->bus_width); - LOG_D("clock:%d bus_width:%d", io_cfg->clock, io_cfg->bus_width); -} - -static const struct rt_mmcsd_host_ops ops = -{ - mmc_request_send, - mmc_set_iocfg, - RT_NULL, - RT_NULL, -}; - -int pl180_init(void) -{ - rt_size_t virt; - rt_uint32_t id; - struct rt_mmcsd_host * host = RT_NULL; - struct sdhci_pl180_pdata_t * pdat = RT_NULL; - struct sdhci_t * sdhci = RT_NULL; - - host = mmcsd_alloc_host(); - if (!host) - { - LOG_E("alloc host failed"); - goto err; - } - - sdhci = rt_malloc(sizeof(struct sdhci_t)); - if (!sdhci) - { - LOG_E("alloc sdhci failed"); - goto err; - } - rt_memset(sdhci, 0, sizeof(struct sdhci_t)); - - virt = (rt_size_t)rt_ioremap((void*)MMC_BASE_ADDR, 0x1000); - - id = (((read32((virt + 0xfec)) & 0xff) << 24) | - ((read32((virt + 0xfe8)) & 0xff) << 16) | - ((read32((virt + 0xfe4)) & 0xff) << 8) | - ((read32((virt + 0xfe0)) & 0xff) << 0)); - - LOG_D("id=0x%08x", id); - if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x181) - { - LOG_E("check id failed"); - goto err; - } - - pdat = (struct sdhci_pl180_pdata_t *)rt_malloc(sizeof(struct sdhci_pl180_pdata_t)); - RT_ASSERT(pdat != RT_NULL); - - pdat->virt = (rt_size_t)virt; - - sdhci->name = "sd0"; - sdhci->voltages = VDD_33_34; - sdhci->width = MMCSD_BUSWIDTH_4; - sdhci->clock = 26 * 1000 * 1000; - sdhci->removeable = RT_TRUE; - sdhci->detect = sdhci_pl180_detect; - sdhci->setwidth = sdhci_pl180_setwidth; - sdhci->setclock = sdhci_pl180_setclock; - sdhci->transfer = sdhci_pl180_transfer; - sdhci->priv = pdat; - write32(pdat->virt + PL180_POWER, 0xbf); - - 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 = 4096; - - host->private_data = sdhci; - - mmcsd_change(host); - - return RT_EOK; - -err: - if(host) rt_free(host); - if(sdhci) rt_free(sdhci); - - return -RT_EIO; -} -INIT_DEVICE_EXPORT(pl180_init); - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_sdio.h b/bsp/qemu-vexpress-a53/drivers/drv_sdio.h deleted file mode 100644 index 8b7adfec59..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_sdio.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __DRV_SDIO_H__ -#define __DRV_SDIO_H__ - - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -struct sdhci_cmd_t -{ - rt_uint32_t cmdidx; - rt_uint32_t cmdarg; - rt_uint32_t resptype; - 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; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_smc911x.c b/bsp/qemu-vexpress-a53/drivers/drv_smc911x.c deleted file mode 100644 index b9807a5b6a..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_smc911x.c +++ /dev/null @@ -1,561 +0,0 @@ -#if 1 -#include -#include -#include -#include -#include -#include - -#include "mmu.h" -#include "drv_smc911x.h" - -#define MAX_ADDR_LEN 6 -#define SMC911X_EMAC_DEVICE(eth) (struct eth_device_smc911x*)(eth) - -#define DRIVERNAME "EMAC" - -#define DBG_LVL DBG_LOG -#define DBG_TAG "EMAC" -#include - -struct eth_device_smc911x -{ - /* inherit from Ethernet device */ - struct eth_device parent; - /* interface address info. */ - rt_uint8_t enetaddr[MAX_ADDR_LEN]; /* MAC address */ - - size_t iobase; - uint32_t irqno; -}; -static struct eth_device_smc911x _emac; - -int udelay(int value) -{ - return 0; -} - -int mdelay(int value) -{ - return 0; -} - -#if defined (CONFIG_SMC911X_32_BIT) -rt_inline uint32_t smc911x_reg_read(struct eth_device_smc911x *dev, uint32_t offset) -{ - return *(volatile uint32_t*)(dev->iobase + offset); -} - -rt_inline void smc911x_reg_write(struct eth_device_smc911x *dev, uint32_t offset, uint32_t val) -{ - *(volatile uint32_t*)(dev->iobase + offset) = val; -} - -#elif defined (CONFIG_SMC911X_16_BIT) -rt_inline uint32_t smc911x_reg_read(struct eth_device_smc911x *dev, uint32_t offset) -{ - volatile uint16_t *addr_16 = (uint16_t *)(dev->iobase + offset); - return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); -} - -rt_inline void smc911x_reg_write(struct eth_device_smc911x *dev, uint32_t offset, uint32_t val) -{ - *(volatile uint16_t *)(dev->iobase + offset) = (uint16_t)val; - *(volatile uint16_t *)(dev->iobase + offset + 2) = (uint16_t)(val >> 16); -} -#else -#error "SMC911X: undefined bus width" -#endif /* CONFIG_SMC911X_16_BIT */ - -struct chip_id -{ - uint16_t id; - char *name; -}; - -static const struct chip_id chip_ids[] = -{ - { CHIP_89218,"LAN89218" }, - { CHIP_9115, "LAN9115" }, - { CHIP_9116, "LAN9116" }, - { CHIP_9117, "LAN9117" }, - { CHIP_9118, "LAN9118" }, - { CHIP_9211, "LAN9211" }, - { CHIP_9215, "LAN9215" }, - { CHIP_9216, "LAN9216" }, - { CHIP_9217, "LAN9217" }, - { CHIP_9218, "LAN9218" }, - { CHIP_9220, "LAN9220" }, - { CHIP_9221, "LAN9221" }, - { 0, RT_NULL }, -}; - -static uint32_t smc911x_get_mac_csr(struct eth_device_smc911x *dev, uint8_t reg) -{ - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - - smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); - - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - - return smc911x_reg_read(dev, MAC_CSR_DATA); -} - -static void smc911x_set_mac_csr(struct eth_device_smc911x *dev, uint8_t reg, uint32_t data) -{ - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; - - smc911x_reg_write(dev, MAC_CSR_DATA, data); - smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); - - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ; -} - -static int smc911x_detect_chip(struct eth_device_smc911x *dev) -{ - unsigned long val, i; - - val = smc911x_reg_read(dev, BYTE_TEST); - if (val == 0xffffffff) - { - /* Special case -- no chip present */ - return -1; - } - else if (val != 0x87654321) - { - LOG_E("Invalid chip endian 0x%08lx\n", val); - return -1; - } - - val = smc911x_reg_read(dev, ID_REV) >> 16; - for (i = 0; chip_ids[i].id != 0; i++) - { - if (chip_ids[i].id == val) break; - } - - if (!chip_ids[i].id) - { - rt_kprintf(DRIVERNAME ": Unknown chip ID %04lx\n", val); - return -1; - } - - return 0; -} - -static void smc911x_reset(struct eth_device_smc911x *dev) -{ - int timeout; - - /* - * Take out of PM setting first - * Device is already wake up if PMT_CTRL_READY bit is set - */ - if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) - { - /* Write to the bytetest will take out of powerdown */ - smc911x_reg_write(dev, BYTE_TEST, 0x0); - - timeout = 10; - - while (timeout-- && !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY)) - udelay(10); - - if (timeout < 0) - { - rt_kprintf(DRIVERNAME - ": timeout waiting for PM restore\n"); - return; - } - } - - /* Disable interrupts */ - smc911x_reg_write(dev, INT_EN, 0); - smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST); - - timeout = 1000; - while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY) - udelay(10); - - if (timeout < 0) - { - rt_kprintf(DRIVERNAME ": reset timeout\n"); - return; - } - - /* Reset the FIFO level and flow control settings */ - smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN); - smc911x_reg_write(dev, AFC_CFG, 0x0050287F); - - /* Set to LED outputs */ - smc911x_reg_write(dev, GPIO_CFG, 0x70070000); -} - -static void smc911x_handle_mac_address(struct eth_device_smc911x *dev) -{ - unsigned long addrh, addrl; - uint8_t *m = dev->enetaddr; - - addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24); - addrh = m[4] | (m[5] << 8); - - smc911x_set_mac_csr(dev, ADDRL, addrl); - smc911x_set_mac_csr(dev, ADDRH, addrh); -} - -static int smc911x_eth_phy_read(struct eth_device_smc911x *dev, - uint8_t phy, uint8_t reg, uint16_t *val) -{ - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) ; - - smc911x_set_mac_csr(dev, MII_ACC, phy << 11 | reg << 6 | MII_ACC_MII_BUSY); - - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) ; - - *val = smc911x_get_mac_csr(dev, MII_DATA); - - return 0; -} - -static int smc911x_eth_phy_write(struct eth_device_smc911x *dev, - uint8_t phy, uint8_t reg, uint16_t val) -{ - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) - ; - - smc911x_set_mac_csr(dev, MII_DATA, val); - smc911x_set_mac_csr(dev, MII_ACC, - phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE); - - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) - ; - return 0; -} - -static int smc911x_phy_reset(struct eth_device_smc911x *dev) -{ - uint32_t reg; - - reg = smc911x_reg_read(dev, PMT_CTRL); - reg &= ~0xfffff030; - reg |= PMT_CTRL_PHY_RST; - smc911x_reg_write(dev, PMT_CTRL, reg); - - mdelay(100); - - return 0; -} - -static void smc911x_phy_configure(struct eth_device_smc911x *dev) -{ - int timeout; - uint16_t status; - - smc911x_phy_reset(dev); - - smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_RESET); - mdelay(1); - smc911x_eth_phy_write(dev, 1, MII_ADVERTISE, 0x01e1); - smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); - - timeout = 5000; - do - { - mdelay(1); - if ((timeout--) == 0) - goto err_out; - - if (smc911x_eth_phy_read(dev, 1, MII_BMSR, &status) != 0) - goto err_out; - } - while (!(status & BMSR_LSTATUS)); - - return; - -err_out: - rt_kprintf(DRIVERNAME ": autonegotiation timed out\n"); -} - -static void smc911x_enable(struct eth_device_smc911x *dev) -{ - /* Enable TX */ - smc911x_reg_write(dev, HW_CFG, 8 << 16 | HW_CFG_SF); - - smc911x_reg_write(dev, GPT_CFG, GPT_CFG_TIMER_EN | 10000); - - smc911x_reg_write(dev, TX_CFG, TX_CFG_TX_ON); - - /* no padding to start of packets */ - smc911x_reg_write(dev, RX_CFG, 0); - - smc911x_set_mac_csr(dev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | - MAC_CR_HBDIS); -} - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -/* wrapper for smc911x_eth_phy_read */ -static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad, - int reg) -{ - uint16_t val = 0; - struct eth_device_smc911x *dev = eth_get_dev_by_name(bus->name); - if (dev) - { - int retval = smc911x_eth_phy_read(dev, phy, reg, &val); - if (retval < 0) - return retval; - return val; - } - return -ENODEV; -} - -/* wrapper for smc911x_eth_phy_write */ -static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad, - int reg, uint16_t val) -{ - struct eth_device_smc911x *dev = eth_get_dev_by_name(bus->name); - if (dev) - return smc911x_eth_phy_write(dev, phy, reg, val); - return -ENODEV; -} -#endif - -static void smc911x_isr(int vector, void *param) -{ - uint32_t status; - struct eth_device_smc911x *emac; - - emac = SMC911X_EMAC_DEVICE(param); - - status = smc911x_reg_read(emac, INT_STS); - - if (status & INT_STS_RSFL) - { - eth_device_ready(&emac->parent); - } - smc911x_reg_write(emac, INT_STS, status); - - return ; -} - -static rt_err_t smc911x_emac_init(rt_device_t dev) -{ - // uint32_t value; - struct eth_device_smc911x *emac; - - emac = SMC911X_EMAC_DEVICE(dev); - RT_ASSERT(emac != RT_NULL); - - smc911x_reset(emac); - - /* Configure the PHY, initialize the link state */ - smc911x_phy_configure(emac); - smc911x_handle_mac_address(emac); - - /* Turn on Tx + Rx */ - smc911x_enable(emac); - - /* Interrupt on every received packet */ - smc911x_reg_write(emac, FIFO_INT, 0x01 << 8); - smc911x_reg_write(emac, INT_EN, INT_EN_RDFL_EN | INT_EN_RSFL_EN); - - /* enable interrupt */ - smc911x_reg_write(emac, INT_CFG, INT_CFG_IRQ_EN | INT_CFG_IRQ_POL | INT_CFG_IRQ_TYPE); - - rt_hw_interrupt_install(emac->irqno, smc911x_isr, emac, "smc911x"); - rt_hw_interrupt_umask(emac->irqno); - - return RT_EOK; -} - -static rt_err_t smc911x_emac_control(rt_device_t dev, int cmd, void *args) -{ - struct eth_device_smc911x *emac; - - emac = SMC911X_EMAC_DEVICE(dev); - RT_ASSERT(emac != RT_NULL); - - switch(cmd) - { - case NIOCTL_GADDR: - /* get MAC address */ - if(args) rt_memcpy(args, emac->enetaddr, 6); - else return -RT_ERROR; - break; - - default : - break; - } - return RT_EOK; -} - -/* Ethernet device interface */ -/* transmit packet. */ -static uint8_t tx_buf[2048]; -rt_err_t smc911x_emac_tx(rt_device_t dev, struct pbuf* p) -{ - struct eth_device_smc911x *emac; - - uint32_t *data; - uint32_t tmplen; - uint32_t status; - uint32_t length; - - emac = SMC911X_EMAC_DEVICE(dev); - RT_ASSERT(emac != RT_NULL); - - /* copy pbuf to a whole ETH frame */ - pbuf_copy_partial(p, tx_buf, p->tot_len, 0); - - /* send it out */ - data = (uint32_t*)tx_buf; - length = p->tot_len; - - smc911x_reg_write(emac, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length); - smc911x_reg_write(emac, TX_DATA_FIFO, length); - - tmplen = (length + 3) / 4; - while (tmplen--) - { - smc911x_reg_write(emac, TX_DATA_FIFO, *data++); - } - - /* wait for transmission */ - while (!((smc911x_reg_read(emac, TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16)); - - /* get status. Ignore 'no carrier' error, it has no meaning for - * full duplex operation - */ - status = smc911x_reg_read(emac, TX_STATUS_FIFO) & - (TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL | - TX_STS_MANY_DEFER | TX_STS_UNDERRUN); - - if (!status) return 0; - - LOG_E("failed to send packet: %s%s%s%s%s", - status & TX_STS_LOC ? "TX_STS_LOC " : "", - status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "", - status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "", - status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "", - status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : ""); - - return -RT_EIO; -} - -/* reception packet. */ -struct pbuf *smc911x_emac_rx(rt_device_t dev) -{ - struct pbuf* p = RT_NULL; - struct eth_device_smc911x *emac; - - emac = SMC911X_EMAC_DEVICE(dev); - RT_ASSERT(emac != RT_NULL); - - /* take the emac buffer to the pbuf */ - if ((smc911x_reg_read(emac, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) - { - uint32_t status; - uint32_t pktlen, tmplen; - - status = smc911x_reg_read(emac, RX_STATUS_FIFO); - - /* get frame length */ - pktlen = (status & RX_STS_PKT_LEN) >> 16; - - smc911x_reg_write(emac, RX_CFG, 0); - - tmplen = (pktlen + 3) / 4; - - /* allocate pbuf */ - p = pbuf_alloc(PBUF_RAW, tmplen * 4, PBUF_RAM); - if (p) - { - uint32_t *data = (uint32_t *)p->payload; - while (tmplen--) - { - *data++ = smc911x_reg_read(emac, RX_DATA_FIFO); - } - } - - if (status & RX_STS_ES) - { - rt_kprintf(DRIVERNAME ": dropped bad packet. Status: 0x%08x\n", status); - } - } - - return p; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops smc911x_emac_ops = -{ - smc911x_emac_init, - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - smc911x_emac_control -}; -#endif - -int smc911x_emac_hw_init(void) -{ - rt_memset(&_emac, 0x0, sizeof(_emac)); - - _emac.iobase = (size_t)rt_ioremap((void*)VEXPRESS_ETH_BASE, 0x1000); - _emac.irqno = IRQ_VEXPRESS_A9_ETH; - - if (smc911x_detect_chip(&_emac)) - { - rt_kprintf("no smc911x network interface found!\n"); - return -1; - } - - /* set INT CFG */ - smc911x_reg_write(&_emac, INT_CFG, INT_CFG_IRQ_POL | INT_CFG_IRQ_TYPE); - - /* test MAC address */ - _emac.enetaddr[0] = AUTOMAC0; - _emac.enetaddr[1] = AUTOMAC1; - _emac.enetaddr[2] = AUTOMAC2; - _emac.enetaddr[3] = AUTOMAC3; - _emac.enetaddr[4] = AUTOMAC4; - _emac.enetaddr[5] = AUTOMAC5; - -#ifdef RT_USING_DEVICE_OPS - _emac.parent.parent.ops = &smc911x_emac_ops; -#else - _emac.parent.parent.init = smc911x_emac_init; - _emac.parent.parent.open = RT_NULL; - _emac.parent.parent.close = RT_NULL; - _emac.parent.parent.read = RT_NULL; - _emac.parent.parent.write = RT_NULL; - _emac.parent.parent.control = smc911x_emac_control; -#endif - _emac.parent.parent.user_data = RT_NULL; - _emac.parent.eth_rx = smc911x_emac_rx; - _emac.parent.eth_tx = smc911x_emac_tx; - - /* register ETH device */ - eth_device_init(&(_emac.parent), "e0"); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - { - int retval; - struct mii_dev *mdiodev = mdio_alloc(); - if (!mdiodev) - return -ENOMEM; - strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); - mdiodev->read = smc911x_miiphy_read; - mdiodev->write = smc911x_miiphy_write; - - retval = mdio_register(mdiodev); - if (retval < 0) - return retval; - } -#endif - - eth_device_linkchange(&_emac.parent, RT_TRUE); - return 0; -} -INIT_APP_EXPORT(smc911x_emac_hw_init); -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_smc911x.h b/bsp/qemu-vexpress-a53/drivers/drv_smc911x.h deleted file mode 100644 index abaa24f9fd..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_smc911x.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - * SMSC LAN9[12]1[567] Network driver - * - * (c) 2007 Pengutronix, Sascha Hauer - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _SMC911X_H_ -#define _SMC911X_H_ - -#include - -#define CONFIG_SMC911X_32_BIT - -/* Below are the register offsets and bit definitions - * of the Lan911x memory space - */ -#define RX_DATA_FIFO 0x00 - -#define TX_DATA_FIFO 0x20 -#define TX_CMD_A_INT_ON_COMP 0x80000000 -#define TX_CMD_A_INT_BUF_END_ALGN 0x03000000 -#define TX_CMD_A_INT_4_BYTE_ALGN 0x00000000 -#define TX_CMD_A_INT_16_BYTE_ALGN 0x01000000 -#define TX_CMD_A_INT_32_BYTE_ALGN 0x02000000 -#define TX_CMD_A_INT_DATA_OFFSET 0x001F0000 -#define TX_CMD_A_INT_FIRST_SEG 0x00002000 -#define TX_CMD_A_INT_LAST_SEG 0x00001000 -#define TX_CMD_A_BUF_SIZE 0x000007FF -#define TX_CMD_B_PKT_TAG 0xFFFF0000 -#define TX_CMD_B_ADD_CRC_DISABLE 0x00002000 -#define TX_CMD_B_DISABLE_PADDING 0x00001000 -#define TX_CMD_B_PKT_BYTE_LENGTH 0x000007FF - -#define RX_STATUS_FIFO 0x40 -#define RX_STS_PKT_LEN 0x3FFF0000 -#define RX_STS_ES 0x00008000 -#define RX_STS_BCST 0x00002000 -#define RX_STS_LEN_ERR 0x00001000 -#define RX_STS_RUNT_ERR 0x00000800 -#define RX_STS_MCAST 0x00000400 -#define RX_STS_TOO_LONG 0x00000080 -#define RX_STS_COLL 0x00000040 -#define RX_STS_ETH_TYPE 0x00000020 -#define RX_STS_WDOG_TMT 0x00000010 -#define RX_STS_MII_ERR 0x00000008 -#define RX_STS_DRIBBLING 0x00000004 -#define RX_STS_CRC_ERR 0x00000002 -#define RX_STATUS_FIFO_PEEK 0x44 -#define TX_STATUS_FIFO 0x48 -#define TX_STS_TAG 0xFFFF0000 -#define TX_STS_ES 0x00008000 -#define TX_STS_LOC 0x00000800 -#define TX_STS_NO_CARR 0x00000400 -#define TX_STS_LATE_COLL 0x00000200 -#define TX_STS_MANY_COLL 0x00000100 -#define TX_STS_COLL_CNT 0x00000078 -#define TX_STS_MANY_DEFER 0x00000004 -#define TX_STS_UNDERRUN 0x00000002 -#define TX_STS_DEFERRED 0x00000001 -#define TX_STATUS_FIFO_PEEK 0x4C -#define ID_REV 0x50 -#define ID_REV_CHIP_ID 0xFFFF0000 /* RO */ -#define ID_REV_REV_ID 0x0000FFFF /* RO */ - -#define INT_CFG 0x54 -#define INT_CFG_INT_DEAS 0xFF000000 /* R/W */ -#define INT_CFG_INT_DEAS_CLR 0x00004000 -#define INT_CFG_INT_DEAS_STS 0x00002000 -#define INT_CFG_IRQ_INT 0x00001000 /* RO */ -#define INT_CFG_IRQ_EN 0x00000100 /* R/W */ -/* R/W Not Affected by SW Reset */ -#define INT_CFG_IRQ_POL 0x00000010 -/* R/W Not Affected by SW Reset */ -#define INT_CFG_IRQ_TYPE 0x00000001 - -#define INT_STS 0x58 -#define INT_STS_SW_INT 0x80000000 /* R/WC */ -#define INT_STS_TXSTOP_INT 0x02000000 /* R/WC */ -#define INT_STS_RXSTOP_INT 0x01000000 /* R/WC */ -#define INT_STS_RXDFH_INT 0x00800000 /* R/WC */ -#define INT_STS_RXDF_INT 0x00400000 /* R/WC */ -#define INT_STS_TX_IOC 0x00200000 /* R/WC */ -#define INT_STS_RXD_INT 0x00100000 /* R/WC */ -#define INT_STS_GPT_INT 0x00080000 /* R/WC */ -#define INT_STS_PHY_INT 0x00040000 /* RO */ -#define INT_STS_PME_INT 0x00020000 /* R/WC */ -#define INT_STS_TXSO 0x00010000 /* R/WC */ -#define INT_STS_RWT 0x00008000 /* R/WC */ -#define INT_STS_RXE 0x00004000 /* R/WC */ -#define INT_STS_TXE 0x00002000 /* R/WC */ -/*#define INT_STS_ERX 0x00001000*/ /* R/WC */ -#define INT_STS_TDFU 0x00000800 /* R/WC */ -#define INT_STS_TDFO 0x00000400 /* R/WC */ -#define INT_STS_TDFA 0x00000200 /* R/WC */ -#define INT_STS_TSFF 0x00000100 /* R/WC */ -#define INT_STS_TSFL 0x00000080 /* R/WC */ -/*#define INT_STS_RXDF 0x00000040*/ /* R/WC */ -#define INT_STS_RDFO 0x00000040 /* R/WC */ -#define INT_STS_RDFL 0x00000020 /* R/WC */ -#define INT_STS_RSFF 0x00000010 /* R/WC */ -#define INT_STS_RSFL 0x00000008 /* R/WC */ -#define INT_STS_GPIO2_INT 0x00000004 /* R/WC */ -#define INT_STS_GPIO1_INT 0x00000002 /* R/WC */ -#define INT_STS_GPIO0_INT 0x00000001 /* R/WC */ -#define INT_EN 0x5C -#define INT_EN_SW_INT_EN 0x80000000 /* R/W */ -#define INT_EN_TXSTOP_INT_EN 0x02000000 /* R/W */ -#define INT_EN_RXSTOP_INT_EN 0x01000000 /* R/W */ -#define INT_EN_RXDFH_INT_EN 0x00800000 /* R/W */ -/*#define INT_EN_RXDF_INT_EN 0x00400000*/ /* R/W */ -#define INT_EN_TIOC_INT_EN 0x00200000 /* R/W */ -#define INT_EN_RXD_INT_EN 0x00100000 /* R/W */ -#define INT_EN_GPT_INT_EN 0x00080000 /* R/W */ -#define INT_EN_PHY_INT_EN 0x00040000 /* R/W */ -#define INT_EN_PME_INT_EN 0x00020000 /* R/W */ -#define INT_EN_TXSO_EN 0x00010000 /* R/W */ -#define INT_EN_RWT_EN 0x00008000 /* R/W */ -#define INT_EN_RXE_EN 0x00004000 /* R/W */ -#define INT_EN_TXE_EN 0x00002000 /* R/W */ -/*#define INT_EN_ERX_EN 0x00001000*/ /* R/W */ -#define INT_EN_TDFU_EN 0x00000800 /* R/W */ -#define INT_EN_TDFO_EN 0x00000400 /* R/W */ -#define INT_EN_TDFA_EN 0x00000200 /* R/W */ -#define INT_EN_TSFF_EN 0x00000100 /* R/W */ -#define INT_EN_TSFL_EN 0x00000080 /* R/W */ -/*#define INT_EN_RXDF_EN 0x00000040*/ /* R/W */ -#define INT_EN_RDFO_EN 0x00000040 /* R/W */ -#define INT_EN_RDFL_EN 0x00000020 /* R/W */ -#define INT_EN_RSFF_EN 0x00000010 /* R/W */ -#define INT_EN_RSFL_EN 0x00000008 /* R/W */ -#define INT_EN_GPIO2_INT 0x00000004 /* R/W */ -#define INT_EN_GPIO1_INT 0x00000002 /* R/W */ -#define INT_EN_GPIO0_INT 0x00000001 /* R/W */ - -#define BYTE_TEST 0x64 -#define FIFO_INT 0x68 -#define FIFO_INT_TX_AVAIL_LEVEL 0xFF000000 /* R/W */ -#define FIFO_INT_TX_STS_LEVEL 0x00FF0000 /* R/W */ -#define FIFO_INT_RX_AVAIL_LEVEL 0x0000FF00 /* R/W */ -#define FIFO_INT_RX_STS_LEVEL 0x000000FF /* R/W */ - -#define RX_CFG 0x6C -#define RX_CFG_RX_END_ALGN 0xC0000000 /* R/W */ -#define RX_CFG_RX_END_ALGN4 0x00000000 /* R/W */ -#define RX_CFG_RX_END_ALGN16 0x40000000 /* R/W */ -#define RX_CFG_RX_END_ALGN32 0x80000000 /* R/W */ -#define RX_CFG_RX_DMA_CNT 0x0FFF0000 /* R/W */ -#define RX_CFG_RX_DUMP 0x00008000 /* R/W */ -#define RX_CFG_RXDOFF 0x00001F00 /* R/W */ -/*#define RX_CFG_RXBAD 0x00000001*/ /* R/W */ - -#define TX_CFG 0x70 -/*#define TX_CFG_TX_DMA_LVL 0xE0000000*/ /* R/W */ -/* R/W Self Clearing */ -/*#define TX_CFG_TX_DMA_CNT 0x0FFF0000*/ -#define TX_CFG_TXS_DUMP 0x00008000 /* Self Clearing */ -#define TX_CFG_TXD_DUMP 0x00004000 /* Self Clearing */ -#define TX_CFG_TXSAO 0x00000004 /* R/W */ -#define TX_CFG_TX_ON 0x00000002 /* R/W */ -#define TX_CFG_STOP_TX 0x00000001 /* Self Clearing */ - -#define HW_CFG 0x74 -#define HW_CFG_TTM 0x00200000 /* R/W */ -#define HW_CFG_SF 0x00100000 /* R/W */ -#define HW_CFG_TX_FIF_SZ 0x000F0000 /* R/W */ -#define HW_CFG_TR 0x00003000 /* R/W */ -#define HW_CFG_PHY_CLK_SEL 0x00000060 /* R/W */ -#define HW_CFG_PHY_CLK_SEL_INT_PHY 0x00000000 /* R/W */ -#define HW_CFG_PHY_CLK_SEL_EXT_PHY 0x00000020 /* R/W */ -#define HW_CFG_PHY_CLK_SEL_CLK_DIS 0x00000040 /* R/W */ -#define HW_CFG_SMI_SEL 0x00000010 /* R/W */ -#define HW_CFG_EXT_PHY_DET 0x00000008 /* RO */ -#define HW_CFG_EXT_PHY_EN 0x00000004 /* R/W */ -#define HW_CFG_32_16_BIT_MODE 0x00000004 /* RO */ -#define HW_CFG_SRST_TO 0x00000002 /* RO */ -#define HW_CFG_SRST 0x00000001 /* Self Clearing */ - -#define RX_DP_CTRL 0x78 -#define RX_DP_CTRL_RX_FFWD 0x80000000 /* R/W */ -#define RX_DP_CTRL_FFWD_BUSY 0x80000000 /* RO */ - -#define RX_FIFO_INF 0x7C -#define RX_FIFO_INF_RXSUSED 0x00FF0000 /* RO */ -#define RX_FIFO_INF_RXDUSED 0x0000FFFF /* RO */ - -#define TX_FIFO_INF 0x80 -#define TX_FIFO_INF_TSUSED 0x00FF0000 /* RO */ -#define TX_FIFO_INF_TDFREE 0x0000FFFF /* RO */ - -#define PMT_CTRL 0x84 -#define PMT_CTRL_PM_MODE 0x00003000 /* Self Clearing */ -#define PMT_CTRL_PHY_RST 0x00000400 /* Self Clearing */ -#define PMT_CTRL_WOL_EN 0x00000200 /* R/W */ -#define PMT_CTRL_ED_EN 0x00000100 /* R/W */ -/* R/W Not Affected by SW Reset */ -#define PMT_CTRL_PME_TYPE 0x00000040 -#define PMT_CTRL_WUPS 0x00000030 /* R/WC */ -#define PMT_CTRL_WUPS_NOWAKE 0x00000000 /* R/WC */ -#define PMT_CTRL_WUPS_ED 0x00000010 /* R/WC */ -#define PMT_CTRL_WUPS_WOL 0x00000020 /* R/WC */ -#define PMT_CTRL_WUPS_MULTI 0x00000030 /* R/WC */ -#define PMT_CTRL_PME_IND 0x00000008 /* R/W */ -#define PMT_CTRL_PME_POL 0x00000004 /* R/W */ -/* R/W Not Affected by SW Reset */ -#define PMT_CTRL_PME_EN 0x00000002 -#define PMT_CTRL_READY 0x00000001 /* RO */ - -#define GPIO_CFG 0x88 -#define GPIO_CFG_LED3_EN 0x40000000 /* R/W */ -#define GPIO_CFG_LED2_EN 0x20000000 /* R/W */ -#define GPIO_CFG_LED1_EN 0x10000000 /* R/W */ -#define GPIO_CFG_GPIO2_INT_POL 0x04000000 /* R/W */ -#define GPIO_CFG_GPIO1_INT_POL 0x02000000 /* R/W */ -#define GPIO_CFG_GPIO0_INT_POL 0x01000000 /* R/W */ -#define GPIO_CFG_EEPR_EN 0x00700000 /* R/W */ -#define GPIO_CFG_GPIOBUF2 0x00040000 /* R/W */ -#define GPIO_CFG_GPIOBUF1 0x00020000 /* R/W */ -#define GPIO_CFG_GPIOBUF0 0x00010000 /* R/W */ -#define GPIO_CFG_GPIODIR2 0x00000400 /* R/W */ -#define GPIO_CFG_GPIODIR1 0x00000200 /* R/W */ -#define GPIO_CFG_GPIODIR0 0x00000100 /* R/W */ -#define GPIO_CFG_GPIOD4 0x00000010 /* R/W */ -#define GPIO_CFG_GPIOD3 0x00000008 /* R/W */ -#define GPIO_CFG_GPIOD2 0x00000004 /* R/W */ -#define GPIO_CFG_GPIOD1 0x00000002 /* R/W */ -#define GPIO_CFG_GPIOD0 0x00000001 /* R/W */ - -#define GPT_CFG 0x8C -#define GPT_CFG_TIMER_EN 0x20000000 /* R/W */ -#define GPT_CFG_GPT_LOAD 0x0000FFFF /* R/W */ - -#define GPT_CNT 0x90 -#define GPT_CNT_GPT_CNT 0x0000FFFF /* RO */ - -#define ENDIAN 0x98 -#define FREE_RUN 0x9C -#define RX_DROP 0xA0 -#define MAC_CSR_CMD 0xA4 -#define MAC_CSR_CMD_CSR_BUSY 0x80000000 /* Self Clearing */ -#define MAC_CSR_CMD_R_NOT_W 0x40000000 /* R/W */ -#define MAC_CSR_CMD_CSR_ADDR 0x000000FF /* R/W */ - -#define MAC_CSR_DATA 0xA8 -#define AFC_CFG 0xAC -#define AFC_CFG_AFC_HI 0x00FF0000 /* R/W */ -#define AFC_CFG_AFC_LO 0x0000FF00 /* R/W */ -#define AFC_CFG_BACK_DUR 0x000000F0 /* R/W */ -#define AFC_CFG_FCMULT 0x00000008 /* R/W */ -#define AFC_CFG_FCBRD 0x00000004 /* R/W */ -#define AFC_CFG_FCADD 0x00000002 /* R/W */ -#define AFC_CFG_FCANY 0x00000001 /* R/W */ - -#define E2P_CMD 0xB0 -#define E2P_CMD_EPC_BUSY 0x80000000 /* Self Clearing */ -#define E2P_CMD_EPC_CMD 0x70000000 /* R/W */ -#define E2P_CMD_EPC_CMD_READ 0x00000000 /* R/W */ -#define E2P_CMD_EPC_CMD_EWDS 0x10000000 /* R/W */ -#define E2P_CMD_EPC_CMD_EWEN 0x20000000 /* R/W */ -#define E2P_CMD_EPC_CMD_WRITE 0x30000000 /* R/W */ -#define E2P_CMD_EPC_CMD_WRAL 0x40000000 /* R/W */ -#define E2P_CMD_EPC_CMD_ERASE 0x50000000 /* R/W */ -#define E2P_CMD_EPC_CMD_ERAL 0x60000000 /* R/W */ -#define E2P_CMD_EPC_CMD_RELOAD 0x70000000 /* R/W */ -#define E2P_CMD_EPC_TIMEOUT 0x00000200 /* RO */ -#define E2P_CMD_MAC_ADDR_LOADED 0x00000100 /* RO */ -#define E2P_CMD_EPC_ADDR 0x000000FF /* R/W */ - -#define E2P_DATA 0xB4 -#define E2P_DATA_EEPROM_DATA 0x000000FF /* R/W */ -/* end of LAN register offsets and bit definitions */ - -/* MAC Control and Status registers */ -#define MAC_CR 0x01 /* R/W */ - -/* MAC_CR - MAC Control Register */ -#define MAC_CR_RXALL 0x80000000 -/* TODO: delete this bit? It is not described in the data sheet. */ -#define MAC_CR_HBDIS 0x10000000 -#define MAC_CR_RCVOWN 0x00800000 -#define MAC_CR_LOOPBK 0x00200000 -#define MAC_CR_FDPX 0x00100000 -#define MAC_CR_MCPAS 0x00080000 -#define MAC_CR_PRMS 0x00040000 -#define MAC_CR_INVFILT 0x00020000 -#define MAC_CR_PASSBAD 0x00010000 -#define MAC_CR_HFILT 0x00008000 -#define MAC_CR_HPFILT 0x00002000 -#define MAC_CR_LCOLL 0x00001000 -#define MAC_CR_BCAST 0x00000800 -#define MAC_CR_DISRTY 0x00000400 -#define MAC_CR_PADSTR 0x00000100 -#define MAC_CR_BOLMT_MASK 0x000000C0 -#define MAC_CR_DFCHK 0x00000020 -#define MAC_CR_TXEN 0x00000008 -#define MAC_CR_RXEN 0x00000004 - -#define ADDRH 0x02 /* R/W mask 0x0000FFFFUL */ -#define ADDRL 0x03 /* R/W mask 0xFFFFFFFFUL */ -#define HASHH 0x04 /* R/W */ -#define HASHL 0x05 /* R/W */ - -#define MII_ACC 0x06 /* R/W */ -#define MII_ACC_PHY_ADDR 0x0000F800 -#define MII_ACC_MIIRINDA 0x000007C0 -#define MII_ACC_MII_WRITE 0x00000002 -#define MII_ACC_MII_BUSY 0x00000001 - -#define MII_DATA 0x07 /* R/W mask 0x0000FFFFUL */ - -#define FLOW 0x08 /* R/W */ -#define FLOW_FCPT 0xFFFF0000 -#define FLOW_FCPASS 0x00000004 -#define FLOW_FCEN 0x00000002 -#define FLOW_FCBSY 0x00000001 - -#define VLAN1 0x09 /* R/W mask 0x0000FFFFUL */ -#define VLAN1_VTI1 0x0000ffff - -#define VLAN2 0x0A /* R/W mask 0x0000FFFFUL */ -#define VLAN2_VTI2 0x0000ffff - -#define WUFF 0x0B /* WO */ - -#define WUCSR 0x0C /* R/W */ -#define WUCSR_GUE 0x00000200 -#define WUCSR_WUFR 0x00000040 -#define WUCSR_MPR 0x00000020 -#define WUCSR_WAKE_EN 0x00000004 -#define WUCSR_MPEN 0x00000002 - -/* Chip ID values */ -#define CHIP_89218 0x218a -#define CHIP_9115 0x115 -#define CHIP_9116 0x116 -#define CHIP_9117 0x117 -#define CHIP_9118 0x118 -#define CHIP_9211 0x9211 -#define CHIP_9215 0x115a -#define CHIP_9216 0x116a -#define CHIP_9217 0x117a -#define CHIP_9218 0x118a -#define CHIP_9220 0x9220 -#define CHIP_9221 0x9221 - - -/* Generic MII registers. */ - -#define MII_BMCR 0x00 /* Basic mode control register */ -#define MII_BMSR 0x01 /* Basic mode status register */ -#define MII_PHYSID1 0x02 /* PHYS ID 1 */ -#define MII_PHYSID2 0x03 /* PHYS ID 2 */ -#define MII_ADVERTISE 0x04 /* Advertisement control reg */ -#define MII_LPA 0x05 /* Link partner ability reg */ -#define MII_EXPANSION 0x06 /* Expansion register */ -#define MII_CTRL1000 0x09 /* 1000BASE-T control */ -#define MII_STAT1000 0x0a /* 1000BASE-T status */ -#define MII_ESTATUS 0x0f /* Extended Status */ -#define MII_DCOUNTER 0x12 /* Disconnect counter */ -#define MII_FCSCOUNTER 0x13 /* False carrier counter */ -#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ -#define MII_RERRCOUNTER 0x15 /* Receive error counter */ -#define MII_SREVISION 0x16 /* Silicon revision */ -#define MII_RESV1 0x17 /* Reserved... */ -#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ -#define MII_PHYADDR 0x19 /* PHY address */ -#define MII_RESV2 0x1a /* Reserved... */ -#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ -#define MII_NCONFIG 0x1c /* Network interface config */ - -/* Basic mode control register. */ -#define BMCR_RESV 0x003f /* Unused... */ -#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ -#define BMCR_CTST 0x0080 /* Collision test */ -#define BMCR_FULLDPLX 0x0100 /* Full duplex */ -#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ -#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ -#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ -#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ -#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ -#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ -#define BMCR_RESET 0x8000 /* Reset the DP83840 */ - -/* Basic mode status register. */ -#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ -#define BMSR_JCD 0x0002 /* Jabber detected */ -#define BMSR_LSTATUS 0x0004 /* Link status */ -#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ -#define BMSR_RFAULT 0x0010 /* Remote fault detected */ -#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ -#define BMSR_RESV 0x00c0 /* Unused... */ -#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ -#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ -#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ -#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ -#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ -#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ -#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ -#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/drv_timer.c b/bsp/qemu-vexpress-a53/drivers/drv_timer.c deleted file mode 100644 index 8dcc6e2c3e..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_timer.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-11-22 Jesven first version - */ - -#include -#include -#include - -#include "mmu.h" -#include "board.h" - -#define TIMER01_HW_BASE_PHY 0x10011000 -#define TIMER23_HW_BASE_PHY 0x10012000 - -void* timer01_hw_base; -void* timer23_hw_base; - -#define TIMER01_HW_BASE timer01_hw_base -#define TIMER23_HW_BASE timer23_hw_base - -#define TIMER_LOAD(hw_base) __REG32(hw_base + 0x00) -#define TIMER_VALUE(hw_base) __REG32(hw_base + 0x04) -#define TIMER_CTRL(hw_base) __REG32(hw_base + 0x08) -#define TIMER_CTRL_ONESHOT (1 << 0) -#define TIMER_CTRL_32BIT (1 << 1) -#define TIMER_CTRL_DIV1 (0 << 2) -#define TIMER_CTRL_DIV16 (1 << 2) -#define TIMER_CTRL_DIV256 (2 << 2) -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ -#define TIMER_CTRL_PERIODIC (1 << 6) -#define TIMER_CTRL_ENABLE (1 << 7) - -#define TIMER_INTCLR(hw_base) __REG32(hw_base + 0x0c) -#define TIMER_RIS(hw_base) __REG32(hw_base + 0x10) -#define TIMER_MIS(hw_base) __REG32(hw_base + 0x14) -#define TIMER_BGLOAD(hw_base) __REG32(hw_base + 0x18) - -#define TIMER_LOAD(hw_base) __REG32(hw_base + 0x00) -#define TIMER_VALUE(hw_base) __REG32(hw_base + 0x04) -#define TIMER_CTRL(hw_base) __REG32(hw_base + 0x08) -#define TIMER_CTRL_ONESHOT (1 << 0) -#define TIMER_CTRL_32BIT (1 << 1) -#define TIMER_CTRL_DIV1 (0 << 2) -#define TIMER_CTRL_DIV16 (1 << 2) -#define TIMER_CTRL_DIV256 (2 << 2) -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ -#define TIMER_CTRL_PERIODIC (1 << 6) -#define TIMER_CTRL_ENABLE (1 << 7) - -#define TIMER_INTCLR(hw_base) __REG32(hw_base + 0x0c) -#define TIMER_RIS(hw_base) __REG32(hw_base + 0x10) -#define TIMER_MIS(hw_base) __REG32(hw_base + 0x14) -#define TIMER_BGLOAD(hw_base) __REG32(hw_base + 0x18) - -void* sys_ctrl; -#define SYS_CTRL __REG32(sys_ctrl) -void* timer_hw_base; -#define TIMER_HW_BASE timer_hw_base - -static void rt_hw_timer_isr(int vector, void *param) -{ - rt_tick_increase(); - /* clear interrupt */ - TIMER_INTCLR(TIMER_HW_BASE) = 0x01; -} - -int rt_hw_timer_init(void) -{ - rt_uint32_t val; - - sys_ctrl = (void*)rt_ioremap((void*)REALVIEW_SCTL_BASE, 0x1000); - timer_hw_base = (void*)rt_ioremap((void*)REALVIEW_TIMER2_3_BASE, 0x1000); - - SYS_CTRL |= REALVIEW_REFCLK; - - /* Setup Timer0 for generating irq */ - val = TIMER_CTRL(TIMER_HW_BASE); - val &= ~TIMER_CTRL_ENABLE; - val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); - TIMER_CTRL(TIMER_HW_BASE) = val; - - TIMER_LOAD(TIMER_HW_BASE) = 1000000/RT_TICK_PER_SECOND; - - /* enable timer */ - TIMER_CTRL(TIMER_HW_BASE) |= TIMER_CTRL_ENABLE; - - rt_hw_interrupt_install(IRQ_PBA8_TIMER2_3, rt_hw_timer_isr, RT_NULL, "tick"); - rt_hw_interrupt_umask(IRQ_PBA8_TIMER2_3); - - return 0; -} -INIT_BOARD_EXPORT(rt_hw_timer_init); - -void timer_init(int timer, unsigned int preload) -{ - uint32_t val; - - if (timer == 0) - { - timer01_hw_base = (void*)rt_ioremap((void*)TIMER01_HW_BASE_PHY, 0x1000); - /* Setup Timer0 for generating irq */ - val = TIMER_CTRL(TIMER01_HW_BASE); - val &= ~TIMER_CTRL_ENABLE; - val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); - TIMER_CTRL(TIMER01_HW_BASE) = val; - - TIMER_LOAD(TIMER01_HW_BASE) = preload; - - /* enable timer */ - TIMER_CTRL(TIMER01_HW_BASE) |= TIMER_CTRL_ENABLE; - } - else - { - timer23_hw_base = (void*)rt_ioremap((void*)TIMER23_HW_BASE_PHY, 0x1000); - /* Setup Timer1 for generating irq */ - val = TIMER_CTRL(TIMER23_HW_BASE); - val &= ~TIMER_CTRL_ENABLE; - val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); - TIMER_CTRL(TIMER23_HW_BASE) = val; - - TIMER_LOAD(TIMER23_HW_BASE) = preload; - - /* enable timer */ - TIMER_CTRL(TIMER23_HW_BASE) |= TIMER_CTRL_ENABLE; - } -} - -void timer_clear_pending(int timer) -{ - if (timer == 0) - { - TIMER_INTCLR(TIMER01_HW_BASE) = 0x01; - } - else - { - TIMER_INTCLR(TIMER23_HW_BASE) = 0x01; - } -} diff --git a/bsp/qemu-vexpress-a53/drivers/drv_timer.h b/bsp/qemu-vexpress-a53/drivers/drv_timer.h deleted file mode 100644 index 718f5d43cf..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/drv_timer.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-11-22 Jesven first version - */ - -#ifndef DRV_TIMER_H__ -#define DRV_TIMER_H__ - -void timer_init(int timer, unsigned int preload); -void timer_clear_pending(int timer); - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/realview.h b/bsp/qemu-vexpress-a53/drivers/realview.h deleted file mode 100644 index d63df40f45..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/realview.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef __AM33XX_H__ -#define __AM33XX_H__ - -#define __REG32(x) (*((volatile unsigned int *)(x))) -#define __REG16(x) (*((volatile unsigned short *)(x))) - -/* - * Peripheral addresses - */ -#define REALVIEW_UART0_BASE 0x10009000 /* UART 0 */ -#define REALVIEW_UART1_BASE 0x1000A000 /* UART 1 */ -#define REALVIEW_UART2_BASE 0x1000B000 /* UART 2 */ -#define REALVIEW_UART3_BASE 0x1000C000 /* UART 3 */ -#define REALVIEW_SSP_BASE 0x1000D000 /* Synchronous Serial Port */ -#define REALVIEW_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */ -#define REALVIEW_WATCHDOG_BASE 0x10010000 /* watchdog interface */ -#define REALVIEW_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */ -#define REALVIEW_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */ -#define REALVIEW_GPIO0_BASE 0x10013000 /* GPIO port 0 */ -#define REALVIEW_RTC_BASE 0x10017000 /* Real Time Clock */ -#define REALVIEW_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */ -#define REALVIEW_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */ -#define REALVIEW_SCTL_BASE 0x10001000 /* System Controller */ -#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */ -#define REALVIEW_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */ -#define REALVIEW_DMC_BASE 0x100E0000 /* DMC configuration */ -#define REALVIEW_SMC_BASE 0x100E1000 /* SMC configuration */ -#define REALVIEW_CAN_BASE 0x100E2000 /* CAN bus */ -#define REALVIEW_GIC_CPU_BASE 0x1E000100 /* Generic interrupt controller CPU interface */ -#define REALVIEW_FLASH0_BASE 0x40000000 -#define REALVIEW_FLASH0_SIZE SZ_64M -#define REALVIEW_FLASH1_BASE 0x44000000 -#define REALVIEW_FLASH1_SIZE SZ_64M - -#define VEXPRESS_SRAM_BASE 0x48000000 - -#define REALVIEW_ETH_BASE 0x4E000000 /* Ethernet */ -#define VEXPRESS_ETH_BASE 0x4E000000 /* Ethernet */ - -#define REALVIEW_USB_BASE 0x4F000000 /* USB */ -#define REALVIEW_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */ -#define REALVIEW_LT_BASE 0xC0000000 /* Logic Tile expansion */ -#define REALVIEW_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */ -#define REALVIEW_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */ - -#define REALVIEW_SYS_PLD_CTRL1 0x74 - -/* - * PCI regions - */ -#define REALVIEW_PCI_BASE 0x90040000 /* PCI-X Unit base */ -#define REALVIEW_PCI_IO_BASE 0x90050000 /* IO Region on AHB */ -#define REALVIEW_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */ - -#define REALVIEW_PCI_BASE_SIZE 0x10000 /* 16 Kb */ -#define REALVIEW_PCI_IO_SIZE 0x1000 /* 4 Kb */ -#define REALVIEW_PCI_MEM_SIZE 0x20000000 /* 512 MB */ - -/* - * Memory definitions - */ -#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)... */ -#define REALVIEW_BOOT_ROM_HI 0x30000000 -#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */ -#define REALVIEW_BOOT_ROM_SIZE SZ_64M - -#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */ -#define REALVIEW_SSRAM_SIZE SZ_2M - -/* - * SDRAM - */ -#define REALVIEW_SDRAM_BASE 0x00000000 - -/* - * Logic expansion modules - * - */ -#define IRQ_PBA8_GIC_START 32 - -/* - * PB-A8 on-board gic irq sources - */ -#define IRQ_PBA8_WATCHDOG (IRQ_PBA8_GIC_START + 0) /* Watchdog timer */ -#define IRQ_PBA8_SOFT (IRQ_PBA8_GIC_START + 1) /* Software interrupt */ -#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 2) /* Timer 0/1 (default timer) */ -#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 3) /* Timer 2/3 */ -#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 4) /* Timer 2/3 */ -#define IRQ_VEXPRESS_A9_RTC (IRQ_PBA8_GIC_START + 4) - -#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 5) /* UART 0 on development chip */ -#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 6) /* UART 1 on development chip */ -#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 7) /* UART 2 on development chip */ -#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 8) /* UART 3 on development chip */ - -#define IRQ_VEXPRESS_A9_KBD (IRQ_PBA8_GIC_START + 12) -#define IRQ_VEXPRESS_A9_MOUSE (IRQ_PBA8_GIC_START + 13) -#define IRQ_VEXPRESS_A9_CLCD (IRQ_PBA8_GIC_START + 14) -#define IRQ_VEXPRESS_A9_ETH (IRQ_PBA8_GIC_START + 15) - -/* 9 reserved */ -#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11) /* Synchronous Serial Port */ -#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16) /* Smart Card Interface */ -#define IRQ_PBA8_MMCI0A (IRQ_PBA8_GIC_START + 17) /* Multimedia Card 0A */ -#define IRQ_PBA8_MMCI0B (IRQ_PBA8_GIC_START + 18) /* Multimedia Card 0B */ -#define IRQ_PBA8_AACI (IRQ_PBA8_GIC_START + 19) /* Audio Codec */ -#define IRQ_PBA8_KMI0 (IRQ_PBA8_GIC_START + 20) /* Keyboard/Mouse port 0 */ -#define IRQ_PBA8_KMI1 (IRQ_PBA8_GIC_START + 21) /* Keyboard/Mouse port 1 */ -#define IRQ_PBA8_CHARLCD (IRQ_PBA8_GIC_START + 22) /* Character LCD */ -#define IRQ_PBA8_CLCD (IRQ_PBA8_GIC_START + 23) /* CLCD controller */ -#define IRQ_PBA8_DMAC (IRQ_PBA8_GIC_START + 24) /* DMA controller */ -#define IRQ_PBA8_PWRFAIL (IRQ_PBA8_GIC_START + 25) /* Power failure */ -#define IRQ_PBA8_PISMO (IRQ_PBA8_GIC_START + 26) /* PISMO interface */ -#define IRQ_PBA8_DoC (IRQ_PBA8_GIC_START + 27) /* Disk on Chip memory controller */ -#define IRQ_PBA8_ETH (IRQ_PBA8_GIC_START + 28) /* Ethernet controller */ -#define IRQ_PBA8_USB (IRQ_PBA8_GIC_START + 29) /* USB controller */ -#define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */ -#define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */ - -#define IRQ_PBA8_PMU (IRQ_PBA8_GIC_START + 47) /* Cortex-A8 PMU */ - -/* ... */ -#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50) -#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51) -#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52) -#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53) - -#define IRQ_PBA8_SMC -1 -#define IRQ_PBA8_SCTL -1 - -#define NR_GIC_PBA8 1 - -/* - * Only define NR_IRQS if less than NR_IRQS_PBA8 - */ -#define NR_IRQS_PBA8 (IRQ_PBA8_GIC_START + 64) - -/* ------------------------------------------------------------------------ - * RealView Registers - * ------------------------------------------------------------------------ - * - */ -#define REALVIEW_SYS_ID_OFFSET 0x00 -#define REALVIEW_SYS_SW_OFFSET 0x04 -#define REALVIEW_SYS_LED_OFFSET 0x08 -#define REALVIEW_SYS_OSC0_OFFSET 0x0C - -#define REALVIEW_SYS_OSC1_OFFSET 0x10 -#define REALVIEW_SYS_OSC2_OFFSET 0x14 -#define REALVIEW_SYS_OSC3_OFFSET 0x18 -#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */ - -#define REALVIEW_SYS_LOCK_OFFSET 0x20 -#define REALVIEW_SYS_100HZ_OFFSET 0x24 -#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28 -#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C -#define REALVIEW_SYS_FLAGS_OFFSET 0x30 -#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30 -#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34 -#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38 -#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38 -#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C -#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 -#define REALVIEW_SYS_PCICTL_OFFSET 0x44 -#define REALVIEW_SYS_MCI_OFFSET 0x48 -#define REALVIEW_SYS_FLASH_OFFSET 0x4C -#define REALVIEW_SYS_CLCD_OFFSET 0x50 -#define REALVIEW_SYS_CLCDSER_OFFSET 0x54 -#define REALVIEW_SYS_BOOTCS_OFFSET 0x58 -#define REALVIEW_SYS_24MHz_OFFSET 0x5C -#define REALVIEW_SYS_MISC_OFFSET 0x60 -#define REALVIEW_SYS_IOSEL_OFFSET 0x70 -#define REALVIEW_SYS_PROCID_OFFSET 0x84 -#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0 -#define REALVIEW_SYS_TEST_OSC1_OFFSET 0xC4 -#define REALVIEW_SYS_TEST_OSC2_OFFSET 0xC8 -#define REALVIEW_SYS_TEST_OSC3_OFFSET 0xCC -#define REALVIEW_SYS_TEST_OSC4_OFFSET 0xD0 - -#define REALVIEW_SYS_BASE 0x10000000 -#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET) -#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET) -#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET) -#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET) -#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET) - -#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET) -#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET) -#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET) -#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET) -#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET) -#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET) -#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET) -#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET) -#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET) -#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET) -#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET) -#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET) -#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET) -#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET) -#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET) -#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET) -#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET) -#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET) -#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET) -#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET) -#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET) -#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET) -#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET) -#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET) -#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) -#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) - -#define REALVIEW_SYS_CTRL_LED (1 << 0) - -/* ------------------------------------------------------------------------ - * RealView control registers - * ------------------------------------------------------------------------ - */ - -/* - * REALVIEW_IDFIELD - * - * 31:24 = manufacturer (0x41 = ARM) - * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus) - * 15:12 = FPGA (0x3 = XVC600 or XVC600E) - * 11:4 = build value - * 3:0 = revision number (0x1 = rev B (AHB)) - */ - -/* - * REALVIEW_SYS_LOCK - * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, - * SYS_CLD, SYS_BOOTCS - */ -#define REALVIEW_SYS_LOCK_LOCKED (1 << 16) -#define REALVIEW_SYS_LOCKVAL 0xA05F -#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ - -/* - * REALVIEW_SYS_FLASH - */ -#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */ - -/* - * REALVIEW_INTREG - * - used to acknowledge and control MMCI and UART interrupts - */ -#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */ -#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */ -#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */ -/* write 1 to acknowledge and clear */ -#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */ -#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */ - -/* - * LED settings, bits [7:0] - */ -#define REALVIEW_SYS_LED0 (1 << 0) -#define REALVIEW_SYS_LED1 (1 << 1) -#define REALVIEW_SYS_LED2 (1 << 2) -#define REALVIEW_SYS_LED3 (1 << 3) -#define REALVIEW_SYS_LED4 (1 << 4) -#define REALVIEW_SYS_LED5 (1 << 5) -#define REALVIEW_SYS_LED6 (1 << 6) -#define REALVIEW_SYS_LED7 (1 << 7) - -#define ALL_LEDS 0xFF - -#define LED_BANK REALVIEW_SYS_LED - -/* - * Control registers - */ -#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */ -#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */ -#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */ -#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ - -/* - * Clean base - dummy - * - */ -#define CLEAN_BASE REALVIEW_BOOT_ROM_HI - -/* - * System controller bit assignment - */ -#define REALVIEW_REFCLK 0 -#define REALVIEW_TIMCLK 1 - -#define REALVIEW_TIMER1_EnSel 15 -#define REALVIEW_TIMER2_EnSel 17 -#define REALVIEW_TIMER3_EnSel 19 -#define REALVIEW_TIMER4_EnSel 21 - -struct rt_hw_register -{ - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long sp; - unsigned long lr; - unsigned long pc; - unsigned long cpsr; - unsigned long ORIG_r0; -}; - -#include -#include - -/* Interrupt Control Interface */ -#define ARM_GIC_CPU_BASE 0x1E000000 - -/* number of interrupts on board */ -#define ARM_GIC_NR_IRQS 96 -/* only one GIC available */ -#define ARM_GIC_MAX_NR 1 - -#endif - diff --git a/bsp/qemu-vexpress-a53/drivers/rt_lcd.h b/bsp/qemu-vexpress-a53/drivers/rt_lcd.h deleted file mode 100644 index e496a871da..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/rt_lcd.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef RT_LCD_H__ -#define RT_LCD_H__ - - -/* ioctls - 0x46 is 'F' */ -#define FBIOGET_VSCREENINFO 0x4600 -#define FBIOPUT_VSCREENINFO 0x4601 -#define FBIOGET_FSCREENINFO 0x4602 -#define FBIOGETCMAP 0x4604 -#define FBIOPUTCMAP 0x4605 -#define FBIOPAN_DISPLAY 0x4606 -#define FBIO_CURSOR 0x4608 -/* #define FBIOGET_MONITORSPEC 0x460C */ -/* #define FBIOPUT_MONITORSPEC 0x460D */ -/* #define FBIOSWITCH_MONIBIT 0x460E */ -#define FBIOGET_CON2FBMAP 0x460F -#define FBIOPUT_CON2FBMAP 0x4610 -#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */ -#define FBIOGET_VBLANK 0x4612 -#define FBIO_ALLOC 0x4613 -#define FBIO_FREE 0x4614 -#define FBIOGET_GLYPH 0x4615 -#define FBIOGET_HWCINFO 0x4616 -#define FBIOPUT_MODEINFO 0x4617 -#define FBIOGET_DISPINFO 0x4618 -#define FBIO_WAITFORVSYNC 0x4620 - -struct fb_bitfield -{ - uint32_t offset; /* beginning of bitfield */ - uint32_t length; /* length of bitfield */ - uint32_t msb_right; /* != 0 : Most significant bit is */ - /* right */ -}; - -struct fb_var_screeninfo -{ - uint32_t xres; - uint32_t yres; - - uint32_t bits_per_pixel; - - struct fb_bitfield red; /* bitfield in fb mem if true color, */ - struct fb_bitfield green; /* else only length is significant */ - struct fb_bitfield blue; - struct fb_bitfield transp; /* transparency */ -}; - -struct fb_fix_screeninfo -{ - char id[16]; - unsigned long smem_start; - uint32_t smem_len; - - uint32_t line_length; -}; - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/secondary_cpu.c b/bsp/qemu-vexpress-a53/drivers/secondary_cpu.c deleted file mode 100644 index b455beb53a..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/secondary_cpu.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-11-22 Jesven first version - */ - -#include -#include -#include - -#include "board.h" -#include "gic.h" -#include "drv_timer.h" - -#ifdef RT_USING_SMP -#include - -#ifdef RT_USING_USERSPACE -#include -#endif - -static void rt_hw_timer2_isr(int vector, void *param) -{ - rt_tick_increase(); - /* clear interrupt */ - timer_clear_pending(0); -} - -void rt_hw_secondary_cpu_up(void) -{ - volatile void **plat_boot_reg = (volatile void **)0x10000034; - char *entry = (char *)rt_secondary_cpu_entry; - -#ifdef RT_USING_USERSPACE - plat_boot_reg = (volatile void **)rt_hw_mmu_map(&mmu_info, 0, (void *)plat_boot_reg, 0x1000, MMU_MAP_K_RW); - if (!plat_boot_reg) - { - /* failed */ - return; - } - entry += PV_OFFSET; -#endif - *plat_boot_reg-- = (void *)(size_t)-1; - *plat_boot_reg = (void *)entry; - rt_hw_dsb(); - rt_hw_ipi_send(0, 1 << 1); -} - -/* Interface */ -void rt_hw_secondary_cpu_bsp_start(void) -{ - rt_hw_vector_init(); - - rt_hw_spin_lock(&_cpus_lock); - - arm_gic_cpu_init(0, 0); - arm_gic_set_cpu(0, IRQ_PBA8_TIMER0_1, 0x2); - - timer_init(0, 10000); - rt_hw_interrupt_install(IRQ_PBA8_TIMER0_1, rt_hw_timer2_isr, RT_NULL, "tick"); - rt_hw_interrupt_umask(IRQ_PBA8_TIMER0_1); - - rt_system_scheduler_start(); -} - -void rt_hw_secondary_cpu_idle_exec(void) -{ - asm volatile ("wfe":::"memory", "cc"); -} - -#endif diff --git a/bsp/qemu-vexpress-a53/drivers/serial.c b/bsp/qemu-vexpress-a53/drivers/serial.c deleted file mode 100644 index bf54cee6e3..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/serial.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * serial.c UART driver - * - * COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd - * - * This file is part of RT-Thread (http://www.rt-thread.org) - * Maintainer: bernard.xiong - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2013-03-30 Bernard the first verion - */ - -#include -#include - -#include "serial.h" -#include "board.h" -#include "mmu.h" - -struct hw_uart_device -{ - rt_size_t hw_base; - rt_size_t irqno; -}; - -#define UART_DR(base) __REG32(base + 0x00) -#define UART_FR(base) __REG32(base + 0x18) -#define UART_CR(base) __REG32(base + 0x30) -#define UART_IMSC(base) __REG32(base + 0x38) -#define UART_ICR(base) __REG32(base + 0x44) - -#define UARTFR_RXFE 0x10 -#define UARTFR_TXFF 0x20 -#define UARTIMSC_RXIM 0x10 -#define UARTIMSC_TXIM 0x20 -#define UARTICR_RXIC 0x10 -#define UARTICR_TXIC 0x20 - -static void rt_hw_uart_isr(int irqno, void *param) -{ - struct rt_serial_device *serial = (struct rt_serial_device *)param; - - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); -} - -static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) -{ - return RT_EOK; -} - -static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) -{ - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - /* disable rx irq */ - UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM; - break; - - case RT_DEVICE_CTRL_SET_INT: - /* enable rx irq */ - UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM; - rt_hw_interrupt_umask(uart->irqno); - break; - } - - return RT_EOK; -} - -static int uart_putc(struct rt_serial_device *serial, char c) -{ - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - while (UART_FR(uart->hw_base) & UARTFR_TXFF); - UART_DR(uart->hw_base) = c; - - return 1; -} - -static int uart_getc(struct rt_serial_device *serial) -{ - int ch; - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - ch = -1; - if (!(UART_FR(uart->hw_base) & UARTFR_RXFE)) - { - ch = UART_DR(uart->hw_base) & 0xff; - } - - return ch; -} - -static const struct rt_uart_ops _uart_ops = -{ - uart_configure, - uart_control, - uart_putc, - uart_getc, -}; - -#ifdef RT_USING_UART0 -/* UART device driver structure */ -static struct hw_uart_device _uart0_device = -{ - REALVIEW_UART0_BASE, - IRQ_PBA8_UART0, -}; -static struct rt_serial_device _serial0; -#endif - -#ifdef RT_USING_UART1 -/* UART1 device driver structure */ -static struct hw_uart_device _uart1_device = -{ - REALVIEW_UART1_BASE, - IRQ_PBA8_UART1, -}; -static struct rt_serial_device _serial1; -#endif - -int rt_hw_uart_init(void) -{ - struct hw_uart_device *uart; - struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - -#ifdef RT_USING_UART0 - _uart0_device.hw_base = (rt_size_t)rt_ioremap((void*)_uart0_device.hw_base, 0x1000); - uart = &_uart0_device; - - _serial0.ops = &_uart_ops; - _serial0.config = config; - - /* register UART1 device */ - rt_hw_serial_register(&_serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); - rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0"); - /* enable Rx and Tx of UART */ - UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); -#endif - -#ifdef RT_USING_UART1 - _uart1_device.hw_base = (rt_size_t)rt_ioremap((void*)_uart1_device.hw_base, 0x1000); - uart = &_uart1_device; - _serial1.ops = &_uart_ops; - _serial1.config = config; - - /* register UART1 device */ - rt_hw_serial_register(&_serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); - /* enable Rx and Tx of UART */ - UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); - rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial1, "uart1"); -#endif - - return 0; -} -INIT_BOARD_EXPORT(rt_hw_uart_init); diff --git a/bsp/qemu-vexpress-a53/drivers/serial.h b/bsp/qemu-vexpress-a53/drivers/serial.h deleted file mode 100644 index 52e6f07ea3..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/serial.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * UART driver - * - * COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd - * - * This file is part of RT-Thread (http://www.rt-thread.org) - * Maintainer: bernard.xiong - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2013-03-30 Bernard the first verion - */ - -#ifndef __UART_H__ -#define __UART_H__ - -#include - -int rt_hw_uart_init(void); - -#endif - - diff --git a/bsp/qemu-vexpress-a53/drivers/vexpress_a9.h b/bsp/qemu-vexpress-a53/drivers/vexpress_a9.h deleted file mode 100644 index 86ab590932..0000000000 --- a/bsp/qemu-vexpress-a53/drivers/vexpress_a9.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-03-22 quanzhao first version - */ - -#ifndef __VEXPRESS_A9_H__ -#define __VEXPRESS_A9_H__ - -/* for 'rt_inline' */ -#include -/* SOC-relative definitions */ -#include "realview.h" - -/* the maximum entries of the exception table */ -#define MAX_HANDLERS NR_IRQS_PBA8 - -/* the basic constants and interfaces needed by gic */ -rt_inline rt_uint64_t platform_get_gic_dist_base(void) -{ - return REALVIEW_GIC_DIST_BASE; -} - -rt_inline rt_uint64_t platform_get_gic_cpu_base(void) -{ - return REALVIEW_GIC_CPU_BASE; -} - -#define GIC_IRQ_START 0 - -#define GIC_ACK_INTID_MASK 0x000003ff - -#endif /* __VEXPRESS_A9_H__ */ diff --git a/bsp/qemu-vexpress-a53/link.lds b/bsp/qemu-vexpress-a53/link.lds deleted file mode 100644 index d21ab041db..0000000000 --- a/bsp/qemu-vexpress-a53/link.lds +++ /dev/null @@ -1,109 +0,0 @@ -OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") -OUTPUT_ARCH(aarch64) -SECTIONS -{ - /*. = 0x60080000; */ - . = 0xffff000000080000; - - __text_start = .; - .text : - { - KEEP(*(.text.entrypoint)) - KEEP(*(.vectors)) - *(.text) - *(.text.*) - - /* section information for utest */ - . = ALIGN(4); - __rt_utest_tc_tab_start = .; - KEEP(*(UtestTcTab)) - __rt_utest_tc_tab_end = .; - - /* section information for finsh shell */ - . = ALIGN(4); - __fsymtab_start = .; - KEEP(*(FSymTab)) - __fsymtab_end = .; - . = ALIGN(4); - __vsymtab_start = .; - KEEP(*(VSymTab)) - __vsymtab_end = .; - . = ALIGN(4); - - /* section information for modules */ - . = ALIGN(4); - __rtmsymtab_start = .; - KEEP(*(RTMSymTab)) - __rtmsymtab_end = .; - - /* section information for initialization */ - . = ALIGN(4); - __rt_init_start = .; - KEEP(*(SORT(.rti_fn*))) - __rt_init_end = .; - } =0 - __text_end = .; - - .ARM.exidx : - { - __exidx_start = .; - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - __exidx_end = .; - } - - __rodata_start = .; - .rodata : { *(.rodata) *(.rodata.*) } - __rodata_end = .; - - . = ALIGN(4); - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } - - . = ALIGN(8); - __data_start = .; - .data : - { - *(.data) - *(.data.*) - } - __data_end = .; - - . = ALIGN(8); - __bss_start = .; - .bss : - { - *(.bss) - *(.bss.*) - *(COMMON) - . = ALIGN(4); - } - . = ALIGN(4); - __bss_end = .; - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - - __data_size = SIZEOF(.data); - __bss_size = SIZEOF(.bss); - - _end = .; -} diff --git a/bsp/qemu-vexpress-a53/makefile.targets b/bsp/qemu-vexpress-a53/makefile.targets deleted file mode 100644 index a00129bd90..0000000000 --- a/bsp/qemu-vexpress-a53/makefile.targets +++ /dev/null @@ -1,4 +0,0 @@ -clean2: - -$(RM) $(CC_DEPS)$(C++_DEPS)$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS) - -$(RM) $(OBJS) *.elf - -@echo ' ' \ No newline at end of file diff --git a/bsp/qemu-vexpress-a53/qemu-dbg.sh b/bsp/qemu-vexpress-a53/qemu-dbg.sh deleted file mode 100755 index 3c79dfe607..0000000000 --- a/bsp/qemu-vexpress-a53/qemu-dbg.sh +++ /dev/null @@ -1,6 +0,0 @@ -if [ ! -f "sd.bin" ]; then -dd if=/dev/zero of=sd.bin bs=1024 count=65536 -fi - -qemu-system-aarch64 -cpu cortex-a53 -M vexpress-a9 -kernel rtthread.bin -nographic -sd sd.bin -S -s - diff --git a/bsp/qemu-vexpress-a53/qemu-nographic.sh b/bsp/qemu-vexpress-a53/qemu-nographic.sh deleted file mode 100755 index 9eda5342ca..0000000000 --- a/bsp/qemu-vexpress-a53/qemu-nographic.sh +++ /dev/null @@ -1,5 +0,0 @@ -if [ ! -f "sd.bin" ]; then -dd if=/dev/zero of=sd.bin bs=1024 count=65536 -fi - -qemu-system-aarch64 -cpu cortex-a53 -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -nographic -sd sd.bin diff --git a/bsp/qemu-vexpress-a53/qemu.sh b/bsp/qemu-vexpress-a53/qemu.sh deleted file mode 100755 index f97c57cad2..0000000000 --- a/bsp/qemu-vexpress-a53/qemu.sh +++ /dev/null @@ -1,5 +0,0 @@ -if [ ! -f "sd.bin" ]; then -dd if=/dev/zero of=sd.bin bs=1024 count=65536 -fi - -qemu-system-aarch64 -cpu cortex-a53 -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -serial stdio -sd sd.bin diff --git a/bsp/qemu-vexpress-a53/rtconfig.h b/bsp/qemu-vexpress-a53/rtconfig.h deleted file mode 100644 index c23bd4a36e..0000000000 --- a/bsp/qemu-vexpress-a53/rtconfig.h +++ /dev/null @@ -1,292 +0,0 @@ -#ifndef RT_CONFIG_H__ -#define RT_CONFIG_H__ - -/* Automatically generated file; DO NOT EDIT. */ -/* RT-Thread Project Configuration */ - -/* RT-Thread Kernel */ - -#define RT_NAME_MAX 8 -#define RT_USING_SMART -#define RT_ALIGN_SIZE 4 -#define RT_THREAD_PRIORITY_32 -#define RT_THREAD_PRIORITY_MAX 32 -#define RT_TICK_PER_SECOND 100 -#define RT_USING_OVERFLOW_CHECK -#define RT_USING_HOOK -#define RT_USING_IDLE_HOOK -#define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 8192 -#define RT_USING_TIMER_SOFT -#define RT_TIMER_THREAD_PRIO 4 -#define RT_TIMER_THREAD_STACK_SIZE 8192 -#define RT_DEBUG -#define RT_DEBUG_COLOR - -/* Inter-Thread communication */ - -#define RT_USING_SEMAPHORE -#define RT_USING_MUTEX -#define RT_USING_EVENT -#define RT_USING_MAILBOX -#define RT_USING_MESSAGEQUEUE -#define RT_USING_SIGNALS - -/* Memory Management */ - -#define RT_USING_MEMPOOL -#define RT_USING_MEMHEAP -#define RT_USING_SMALL_MEM -#define RT_USING_MEMTRACE -#define RT_USING_HEAP - -/* Kernel Device Object */ - -#define RT_USING_DEVICE -#define RT_USING_DEVICE_OPS -#define RT_USING_INTERRUPT_INFO -#define RT_USING_CONSOLE -#define RT_CONSOLEBUF_SIZE 256 -#define RT_CONSOLE_DEVICE_NAME "uart0" -#define RT_VER_NUM 0x50000 -#define ARCH_CPU_64BIT -#define RT_USING_CACHE -#define ARCH_ARM_MMU -#define RT_USING_USERSPACE -#define KERNEL_VADDR_START 0xffff000000000000 -#define PV_OFFSET 0x1000060000000 -#define ARCH_ARMV8 - -/* RT-Thread Components */ - -#define RT_USING_COMPONENTS_INIT -#define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 8192 -#define RT_MAIN_THREAD_PRIORITY 10 - -/* C++ features */ - - -/* Command shell */ - -#define RT_USING_FINSH -#define RT_USING_MSH -#define FINSH_THREAD_NAME "tshell" -#define FINSH_USING_HISTORY -#define FINSH_HISTORY_LINES 10 -#define FINSH_USING_SYMTAB -#define FINSH_USING_DESCRIPTION -#define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 -#define FINSH_CMD_SIZE 256 -#define FINSH_ARG_MAX 10 - -/* Device virtual file system */ - -#define RT_USING_DFS -#define DFS_USING_WORKDIR -#define DFS_FILESYSTEMS_MAX 4 -#define DFS_FILESYSTEM_TYPES_MAX 8 -#define DFS_FD_MAX 32 -#define RT_USING_DFS_ELMFAT - -/* elm-chan's FatFs, Generic FAT Filesystem Module */ - -#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_MAX_LFN 255 -#define RT_DFS_ELM_DRIVES 2 -#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 -#define RT_DFS_ELM_REENTRANT -#define RT_USING_DFS_DEVFS -#define RT_USING_DFS_ROMFS -#define RT_USING_DFS_RAMFS - -/* Device Drivers */ - -#define RT_USING_DEVICE_IPC -#define RT_PIPE_BUFSZ 512 -#define RT_USING_SYSTEM_WORKQUEUE -#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 -#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 -#define RT_USING_SERIAL -#define RT_SERIAL_USING_DMA -#define RT_SERIAL_RB_BUFSZ 256 -#define RT_USING_I2C -#define RT_USING_I2C_BITOPS -#define RT_USING_PIN -#define RT_USING_NULL -#define RT_USING_ZERO -#define RT_USING_RANDOM -#define RT_USING_MTD_NOR -#define RT_USING_MTD_NAND -#define RT_MTD_NAND_DEBUG -#define RT_USING_RTC -#define RT_USING_SOFT_RTC -#define RT_USING_SDIO -#define RT_SDIO_STACK_SIZE 512 -#define RT_SDIO_THREAD_PRIORITY 15 -#define RT_MMCSD_STACK_SIZE 8192 -#define RT_MMCSD_THREAD_PREORITY 22 -#define RT_MMCSD_MAX_PARTITION 16 -#define RT_USING_SPI -#define RT_USING_SPI_MSD -#define RT_USING_SFUD -#define RT_SFUD_USING_SFDP -#define RT_SFUD_USING_FLASH_INFO_TABLE -#define RT_SFUD_SPI_MAX_HZ 50000000 -#define RT_USING_WDT - -/* Using USB */ - - -/* POSIX layer and C standard library */ - -#define RT_USING_LIBC -#define RT_USING_MUSL -#define RT_USING_POSIX -#define RT_USING_POSIX_MMAP -#define RT_USING_POSIX_TERMIOS -#define RT_USING_POSIX_AIO -#define RT_USING_POSIX_CLOCKTIME - -/* Network */ - -/* Socket abstraction layer */ - -#define RT_USING_SAL - -/* protocol stack implement */ - -#define SAL_USING_LWIP -#define SAL_USING_POSIX - -/* 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_LWIP202 -#define RT_LWIP_MEM_ALIGNMENT 4 -#define RT_LWIP_IGMP -#define RT_LWIP_ICMP -#define RT_LWIP_DNS - -/* Static IPv4 Address */ - -#define RT_LWIP_IPADDR "10.0.2.100" -#define RT_LWIP_GWADDR "10.0.2.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 8192 -#define RT_LWIP_ETHTHREAD_PRIORITY 12 -#define RT_LWIP_ETHTHREAD_STACKSIZE 8192 -#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 */ - - -/* VBUS(Virtual Software BUS) */ - - -/* Utilities */ - -#define RT_USING_LWP -#define RT_LWP_MAX_NR 30 -#define LWP_TASK_STACK_SIZE 16384 -#define RT_CH_MSG_MAX_NR 1024 -#define RT_LWP_SHM_MAX_NR 64 -#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 -#define LWP_TID_MAX_NR 64 - -/* RT-Thread online packages */ - -/* IoT - internet of things */ - - -/* Wi-Fi */ - -/* Marvell WiFi */ - - -/* Wiced WiFi */ - - -/* IoT Cloud */ - - -/* security packages */ - - -/* language packages */ - - -/* multimedia packages */ - - -/* tools packages */ - - -/* system packages */ - - -/* Micrium: Micrium software products porting for RT-Thread */ - - -/* peripheral libraries and drivers */ - - -/* miscellaneous packages */ - - -/* samples: kernel and components samples */ - - -/* games: games run on RT-Thread console */ - - -/* Privated Packages of RealThread */ - - -/* Network Utilities */ - -#define SOC_VEXPRESS_A53 -#define RT_USING_UART0 -#define RT_USING_UART1 -#define BSP_DRV_CLCD -#define BSP_LCD_WIDTH 640 -#define BSP_LCD_HEIGHT 480 -#define BSP_DRV_EMAC - -#endif diff --git a/bsp/qemu-vexpress-a53/rtconfig.py b/bsp/qemu-vexpress-a53/rtconfig.py deleted file mode 100644 index 431d06a14a..0000000000 --- a/bsp/qemu-vexpress-a53/rtconfig.py +++ /dev/null @@ -1,70 +0,0 @@ -import os - -import uuid -def get_mac_address(): - mac=uuid.UUID(int = uuid.getnode()).hex[-12:] - return "#define AUTOMAC".join([str(int(e/2) + 1) + ' 0x' + mac[e:e+2] + '\n' for e in range(5,11,2)]) - -header = ''' -#ifndef __MAC_AUTO_GENERATE_H__ -#define __MAC_AUTO_GENERATE_H__ - -/* Automatically generated file; DO NOT EDIT. */ -/* mac configure file for RT-Thread qemu */ - -#define AUTOMAC0 0x52 -#define AUTOMAC1 0x54 -#define AUTOMAC2 0x00 -#define AUTOMAC''' - -end = ''' -#endif -''' - -automac_h_fn = os.path.join(os.path.dirname(__file__), 'drivers', 'automac.h') -with open(automac_h_fn, 'w') as f: - f.write(header + get_mac_address() + end) - -# toolchains options -ARCH ='aarch64' -CPU ='cortex-a' -CROSS_TOOL = 'gcc' -PLATFORM = 'gcc' -EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin' -BUILD = 'debug' - -if PLATFORM == 'gcc': - # toolchains - PREFIX = os.getenv('RTT_CC_PREFIX') or 'arm-none-eabi-' - CC = PREFIX + 'gcc' - CXX = PREFIX + 'g++' - AS = PREFIX + 'gcc' - AR = PREFIX + 'ar' - LINK = PREFIX + 'gcc' - TARGET_EXT = 'elf' - SIZE = PREFIX + 'size' - OBJDUMP = PREFIX + 'objdump' - OBJCPY = PREFIX + 'objcopy' - STRIP = PREFIX + 'strip' - CFPFLAGS = ' ' - AFPFLAGS = ' ' - DEVICE = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' - - CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall' - CFLAGS = DEVICE + CFPFLAGS + ' -Wall -std=gnu99' - AFLAGS = ' -c' + AFPFLAGS + ' -x assembler-with-cpp' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc' - CPATH = '' - LPATH = '' - - if BUILD == 'debug': - CFLAGS += ' -O0 -gdwarf-2' - CXXFLAGS += ' -O0 -gdwarf-2' - AFLAGS += ' -gdwarf-2' - else: - CFLAGS += ' -Os' - CXXFLAGS += ' -Os' - CXXFLAGS += ' -Woverloaded-virtual -fno-exceptions -fno-rtti' - -DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' -POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' diff --git a/bsp/raspberry-pi/raspi4-64/.config b/bsp/raspberry-pi/raspi4-64/.config index 0ab68e8fe3..64afe4a82a 100644 --- a/bsp/raspberry-pi/raspi4-64/.config +++ b/bsp/raspberry-pi/raspi4-64/.config @@ -8,23 +8,24 @@ # CONFIG_RT_NAME_MAX=8 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set +CONFIG_RT_USING_SMART=y # CONFIG_RT_USING_SMP is not set CONFIG_RT_ALIGN_SIZE=4 # CONFIG_RT_THREAD_PRIORITY_8 is not set CONFIG_RT_THREAD_PRIORITY_32=y # CONFIG_RT_THREAD_PRIORITY_256 is not set CONFIG_RT_THREAD_PRIORITY_MAX=32 -CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_TICK_PER_SECOND=1000 CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=2048 +CONFIG_IDLE_THREAD_STACK_SIZE=8192 CONFIG_RT_USING_TIMER_SOFT=y CONFIG_RT_TIMER_THREAD_PRIO=4 -CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=8192 CONFIG_RT_DEBUG=y -# CONFIG_RT_DEBUG_COLOR is not set +CONFIG_RT_DEBUG_COLOR=y # CONFIG_RT_DEBUG_INIT_CONFIG is not set # CONFIG_RT_DEBUG_THREAD_CONFIG is not set # CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set @@ -50,10 +51,11 @@ CONFIG_RT_USING_MESSAGEQUEUE=y # Memory Management # CONFIG_RT_USING_MEMPOOL=y -# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_MEMHEAP=y # CONFIG_RT_USING_NOHEAP is not set 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_MEMTRACE is not set CONFIG_RT_USING_HEAP=y @@ -62,22 +64,27 @@ CONFIG_RT_USING_HEAP=y # CONFIG_RT_USING_DEVICE=y # CONFIG_RT_USING_DEVICE_OPS is not set -# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_INTERRUPT_INFO=y CONFIG_RT_USING_CONSOLE=y -CONFIG_RT_CONSOLEBUF_SIZE=128 -CONFIG_RT_CONSOLE_DEVICE_NAME="uart" -CONFIG_RT_VER_NUM=0x40003 +CONFIG_RT_CONSOLEBUF_SIZE=512 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart0" +CONFIG_RT_VER_NUM=0x50000 CONFIG_ARCH_CPU_64BIT=y +CONFIG_RT_USING_CACHE=y # CONFIG_RT_USING_CPU_FFS is not set -CONFIG_ARCH_ARMV8=y # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_ARCH_ARM_MMU=y +CONFIG_RT_USING_USERSPACE=y +CONFIG_KERNEL_VADDR_START=0xffff000000000000 +CONFIG_PV_OFFSET=0x0001000000200000 +CONFIG_ARCH_ARMV8=y # # RT-Thread Components # CONFIG_RT_USING_COMPONENTS_INIT=y CONFIG_RT_USING_USER_MAIN=y -CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192 CONFIG_RT_MAIN_THREAD_PRIORITY=10 # @@ -89,6 +96,7 @@ CONFIG_RT_MAIN_THREAD_PRIORITY=10 # Command shell # CONFIG_RT_USING_FINSH=y +CONFIG_RT_USING_MSH=y CONFIG_FINSH_THREAD_NAME="tshell" CONFIG_FINSH_USING_HISTORY=y CONFIG_FINSH_HISTORY_LINES=5 @@ -96,12 +104,9 @@ CONFIG_FINSH_USING_SYMTAB=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_THREAD_STACK_SIZE=8192 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 # @@ -109,40 +114,81 @@ CONFIG_FINSH_ARG_MAX=10 # CONFIG_RT_USING_DFS=y CONFIG_DFS_USING_WORKDIR=y -CONFIG_DFS_FILESYSTEMS_MAX=2 -CONFIG_DFS_FILESYSTEM_TYPES_MAX=2 +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 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_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_ROMFS=y +# CONFIG_RT_USING_DFS_CROMFS 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=8192 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 CONFIG_RT_USING_SERIAL=y -CONFIG_RT_SERIAL_USING_DMA=y +# CONFIG_RT_SERIAL_USING_DMA is not set CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_CAN is not set -# CONFIG_RT_USING_HWTIMER is not set +CONFIG_RT_USING_HWTIMER=y # CONFIG_RT_USING_CPUTIME is not set -# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_I2C=y +# CONFIG_RT_I2C_DEBUG is not set +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_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y # CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set -# CONFIG_RT_USING_RTC is not set -# CONFIG_RT_USING_SDIO is not set -# CONFIG_RT_USING_SPI is not set -# CONFIG_RT_USING_WDT is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +CONFIG_RT_USING_SOFT_RTC=y +CONFIG_RT_USING_SDIO=y +CONFIG_RT_SDIO_STACK_SIZE=8192 +CONFIG_RT_SDIO_THREAD_PRIORITY=15 +CONFIG_RT_MMCSD_STACK_SIZE=8192 +CONFIG_RT_MMCSD_THREAD_PREORITY=22 +CONFIG_RT_MMCSD_MAX_PARTITION=16 +# CONFIG_RT_SDIO_DEBUG is not set +CONFIG_RT_USING_SPI=y +# CONFIG_RT_USING_QSPI is not set +# CONFIG_RT_USING_SPI_MSD is not set +# CONFIG_RT_USING_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +CONFIG_RT_USING_WDT=y # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set # CONFIG_RT_USING_TOUCH is not set @@ -161,11 +207,15 @@ CONFIG_RT_USING_PIN=y # POSIX layer and C standard library # CONFIG_RT_USING_LIBC=y +# CONFIG_RT_USING_NEWLIB is not set +CONFIG_RT_USING_MUSL=y # CONFIG_RT_USING_PTHREADS is not set 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_AIO is not set +CONFIG_RT_USING_POSIX_MMAP=y +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_GETLINE is not set +CONFIG_RT_USING_POSIX_AIO=y +CONFIG_RT_USING_POSIX_CLOCKTIME=y # CONFIG_RT_USING_MODULE is not set # @@ -175,22 +225,90 @@ CONFIG_RT_USING_POSIX=y # # Socket abstraction layer # -# CONFIG_RT_USING_SAL is not set +CONFIG_RT_USING_SAL=y + +# +# protocol stack implement +# +CONFIG_SAL_USING_LWIP=y +CONFIG_SAL_USING_POSIX=y # # 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=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.137.100" +CONFIG_RT_LWIP_GWADDR="192.168.137.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=16 +CONFIG_RT_LWIP_PBUF_NUM=16 +CONFIG_RT_LWIP_RAW_PCB_NUM=4 +CONFIG_RT_LWIP_UDP_PCB_NUM=8 +CONFIG_RT_LWIP_TCP_PCB_NUM=8 +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=8192 +# 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=8192 +CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8 +CONFIG_RT_LWIP_REASSEMBLY_FRAG=y +CONFIG_LWIP_NETIF_STATUS_CALLBACK=1 +CONFIG_LWIP_NETIF_LINK_CALLBACK=1 +CONFIG_SO_REUSE=1 +CONFIG_LWIP_SO_RCVTIMEO=1 +CONFIG_LWIP_SO_SNDTIMEO=1 +CONFIG_LWIP_SO_RCVBUF=1 +CONFIG_LWIP_SO_LINGER=0 +# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=0 +# CONFIG_RT_LWIP_STATS is not set +# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set +CONFIG_RT_LWIP_USING_PING=y +# CONFIG_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) @@ -203,6 +321,15 @@ 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_LWP=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +# CONFIG_RT_USING_GDBSERVER is not set +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_RT_LWP_SHM_MAX_NR=64 +CONFIG_LWP_CONSOLE_INPUT_BUFFER_SIZE=1024 +CONFIG_LWP_TID_MAX_NR=64 +# CONFIG_LWP_UNIX98_PTY is not set # # RT-Thread online packages @@ -211,7 +338,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 @@ -257,7 +386,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 @@ -279,6 +408,12 @@ 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 # # security packages @@ -287,6 +422,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 @@ -303,6 +439,9 @@ 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_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set # # tools packages @@ -314,14 +453,26 @@ CONFIG_RT_USING_POSIX=y # 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 # # system packages @@ -345,6 +496,27 @@ CONFIG_RT_USING_POSIX=y # 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 + +# +# 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_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# 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 +# CONFIG_PKG_USING_LPM is not set # # peripheral libraries and drivers @@ -353,6 +525,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 @@ -382,6 +555,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,6 +564,21 @@ 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 # # miscellaneous packages @@ -399,6 +588,7 @@ CONFIG_RT_USING_POSIX=y # 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 @@ -419,6 +609,7 @@ CONFIG_RT_USING_POSIX=y # 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 # CONFIG_PKG_USING_NNOM is not set # CONFIG_PKG_USING_LIBANN is not set # CONFIG_PKG_USING_ELAPACK is not set @@ -426,6 +617,64 @@ CONFIG_RT_USING_POSIX=y # 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 + +# +# games: games run on RT-Thread console +# +# 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_LWGPS is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set + +# +# Privated Packages of RealThread +# +# CONFIG_PKG_USING_CODEC is not set +# CONFIG_PKG_USING_PLAYER is not set +# CONFIG_PKG_USING_MPLAYER is not set +# CONFIG_PKG_USING_PERSIMMON_SRC is not set +# CONFIG_PKG_USING_JS_PERSIMMON is not set +# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set + +# +# Network Utilities +# +# CONFIG_PKG_USING_MDNS is not set +# CONFIG_PKG_USING_UPNP is not set +# CONFIG_PKG_USING_WICED is not set +# CONFIG_PKG_USING_CLOUDSDK is not set +# CONFIG_PKG_USING_POWER_MANAGER is not set +# CONFIG_PKG_USING_RT_OTA is not set +# CONFIG_PKG_USING_RDBD_SRC is not set +# CONFIG_PKG_USING_RTINSIGHT is not set +# CONFIG_PKG_USING_SMARTCONFIG is not set +# CONFIG_PKG_USING_RTX is not set +# CONFIG_RT_USING_TESTCASE is not set +# CONFIG_PKG_USING_NGHTTP2 is not set +# CONFIG_PKG_USING_AVS is not set +# CONFIG_PKG_USING_ALI_LINKKIT is not set +# CONFIG_PKG_USING_STS is not set +# CONFIG_PKG_USING_DLMS is not set +# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set +# CONFIG_PKG_USING_ZBAR is not set +# CONFIG_PKG_USING_MCF is not set +# CONFIG_PKG_USING_URPC is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_DCM is not set +# CONFIG_PKG_USING_EMQ is not set +# CONFIG_PKG_USING_CFGM is not set +# CONFIG_PKG_USING_RT_CMSIS_DAP is not set +# CONFIG_PKG_USING_SMODULE is not set +# CONFIG_PKG_USING_SNFD is not set +# CONFIG_PKG_USING_UDBD is not set +# CONFIG_PKG_USING_BENCHMARK is not set +# CONFIG_PKG_USING_UBJSON is not set +# CONFIG_PKG_USING_DATATYPE is not set +# CONFIG_PKG_USING_FASTFS is not set CONFIG_BCM2711_SOC=y # CONFIG_BSP_SUPPORT_FPU is not set @@ -438,17 +687,24 @@ 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=y +CONFIG_RT_USING_UART4=y +# 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_SPI is not set CONFIG_BSP_USING_CORETIMER=y # CONFIG_BSP_USING_SYSTIMER is not set -# CONFIG_BSP_USING_WDT is not set +CONFIG_BSP_USING_WDT=y # CONFIG_BSP_USING_RTC is not set -# CONFIG_BSP_USING_SDIO is not set +CONFIG_BSP_USING_SDIO=y +CONFIG_BSP_USING_SDIO0=y # # Board Peripheral Drivers # -# CONFIG_BSP_USING_HDMI is not set +CONFIG_BSP_USING_HDMI=y +# CONFIG_BSP_USING_HDMI_DISPLAY is not set diff --git a/bsp/raspberry-pi/raspi4-64/Kconfig b/bsp/raspberry-pi/raspi4-64/Kconfig index c1ee600450..5b683102b2 100644 --- a/bsp/raspberry-pi/raspi4-64/Kconfig +++ b/bsp/raspberry-pi/raspi4-64/Kconfig @@ -21,9 +21,11 @@ source "$PKGS_DIR/Kconfig" config BCM2711_SOC bool select ARCH_ARMV8 + select ARCH_CPU_64BIT + select RT_USING_CACHE + select ARCH_ARM_MMU select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN - select ARCH_CPU_64BIT default y -source "driver/Kconfig" +source "drivers/Kconfig" diff --git a/bsp/raspberry-pi/raspi4-64/README.md b/bsp/raspberry-pi/raspi4-64/README.md index b2456277b8..94eac22e67 100644 --- a/bsp/raspberry-pi/raspi4-64/README.md +++ b/bsp/raspberry-pi/raspi4-64/README.md @@ -11,88 +11,108 @@ ## 2. 编译说明 +推荐使用[env工具](https://www.rt-thread.org/page/download.html),可以在console下进入到`bsp\raspberry-pi\raspi4-32`目录中,运行以下命令: +``` +scons +``` -### 2.1 Window上的环境搭建 - -Windows环境下推荐使用[env工具](https://www.rt-thread.org/page/download.html)进行编译。 - -首先下载windows上的aarch64的gcc交叉编译工具,版本为gcc-arm-8.3选择aarch64-elf就可以。 +来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、kernel7.img文件。 -将推荐将gcc解压到`\env\tools\gnu_gcc\arm_gcc`目录下。 -接着修改`bsp\raspberry-pi\raspi4-64\rtconfig.py` +## 3. 环境搭建 +### 3.1 准备好串口线 -修改路径: +目前版本是使用raspi4的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示: -``` -EXEC_PATH = r'E:/env_released_1.1.2/env/tools/gnu_gcc/arm_gcc/gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf/bin' -``` +![raspi2](../raspi3-32/figures/raspberrypi-console.png) -然后在`bsp\raspberry-pi\raspi4-64\`下输入scons编译即可。 +串口参数: 115200 8N1 ,硬件和软件流控为关。 -**window环境搭建注意** +### 3.2 RTT固件放在SD卡运行 -下载完成`gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf.tar.xz`交叉编译工具链后,最好采用7-zip解压工具进行两次解压。 -确保解压目录下的`/bin/aarch64-elf-ld.exe`文件的size不为0。 -否则编译会出现如下错误: +首先需要准备一张空的32GB以下的SD卡,如果不想自己制作启动固件,可以直接从百度网盘上下载boot的固件。 ``` -collect2.exe:fatal error:CreateProcess:No such file or directory +链接:https://pan.baidu.com/s/1PxgvXAChUIOgueNXhgMs8w +提取码:pioj ``` -### 2.2 Linux上的环境搭建 +解压后将sd目录下的文件拷贝到sd卡即可。以后每次编译后,将生成的kernel7.img进行替换即可。上电后可以看到程序正常运行。 -Linux下推荐使用[gcc工具][2]。Linux版本下gcc版本可采用`gcc-arm-8.3-2019.03-x86_64-aarch64-elf`。 +### 3.3 RTT程序用uboot加载 -将工具链解压到指定目录,并修改当前bsp下的`EXEC_PATH`为自定义gcc目录。 +为了调试方便,已经将uboot引导程序放入uboot目录下,直接将这些文件放到sd卡中即可。 -``` -PLATFORM = 'gcc' -EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/' -``` +需要注意的以下步骤: -直接进入`bsp\raspberry-pi\raspi4-64`,输入scons编译即可。 +**1.电脑上启动tftp服务器** +windows系统电脑上可以安装tftpd搭建tftp服务器。将目录指定到`bsp\raspberry-pi\raspi4-32`。 -## 3. 执行 +**2.修改设置uboot** -### 3.1 下载**Raspberry Pi Imager**,生成可以运行的raspbian SD卡 +在控制台输入下列命令: -首先下载镜像 +``` +setenv bootcmd "dhcp 0x00200000 x.x.x.x:kernel7.img;dcache flush;go 0x00200000" +saveenv +reset +``` -* [Raspberry Pi Imager for Ubuntu](https://downloads.raspberrypi.org/imager/imager_amd64.deb) -* [Raspberry Pi Imager for Windows](https://downloads.raspberrypi.org/imager/imager.exe) -* [Raspberry Pi Imager for macOS](https://downloads.raspberrypi.org/imager/imager.dmg) +其中`x.x.x.x`为tftp服务器的pc的ip地址。 -### 3.2 准备好串口线 +**3.修改链接脚本** -目前版本是使用raspi4的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示: +将树莓派`bsp\raspberry-pi\raspi4-32\link.ld`的文件链接地址改为`0x200000`。 -![raspi2](../raspi3-32/figures/raspberrypi-console.png) +``` +SECTIONS +{ + . = 0x8000; + . = ALIGN(4096); + . + . + . +} +``` -串口参数: 115200 8N1 ,硬件和软件流控为关。 +改为 -### 3.3 程序下载 +``` +SECTIONS +{ + . = 0x200000; + . = ALIGN(4096); + . + . + . +} +``` -当编译生成了rtthread.bin文件后,我们可以将该文件放到sd卡上,并修改sd卡中的`config.txt`文件如下: +重新编译程序: ``` -enable_uart=1 -arm_64bit=1 -kernel=rtthread.bin -core_freq=250 +scons -c +scons ``` -按上面的方法做好SD卡后,插入树莓派4,通电可以在串口上看到如下所示的输出信息: +**3.插入网线** + +上述准备完成后,将网线插入,保证开发板和tftp服务器在同一个网段的路由器上。上电后uboot可以自动从tftp服务器上获取固件,然后开始执行了。 + +完成后可以看到串口的输出信息 -```text -heap: 0x000c9350 - 0x040c9350 +``` +heap: 0x000607e8 - 0x040607e8 \ | / - RT - Thread Operating System - / | \ 4.0.3 build Apr 16 2020 + / | \ 4.0.3 build Oct 27 2020 2006 - 2020 Copyright by rt-thread team +[I/SDIO] SD card capacity 31205376 KB. +found part[0], begin: 1048576, size: 29.777GB +file system initialization done! Hi, this is RT-Thread!! msh /> ``` @@ -101,9 +121,20 @@ msh /> | 驱动 | 支持情况 | 备注 | | ------ | ---- | :------: | -| UART | 支持 | UART0| +| UART | 支持 | UART0,UART2,UART3,UART4,UART5 | +| GPIO | 支持 | - | +| SPI | 支持 | SPI0 | +| MAILBOX | 支持 | - | +| WATCHDOG | 支持 | - | +| HDMI | 支持 | - | +| SDIO | 支持 | - | +| ETH | 支持 | - | + +## 5. 注意事项 + +目前rt-thread程序可以使用的内存在100MB以内,可以通过调整`board.c`中`platform_mem_desc`表的数据进行相关内存的映射以及修改`board.h`来确定程序使用的堆栈大小。目前在地址`0x08000000`处的1M空间被映射成非cache区供树莓派4的CPU与GPU通信的消息管道。若需要扩大系统内存使用,可自行修改代码进行调整。 -## 5. 联系人信息 +## 6. 联系人信息 维护人:[bernard][5] diff --git a/bsp/raspberry-pi/raspi4-64/SConstruct b/bsp/raspberry-pi/raspi4-64/SConstruct index 93f349aab8..1e5eae0d35 100644 --- a/bsp/raspberry-pi/raspi4-64/SConstruct +++ b/bsp/raspberry-pi/raspi4-64/SConstruct @@ -2,7 +2,10 @@ import os import sys import rtconfig -from rtconfig import RTT_ROOT +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.join(os.getcwd(), '..', '..', '..') sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] from building import * @@ -11,20 +14,20 @@ TARGET = 'rtthread.' + rtconfig.TARGET_EXT DefaultEnvironment(tools=[]) env = Environment(tools = ['mingw'], - AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, - CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, - CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, - AR = rtconfig.AR, ARFLAGS = '-rc', + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) env['ASCOM'] = env['ASPPCOM'] +env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group' Export('RTT_ROOT') Export('rtconfig') # prepare building environment -objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False) +objs = PrepareBuilding(env, RTT_ROOT) # make a building DoBuilding(TARGET, objs) - diff --git a/bsp/raspberry-pi/raspi4-64/applications/main.c b/bsp/raspberry-pi/raspi4-64/applications/main.c index 9664e67d01..26a2bf3ee7 100644 --- a/bsp/raspberry-pi/raspi4-64/applications/main.c +++ b/bsp/raspberry-pi/raspi4-64/applications/main.c @@ -4,16 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2020-04-16 bigmagic first version + * Date Author Notes + * 2017-5-30 bernard the first version */ - #include -#include -#include int main(int argc, char** argv) { - rt_kprintf("Hi, this is RT-Thread!!\n"); + rt_kprintf("hello rt-thread!\n"); + return 0; } 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..215f810bbc --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/applications/mnt.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2006-2019, 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("%s %d\n", __FILE__, __LINE__); + rt_kprintf("file system initialization done!\n"); + } + + return 0; +} +INIT_ENV_EXPORT(mnt_init); +#endif diff --git a/bsp/raspberry-pi/raspi4-64/driver/SConscript b/bsp/raspberry-pi/raspi4-64/driver/SConscript deleted file mode 100644 index 533df8ac31..0000000000 --- a/bsp/raspberry-pi/raspi4-64/driver/SConscript +++ /dev/null @@ -1,9 +0,0 @@ -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') -CPPPATH = [cwd, str(Dir('#'))] - -group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/raspberry-pi/raspi4-64/driver/board.c b/bsp/raspberry-pi/raspi4-64/driver/board.c deleted file mode 100644 index 79a24d184f..0000000000 --- a/bsp/raspberry-pi/raspi4-64/driver/board.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-04-16 bigmagic first version - */ - -#include -#include - -#include "board.h" -#include "drv_uart.h" - -#include "cp15.h" -#include "mmu.h" - -static rt_uint64_t timerStep; - -int rt_hw_get_gtimer_frq(void); -void rt_hw_set_gtimer_val(rt_uint64_t value); -int rt_hw_get_gtimer_val(void); -int rt_hw_get_cntpct_val(void); -void rt_hw_gtimer_enable(void); - -void core0_timer_enable_interrupt_controller(void) -{ - CORE0_TIMER_IRQ_CTRL |= NON_SECURE_TIMER_IRQ; -} - -void rt_hw_timer_isr(int vector, void *parameter) -{ - rt_hw_set_gtimer_val(timerStep); - rt_tick_increase(); -} - -void rt_hw_timer_init(void) -{ - rt_hw_interrupt_install(TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick"); - rt_hw_interrupt_umask(TIMER_IRQ); - __ISB(); - timerStep = rt_hw_get_gtimer_frq(); - __DSB(); - timerStep /= RT_TICK_PER_SECOND; - - rt_hw_gtimer_enable(); - rt_hw_set_gtimer_val(timerStep); - core0_timer_enable_interrupt_controller(); -} - -void idle_wfi(void) -{ - asm volatile ("wfi"); -} - -/** - * Initialize the Hardware related stuffs. Called from rtthread_startup() - * after interrupt disabled. - */ -void rt_hw_board_init(void) -{ - mmu_init(); - armv8_map(0, 0, 0x6400000, MEM_ATTR_MEMORY); - armv8_map(0xFE200000, 0xFE200000, 0x200000, MEM_ATTR_IO);//uart gpio - armv8_map(0xFF800000, 0xFF800000, 0x200000, MEM_ATTR_IO);//gic timer - mmu_enable(); - - /* initialize hardware interrupt */ - rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device - rt_hw_vector_init(); // in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors); - - /* initialize uart */ - rt_hw_uart_init(); // driver/drv_uart.c -#ifdef RT_USING_CONSOLE - /* set console device */ - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); -#endif /* RT_USING_CONSOLE */ - -#ifdef RT_USING_HEAP - /* initialize memory system */ - rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); - rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); -#endif - /* initialize timer for os tick */ - rt_hw_timer_init(); - rt_thread_idle_sethook(idle_wfi); - -#ifdef RT_USING_COMPONENTS_INIT - rt_components_board_init(); -#endif -} diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c b/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c deleted file mode 100644 index bba20a86a4..0000000000 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-04-16 bigmagic first version - */ - -#include "drv_gpio.h" - -#ifdef BSP_USING_PIN - -static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode) -{ - uint32_t fselnum = pin / 10; - uint32_t fselrest = pin % 10; - - uint32_t gpfsel = 0; - gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3))); - gpfsel |= (uint32_t)(mode << (fselrest * 3)); - - 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_write(struct rt_device *dev, rt_base_t pin, rt_base_t value) -{ - uint32_t num = pin / 32; - - if(num == 0) - { - if(value == 0) - { - GPIO_REG_GPSET0(GPIO_BASE) = 1 << (pin % 32); - } - else - { - GPIO_REG_GPCLR0(GPIO_BASE) = 1 << (pin % 32); - } - } - else - { - if(value == 0) - { - GPIO_REG_GPSET1(GPIO_BASE) = 1 << (pin % 32); - } - else - { - GPIO_REG_GPCLR1(GPIO_BASE) = 1 << (pin % 32); - } - - } -} - -static int raspi_pin_read(struct rt_device *device, rt_base_t pin) -{ - return 0; -} - -static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) -{ - return RT_EOK; -} - -static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin) -{ - return RT_EOK; -} - -rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) -{ - return RT_EOK; -} - -static const struct rt_pin_ops ops = -{ - raspi_pin_mode, - raspi_pin_write, - raspi_pin_read, - raspi_pin_attach_irq, - raspi_pin_detach_irq, - raspi_pin_irq_enable, - RT_NULL, -}; -#endif - -int rt_hw_gpio_init(void) -{ -#ifdef BSP_USING_PIN - rt_device_pin_register("gpio", &ops, RT_NULL); -#endif - - return 0; -} -INIT_DEVICE_EXPORT(rt_hw_gpio_init); diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_uart.c b/bsp/raspberry-pi/raspi4-64/driver/drv_uart.c deleted file mode 100644 index 6a70cdfb3a..0000000000 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_uart.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2006-2020, 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 "board.h" -#include "drv_uart.h" -#include "drv_gpio.h" - -struct hw_uart_device -{ - rt_ubase_t hw_base; - rt_uint32_t irqno; -}; - -static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) -{ - struct hw_uart_device *uart; - uint32_t bauddiv = (UART_REFERENCE_CLOCK / cfg->baud_rate)* 1000 / 16; - uint32_t ibrd = bauddiv / 1000; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - if(uart->hw_base == PL011_BASE) - { - uint32_t gpfsel = 0; - - gpfsel &= ~((uint32_t)(0x07 << (4 * 3))); - gpfsel |= (uint32_t)(ALT0 << (4 * 3)); - GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel; - - gpfsel &= ~((uint32_t)(0x07 << (5 * 3))); - gpfsel |= (uint32_t)(ALT0 << (5 * 3)); - GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel; - - PL011_REG_CR(uart->hw_base) = 0;/*Clear UART setting*/ - PL011_REG_LCRH(uart->hw_base) = 0;/*disable FIFO*/ - PL011_REG_IBRD(uart->hw_base) = ibrd; - PL011_REG_FBRD(uart->hw_base) = (((bauddiv - ibrd * 1000) * 64 + 500) / 1000); - PL011_REG_LCRH(uart->hw_base) = PL011_LCRH_WLEN_8;/*FIFO*/ - PL011_REG_CR(uart->hw_base) = PL011_CR_UARTEN | PL011_CR_TXE | PL011_CR_RXE;/*art enable, TX/RX enable*/ - } - - return RT_EOK; -} - -static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) -{ - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - /* disable rx irq */ - PL011_REG_IMSC(uart->hw_base) &= ~((uint32_t)PL011_IMSC_RXIM); - rt_hw_interrupt_mask(uart->irqno); - break; - - case RT_DEVICE_CTRL_SET_INT: - /* enable rx irq */ - PL011_REG_IMSC(uart->hw_base) |= PL011_IMSC_RXIM; - rt_hw_interrupt_umask(uart->irqno); - break; - } - - return RT_EOK; -} - -static int uart_putc(struct rt_serial_device *serial, char c) -{ - struct hw_uart_device *uart; - - 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; - - return 1; -} - -static int uart_getc(struct rt_serial_device *serial) -{ - int ch = -1; - struct hw_uart_device *uart; - - 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) - { - ch = PL011_REG_DR(uart->hw_base) & 0xff; - } - - return ch; -} - -static const struct rt_uart_ops _uart_ops = -{ - uart_configure, - uart_control, - uart_putc, - uart_getc, -}; - -static void rt_hw_uart_isr(int irqno, void *param) -{ - struct rt_serial_device *serial = (struct rt_serial_device*)param; - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); - PL011_REG_ICR(UART0_BASE) = PL011_INTERRUPT_RECEIVE; -} - - -/* UART device driver structure */ -static struct hw_uart_device _uart0_device = -{ - PL011_BASE, - IRQ_PL011, -}; - -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; - - _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"); - - return 0; -} diff --git a/bsp/raspberry-pi/raspi4-64/driver/raspi4.h b/bsp/raspberry-pi/raspi4-64/driver/raspi4.h deleted file mode 100644 index 3f18353904..0000000000 --- a/bsp/raspberry-pi/raspi4-64/driver/raspi4.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __RASPI4_H__ -#define __RASPI4_H__ - -//gpio -#define GPIO_BASE (0xFE000000 + 0x00200000) - -//uart -#define UART0_BASE (0xFE000000 + 0x00201000) -#define PL011_BASE UART0_BASE -#define IRQ_PL011 (121 + 32) -#define UART_REFERENCE_CLOCK (48000000) - -// 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) - -//gic max -#define ARM_GIC_NR_IRQS (512) -#define INTC_BASE (0xff800000) -#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_PL400_DISTRIBUTOR_PPTR GIC_V2_DISTRIBUTOR_BASE -#define GIC_PL400_CONTROLLER_PPTR GIC_V2_CPU_INTERFACE_BASE - -#endif diff --git a/bsp/raspberry-pi/raspi4-64/driver/Kconfig b/bsp/raspberry-pi/raspi4-64/drivers/Kconfig similarity index 70% rename from bsp/raspberry-pi/raspi4-64/driver/Kconfig rename to bsp/raspberry-pi/raspi4-64/drivers/Kconfig index 208b4b4300..5dca313513 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/Kconfig +++ b/bsp/raspberry-pi/raspi4-64/drivers/Kconfig @@ -14,6 +14,22 @@ 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 @@ -34,6 +50,25 @@ menu "Hardware Drivers Config" select RT_USING_PIN default y + menuconfig BSP_USING_SPI + bool "Enable SPI" + select RT_USING_SPI + default n + + if BSP_USING_SPI + config BSP_USING_SPI0_BUS + bool "Enable SPI0 BUS" + default n + config BSP_USING_SPI0_DEVICE0 + bool "Enable SPI0 DEVICE0" + select BSP_USING_SPI0_BUS + default n + config BSP_USING_SPI0_DEVICE1 + bool "Enable SPI0 DEVICE1" + select BSP_USING_SPI0_BUS + default n + endif + config BSP_USING_CORETIMER bool "Using core timer" select RT_USING_CORETIMER diff --git a/bsp/qemu-vexpress-a53/SConscript b/bsp/raspberry-pi/raspi4-64/drivers/SConscript similarity index 49% rename from bsp/qemu-vexpress-a53/SConscript rename to bsp/raspberry-pi/raspi4-64/drivers/SConscript index c7ef7659ec..64c764c1b3 100644 --- a/bsp/qemu-vexpress-a53/SConscript +++ b/bsp/raspberry-pi/raspi4-64/drivers/SConscript @@ -1,14 +1,19 @@ -# for module compiling -import os from building import * -cwd = GetCurrentDir() -objs = [] +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('driver', src, depend = [''], CPPPATH = CPPPATH) + +# build for sub-directory list = os.listdir(cwd) +objs = [] 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')) +group = group + objs -Return('objs') +Return('group') diff --git a/bsp/raspberry-pi/raspi4-64/drivers/board.c b/bsp/raspberry-pi/raspi4-64/drivers/board.c new file mode 100644 index 0000000000..e5960b0fa5 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/board.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-04-16 bigmagic first version + */ + +#include +#include + +#include "board.h" +#include "drv_uart.h" + +#include "cp15.h" +#include "mmu.h" +#include "mbox.h" + +#ifdef RT_USING_USERSPACE +#include +#include +#endif + +rt_mmu_info mmu_info; +extern size_t MMUTable[]; + +size_t gpio_base_addr = GPIO_BASE_ADDR; + +size_t uart_base_addr = UART_BASE; + +size_t gic_base_addr = GIC_V2_BASE; + +size_t arm_timer_base = ARM_TIMER_BASE; + +size_t pactl_cs_base = PACTL_CS_ADDR; + +size_t stimer_base_addr = STIMER_BASE; + +size_t mmc2_base_addr = MMC2_BASE_ADDR; + +size_t videocore_mbox = VIDEOCORE_MBOX; + +size_t mbox_addr = MBOX_ADDR; + +size_t wdt_base_addr = WDT_BASE; + +void* mac_reg_base_addr = (void *)MAC_REG; + +void* eth_send_no_cache = (void *)SEND_DATA_NO_CACHE; +void* eth_recv_no_cache = (void *)RECV_DATA_NO_CACHE; + +#ifdef RT_USING_USERSPACE +struct mem_desc platform_mem_desc[] = { + {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM} +}; +#else +struct mem_desc platform_mem_desc[] = { + {0x0, 0x6400000, 0x0, NORMAL_MEM}, + {0xFE000000, 0xFE400000, 0xFE000000, DEVICE_MEM},//uart gpio + {0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM} //gic +}; +#endif + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]); + +void rt_hw_timer_isr(int vector, void *parameter) +{ + ARM_TIMER_IRQCLR = 1; + rt_tick_increase(); +} + +void rt_hw_timer_init(void) +{ + rt_uint32_t apb_clock = 0; + rt_uint32_t timer_clock = 1000000; + + /* timer_clock = apb_clock/(pre_divider + 1) */ + apb_clock = bcm271x_mbox_clock_get_rate(CORE_CLK_ID); + ARM_TIMER_PREDIV = (apb_clock/timer_clock - 1); + + ARM_TIMER_CTRL = 0; + ARM_TIMER_IRQCLR = 1; + ARM_TIMER_RELOAD = 0; + ARM_TIMER_LOAD = 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); +} + +void idle_wfi(void) +{ + //rt_ubase_t level; + asm volatile ("wfi"); + //level = rt_hw_interrupt_disable(); + //gic_dump(); + //rt_hw_interrupt_enable(level); +} + +/** + * This function will initialize board + */ + +rt_mmu_info mmu_info; + +extern size_t MMUTable[]; + +#ifdef RT_USING_USERSPACE +rt_region_t init_page_region = { + PAGE_START, + PAGE_END, +}; +#endif + +/** + * Initialize the Hardware related stuffs. Called from rtthread_startup() + * after interrupt disabled. + */ +void rt_hw_board_init(void) +{ + /* io device remap */ +#ifdef RT_USING_USERSPACE + rt_page_init(init_page_region); + rt_hw_mmu_setup(platform_mem_desc, platform_mem_desc_size); + + rt_hw_mmu_map_init(&mmu_info, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET); + + arch_kuser_init(&mmu_info, (void*)0xffffffffffff0000); +#else + rt_hw_mmu_map_init(&mmu_info, (void*)GPIO_BASE_ADDR, 0x10000000, MMUTable, 0); +#endif + /* map peripheral address to virtual address */ +#ifdef RT_USING_HEAP + /* initialize system heap */ + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif + + /* initialize hardware interrupt */ + rt_hw_interrupt_init(); + + //gpio + gpio_base_addr = (size_t)rt_ioremap((void*)GPIO_BASE_ADDR, 0x1000); + //uart + //uart_base_addr = (size_t)rt_ioremap((void*)UART_BASE, 0x1000); + //aux + //aux_addr = (size_t)rt_ioremap((void*)AUX_BASE_ADDR, 0x1000); + //timer + arm_timer_base = (size_t)rt_ioremap((void*)ARM_TIMER_BASE, 0x1000); + //gic + //gic_base_addr = (size_t)rt_ioremap((void*)GIC_V2_BASE, 0x10000); + //pactl + pactl_cs_base = (size_t)rt_ioremap((void*)PACTL_CS_ADDR, 0x1000); + + //stimer + stimer_base_addr = (size_t)rt_ioremap((void*)STIMER_BASE, 0x1000); + + //mmc2_base_addr + mmc2_base_addr = (size_t)rt_ioremap((void*)MMC2_BASE_ADDR, 0x1000); + + //mbox + videocore_mbox = (size_t)rt_ioremap((void*)VIDEOCORE_MBOX, 0x1000); + + //mbox msg + mbox_addr = (size_t)rt_ioremap((void*)MBOX_ADDR, 0x1000); + mbox = (volatile unsigned int *)mbox_addr; + + //wdt + wdt_base_addr = (size_t)rt_ioremap((void*)WDT_BASE, 0x1000); + + //mac + mac_reg_base_addr = (void *)rt_ioremap((void*)MAC_REG, 0x80000); + + //eth data + eth_send_no_cache = (void *)rt_ioremap((void*)SEND_DATA_NO_CACHE, 0x200000); + eth_recv_no_cache = (void *)rt_ioremap((void*)RECV_DATA_NO_CACHE, 0x200000); + + /* initialize uart */ + rt_hw_uart_init(); + + /* initialize timer for os tick */ + rt_hw_timer_init(); + +#ifdef RT_USING_CONSOLE + /* set console device */ + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif /* RT_USING_CONSOLE */ + + rt_kprintf("heap: 0x%08x - 0x%08x\n", HEAP_BEGIN, HEAP_END); + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + rt_thread_idle_sethook(idle_wfi); +} + +#ifdef RT_USING_GDBSERVER +#include + +#define GDB_CONNECT_DEVICE "/dev/uart4" + +/* for gdb */ +int gdb_com_open(void) +{ + return open(GDB_CONNECT_DEVICE, O_RDWR); +} + +void gdb_com_close(int fd) +{ + close(fd); +} + +ssize_t gdb_com_read(int fd, void *buff, size_t len) +{ + return read(fd, buff, len); +} + +ssize_t gdb_com_write(int fd, void *buff, size_t len) +{ + return write(fd, buff, len); +} + +#endif diff --git a/bsp/raspberry-pi/raspi4-64/driver/board.h b/bsp/raspberry-pi/raspi4-64/drivers/board.h similarity index 45% rename from bsp/raspberry-pi/raspi4-64/driver/board.h rename to bsp/raspberry-pi/raspi4-64/drivers/board.h index d675cc658e..64e79dc50a 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/board.h +++ b/bsp/raspberry-pi/raspi4-64/drivers/board.h @@ -13,13 +13,22 @@ #include #include "raspi4.h" +#include "mmu.h" +#include "ioremap.h" -extern unsigned char __bss_start; -extern unsigned char __bss_end; +extern int __bss_end; +#define HEAP_BEGIN ((void*)&__bss_end) -#define RT_HW_HEAP_BEGIN (void*)&__bss_end -#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024) +#ifdef RT_USING_USERSPACE +#define HEAP_END ((size_t)KERNEL_VADDR_START + 16 * 1024 * 1024) +#define PAGE_START HEAP_END +#define PAGE_END ((size_t)KERNEL_VADDR_START + 128 * 1024 * 1024) +#else +#define HEAP_END ((size_t)0x60000000 + 64 * 1024 * 1024) +#endif void rt_hw_board_init(void); +extern rt_mmu_info mmu_info; + #endif diff --git a/bsp/raspberry-pi/raspi4-64/drivers/drv_eth.c b/bsp/raspberry-pi/raspi4-64/drivers/drv_eth.c new file mode 100644 index 0000000000..29b598b1f5 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_eth.c @@ -0,0 +1,698 @@ + +/* + * Copyright (c) 2006-2020, 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 "mbox.h" +#include "raspi4.h" +#include "drv_eth.h" + +#define DBG_LEVEL DBG_LOG +#include +#define LOG_TAG "drv.eth" + +static int link_speed = 0; +static int link_flag = 0; + +#define RECV_CACHE_BUF (2048) +#define DMA_DISC_ADDR_SIZE (4 * 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)) + +static rt_thread_t link_thread_tid = RT_NULL; +#define LINK_THREAD_STACK_SIZE (8192) +#define LINK_THREAD_PRIORITY (20) +#define LINK_THREAD_TIMESLICE (10) + +static rt_uint32_t tx_index = 0; +static rt_uint32_t rx_index = 0; +static rt_uint32_t index_flag = 0; + +static rt_uint8_t send_cache_pbuf[RECV_CACHE_BUF]; +//static rt_uint8_t recv_data[RX_BUF_LENGTH]; + +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 sem_lock; +static struct rt_semaphore link_ack; + +static inline rt_uint32_t read32(void *addr) +{ + return (*((volatile unsigned int*)(addr))); +} + +static 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) + { + //todo + } +} + +/* 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; + val = MDIO_WR | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT) | (0xffff & value); + write32(mac_reg_base_addr + MDIO_CMD, val); + + rt_uint32_t 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) +{ + rt_uint32_t ret = 0; + /*get ethernet uid*/ + ret = get_ethernet_uid(); + if (ret == 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; + + 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; + } + + rt_uint32_t reg1 = read32(mac_reg_base_addr + EXT_RGMII_OOB_CTRL); + //reg1 &= ~(1UL << OOB_DISABLE); + + //rt_kprintf("OOB_DISABLE is %d\n", OOB_DISABLE); + 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(); + + /* Update 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 % 256; + + 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; + size_t addr = 0; + rt_uint32_t prod_index = read32(mac_reg_base_addr + RDMA_PROD_INDEX); + //get next + if(prod_index == index_flag) + { + cur_recv_cnt = index_flag; + index_flag = 0x7fffffff; + //no buff + return 0; + } + else + { + if(prev_recv_cnt == prod_index) + { + 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 + */ + *packetp = (rt_uint8_t *)(addr + RX_BUF_OFFSET); + + rx_index = rx_index + 1; + if(rx_index >= 256) + { + 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; + } +} + +static int bcmgenet_gmac_eth_send(void *packet, int length) +{ + rt_ubase_t level; + void *desc_base = (TX_DESC_BASE + tx_index * DMA_DESC_SIZE); + rt_uint32_t len_stat = length << DMA_BUFLENGTH_SHIFT; + + rt_uint32_t prod_index, cons; + rt_uint32_t tries = 100; + + prod_index = read32(mac_reg_base_addr + TDMA_PROD_INDEX); + + len_stat |= 0x3F << DMA_TX_QTAG_SHIFT; + len_stat |= DMA_TX_APPEND_CRC | DMA_SOP | DMA_EOP; + + write32((desc_base + DMA_DESC_ADDRESS_LO), SEND_DATA_NO_CACHE); + write32((desc_base + DMA_DESC_ADDRESS_HI), 0); + write32((desc_base + DMA_DESC_LENGTH_STATUS), len_stat); + + tx_index = tx_index == 255? 0 : tx_index + 1; + prod_index = prod_index + 1; + + if (prod_index == 0xe000) + { + write32(mac_reg_base_addr + TDMA_PROD_INDEX, 0); + prod_index = 0; + } + + /* Start Transmisson */ + write32(mac_reg_base_addr + TDMA_PROD_INDEX, prod_index); + + level = rt_hw_interrupt_disable(); + do + { + cons = read32(mac_reg_base_addr + TDMA_CONS_INDEX); + } while ((cons & 0xffff) < prod_index && --tries); + rt_hw_interrupt_enable(level); + + if (!tries) + { + rt_kprintf("send err! tries is %d\n", tries); + return -1; + } + + 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); + eth_device_linkchange(ð_dev.parent, RT_TRUE); //link up + rt_timer_stop(&dev->link_timer); + + //set mac + // bcmgenet_gmac_write_hwaddr(); + 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"); + } + + 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) +{ + size_t sendbuf = (size_t)eth_send_no_cache; + /* lock eth device */ + if (link_flag == 1) + { + rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + pbuf_copy_partial(p, (void *)&send_cache_pbuf[0], p->tot_len, 0); + rt_memcpy((void *)sendbuf, send_cache_pbuf, p->tot_len); + + bcmgenet_gmac_eth_send((void *)sendbuf, p->tot_len); + rt_sem_release(&sem_lock); + } + return RT_EOK; +} + +struct pbuf *rt_eth_rx(rt_device_t device) +{ + int recv_len = 0; + size_t addr_point[8]; + struct pbuf *pbuf = RT_NULL; + if (link_flag == 1) + { + rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + recv_len = bcmgenet_gmac_eth_recv((rt_uint8_t **)&addr_point[0]); + if (recv_len > 0) + { + pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM); + //calc offset + addr_point[0] = (size_t)(addr_point[0] + (eth_recv_no_cache - RECV_DATA_NO_CACHE)); + rt_memcpy(pbuf->payload, (char *)addr_point[0], recv_len); + } + rt_sem_release(&sem_lock); + } + return pbuf; +} + +int rt_hw_eth_init(void) +{ + rt_uint8_t mac_addr[6]; + + rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO); + rt_sem_init(&link_ack, "link_ack", 0, RT_IPC_FLAG_FIFO); + + memset(ð_dev, 0, sizeof(eth_dev)); + memset((void *)eth_send_no_cache, 0, sizeof(DMA_DISC_ADDR_SIZE)); + memset((void *)eth_recv_no_cache, 0, sizeof(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"); + eth_device_linkchange(ð_dev.parent, RT_FALSE); //link down + return 0; +} +INIT_COMPONENT_EXPORT(rt_hw_eth_init); diff --git a/bsp/raspberry-pi/raspi4-64/drivers/drv_eth.h b/bsp/raspberry-pi/raspi4-64/drivers/drv_eth.h new file mode 100644 index 0000000000..860674847a --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_eth.h @@ -0,0 +1,224 @@ + +/* + * Copyright (c) 2006-2020, 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 BIT(nr) (1UL << (nr)) + +#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/drivers/drv_gpio.c b/bsp/raspberry-pi/raspi4-64/drivers/drv_gpio.c new file mode 100644 index 0000000000..b9f6689ae3 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_gpio.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-04-16 bigmagic first version + * 2020-06-16 bigmagic add gpio irq + */ + +#include "drv_gpio.h" + +#ifdef BSP_USING_PIN + +/* + * gpio_int[0] for BANK0 (pins 0-27) + * gpio_int[1] for BANK1 (pins 28-45) + * gpio_int[2] for BANK2 (pins 46-53) + */ +static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM]; + +uint32_t raspi_get_pin_state(uint32_t fselnum) +{ + uint32_t gpfsel = 0; + + switch (fselnum) + { + case 0: + gpfsel = GPIO_REG_GPFSEL0(gpio_base_addr); + break; + case 1: + gpfsel = GPIO_REG_GPFSEL1(gpio_base_addr); + break; + case 2: + gpfsel = GPIO_REG_GPFSEL2(gpio_base_addr); + break; + case 3: + gpfsel = GPIO_REG_GPFSEL3(gpio_base_addr); + break; + case 4: + gpfsel = GPIO_REG_GPFSEL4(gpio_base_addr); + break; + case 5: + gpfsel = GPIO_REG_GPFSEL5(gpio_base_addr); + 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_addr) = gpfsel; + break; + case 1: + GPIO_REG_GPFSEL1(gpio_base_addr) = gpfsel; + break; + case 2: + GPIO_REG_GPFSEL2(gpio_base_addr) = gpfsel; + break; + case 3: + GPIO_REG_GPFSEL3(gpio_base_addr) = gpfsel; + break; + case 4: + GPIO_REG_GPFSEL4(gpio_base_addr) = gpfsel; + break; + case 5: + GPIO_REG_GPFSEL5(gpio_base_addr) = gpfsel; + break; + default: + break; + } +} + +static void gpio_set_pud(GPIO_PIN pin, GPIO_PUPD_FUNC mode) +{ + uint32_t fselnum = pin / 16; + uint32_t fselrest = pin % 16; + uint32_t reg_value = 0; + + switch (fselnum) + { + case 0: + reg_value = GPIO_PUP_PDN_CNTRL_REG0(gpio_base_addr); + GPIO_PUP_PDN_CNTRL_REG0(gpio_base_addr) = (reg_value | (mode << (fselrest*2))); + break; + case 1: + reg_value = GPIO_PUP_PDN_CNTRL_REG1(gpio_base_addr); + GPIO_PUP_PDN_CNTRL_REG1(gpio_base_addr) = (reg_value | (mode << (fselrest*2))); + break; + + case 2: + reg_value = GPIO_PUP_PDN_CNTRL_REG2(gpio_base_addr); + GPIO_PUP_PDN_CNTRL_REG2(gpio_base_addr) = (reg_value | (mode << (fselrest*2))); + break; + + case 3: + reg_value = GPIO_PUP_PDN_CNTRL_REG3(gpio_base_addr); + GPIO_PUP_PDN_CNTRL_REG3(gpio_base_addr) = (reg_value | (mode << (fselrest*2))); + break; + default: + break; + } +} + +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); +} + +void prev_raspi_pin_write(GPIO_PIN pin, int pin_value) +{ + uint32_t num = pin / 32; + + if(num == 0) + { + if(pin_value == 1) + { + GPIO_REG_GPSET0(gpio_base_addr) = 1 << (pin % 32); + } + else + { + GPIO_REG_GPCLR0(gpio_base_addr) = 1 << (pin % 32); + } + } + else + { + if(pin_value == 1) + { + GPIO_REG_GPSET1(gpio_base_addr) = 1 << (pin % 32); + } + else + { + GPIO_REG_GPCLR1(gpio_base_addr) = 1 << (pin % 32); + } + + } +} + +static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode) +{ + GPIO_FUNC raspi_mode = OUTPUT; + + switch (mode) + { + case PIN_MODE_OUTPUT: + raspi_mode = OUTPUT; + break; + case PIN_MODE_INPUT: + raspi_mode = INPUT; + break; + case PIN_MODE_INPUT_PULLUP: + gpio_set_pud(pin, RASPI_PULL_UP); + raspi_mode = INPUT; + break; + case PIN_MODE_INPUT_PULLDOWN: + gpio_set_pud(pin, RASPI_PULL_DOWN); + raspi_mode = INPUT; + break; + case PIN_MODE_OUTPUT_OD: + raspi_mode = OUTPUT; + break; + } + prev_raspi_pin_mode((GPIO_PIN)pin, raspi_mode); +} + +static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value) +{ + prev_raspi_pin_write(pin, value); +} + +static int raspi_pin_read(struct rt_device *device, rt_base_t pin) +{ + uint32_t num = pin / 32; + uint32_t pin_level = 0; + + if(num == 0) + { + if(GPIO_REG_GPLEV0(gpio_base_addr) & (1 << pin)) + { + pin_level = 1; + } + else + { + pin_level = 0; + } + + } + else + { + if(GPIO_REG_GPLEV1(gpio_base_addr) & (1 << pin)) + { + pin_level = 1; + } + else + { + pin_level = 0; + } + } + + return pin_level; +} + +static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) +{ + rt_uint8_t index; + rt_uint32_t reg_value; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + _g_gpio_irq_tbl[index].irq_cb[pin] = hdr; + _g_gpio_irq_tbl[index].irq_arg[pin] = args; + _g_gpio_irq_tbl[index].irq_type[pin] = mode; + + rt_uint8_t shift = pin % 32; + rt_uint8_t pin_num = pin / 32; + rt_uint32_t mask = 1 << shift; + + switch (mode) + { + case PIN_IRQ_MODE_RISING: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPREN0(gpio_base_addr); + GPIO_REG_GPREN0(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPREN1(gpio_base_addr); + GPIO_REG_GPREN1(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + break; + case PIN_IRQ_MODE_FALLING: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPFEN0(gpio_base_addr); + GPIO_REG_GPFEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPFEN1(gpio_base_addr); + GPIO_REG_GPFEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + break; + case PIN_IRQ_MODE_RISING_FALLING: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPAREN0(gpio_base_addr); + GPIO_REG_GPAREN0(gpio_base_addr) = (reg_value & ~ mask) | (mask); + reg_value = GPIO_REG_GPFEN0(gpio_base_addr); + GPIO_REG_GPFEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPAREN1(gpio_base_addr); + GPIO_REG_GPAREN1(gpio_base_addr) = (reg_value & ~ mask) | (mask); + reg_value = GPIO_REG_GPFEN1(gpio_base_addr); + GPIO_REG_GPFEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + break; + case PIN_IRQ_MODE_HIGH_LEVEL: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPHEN0(gpio_base_addr); + GPIO_REG_GPHEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPHEN1(gpio_base_addr); + GPIO_REG_GPHEN1(gpio_base_addr) = (reg_value & ~ mask) | ( mask); + } + break; + case PIN_IRQ_MODE_LOW_LEVEL: + if(pin_num == 0) + { + reg_value = GPIO_REG_GPLEN0(gpio_base_addr); + GPIO_REG_GPLEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + else + { + reg_value = GPIO_REG_GPLEN1(gpio_base_addr); + GPIO_REG_GPLEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask); + } + break; + } + return RT_EOK; +} + +static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + rt_uint8_t index; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + + _g_gpio_irq_tbl[index].irq_cb[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL; + _g_gpio_irq_tbl[index].state[pin] = RT_NULL; + + return RT_EOK; +} + +rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +{ + rt_uint8_t index; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + + if (enabled) + _g_gpio_irq_tbl[index].state[pin] = 1; + else + _g_gpio_irq_tbl[index].state[pin] = 0; + + return RT_EOK; +} + +static const struct rt_pin_ops ops = +{ + raspi_pin_mode, + raspi_pin_write, + raspi_pin_read, + raspi_pin_attach_irq, + raspi_pin_detach_irq, + raspi_pin_irq_enable, + RT_NULL, +}; + +static void gpio_irq_handler(int irq, void *param) +{ + struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param; + rt_uint32_t pin; + rt_uint32_t value; + rt_uint32_t tmpvalue; + + if(irq == IRQ_GPIO0) + { + /* 0~27 */ + value = GPIO_REG_GPEDS0(gpio_base_addr); + value &= 0x0fffffff; + pin = 0; + GPIO_REG_GPEDS0(gpio_base_addr) = value; + } + else if(irq == IRQ_GPIO1) + { + /* 28-45 */ + tmpvalue = GPIO_REG_GPEDS0(gpio_base_addr); + tmpvalue &= (~0x0fffffff); + GPIO_REG_GPEDS0(gpio_base_addr) = tmpvalue; + + value = GPIO_REG_GPEDS1(gpio_base_addr); + value &= 0x3fff; + GPIO_REG_GPEDS1(gpio_base_addr) = value; + value = (value) | tmpvalue; + pin = 28; + } + else if (irq == IRQ_GPIO2) + { + /* 46-53 */ + value = GPIO_REG_GPEDS1(gpio_base_addr); + value &= (~0x3fff); + GPIO_REG_GPEDS1(gpio_base_addr) = value; + pin = 46; + } + + while (value) + { + if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL)) + { + if(irq_def->state[pin]) + { + irq_def->irq_cb[pin](irq_def->irq_arg[pin]); + } + } + pin++; + value = value >> 1; + } +} +#endif + +int rt_hw_gpio_init(void) +{ +#ifdef BSP_USING_PIN + rt_device_pin_register("gpio", &ops, RT_NULL); + + //disable all intr + GPIO_REG_GPEDS0(gpio_base_addr) = 0xffffffff; + GPIO_REG_GPEDS1(gpio_base_addr) = 0xffffffff; + + GPIO_REG_GPREN0(gpio_base_addr) = 0x0; + GPIO_REG_GPREN1(gpio_base_addr) = 0x0; + + GPIO_REG_GPFEN0(gpio_base_addr) = 0x0; + GPIO_REG_GPFEN1(gpio_base_addr) = 0x0; + + GPIO_REG_GPHEN0(gpio_base_addr) = 0x0; + GPIO_REG_GPHEN1(gpio_base_addr) = 0x0; + + GPIO_REG_GPAREN0(gpio_base_addr) = 0x0; + GPIO_REG_GPAREN1(gpio_base_addr) = 0x0; + + GPIO_REG_GPAFEN0(gpio_base_addr) = 0x0; + GPIO_REG_GPAFEN0(gpio_base_addr) = 0x0; + + rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq"); + rt_hw_interrupt_umask(IRQ_GPIO0); + + rt_hw_interrupt_install(IRQ_GPIO1, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq"); + rt_hw_interrupt_umask(IRQ_GPIO1); + + rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq"); + rt_hw_interrupt_umask(IRQ_GPIO2); + +#endif + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_gpio_init); diff --git a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h b/bsp/raspberry-pi/raspi4-64/drivers/drv_gpio.h similarity index 70% rename from bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h rename to bsp/raspberry-pi/raspi4-64/drivers/drv_gpio.h index c4658fcebb..7594759f97 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_gpio.h +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_gpio.h @@ -17,6 +17,14 @@ #include "board.h" #include "interrupt.h" +struct gpio_irq_def +{ + void *irq_arg[32]; + void (*irq_cb[32])(void *param); + rt_uint8_t irq_type[32]; + rt_uint8_t state[32]; +}; + #define GPIO_REG_GPFSEL0(BASE) HWREG32(BASE + 0x00) #define GPIO_REG_GPFSEL1(BASE) HWREG32(BASE + 0x04) #define GPIO_REG_GPFSEL2(BASE) HWREG32(BASE + 0x08) @@ -59,6 +67,54 @@ #define GPIO_REG_GPPUDCLK1(BASE) HWREG32(BASE + 0x9C) #define GPIO_REG_REV9(BASE) HWREG32(BASE + 0xA0) #define GPIO_REG_TEST(BASE) HWREG32(BASE + 0xA4) +#define GPIO_PUP_PDN_CNTRL_REG0(BASE) HWREG32(BASE + 0xE4) +#define GPIO_PUP_PDN_CNTRL_REG1(BASE) HWREG32(BASE + 0xE8) +#define GPIO_PUP_PDN_CNTRL_REG2(BASE) HWREG32(BASE + 0xEC) +#define GPIO_PUP_PDN_CNTRL_REG3(BASE) HWREG32(BASE + 0xF0) + +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, @@ -71,7 +127,14 @@ typedef enum { ALT5 = 0b010 } GPIO_FUNC; +typedef enum { + RASPI_NO_RESISTOR = 0x00, + RASPI_PULL_UP = 0x01, + RASPI_PULL_DOWN = 0x10 +} GPIO_PUPD_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/drivers/drv_hdmi.c b/bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.c new file mode 100644 index 0000000000..d51ab2898e --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-26 bigmagic first version + */ + +#include +#include +#include "mbox.h" +#include "drv_hdmi.h" + +#ifdef BSP_USING_HDMI +#define LCD_WIDTH (800) +#define LCD_HEIGHT (480) +#define LCD_DEPTH (32) +#define LCD_BPP (32) + +#define TAG_ALLOCATE_BUFFER 0x00040001 +#define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003 +#define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004 +#define TAG_SET_DEPTH 0x00048005 +#define TAG_SET_PIXEL_ORDER 0x00048006 +#define TAG_GET_PITCH 0x00040008 +#define TAG_SET_VIRT_OFFSET 0x00048009 +#define TAG_END 0x00000000 + + +enum { + MBOX_TAG_FB_GET_GPIOVIRT = 0x00040010, + MBOX_TAG_FB_ALLOCATE_BUFFER = 0x00040001, + MBOX_TAG_FB_RELEASE_BUFFER = 0x00048001, + MBOX_TAG_FB_BLANK_SCREEN = 0x00040002, + MBOX_TAG_FB_GET_PHYS_WH = 0x00040003, + MBOX_TAG_FB_TEST_PHYS_WH = 0x00044003, + MBOX_TAG_FB_SET_PHYS_WH = 0x00048003, + MBOX_TAG_FB_GET_VIRT_WH = 0x00040004, + MBOX_TAG_FB_TEST_VIRT_WH = 0x00044004, + MBOX_TAG_FB_SET_VIRT_WH = 0x00048004, + MBOX_TAG_FB_GET_DEPTH = 0x00040005, + MBOX_TAG_FB_TEST_DEPTH = 0x00044005, + MBOX_TAG_FB_SET_DEPTH = 0x00048005, + MBOX_TAG_FB_GET_PIXEL_ORDER = 0x00040006, + MBOX_TAG_FB_TEST_PIXEL_ORDER = 0x00044006, + MBOX_TAG_FB_SET_PIXEL_ORDER = 0x00048006, + MBOX_TAG_FB_GET_ALPHA_MODE = 0x00040007, + MBOX_TAG_FB_TEST_ALPHA_MODE = 0x00044007, + MBOX_TAG_FB_SET_ALPHA_MODE = 0x00048007, + MBOX_TAG_FB_GET_PITCH = 0x00040008, + MBOX_TAG_FB_GET_VIRT_OFFSET = 0x00040009, + MBOX_TAG_FB_TEST_VIRT_OFFSET = 0x00044009, + MBOX_TAG_FB_SET_VIRT_OFFSET = 0x00048009, + MBOX_TAG_FB_GET_OVERSCAN = 0x0004000a, + MBOX_TAG_FB_TEST_OVERSCAN = 0x0004400a, + MBOX_TAG_FB_SET_OVERSCAN = 0x0004800a, + MBOX_TAG_FB_GET_PALETTE = 0x0004000b, + MBOX_TAG_FB_TEST_PALETTE = 0x0004400b, + MBOX_TAG_FB_SET_PALETTE = 0x0004800b, +}; + +#define LCD_DEVICE(dev) (struct rt_hdmi_fb_device*)(dev) + +static struct rt_hdmi_fb_device _hdmi; + +typedef rt_uint16_t color_t; + +rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +rt_err_t hdmi_fb_close(rt_device_t dev) +{ + return RT_EOK; +} + +rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size) +{ + return 0; +} + +rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + return size; +} + +rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args) +{ + struct rt_hdmi_fb_device *lcd = LCD_DEVICE(dev); + switch (cmd) + { + case RTGRAPHIC_CTRL_RECT_UPDATE: + { + struct rt_device_rect_info *info = (struct rt_device_rect_info*)args; + info = info; + } + break; + + case RTGRAPHIC_CTRL_GET_INFO: + { + struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args; + + RT_ASSERT(info != RT_NULL); + info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888; + info->bits_per_pixel= LCD_DEPTH; + info->width = lcd->width; + info->height = lcd->height; + info->framebuffer = lcd->fb; + } + break; + } + return RT_EOK; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops hdmi_fb_ops = +{ + RT_NULL, + hdmi_fb_open, + hdmi_fb_close, + hdmi_fb_read, + hdmi_fb_write, + hdmi_fb_control, +}; +#endif + +rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name) +{ + struct rt_device *device; + RT_ASSERT(hdmi_fb != RT_NULL); + + device = &hdmi_fb->parent; + + /* set device type */ + device->type = RT_Device_Class_Graphic; + /* initialize device interface */ +#ifdef RT_USING_DEVICE_OPS + device->ops = &hdmi_fb_ops; +#else + device->init = RT_NULL; + device->open = hdmi_fb_open; + device->close = hdmi_fb_close; + device->read = hdmi_fb_read; + device->write = hdmi_fb_write; + device->control = hdmi_fb_control; +#endif + + /* register to device manager */ + rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); + + return RT_EOK; +} + +rt_uint32_t bcm271x_mbox_fb_get_gpiovirt(void) +{ + mbox[0] = 8*4; // length of the message + mbox[1] = MBOX_REQUEST; // this is a request message + + mbox[2] = MBOX_TAG_FB_GET_GPIOVIRT; + 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 (mbox[5] & 0x3fffffff); +} + +rt_uint32_t bcm271x_mbox_fb_get_pitch(void) +{ + mbox[0] = 8*4; // length of the message + mbox[1] = MBOX_REQUEST; // this is a request message + + mbox[2] = MBOX_TAG_FB_GET_PITCH; + 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 mbox[5]; +} + +void bcm271x_mbox_fb_set_porder(int rgb) +{ + mbox[0] = 8*4; // length of the message + mbox[1] = MBOX_REQUEST; // this is a request message + + mbox[2] = MBOX_TAG_FB_SET_PIXEL_ORDER; + mbox[3] = 4; // buffer size + mbox[4] = 4; // len + + mbox[5] = rgb; // id + mbox[6] = 0; + + mbox[7] = MBOX_TAG_LAST; + mbox_call(8, MMU_DISABLE); +} + +void bcm271x_mbox_fb_setoffset(int xoffset, int yoffset) +{ + mbox[0] = 8*4; // length of the message + mbox[1] = MBOX_REQUEST; // this is a request message + + mbox[2] = MBOX_TAG_FB_SET_VIRT_OFFSET; + mbox[3] = 8; // buffer size + mbox[4] = 8; // len + + mbox[5] = xoffset; // id + mbox[6] = yoffset; + + mbox[7] = MBOX_TAG_LAST; + mbox_call(8, MMU_DISABLE); +} + + +void bcm271x_mbox_fb_setalpha(int alpha) +{ + + mbox[0] = 8*4; // length of the message + mbox[1] = MBOX_REQUEST; // this is a request message + + mbox[2] = MBOX_TAG_FB_SET_ALPHA_MODE; + mbox[3] = 4; // buffer size + mbox[4] = 4; // len + + mbox[5] = alpha; // id + mbox[6] = 0; + + mbox[7] = MBOX_TAG_LAST; + mbox_call(8, MMU_DISABLE); +} + +void *bcm271x_mbox_fb_alloc(int width, int height, int bpp, int nrender) +{ + mbox[0] = 4 * 35; + mbox[1] = MBOX_REQUEST; + + mbox[2] = TAG_ALLOCATE_BUFFER;//get framebuffer, gets alignment on request + mbox[3] = 8; //size + mbox[4] = 4; //len + mbox[5] = 4096; //The design of MBOX driver forces us to give the virtual address 0x3C100000 + mbox[6] = 0; //FrameBufferInfo.size + + mbox[7] = TAG_SET_PHYS_WIDTH_HEIGHT; + mbox[8] = 8; + mbox[9] = 8; + mbox[10] = width; + mbox[11] = height; + + mbox[12] = TAG_SET_VIRT_WIDTH_HEIGHT; + mbox[13] = 8; + mbox[14] = 8; + mbox[15] = width; + mbox[16] = height * nrender; + + mbox[17] = TAG_SET_DEPTH; + mbox[18] = 4; + mbox[19] = 4; + mbox[20] = bpp; + + mbox[21] = TAG_SET_PIXEL_ORDER; + mbox[22] = 4; + mbox[23] = 0; + mbox[24] = 0; //RGB, not BGR preferably + + mbox[25] = TAG_GET_PITCH; + mbox[26] = 4; + mbox[27] = 0; + mbox[28] = 0; + + mbox[29] = TAG_SET_VIRT_OFFSET; + mbox[30] = 8; + mbox[31] = 8; + mbox[32] = 0; + mbox[33] = 0; + + mbox[34] = TAG_END; + + mbox_call(8, MMU_DISABLE); + return (void *)((size_t)(mbox[5] & 0x3fffffff)); +} + +int hdmi_fb_init(void) +{ + _hdmi.fb = (rt_uint8_t *)bcm271x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1); + bcm271x_mbox_fb_setoffset(0, 0); + bcm271x_mbox_fb_set_porder(0); + _hdmi.width = LCD_WIDTH; + _hdmi.height = LCD_HEIGHT; + _hdmi.depth = LCD_DEPTH; + _hdmi.pitch = 0; + _hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888; + + //rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb); + rt_hdmi_fb_device_init(&_hdmi, "lcd"); + + return 0; +} + +INIT_DEVICE_EXPORT(hdmi_fb_init); +#endif /*BSP_USING_HDMI */ diff --git a/bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.h b/bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.h new file mode 100644 index 0000000000..c9a06358d0 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_hdmi.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-26 bigmagic first version + */ +#ifndef __DRV_HDMI_H__ +#define __DRV_HDMI_H__ + +#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b))) + +struct rt_hdmi_fb_device +{ + struct rt_device parent; + + rt_uint32_t width; + rt_uint32_t height; + rt_uint32_t depth; + rt_uint32_t pitch; + rt_uint32_t pixel_format; + + rt_uint8_t *fb; +}; +#endif/* __DRV_HDMI_H__ */ diff --git a/bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.c b/bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.c new file mode 100644 index 0000000000..9b03519fe8 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.c @@ -0,0 +1,651 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-27 bigmagic first version + */ + +#include "mbox.h" +#include "raspi4.h" +#include "drv_sdio.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) +}; + +static inline rt_uint32_t read32(size_t addr) +{ + return (*((volatile unsigned int*)(addr))); +} + +static inline void write32(size_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; + + 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 + int divisor = -1; + 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; + + //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); + int cnt = 10000; + do + { + DELAY_MICROS(10); + cnt = cnt - 1; + 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); + //usleep(2000); + + + // Check for a valid card + mmcsd_dbg("EMMC: checking for an inserted card\n"); + cnt = 10000; + do + { + DELAY_MICROS(10); + cnt = cnt - 1; + 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 //12 + 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) +{ + rt_kprintf("EMMC registers:"); + int i = EMMC_ARG2; + 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/drivers/drv_sdio.h b/bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.h new file mode 100644 index 0000000000..1abedf2a0b --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2006-2020, 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) // | SD_CMD_CRCCHK_EN) +#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B) // | SD_CMD_CRCCHK_EN) +#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136) // | SD_CMD_CRCCHK_EN) +#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/drivers/drv_spi.c b/bsp/raspberry-pi/raspi4-64/drivers/drv_spi.c new file mode 100644 index 0000000000..d072869048 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_spi.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-22 bigmagic first version + */ +#include +#include +#include + +#include "raspi4.h" +#include "drv_spi.h" + +#ifdef BSP_USING_SPI + +#define RPI_CORE_CLK_HZ (250000000) +#define BSP_SPI_MAX_HZ (30* 1000 *1000) +#define SPITIMEOUT 0x0FFF + +static rt_uint8_t raspi_byte_reverse_table[] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +#if defined (BSP_USING_SPI0_BUS) +#define SPI0_BUS_NAME "spi0" +#define SPI0_DEVICE0_NAME "spi0.0" +#define SPI0_DEVICE1_NAME "spi0.1" + +struct rt_spi_bus spi0_bus; + +#if defined (BSP_USING_SPI0_DEVICE0) +static struct rt_spi_device spi0_device0; +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) +static struct rt_spi_device spi0_device1; +#endif +#endif + +static rt_err_t raspi_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg) +{ + RT_ASSERT(cfg != RT_NULL); + RT_ASSERT(device != RT_NULL); + rt_uint16_t divider; + struct raspi_spi_device* hw_config = (struct raspi_spi_device *)(device->parent.user_data); + struct raspi_spi_hw_config *hwcfg = (struct raspi_spi_hw_config *)hw_config->spi_hw_config; + // spi clear fifo + SPI_REG_CS(hwcfg->hw_base) = (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX); + if(cfg->mode & RT_SPI_CPOL) + { + SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CPOL; + } + + if(cfg->mode & RT_SPI_CPHA) + { + SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CPHA; + } + + if(cfg->mode & RT_SPI_CS_HIGH) + { + SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CSPOL_HIGH; + } + + //set clk + if (cfg->max_hz > BSP_SPI_MAX_HZ) + cfg->max_hz = BSP_SPI_MAX_HZ; + + divider = (rt_uint16_t) ((rt_uint32_t) RPI_CORE_CLK_HZ / cfg->max_hz); + divider &= 0xFFFE; + + SPI_REG_CLK(hwcfg->hw_base) = divider; + + return RT_EOK; +} + +rt_uint8_t correct_order(rt_uint8_t b, rt_uint8_t flag) +{ + if (flag) + return raspi_byte_reverse_table[b];//reverse + else + return b; +} + +static rt_err_t spi_transfernb(struct raspi_spi_hw_config *hwcfg, rt_uint8_t* tbuf, rt_uint8_t* rbuf, rt_uint32_t len, rt_uint8_t flag) +{ + rt_uint32_t TXCnt=0; + rt_uint32_t RXCnt=0; + + /* Clear TX and RX fifos */ + SPI_REG_CS(hwcfg->hw_base) |= (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX); + + /* Set TA = 1 */ + SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_TA; + + /* Use the FIFO's to reduce the interbyte times */ + while ((TXCnt < len) || (RXCnt < len)) + { + /* TX fifo not full, so add some more bytes */ + while (((SPI_REG_CS(hwcfg->hw_base) & SPI_CS_TX_DATA)) && (TXCnt < len)) + { + SPI_REG_FIFO(hwcfg->hw_base) = correct_order(tbuf[TXCnt],flag); + TXCnt++; + } + /* Rx fifo not empty, so get the next received bytes */ + while (((SPI_REG_CS(hwcfg->hw_base) & SPI_CS_RX_DATA)) && (RXCnt < len)) + { + rbuf[RXCnt] = correct_order(SPI_REG_FIFO(hwcfg->hw_base), flag); + RXCnt++; + } + } + /* Wait for DONE to be set */ + while (!(SPI_REG_CS(hwcfg->hw_base) & SPI_CS_DONE)); + /* Set TA = 0, and also set the barrier */ + SPI_REG_CS(hwcfg->hw_base) |= (0 & SPI_CS_TA); + + return RT_EOK; +} + +static rt_uint32_t raspi_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + rt_err_t res; + rt_uint8_t flag; + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + RT_ASSERT(device->parent.user_data != RT_NULL); + RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL); + + struct rt_spi_configuration config = device->config; + struct raspi_spi_device * hw_config = (struct raspi_spi_device *)device->parent.user_data; + GPIO_PIN cs_pin = (GPIO_PIN)hw_config->cs_pin; + struct raspi_spi_hw_config *hwcfg = (struct raspi_spi_hw_config *)hw_config->spi_hw_config; + + if (config.mode & RT_SPI_MSB) + { + flag = 0; + } + else + { + flag = 1; + } + + if (message->cs_take) + { + (config.mode & RT_SPI_CS_HIGH)?prev_raspi_pin_write(cs_pin, 1):prev_raspi_pin_write(cs_pin, 0); + } + + res = spi_transfernb(hwcfg, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length, flag); + if (message->cs_release) + { + (config.mode & RT_SPI_CS_HIGH)?prev_raspi_pin_write(cs_pin, 0):prev_raspi_pin_write(cs_pin, 1); + } + if (res != RT_EOK) + return RT_ERROR; + + return message->length; +} + +rt_err_t raspi_spi_bus_attach_device(const char *bus_name, struct raspi_spi_device *device) +{ + rt_err_t ret; + RT_ASSERT(device != RT_NULL); + ret = rt_spi_bus_attach_device(device->spi_device, device->device_name, bus_name, (void *)(device)); + return ret; +} + +rt_err_t raspi_spi_hw_init(struct raspi_spi_hw_config *hwcfg) +{ + prev_raspi_pin_mode(hwcfg->sclk_pin, hwcfg->sclk_mode); + prev_raspi_pin_mode(hwcfg->miso_pin, hwcfg->miso_mode); + prev_raspi_pin_mode(hwcfg->mosi_pin, hwcfg->mosi_mode); +#if defined (BSP_USING_SPI0_DEVICE0) + prev_raspi_pin_mode(hwcfg->ce0_pin, hwcfg->ce0_mode); +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + prev_raspi_pin_mode(hwcfg->ce1_pin, hwcfg->ce1_mode); +#endif + //clear rx and tx + SPI_REG_CS(hwcfg->hw_base) = (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX); + //enable chip select +#if defined (BSP_USING_SPI0_DEVICE0) + SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CHIP_SELECT_0; +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CHIP_SELECT_1; +#endif + +#if defined (BSP_USING_SPI0_DEVICE0) && defined (BSP_USING_SPI0_DEVICE1) + HWREG32(SPI_REG_CS(hwcfg->hw_base)) |= (SPI_CS_CHIP_SELECT_0 | SPI_CS_CHIP_SELECT_1); +#endif + return RT_EOK; +} + +static struct rt_spi_ops raspi_spi_ops = +{ + .configure = raspi_spi_configure, + .xfer = raspi_spi_xfer +}; + +struct raspi_spi_hw_config raspi_spi0_hw = +{ + .spi_num = 0, + .sclk_pin = GPIO_PIN_11, + .sclk_mode = ALT0, + .mosi_pin = GPIO_PIN_10, + .mosi_mode = ALT0, + .miso_pin = GPIO_PIN_9, + .miso_mode = ALT0, + +#if defined (BSP_USING_SPI0_DEVICE0) + .ce0_pin = GPIO_PIN_8, + .ce0_mode = ALT0, +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + .ce1_pin = GPIO_PIN_7, + .ce1_mode = ALT0, +#endif + .hw_base = SPI_0_BASE, +}; +#endif + +#if defined (BSP_USING_SPI0_DEVICE0) +struct raspi_spi_device raspi_spi0_device0 = +{ + .device_name = SPI0_DEVICE0_NAME, + .spi_bus = &spi0_bus, + .spi_device = &spi0_device0, + .spi_hw_config = &raspi_spi0_hw, + .cs_pin = GPIO_PIN_8, +}; +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) +struct raspi_spi_device raspi_spi0_device1 = +{ + .device_name = SPI0_DEVICE1_NAME, + .spi_bus = &spi0_bus, + .spi_device = &spi0_device1, + .cs_pin = GPIO_PIN_7, +}; +#endif + +int rt_hw_spi_init(void) +{ +#if defined (BSP_USING_SPI0_BUS) + raspi_spi_hw_init(&raspi_spi0_hw); + rt_spi_bus_register(&spi0_bus, SPI0_BUS_NAME, &raspi_spi_ops); + +#if defined (BSP_USING_SPI0_DEVICE0) + raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device0); +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device1); +#endif +#endif + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_spi_init); diff --git a/bsp/raspberry-pi/raspi4-64/drivers/drv_spi.h b/bsp/raspberry-pi/raspi4-64/drivers/drv_spi.h new file mode 100644 index 0000000000..9cd8e031e4 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_spi.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-16 bigmagic first version + */ +#ifndef __DRV_SPI_H__ +#define __DRV_SPI_H__ + +#include "drv_gpio.h" + +#define SPI_REG_CS(BASE) HWREG32(BASE + 0x00) +#define SPI_REG_FIFO(BASE) HWREG32(BASE + 0x04) +#define SPI_REG_CLK(BASE) HWREG32(BASE + 0x08) +#define SPI_REG_DLEN(BASE) HWREG32(BASE + 0x0C) +#define SPI_REG_LTOH(BASE) HWREG32(BASE + 0x10) +#define SPI_REG_DC(BASE) HWREG32(BASE + 0x14) + +/* CS Register */ +#define SPI_CS_LOSSI_LONG_32BIT (1 << 25) +#define SPI_CS_LOSSI_DMA_MODE (1 << 24) +#define SPI_CS_CSPOL2 (1 << 23) +#define SPI_CS_CSPOL1 (1 << 22) +#define SPI_CS_CSPOL0 (1 << 21) +#define SPI_CS_RX_FIFO_FULL (1 << 20) +#define SPI_CS_RX_FIFO_3_QUARTER (1 << 19) +#define SPI_CS_TX_DATA (1 << 18) +#define SPI_CS_RX_DATA (1 << 17) +#define SPI_CS_DONE (1 << 16) +#define SPI_CS_LOSSI_EN (1 << 13) +#define SPI_CS_READ_EN (1 << 12) +#define SPI_CS_AUTO_CS (1 << 11) +#define SPI_CS_INTR_RXR (1 << 10) +#define SPI_CS_INTR_DONE (1 << 9) +#define SPI_CS_DMA_EN (1 << 8) +#define SPI_CS_TA (1 << 7) +#define SPI_CS_CSPOL_HIGH (1 << 6) +#define SPI_CS_CLEAR_RX (2 << 4) +#define SPI_CS_CLEAR_TX (1 << 4) +#define SPI_CS_CPOL (1 << 3) +#define SPI_CS_CPHA (1 << 2) +#define SPI_CS_CHIP_SELECT_2 (2 << 0) +#define SPI_CS_CHIP_SELECT_1 (1 << 0) +#define SPI_CS_CHIP_SELECT_0 (0 << 0) + +struct raspi_spi_hw_config +{ + rt_uint8_t spi_num; + GPIO_PIN sclk_pin; + GPIO_FUNC sclk_mode; + GPIO_PIN mosi_pin; + GPIO_FUNC mosi_mode; + GPIO_PIN miso_pin; + GPIO_FUNC miso_mode; +#if defined (BSP_USING_SPI0_DEVICE0) || defined (BSP_USING_SPI1_DEVICE0) + GPIO_PIN ce0_pin; + GPIO_FUNC ce0_mode; +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) || defined (BSP_USING_SPI1_DEVICE1) + GPIO_PIN ce1_pin; + GPIO_FUNC ce1_mode; +#endif + +#if defined (BSP_USING_SPI1_DEVICE2) + GPIO_PIN ce2_pin; + GPIO_FUNC ce2_mode; +#endif + rt_ubase_t hw_base; + +}; + +struct raspi_spi_device +{ + char *device_name; + struct rt_spi_bus *spi_bus; + struct rt_spi_device *spi_device; + struct raspi_spi_hw_config *spi_hw_config; + GPIO_PIN cs_pin; +}; + +int rt_hw_spi_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi4-64/drivers/drv_uart.c b/bsp/raspberry-pi/raspi4-64/drivers/drv_uart.c new file mode 100644 index 0000000000..31331a4609 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_uart.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-04-16 bigmagic first version + * 2020-05-26 bigmagic add other uart + */ + +#include +#include +#include + +#include "board.h" +#include "drv_uart.h" +#include "drv_gpio.h" +#include + +size_t uart0_addr = 0; +size_t uart3_addr = 0; +size_t uart4_addr = 0; +size_t uart5_addr = 0; + +#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 + +struct hw_uart_device +{ + rt_ubase_t hw_base; + rt_uint32_t irqno; +}; + +static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct hw_uart_device *uart; + uint32_t bauddiv = (UART_REFERENCE_CLOCK / cfg->baud_rate)* 1000 / 16; + uint32_t ibrd = bauddiv / 1000; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + if(uart->hw_base == AUX_BASE) + { + prev_raspi_pin_mode(GPIO_PIN_14, ALT5); + prev_raspi_pin_mode(GPIO_PIN_15, ALT5); + + AUX_ENABLES(uart->hw_base) = 1; /* Enable UART1 */ + AUX_MU_IER_REG(uart->hw_base) = 0; /* Disable interrupt */ + AUX_MU_CNTL_REG(uart->hw_base) = 0; /* Disable Transmitter and Receiver */ + AUX_MU_LCR_REG(uart->hw_base) = 3; /* Works in 8-bit mode */ + AUX_MU_MCR_REG(uart->hw_base) = 0; /* Disable RTS */ + AUX_MU_IIR_REG(uart->hw_base) = 0xC6; /* Enable FIFO, Clear FIFO */ + AUX_MU_BAUD_REG(uart->hw_base) = 270; /* 115200 = system clock 250MHz / (8 * (baud + 1)), baud = 270 */ + AUX_MU_CNTL_REG(uart->hw_base) = 3; /* Enable Transmitter and Receiver */ + return RT_EOK; + } + + if(uart->hw_base == uart0_addr) + { + prev_raspi_pin_mode(GPIO_PIN_14, ALT0); + prev_raspi_pin_mode(GPIO_PIN_15, ALT0); + } + + if(uart->hw_base == uart3_addr) + { + prev_raspi_pin_mode(GPIO_PIN_4, ALT4); + prev_raspi_pin_mode(GPIO_PIN_5, ALT4); + } + + if(uart->hw_base == uart4_addr) + { + prev_raspi_pin_mode(GPIO_PIN_8, ALT4); + prev_raspi_pin_mode(GPIO_PIN_9, ALT4); + } + + if(uart->hw_base == uart5_addr) + { + 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; +} + +static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + if(uart->hw_base == AUX_BASE) + { + AUX_MU_IER_REG(uart->hw_base) = 0x0; + } + else + { + PL011_REG_IMSC(uart->hw_base) &= ~((uint32_t)PL011_IMSC_RXIM); + } + rt_hw_interrupt_mask(uart->irqno); + break; + + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + 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; + } + return RT_EOK; +} + +static int uart_putc(struct rt_serial_device *serial, char c) +{ + struct hw_uart_device *uart; + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + 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; +} + +static int uart_getc(struct rt_serial_device *serial) +{ + int ch = -1; + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + if(uart->hw_base == AUX_BASE) + { + if ((AUX_MU_LSR_REG(uart->hw_base) & 0x01)) + { + ch = AUX_MU_IO_REG(uart->hw_base) & 0xff; + } + } + else + { + if((PL011_REG_FR(uart->hw_base) & PL011_FR_RXFE) == 0) + { + ch = PL011_REG_DR(uart->hw_base) & 0xff; + } + } + + return ch; +} + +static const struct rt_uart_ops _uart_ops = +{ + uart_configure, + uart_control, + uart_putc, + uart_getc, +}; + +#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); +} +#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_addr) = 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 = +{ + 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 + +int rt_hw_uart_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; +#ifdef RT_USING_UART0 + struct hw_uart_device *uart0; + uart0 = &_uart0_device; + + _serial0.ops = &_uart_ops; + _serial0.config = config; + + uart0_addr = (size_t)rt_ioremap((void*)UART0_BASE, 0x1000); + uart0->hw_base = uart0_addr; + + + /* 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 = (size_t)rt_ioremap((void*)AUX_BASE, 0x1000); + + /* 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 = (size_t)rt_ioremap((void*)UART3_BASE, 0x1000); + uart3->hw_base = uart3_addr; + + /* 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 = (size_t)rt_ioremap((void*)UART4_BASE, 0x1000); + uart4->hw_base = uart4_addr; + + /* 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 = (size_t)rt_ioremap((void*)UART5_BASE, 0x1000); + uart5->hw_base = uart5_addr; + + /* 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/drivers/drv_uart.h similarity index 63% rename from bsp/raspberry-pi/raspi4-64/driver/drv_uart.h rename to bsp/raspberry-pi/raspi4-64/drivers/drv_uart.h index 714043efd3..d57f4e52f4 100644 --- a/bsp/raspberry-pi/raspi4-64/driver/drv_uart.h +++ b/bsp/raspberry-pi/raspi4-64/drivers/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/drivers/drv_wdt.c b/bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.c new file mode 100644 index 0000000000..3c091354bb --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-26 bigmagic first version + */ +#include +#include "drv_wdt.h" +#include "raspi4.h" + +#ifdef BSP_USING_WDT + +#define SECS_TO_WDOG_TICKS(x) ((x) << 16) +#define WDOG_TICKS_TO_SECS(x) ((x) >> 16) + +static struct raspi_wdt_driver bcm_wdt; + +void raspi_watchdog_init(rt_uint32_t time_init) +{ + bcm_wdt.timeout = time_init; +} + +void raspi_watchdog_start() +{ + volatile rt_uint32_t cur; + PM_WDOG = PM_PASSWORD | (SECS_TO_WDOG_TICKS(bcm_wdt.timeout) & PM_WDOG_TIME_SET); + cur = (PM_RSTC); + PM_RSTC = PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET; +} + +void raspi_watchdog_stop() +{ + PM_RSTC = PM_PASSWORD | PM_RSTC_RESET; +} + +void raspi_watchdog_clr() +{ + bcm_wdt.timeout = 0; +} + +void raspi_watchdog_set_timeout(rt_uint32_t timeout_us) +{ + bcm_wdt.timeout = timeout_us; +} + +rt_uint64_t raspi_watchdog_get_timeout() +{ + return bcm_wdt.timeout; +} + +rt_uint64_t raspi_watchdog_get_timeleft() +{ + rt_uint32_t ret = (PM_WDOG); + return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET); +} + +static rt_err_t raspi_wdg_init(rt_watchdog_t *wdt) +{ + /*init for 10S*/ + raspi_watchdog_init(1000000); + raspi_watchdog_start(); + raspi_watchdog_stop(); + return RT_EOK; +} + +static rt_err_t raspi_wdg_control(rt_watchdog_t *wdt, int cmd, void *arg) +{ + rt_uint64_t timeout_us = 0; + switch (cmd) + { + case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: + timeout_us = *((rt_uint32_t *)arg) * 1000000; + if (timeout_us >= 0xFFFFFFFF) + timeout_us = 0xFFFFFFFF; + raspi_watchdog_set_timeout((rt_uint32_t)timeout_us); + break; + case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: + timeout_us = raspi_watchdog_get_timeout(); + *((rt_uint32_t *)arg) = timeout_us / 1000000; + break; + case RT_DEVICE_CTRL_WDT_GET_TIMELEFT: + timeout_us = raspi_watchdog_get_timeleft(); + *((rt_uint32_t *)arg) = timeout_us / 1000000; + break; + case RT_DEVICE_CTRL_WDT_KEEPALIVE: + raspi_watchdog_clr(); + break; + case RT_DEVICE_CTRL_WDT_START: + raspi_watchdog_start(); + break; + case RT_DEVICE_CTRL_WDT_STOP: + raspi_watchdog_stop(); + break; + default: + return RT_EIO; + } + return RT_EOK; +} + +static const struct rt_watchdog_ops raspi_wdg_pos = +{ + raspi_wdg_init, + raspi_wdg_control, +}; + +static rt_watchdog_t raspi_wdg; + +int rt_hw_wdt_init(void) +{ + raspi_wdg.ops = &raspi_wdg_pos; + rt_hw_watchdog_register(&raspi_wdg, "wdg", 0, RT_NULL); + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_wdt_init); + +void reboot(void) +{ + unsigned int r; + + rt_kprintf("reboot system...\n"); + rt_thread_mdelay(100); + r = PM_RSTS; + // trigger a restart by instructing the GPU to boot from partition 0 + r &= ~0xfffffaaa; + PM_RSTS |= (PM_PASSWORD | r); // boot from partition 0 + PM_WDOG |= (PM_PASSWORD | 0x0A); + PM_RSTC |= (PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET); + + while (1); +} +MSH_CMD_EXPORT(reboot,reboot system...); +#endif /*BSP_USING_WDT */ diff --git a/bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.h b/bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.h new file mode 100644 index 0000000000..4c9454ed91 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/drv_wdt.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-26 bigmagic first version + */ +#ifndef __DRV_WDT_H__ +#define __DRV_WDT_H__ + +#include +#include + +#include "board.h" + +struct raspi_wdt_driver +{ + rt_uint32_t timeout; +}; + +int rt_hw_wdt_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi4-64/drivers/mbox.c b/bsp/raspberry-pi/raspi4-64/drivers/mbox.c new file mode 100644 index 0000000000..177b043a8a --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/mbox.c @@ -0,0 +1,499 @@ +/* + * File : mbox.c + * Copyright (c) 2006-2018, 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 +#include "mbox.h" +#include "mmu.h" +//volatile unsigned int __attribute__((aligned(16))) mbox[36]; + +#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000) +volatile unsigned int *mbox; + +/** + * Make a mailbox call. Returns 0 on failure, non-zero on success + */ +int mbox_call(unsigned char ch, int mmu_enable) +{ + unsigned int r = ((((rt_uint32_t)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_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/drivers/mbox.h b/bsp/raspberry-pi/raspi4-64/drivers/mbox.h new file mode 100644 index 0000000000..40c50f4080 --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/mbox.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2006-2020, 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 + +//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) +extern size_t videocore_mbox; +#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 + +#define MBOX_ADDR 0x08000000 +extern size_t mbox_addr; + +#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_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/drivers/raspi4.h b/bsp/raspberry-pi/raspi4-64/drivers/raspi4.h new file mode 100644 index 0000000000..cff7ab906a --- /dev/null +++ b/bsp/raspberry-pi/raspi4-64/drivers/raspi4.h @@ -0,0 +1,189 @@ +#ifndef __RASPI4_H__ +#define __RASPI4_H__ + +//https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0.pdf + +#define __REG32(x) (*((volatile unsigned int *)(x))) +#define __REG16(x) (*((volatile unsigned short *)(x))) + +/* GIC IRQ MAX */ +#define MAX_HANDLERS (256) + +/* base address */ +#define PER_BASE (0xFE000000) + +//gpio offset +#define GPIO_BASE_OFFSET (0x00200000) + + +#define PL011_UART_BASE_OFFSET (0x00201000) +//pl011 offset +#define PL011_UART0_BASE_OFFSET (0x00201000) +#define PL011_UART2_BASE_OFFSET (0x00201400) +#define PL011_UART3_BASE_OFFSET (0x00201600) +#define PL011_UART4_BASE_OFFSET (0x00201800) +#define PL011_UART5_BASE_OFFSET (0x00201A00) + +//pactl cs offset +#define PACTL_CS_OFFSET (0x00204E00) + +//aux offset +#define AUX_BASE_OFFSET (0x00215000) + +/* GPIO */ +#define GPIO_BASE_ADDR (PER_BASE + GPIO_BASE_OFFSET) +extern size_t gpio_base_addr; +#define GPIO_BASE (gpio_base_addr) +#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 + +/* Timer (ARM side) */ +#define ARM_TIMER_IRQ (64) +extern size_t arm_timer_base; +#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 PL011 */ +#define UART_BASE (PER_BASE + PL011_UART_BASE_OFFSET) +//extern uint32_t uart_base_addr; +#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_ADDR (PER_BASE + AUX_BASE_OFFSET) +//extern uint32_t aux_addr; +//#define AUX_BASE (aux_addr + 0x0) + +#define AUX_BASE (PER_BASE + AUX_BASE_OFFSET) +#define IRQ_PL011 (96 + 57) + +/* Peripheral IRQ OR-ing */ +#define PACTL_CS_ADDR (PER_BASE + PACTL_CS_OFFSET) +extern size_t pactl_cs_base; +#define PACTL_CS HWREG32(pactl_cs_base) +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) + +/* GIC */ +#define INTC_BASE (0xff800000) +#define ARM_GIC_NR_IRQS (512) +#define ARM_GIC_MAX_NR (512) +#define GIC_V2_BASE (INTC_BASE + 0x00040000) +extern size_t gic_base_addr; +#define GIC_V2_DISTRIBUTOR_BASE (gic_base_addr + 0x1000) +#define GIC_V2_CPU_INTERFACE_BASE (gic_base_addr + 0x2000) +#define GIC_V2_HYPERVISOR_BASE (gic_base_addr + 0x4000) +#define GIC_V2_VIRTUAL_CPU_BASE (gic_base_addr + 0x6000) + +#define GIC_PL400_DISTRIBUTOR_PPTR GIC_V2_DISTRIBUTOR_BASE +#define GIC_PL400_CONTROLLER_PPTR GIC_V2_CPU_INTERFACE_BASE + +#define GIC_IRQ_START 0 + +#define GIC_ACK_INTID_MASK 0x000003ff + + +//watchdog +#define WDT_BASE (PER_BASE + 0x00100000) +extern size_t wdt_base_addr; +#define PM_RSTC HWREG32(wdt_base_addr + 0x1c) +#define PM_RSTS HWREG32(wdt_base_addr + 0x20) +#define PM_WDOG HWREG32(wdt_base_addr + 0x24) + +#define PM_PASSWORD (0x5A000000) +#define PM_WDOG_TIME_SET (0x000fffff) +#define PM_RSTS_HADWRH_SET (0x00000040) +#define PM_RSTC_WRCFG_FULL_RESET (0x00000020) +#define PM_RSTC_WRCFG_CLR (0xffffffcf) +#define PM_RSTC_RESET (0x00000102) + +//timer +#define ST_BASE_OFFSET (0x003000) +#define STIMER_BASE (PER_BASE + ST_BASE_OFFSET) +extern size_t stimer_base_addr; +#define STIMER_CS __REG32(stimer_base_addr + 0x0000) +#define STIMER_CLO __REG32(stimer_base_addr + 0x0004) +#define STIMER_CHI __REG32(stimer_base_addr + 0x0008) +#define STIMER_C0 __REG32(stimer_base_addr + 0x000C) +#define STIMER_C1 __REG32(stimer_base_addr + 0x0010) +#define STIMER_C2 __REG32(stimer_base_addr + 0x0014) +#define STIMER_C3 __REG32(stimer_base_addr + 0x0018) + +#define DELAY_MICROS(micros) \ + do{ \ + rt_uint32_t compare = STIMER_CLO + micros * 25; \ + while (STIMER_CLO < compare); \ + } while (0) + +//External Mass Media Controller (SD Card) +#define MMC0_BASE_ADDR (PER_BASE+0x300000) +extern size_t mmc0_base_addr; +#define MMC2_BASE_ADDR (PER_BASE+0x340000) +extern size_t mmc2_base_addr; + +//mac +#define MAC_REG (void *)(0xfd580000) +extern void * mac_reg_base_addr; + +#define ETH_IRQ (160+29) + +#define SEND_DATA_NO_CACHE (0x08200000) +extern void * eth_send_no_cache; + +#define RECV_DATA_NO_CACHE (0x08400000) +extern void * eth_recv_no_cache; + +/* the basic constants and interfaces needed by gic */ +rt_inline size_t platform_get_gic_dist_base(void) +{ + return GIC_PL400_DISTRIBUTOR_PPTR; +} + +rt_inline size_t platform_get_gic_cpu_base(void) +{ + return GIC_PL400_CONTROLLER_PPTR; +} + +#endif diff --git a/bsp/raspberry-pi/raspi4-64/link.lds b/bsp/raspberry-pi/raspi4-64/link.lds index b7b2dcc32c..6d0dfd4dcc 100644 --- a/bsp/raspberry-pi/raspi4-64/link.lds +++ b/bsp/raspberry-pi/raspi4-64/link.lds @@ -1,92 +1,61 @@ -/* - * File : link.lds - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * 2017-5-30 bernard first version - */ - -/* _EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 0x20000; */ - +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) SECTIONS { - . = 0x80000; - . = ALIGN(4096); + /*. = 0x0x208000; */ + . = 0xffff000000008000; + + __text_start = .; .text : { - KEEP(*(.text.entrypoint)) /* The entry point */ - *(.vectors) - *(.text) /* remaining code */ - *(.text.*) /* remaining code */ + KEEP(*(.text.entrypoint)) + KEEP(*(.vectors)) + *(.text) + *(.text.*) - *(.rodata) /* read-only data (constants) */ - *(.rodata*) - *(.glue_7) - *(.glue_7t) - *(.gnu.linkonce.t*) + /* section information for utest */ + . = ALIGN(4); + __rt_utest_tc_tab_start = .; + KEEP(*(UtestTcTab)) + __rt_utest_tc_tab_end = .; - *(COMMON) - /* section information for finsh shell */ - . = ALIGN(16); + . = ALIGN(4); __fsymtab_start = .; KEEP(*(FSymTab)) __fsymtab_end = .; - . = ALIGN(16); + . = ALIGN(4); __vsymtab_start = .; KEEP(*(VSymTab)) __vsymtab_end = .; - . = ALIGN(16); + . = ALIGN(4); - /* section information for initial. */ - . = ALIGN(16); + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* section information for initialization */ + . = ALIGN(4); __rt_init_start = .; KEEP(*(SORT(.rti_fn*))) __rt_init_end = .; - . = ALIGN(16); - - . = ALIGN(16); - _etext = .; - } + } =0 + __text_end = .; - .eh_frame_hdr : + .ARM.exidx : { - *(.eh_frame_hdr) - *(.eh_frame_entry) + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - . = ALIGN(16); - .data : - { - *(.data) - *(.data.*) - - *(.data1) - *(.data1.*) + __rodata_start = .; + .rodata : { *(.rodata) *(.rodata.*) } + __rodata_end = .; - . = ALIGN(16); - _gp = ABSOLUTE(.); /* Base of small data */ - - *(.sdata) - *(.sdata.*) - } - - . = ALIGN(16); + . = ALIGN(4); .ctors : { PROVIDE(__ctors_start__ = .); @@ -103,51 +72,38 @@ SECTIONS PROVIDE(__dtors_end__ = .); } - . = ALIGN(16); - .bss : + . = ALIGN(8); + __data_start = .; + .data : { - PROVIDE(__bss_start = .); - *(.bss) - *(.bss.*) - *(.dynbss) - - PROVIDE(__bss_end = .); + *(.data) + *(.data.*) } - _end = .; + __data_end = .; + + . = ALIGN(8); + __bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + } + . = ALIGN(4); + __bss_end = .; /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} + .comment 0 : { *(.comment) } + + __data_size = SIZEOF(.data); + __bss_size = SIZEOF(.bss); -__bss_size = (__bss_end - __bss_start)>>3; + _end = .; +} diff --git a/bsp/raspberry-pi/raspi4-64/rtconfig.h b/bsp/raspberry-pi/raspi4-64/rtconfig.h index bdde9d5f4a..b19321dafb 100644 --- a/bsp/raspberry-pi/raspi4-64/rtconfig.h +++ b/bsp/raspberry-pi/raspi4-64/rtconfig.h @@ -7,19 +7,21 @@ /* RT-Thread Kernel */ #define RT_NAME_MAX 8 +#define RT_USING_SMART #define RT_ALIGN_SIZE 4 #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 -#define RT_TICK_PER_SECOND 100 +#define RT_TICK_PER_SECOND 1000 #define RT_USING_OVERFLOW_CHECK #define RT_USING_HOOK #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 2048 +#define IDLE_THREAD_STACK_SIZE 8192 #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 4 -#define RT_TIMER_THREAD_STACK_SIZE 2048 +#define RT_TIMER_THREAD_STACK_SIZE 8192 #define RT_DEBUG +#define RT_DEBUG_COLOR /* Inter-Thread communication */ @@ -32,24 +34,31 @@ /* Memory Management */ #define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP #define RT_USING_SMALL_MEM #define RT_USING_HEAP /* Kernel Device Object */ #define RT_USING_DEVICE +#define RT_USING_INTERRUPT_INFO #define RT_USING_CONSOLE -#define RT_CONSOLEBUF_SIZE 128 -#define RT_CONSOLE_DEVICE_NAME "uart" -#define RT_VER_NUM 0x40003 +#define RT_CONSOLEBUF_SIZE 512 +#define RT_CONSOLE_DEVICE_NAME "uart0" +#define RT_VER_NUM 0x50000 #define ARCH_CPU_64BIT +#define RT_USING_CACHE +#define ARCH_ARM_MMU +#define RT_USING_USERSPACE +#define KERNEL_VADDR_START 0xffff000000000000 +#define PV_OFFSET 0x0001000000200000 #define ARCH_ARMV8 /* RT-Thread Components */ #define RT_USING_COMPONENTS_INIT #define RT_USING_USER_MAIN -#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_STACK_SIZE 8192 #define RT_MAIN_THREAD_PRIORITY 10 /* C++ features */ @@ -58,35 +67,65 @@ /* Command shell */ #define RT_USING_FINSH +#define RT_USING_MSH #define FINSH_THREAD_NAME "tshell" #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_THREAD_STACK_SIZE 8192 #define FINSH_CMD_SIZE 80 -#define FINSH_USING_MSH -#define FINSH_USING_MSH_DEFAULT #define FINSH_ARG_MAX 10 /* Device virtual file system */ #define RT_USING_DFS #define DFS_USING_WORKDIR -#define DFS_FILESYSTEMS_MAX 2 -#define DFS_FILESYSTEM_TYPES_MAX 2 +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 #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_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 +#define RT_USING_DFS_ROMFS /* Device Drivers */ #define RT_USING_DEVICE_IPC #define RT_PIPE_BUFSZ 512 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 8192 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 #define RT_USING_SERIAL -#define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_HWTIMER +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS #define RT_USING_PIN +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_RTC +#define RT_USING_SOFT_RTC +#define RT_USING_SDIO +#define RT_SDIO_STACK_SIZE 8192 +#define RT_SDIO_THREAD_PRIORITY 15 +#define RT_MMCSD_STACK_SIZE 8192 +#define RT_MMCSD_THREAD_PREORITY 22 +#define RT_MMCSD_MAX_PARTITION 16 +#define RT_USING_SPI +#define RT_USING_WDT /* Using USB */ @@ -94,18 +133,78 @@ /* POSIX layer and C standard library */ #define RT_USING_LIBC +#define RT_USING_MUSL #define RT_USING_POSIX +#define RT_USING_POSIX_MMAP +#define RT_USING_POSIX_TERMIOS +#define RT_USING_POSIX_AIO +#define RT_USING_POSIX_CLOCKTIME /* Network */ /* Socket abstraction layer */ +#define RT_USING_SAL + +/* protocol stack implement */ + +#define SAL_USING_LWIP +#define SAL_USING_POSIX /* 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_LWIP202 +#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.137.100" +#define RT_LWIP_GWADDR "192.168.137.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 16 +#define RT_LWIP_PBUF_NUM 16 +#define RT_LWIP_RAW_PCB_NUM 4 +#define RT_LWIP_UDP_PCB_NUM 8 +#define RT_LWIP_TCP_PCB_NUM 8 +#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 8192 +#define RT_LWIP_ETHTHREAD_PRIORITY 12 +#define RT_LWIP_ETHTHREAD_STACKSIZE 8192 +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 +#define RT_LWIP_REASSEMBLY_FRAG +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define SO_REUSE 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 +#define LWIP_SO_RCVBUF 1 +#define LWIP_SO_LINGER 0 +#define LWIP_NETIF_LOOPBACK 0 +#define RT_LWIP_USING_PING /* AT commands */ @@ -115,6 +214,13 @@ /* Utilities */ +#define RT_USING_LWP +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define RT_LWP_SHM_MAX_NR 64 +#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024 +#define LWP_TID_MAX_NR 64 /* RT-Thread online packages */ @@ -147,6 +253,9 @@ /* system packages */ +/* Micrium: Micrium software products porting for RT-Thread */ + + /* peripheral libraries and drivers */ @@ -155,6 +264,15 @@ /* samples: kernel and components samples */ + +/* games: games run on RT-Thread console */ + + +/* Privated Packages of RealThread */ + + +/* Network Utilities */ + #define BCM2711_SOC /* Hardware Drivers Config */ @@ -163,12 +281,18 @@ #define BSP_USING_UART #define RT_USING_UART0 +#define RT_USING_UART3 +#define RT_USING_UART4 #define BSP_USING_GIC #define BSP_USING_GIC400 #define BSP_USING_PIN #define BSP_USING_CORETIMER +#define BSP_USING_WDT +#define BSP_USING_SDIO +#define BSP_USING_SDIO0 /* Board Peripheral Drivers */ +#define BSP_USING_HDMI #endif diff --git a/bsp/raspberry-pi/raspi4-64/rtconfig.py b/bsp/raspberry-pi/raspi4-64/rtconfig.py index a1dd168d3d..870c797b0e 100644 --- a/bsp/raspberry-pi/raspi4-64/rtconfig.py +++ b/bsp/raspberry-pi/raspi4-64/rtconfig.py @@ -2,26 +2,15 @@ import os # toolchains options ARCH ='aarch64' -CPU ='cortex-a72' -CROSS_TOOL ='gcc' - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = r'../../..' - -if os.getenv('RTT_CC'): - CROSS_TOOL = os.getenv('RTT_CC') - +CPU ='cortex-a' +CROSS_TOOL = 'gcc' PLATFORM = 'gcc' -EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/' - -BUILD = 'debug' +EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin' +BUILD = 'debug' if PLATFORM == 'gcc': # toolchains - # PREFIX = 'arm-none-eabi-' - PREFIX = 'aarch64-elf-' + PREFIX = os.getenv('RTT_CC_PREFIX') or 'arm-none-eabi-' CC = PREFIX + 'gcc' CXX = PREFIX + 'g++' AS = PREFIX + 'gcc' @@ -31,21 +20,27 @@ if PLATFORM == 'gcc': SIZE = PREFIX + 'size' OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' - - DEVICE = ' -march=armv8-a -mtune=cortex-a72' - CFLAGS = DEVICE + ' -Wall' - AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__' - LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + STRIP = PREFIX + 'strip' + CFPFLAGS = ' ' + AFPFLAGS = ' ' + DEVICE = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' + + CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall' + CFLAGS = DEVICE + CFPFLAGS + ' -Wall -std=gnu99' + AFLAGS = ' -c' + AFPFLAGS + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc' CPATH = '' LPATH = '' if BUILD == 'debug': - CFLAGS += ' -O0 -gdwarf-2' - AFLAGS += ' -gdwarf-2' + CFLAGS += ' -O0 -gdwarf-2' + CXXFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' else: - CFLAGS += ' -O2' - - CXXFLAGS = CFLAGS + CFLAGS += ' -Os' + CXXFLAGS += ' -Os' + CXXFLAGS += ' -Woverloaded-virtual -fno-exceptions -fno-rtti' DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' -POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' +POST_ACTION = OBJCPY + ' -O binary $TARGET kernel7.img\n' + SIZE + ' $TARGET \n' +POST_ACTION += 'cp kernel7.img /tftpboot \n' diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c index 72626d5e82..0986d657fe 100644 --- a/components/lwp/lwp_user_mm.c +++ b/components/lwp/lwp_user_mm.c @@ -355,6 +355,8 @@ rt_base_t lwp_brk(void *addr) return ret; } +#define MAP_ANONYMOUS 0x20 + void* lwp_mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset) { @@ -362,17 +364,24 @@ void* lwp_mmap2(void *addr, size_t length, int prot, void *ret = (void *)-1; struct rt_lwp *lwp = RT_NULL; - level = rt_hw_interrupt_disable(); if (fd == -1) { lwp = rt_thread_self()->lwp; + level = rt_hw_interrupt_disable(); ret = lwp_map_user(lwp, addr, length, 0); - if (!ret) + rt_hw_interrupt_enable(level); + if (ret) + { + if ((flags & MAP_ANONYMOUS) != 0) + { + rt_memset(ret, 0, length); + } + } + else { ret = (void *)-1; } } - rt_hw_interrupt_enable(level); return ret; } -- Gitee From 505960d0e30e3164c7d4b346c7b72e03188d7dc2 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Tue, 25 May 2021 10:34:07 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96lwp=5Fuser=5Fsetting=5Fsa?= =?UTF-8?q?ve=E7=9A=84=E6=89=A7=E8=A1=8C=E6=97=B6=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/rthw.h | 2 +- libcpu/aarch64/common/context_gcc.S | 25 ++++++++------- libcpu/arm/cortex-a/context_gcc.S | 48 ++++++++++++++++++++++++----- libcpu/arm/cortex-a/start_gcc.S | 10 ------ src/scheduler.c | 12 +------- 5 files changed, 56 insertions(+), 41 deletions(-) diff --git a/include/rthw.h b/include/rthw.h index c075e784d9..1505a1b46f 100644 --- a/include/rthw.h +++ b/include/rthw.h @@ -132,7 +132,7 @@ void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t t #else void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); void rt_hw_context_switch_to(rt_ubase_t to); -void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); +void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread); #endif /*RT_USING_SMP*/ void rt_hw_console_output(const char *str); diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S index d924b920a6..f4b9f0be0f 100644 --- a/libcpu/aarch64/common/context_gcc.S +++ b/libcpu/aarch64/common/context_gcc.S @@ -8,6 +8,8 @@ * 2021-05-18 Jesven the first version */ +#include "rtconfig.h" + #include "asm-fpu.h" /* @@ -245,24 +247,28 @@ rt_hw_context_switch: RESTORE_CONTEXT /* - * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); + * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread); */ .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: - ADR X2, rt_thread_switch_interrupt_flag - LDR X3, [X2] - CMP X3, #1 + ADR X6, rt_thread_switch_interrupt_flag + LDR X7, [X6] + CMP X7, #1 B.EQ _reswitch ADR X4, rt_interrupt_from_thread // set rt_interrupt_from_thread - MOV X3, #1 // set rt_thread_switch_interrupt_flag to 1 STR X0, [X4] - STR X3, [X2] + MOV X7, #1 // set rt_thread_switch_interrupt_flag to 1 + STR X7, [X6] + STP X1, X30, [SP, #-0x10]! + MOV X0, X2 + BL lwp_user_setting_save + LDP X1, X30, [SP], #0x10 _reswitch: - ADR X2, rt_interrupt_to_thread // set rt_interrupt_to_thread - STR X1, [X2] + ADR X6, rt_interrupt_to_thread // set rt_interrupt_to_thread + STR X1, [X6] RET .text @@ -293,9 +299,6 @@ vector_irq: SAVE_CONTEXT STP X0, X1, [SP, #-0x10]! /* X0 is thread sp */ - BL rt_thread_self - BL lwp_user_setting_save - BL rt_interrupt_enter BL rt_hw_trap_irq BL rt_interrupt_leave diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S index 9c9d990d16..8dc8267ae3 100644 --- a/libcpu/arm/cortex-a/context_gcc.S +++ b/libcpu/arm/cortex-a/context_gcc.S @@ -145,28 +145,60 @@ rt_hw_context_switch_interrupt: * r2 :addr of to_thread's sp * r3 :to_thread's tcb */ - +#ifdef RT_USING_LWP + push {r0 - r3, lr} + bl rt_thread_self + bl lwp_user_setting_save + pop {r0 - r3, lr} +#endif str r0, [r1] ldr sp, [r2] mov r0, r3 + bl rt_cpus_lock_status_restore b rt_hw_context_switch_exit #else /*RT_USING_SMP*/ - ldr r2, =rt_thread_switch_interrupt_flag - ldr r3, [r2] + /* r0 :addr of from_thread's sp + * r1 :addr of to_thread's sp + * r2 :from_thread's tcb + * r3 :to_thread's tcb + */ +#ifdef RT_USING_LWP + /* now to_thread(r3) not used */ + ldr ip, =rt_thread_switch_interrupt_flag + ldr r3, [ip] cmp r3, #1 beq _reswitch - ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + ldr r3, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + str r0, [r3] mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 - str r0, [ip] - str r3, [r2] + str r3, [ip] + push {r1, lr} + mov r0, r2 + bl lwp_user_setting_save + pop {r1, lr} _reswitch: - ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread - str r1, [r2] + ldr ip, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + str r1, [ip] bx lr +#else + /* now from_thread(r2) to_thread(r3) not used */ + ldr ip, =rt_thread_switch_interrupt_flag + ldr r3, [ip] + cmp r3, #1 + beq _reswitch + ldr r3, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + str r0, [r3] + mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 + str r3, [ip] +_reswitch: + ldr ip, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + str r1, [ip] + bx lr +#endif #endif /*RT_USING_SMP*/ .global rt_hw_context_switch_exit diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 3d0ecadd40..68a8099ea8 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -361,11 +361,6 @@ vector_irq: cps #Mode_SVC mov sp, r8 -#ifdef RT_USING_LWP - bl rt_thread_self - bl lwp_user_setting_save -#endif - bl rt_interrupt_enter bl rt_hw_trap_irq bl rt_interrupt_leave @@ -378,11 +373,6 @@ vector_irq: #else stmfd sp!, {r0-r12,lr} -#ifdef RT_USING_LWP - bl rt_thread_self - bl lwp_user_setting_save -#endif - bl rt_interrupt_enter bl rt_hw_trap_irq bl rt_interrupt_leave diff --git a/src/scheduler.c b/src/scheduler.c index c6f675c1b1..28a8a78fcc 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -47,10 +47,6 @@ struct rt_thread *rt_current_thread; rt_uint8_t rt_current_priority; #endif /*RT_USING_SMP*/ -#ifdef RT_USING_LWP -void lwp_user_setting_save(rt_thread_t thread); -#endif - #ifdef RT_USING_HOOK static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to); @@ -377,9 +373,6 @@ void rt_schedule(void) _rt_scheduler_stack_check(to_thread); #endif -#ifdef RT_USING_LWP - lwp_user_setting_save(current_thread); -#endif rt_hw_context_switch((rt_ubase_t)¤t_thread->sp, (rt_ubase_t)&to_thread->sp, to_thread); } @@ -489,9 +482,6 @@ void rt_schedule(void) { extern void rt_thread_handle_sig(rt_bool_t clean_state); -#ifdef RT_USING_LWP - lwp_user_setting_save(from_thread); -#endif rt_hw_context_switch((rt_ubase_t)&from_thread->sp, (rt_ubase_t)&to_thread->sp); @@ -524,7 +514,7 @@ void rt_schedule(void) RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n")); rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp, - (rt_ubase_t)&to_thread->sp); + (rt_ubase_t)&to_thread->sp, from_thread, to_thread); } } else -- Gitee From 9e53ccbc5fd70d8aa76b0e7302fb3e78e326a8aa Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Tue, 25 May 2021 11:47:07 +0800 Subject: [PATCH 4/4] =?UTF-8?q?lwp=E5=90=88=E5=B9=B6arch=5Fuser=5Fstack.c?= =?UTF-8?q?=E5=92=8Carch=5Fuser=5Fspace=5Finit.c=E4=B8=BAlwp=5Farch.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arch/aarch64/cortex-a/arch_user_stack.c | 39 ------------------- .../{arch_user_space_init.c => lwp_arch.c} | 19 +++++++++ .../lwp/arch/arm/cortex-a/arch_user_stack.c | 39 ------------------- .../{arch_user_space_init.c => lwp_arch.c} | 19 +++++++++ 4 files changed, 38 insertions(+), 78 deletions(-) delete mode 100644 components/lwp/arch/aarch64/cortex-a/arch_user_stack.c rename components/lwp/arch/aarch64/cortex-a/{arch_user_space_init.c => lwp_arch.c} (72%) delete mode 100644 components/lwp/arch/arm/cortex-a/arch_user_stack.c rename components/lwp/arch/arm/cortex-a/{arch_user_space_init.c => lwp_arch.c} (81%) diff --git a/components/lwp/arch/aarch64/cortex-a/arch_user_stack.c b/components/lwp/arch/aarch64/cortex-a/arch_user_stack.c deleted file mode 100644 index 767e75292c..0000000000 --- a/components/lwp/arch/aarch64/cortex-a/arch_user_stack.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-11-18 Jesven first version - */ - -#include -#include - -#ifdef RT_USING_USERSPACE - -#include -#include -#include -#include -#include - -int arch_expand_user_stack(void *addr) -{ - int ret = 0; - size_t stack_addr = (size_t)addr; - - stack_addr &= ~ARCH_PAGE_MASK; - if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND)) - { - void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0); - - if (map || lwp_user_accessable(addr, 1)) - { - ret = 1; - } - } - return ret; -} -#endif diff --git a/components/lwp/arch/aarch64/cortex-a/arch_user_space_init.c b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c similarity index 72% rename from components/lwp/arch/aarch64/cortex-a/arch_user_space_init.c rename to components/lwp/arch/aarch64/cortex-a/lwp_arch.c index a8e2ce93d4..c5f4cebdb9 100644 --- a/components/lwp/arch/aarch64/cortex-a/arch_user_space_init.c +++ b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c @@ -55,4 +55,23 @@ void arch_user_space_vtable_free(struct rt_lwp *lwp) rt_pages_free(lwp->mmu_info.vtable, 0); } } + +int arch_expand_user_stack(void *addr) +{ + int ret = 0; + size_t stack_addr = (size_t)addr; + + stack_addr &= ~ARCH_PAGE_MASK; + if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND)) + { + void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0); + + if (map || lwp_user_accessable(addr, 1)) + { + ret = 1; + } + } + return ret; +} + #endif diff --git a/components/lwp/arch/arm/cortex-a/arch_user_stack.c b/components/lwp/arch/arm/cortex-a/arch_user_stack.c deleted file mode 100644 index 767e75292c..0000000000 --- a/components/lwp/arch/arm/cortex-a/arch_user_stack.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-11-18 Jesven first version - */ - -#include -#include - -#ifdef RT_USING_USERSPACE - -#include -#include -#include -#include -#include - -int arch_expand_user_stack(void *addr) -{ - int ret = 0; - size_t stack_addr = (size_t)addr; - - stack_addr &= ~ARCH_PAGE_MASK; - if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND)) - { - void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0); - - if (map || lwp_user_accessable(addr, 1)) - { - ret = 1; - } - } - return ret; -} -#endif diff --git a/components/lwp/arch/arm/cortex-a/arch_user_space_init.c b/components/lwp/arch/arm/cortex-a/lwp_arch.c similarity index 81% rename from components/lwp/arch/arm/cortex-a/arch_user_space_init.c rename to components/lwp/arch/arm/cortex-a/lwp_arch.c index 5577f6a6c9..05bb20b3f7 100644 --- a/components/lwp/arch/arm/cortex-a/arch_user_space_init.c +++ b/components/lwp/arch/arm/cortex-a/lwp_arch.c @@ -68,4 +68,23 @@ void arch_user_space_vtable_free(struct rt_lwp *lwp) rt_pages_free(lwp->mmu_info.vtable, 2); } } + +int arch_expand_user_stack(void *addr) +{ + int ret = 0; + size_t stack_addr = (size_t)addr; + + stack_addr &= ~ARCH_PAGE_MASK; + if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND)) + { + void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE, 0); + + if (map || lwp_user_accessable(addr, 1)) + { + ret = 1; + } + } + return ret; +} + #endif -- Gitee