From 2eb1bef773e099ac93ec74dba7ec216bdf61597c Mon Sep 17 00:00:00 2001 From: qz721 <295354721@qq.com> Date: Mon, 25 Mar 2019 20:03:49 +0800 Subject: [PATCH] Make 'qemu-vexpress-a9' and 'imx6ul' use the same libcpu code. --- bsp/imx6ul/.config | 358 ++++++++++++++ bsp/imx6ul/drivers/board.c | 19 +- bsp/imx6ul/platform/SConscript | 4 +- bsp/imx6ul/platform/cpu/gic.c | 243 ---------- bsp/imx6ul/platform/cpu/mmu.c | 285 ----------- bsp/imx6ul/platform/cpu/mmu.h | 157 ------ bsp/imx6ul/platform/cpu/platform.h | 96 ++++ bsp/imx6ul/platform/include/gic.h | 183 ------- bsp/imx6ul/platform/include/interrupt.h | 101 ---- bsp/imx6ul/rtconfig.py | 2 +- bsp/qemu-vexpress-a9/.config | 1 + bsp/qemu-vexpress-a9/SConstruct | 4 +- bsp/qemu-vexpress-a9/cpu/SConscript | 17 - bsp/qemu-vexpress-a9/cpu/armv7.h | 64 --- bsp/qemu-vexpress-a9/cpu/context_gcc.S | 198 -------- bsp/qemu-vexpress-a9/cpu/cp15.h | 12 - bsp/qemu-vexpress-a9/cpu/cp15_gcc.S | 140 ------ bsp/qemu-vexpress-a9/cpu/cpuport.c | 83 ---- bsp/qemu-vexpress-a9/cpu/interrupt.c | 108 ----- bsp/qemu-vexpress-a9/cpu/interrupt.h | 25 - bsp/qemu-vexpress-a9/cpu/mmu.c | 207 -------- bsp/qemu-vexpress-a9/cpu/pmu.c | 12 - bsp/qemu-vexpress-a9/cpu/pmu.h | 151 ------ bsp/qemu-vexpress-a9/cpu/stack.c | 71 --- bsp/qemu-vexpress-a9/cpu/start_gcc.S | 447 ------------------ bsp/qemu-vexpress-a9/cpu/trap.c | 190 -------- bsp/qemu-vexpress-a9/cpu/vector_gcc.S | 65 --- bsp/qemu-vexpress-a9/drivers/board.c | 9 + bsp/qemu-vexpress-a9/platform/SConscript | 13 + bsp/qemu-vexpress-a9/platform/cpu/platform.h | 37 ++ bsp/qemu-vexpress-a9/rtconfig.h | 149 ++++++ bsp/qemu-vexpress-a9/rtconfig.py | 5 +- components/lwp/SConscript | 2 +- components/lwp/arch/arm/cortex-a/lwp_gcc.S | 70 +++ libcpu/arm/cortex-a/context_gcc.S | 92 ++++ libcpu/arm/cortex-a/cp15.h | 4 + libcpu/arm/cortex-a/cp15_gcc.S | 15 +- libcpu/arm/cortex-a/cpu.c | 66 ++- .../cpu => libcpu/arm/cortex-a}/gic.c | 26 +- .../cpu => libcpu/arm/cortex-a}/gic.h | 16 +- libcpu/arm/cortex-a/interrupt.c | 121 ++--- libcpu/arm/cortex-a/interrupt.h | 32 ++ libcpu/arm/cortex-a/mmu.c | 49 +- libcpu/arm/cortex-a/mmu.h | 48 ++ libcpu/arm/cortex-a/stack.c | 6 +- libcpu/arm/cortex-a/start_gcc.S | 112 ++++- libcpu/arm/cortex-a/trap.c | 70 +-- 47 files changed, 1228 insertions(+), 2957 deletions(-) create mode 100644 bsp/imx6ul/.config delete mode 100644 bsp/imx6ul/platform/cpu/gic.c delete mode 100644 bsp/imx6ul/platform/cpu/mmu.c delete mode 100644 bsp/imx6ul/platform/cpu/mmu.h create mode 100644 bsp/imx6ul/platform/cpu/platform.h delete mode 100644 bsp/imx6ul/platform/include/gic.h delete mode 100644 bsp/imx6ul/platform/include/interrupt.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/SConscript delete mode 100644 bsp/qemu-vexpress-a9/cpu/armv7.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/context_gcc.S delete mode 100644 bsp/qemu-vexpress-a9/cpu/cp15.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/cp15_gcc.S delete mode 100644 bsp/qemu-vexpress-a9/cpu/cpuport.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/interrupt.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/interrupt.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/mmu.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/pmu.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/pmu.h delete mode 100644 bsp/qemu-vexpress-a9/cpu/stack.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/start_gcc.S delete mode 100644 bsp/qemu-vexpress-a9/cpu/trap.c delete mode 100644 bsp/qemu-vexpress-a9/cpu/vector_gcc.S create mode 100644 bsp/qemu-vexpress-a9/platform/SConscript create mode 100644 bsp/qemu-vexpress-a9/platform/cpu/platform.h create mode 100644 components/lwp/arch/arm/cortex-a/lwp_gcc.S rename {bsp/qemu-vexpress-a9/cpu => libcpu/arm/cortex-a}/gic.c (92%) rename {bsp/qemu-vexpress-a9/cpu => libcpu/arm/cortex-a}/gic.h (67%) create mode 100644 libcpu/arm/cortex-a/interrupt.h create mode 100644 libcpu/arm/cortex-a/mmu.h diff --git a/bsp/imx6ul/.config b/bsp/imx6ul/.config new file mode 100644 index 0000000000..a9299a366b --- /dev/null +++ b/bsp/imx6ul/.config @@ -0,0 +1,358 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# +CONFIG_BOARD_IMX6UL=y + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# 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_IDEL_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=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 is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +# CONFIG_RT_USING_MEMHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMTRACE is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart" +CONFIG_RT_VER_NUM=0x40001 +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_CORTEX_A=y +CONFIG_ARCH_ARM_CORTEX_A7=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_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=5 +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=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 + +# +# Device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=2 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=2 +CONFIG_DFS_FD_MAX=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_UFFS is not set +# CONFIG_RT_USING_DFS_JFFS2 is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_PIPE_BUFSZ=512 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_MTD 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_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set + +# +# Using WiFi +# +# 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_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_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT is not set + +# +# VBUS(Virtual Software BUS) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_LOGTRACE is not set +# 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 is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_PAHOMQTT 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_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_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_AT_DEVICE 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_IOTKIT is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER 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 + +# +# 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 + +# +# 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 + +# +# 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_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 + +# +# peripheral libraries and drivers +# + +# +# sensors drivers +# +# CONFIG_PKG_USING_LSM6DSL is not set +# CONFIG_PKG_USING_LPS22HB is not set +# CONFIG_PKG_USING_HTS221 is not set +# CONFIG_PKG_USING_LSM303AGR is not set +# CONFIG_PKG_USING_BME280 is not set +# CONFIG_PKG_USING_BMA400 is not set +# CONFIG_PKG_USING_BMI160_BMX160 is not set +# CONFIG_PKG_USING_SPL0601 is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_AHT10 is not set +# CONFIG_PKG_USING_AP3216C 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_MPU6XXX is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_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 + +# +# 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_RT_USING_UART0 is not set +CONFIG_RT_USING_UART1=y diff --git a/bsp/imx6ul/drivers/board.c b/bsp/imx6ul/drivers/board.c index e53e2405b6..015a3709c1 100644 --- a/bsp/imx6ul/drivers/board.c +++ b/bsp/imx6ul/drivers/board.c @@ -20,6 +20,15 @@ #include #include +#include + +struct mem_desc platform_mem_desc[] = { + {0x00000000, 0x80000000, 0x00000000, DEVICE_MEM}, + {0x80000000, 0xFFF00000, 0x80000000, NORMAL_MEM} +}; + +const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]); + static void rt_hw_timer_isr(int vector, void *param) { rt_tick_increase(); @@ -32,17 +41,17 @@ int rt_hw_timer_init(void) // Make sure the timer is off. HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0; - + HW_ARMGLOBALTIMER_CONTROL.B.FCR0 =1; - + HW_ARMGLOBALTIMER_CONTROL.B.FCR1 =0; - + HW_ARMGLOBALTIMER_CONTROL.B.DBG_ENABLE =0; - + // Clear counter. HW_ARMGLOBALTIMER_COUNTER_HI_WR(0); HW_ARMGLOBALTIMER_COUNTER_LO_WR(0); - + // Now turn on the timer. HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1; diff --git a/bsp/imx6ul/platform/SConscript b/bsp/imx6ul/platform/SConscript index 34834e6391..9ba43b1483 100644 --- a/bsp/imx6ul/platform/SConscript +++ b/bsp/imx6ul/platform/SConscript @@ -8,14 +8,12 @@ drivers/imx_timer.c drivers/imx_i2c.c drivers/imx_uart.c cpu/armv7_cache.c -cpu/gic.c cpu/ccm_pll2.c -cpu/mmu.c cpu/cortex_a_gcc.S ''') CPPPATH = [ cwd + '/cpu', -cwd + '/include', +cwd + '/include', cwd + '/include/mx6ul', cwd + '/include/mx6ul/registers' ] diff --git a/bsp/imx6ul/platform/cpu/gic.c b/bsp/imx6ul/platform/cpu/gic.c deleted file mode 100644 index 2f140e02c6..0000000000 --- a/bsp/imx6ul/platform/cpu/gic.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include "gic.h" -#include "gic_registers.h" -#include "cortex_a.h" - -//////////////////////////////////////////////////////////////////////////////// -// Prototypes -//////////////////////////////////////////////////////////////////////////////// - -static inline gicd_t * gic_get_gicd(void); -static inline gicc_t * gic_get_gicc(void); -static inline uint32_t irq_get_register_offset(uint32_t irqID); -static inline uint32_t irq_get_bit_offset(uint32_t irqID); -static inline uint32_t irq_get_bit_mask(uint32_t irqID); - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -static inline gicd_t * gic_get_gicd(void) -{ - uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset; - return (gicd_t *)base; -} - -static inline gicc_t * gic_get_gicc(void) -{ - uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset; - return (gicc_t *)base; -} - -static inline uint32_t irq_get_register_offset(uint32_t irqID) -{ - return irqID / 32; -} - -static inline uint32_t irq_get_bit_offset(uint32_t irqID) -{ - return irqID & 0x1f; -} - -static inline uint32_t irq_get_bit_mask(uint32_t irqID) -{ - return 1 << irq_get_bit_offset(irqID); -} - -void gic_enable(bool enableIt) -{ - gicd_t * gicd = gic_get_gicd(); - - if (enableIt) - { - // Enable both secure and non-secure. - gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1; - } - else - { - // Clear the enable bits. - gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1); - } -} - -void gic_set_irq_security(uint32_t irqID, bool isSecure) -{ - gicd_t * gicd = gic_get_gicd(); - - uint32_t reg = irq_get_register_offset(irqID); - uint32_t mask = irq_get_bit_mask(irqID); - - uint32_t value = gicd->IGROUPRn[reg]; - if (!isSecure) - { - value &= ~mask; - } - else - { - value |= mask; - } - gicd->IGROUPRn[reg] = value; -} - -void gic_enable_irq(uint32_t irqID, bool isEnabled) -{ - gicd_t * gicd = gic_get_gicd(); - - uint32_t reg = irq_get_register_offset(irqID); - uint32_t mask = irq_get_bit_mask(irqID); - - // Select set-enable or clear-enable register based on enable flag. - if (isEnabled) - { - gicd->ISENABLERn[reg] = mask; - } - else - { - gicd->ICENABLERn[reg] = mask; - } -} - -void gic_set_irq_priority(uint32_t ID, uint32_t priority) -{ - gicd_t * gicd = gic_get_gicd(); - - // Update the priority register. The priority registers are byte accessible, and the register - // struct has the priority registers as a byte array, so we can just index directly by the - // interrupt ID. - gicd->IPRIORITYRn[ID] = priority & 0xff; -} - -void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt) -{ - // Make sure the CPU number is valid. - assert(cpuNumber <= 7); - - gicd_t * gicd = gic_get_gicd(); - uint8_t cpuMask = 1 << cpuNumber; - - // Like the priority registers, the target registers are byte accessible, and the register - // struct has the them as a byte array, so we can just index directly by the - // interrupt ID. - if (enableIt) - { - gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff); - } - else - { - gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff); - } -} - -void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list) -{ - gicd_t * gicd = gic_get_gicd(); - - gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter) - | (target_list << kBP_GICD_SGIR_CPUTargetList) - | (irqID & 0xf); -} - -void gic_cpu_enable(bool enableIt) -{ - gicc_t * gicc = gic_get_gicc(); - - if (enableIt) - { - gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS; - } - else - { - gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS); - } -} - -void gic_set_cpu_priority_mask(uint32_t priority) -{ - gicc_t * gicc = gic_get_gicc(); - gicc->PMR = priority & 0xff; -} - -uint32_t gic_read_irq_ack(void) -{ - gicc_t * gicc = gic_get_gicc(); - return gicc->IAR; -} - -void gic_write_end_of_irq(uint32_t irqID) -{ - gicc_t * gicc = gic_get_gicc(); - gicc->EOIR = irqID; -} - -void gic_init(void) -{ - gicd_t * gicd = gic_get_gicd(); - - // First disable the distributor. - gic_enable(false); - - // Clear all pending interrupts. - int i; - for (i = 0; i < 32; ++i) - { - gicd->ICPENDRn[i] = 0xffffffff; - } - - // Set all interrupts to secure. - for (i = 0; i < 8; ++i) - { - gicd->IGROUPRn[i] = 0; - } - - // Init the GIC CPU interface. - gic_init_cpu(); - - // Now enable the distributor. - gic_enable(true); -} - -void gic_init_cpu(void) -{ - // Init the GIC CPU interface. - gic_set_cpu_priority_mask(0xff); - - // Disable preemption. - gicc_t * gicc = gic_get_gicc(); - gicc->BPR = 7; - - // Enable signaling the CPU. - gic_cpu_enable(true); -} - -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/cpu/mmu.c b/bsp/imx6ul/platform/cpu/mmu.c deleted file mode 100644 index 0cf20c9942..0000000000 --- a/bsp/imx6ul/platform/cpu/mmu.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*! - * @file mmu.c - * @brief System memory arangement. - */ -#include "cortex_a.h" -#include "mmu.h" -#include "arm_cp_registers.h" - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Size in bytes of the first-level page table. -#define MMU_L1_PAGE_TABLE_SIZE (16 * 1024) - -//! @brief First-level 1MB section descriptor entry. -typedef union mmu_l1_section { - uint32_t u; - struct { - uint32_t id:2; //!< ID - uint32_t b:1; //!< Bufferable - uint32_t c:1; //!< Cacheable - uint32_t xn:1; //!< Execute-not - uint32_t domain:4; //!< Domain - uint32_t _impl_defined:1; //!< Implementation defined, should be zero. - uint32_t ap1_0:2; //!< Access permissions AP[1:0] - uint32_t tex:3; //!< TEX remap - uint32_t ap2:1; //!< Access permissions AP[2] - uint32_t s:1; //!< Shareable - uint32_t ng:1; //!< Not-global - uint32_t _zero:1; //!< Should be zero. - uint32_t ns:1; //!< Non-secure - uint32_t address:12; //!< Physical base address - }; -} mmu_l1_section_t; - -enum { - kMMU_L1_Section_ID = 2, //!< ID value for a 1MB section first-level entry. - kMMU_L1_Section_Address_Shift = 20 //!< Bit offset of the physical base address field. -}; - -//////////////////////////////////////////////////////////////////////////////// -// Externs -//////////////////////////////////////////////////////////////////////////////// - -extern char __l1_page_table_start; - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -void mmu_enable() -{ - // invalidate all tlb - arm_unified_tlb_invalidate(); - - // read SCTLR - uint32_t sctlr; - _ARM_MRC(15, 0, sctlr, 1, 0, 0); - - // set MMU enable bit - sctlr |= BM_SCTLR_M; - - // write modified SCTLR - _ARM_MCR(15, 0, sctlr, 1, 0, 0); -} - -void mmu_disable() -{ - // read current SCTLR - uint32_t sctlr; - _ARM_MRC(15, 0, sctlr, 1, 0, 0); - - // clear MMU enable bit - sctlr &=~ BM_SCTLR_M; - - // write modified SCTLR - _ARM_MCR(15, 0, sctlr, 1, 0, 0); -} - -void mmu_init() -{ - // Get the L1 page table base address. - uint32_t * table = (uint32_t *)&__l1_page_table_start; - uint32_t share_attr = kShareable; - - // write table address to TTBR0 - _ARM_MCR(15, 0, table, 2, 0, 0); - - // set Client mode for all Domains - uint32_t dacr = 0x55555555; - _ARM_MCR(15, 0, dacr, 3, 0, 0); // MCR p15, 0, , c3, c0, 0 ; Write DACR - - // Clear the L1 table. - bzero(table, MMU_L1_PAGE_TABLE_SIZE); - - // Create default mappings. - mmu_map_l1_range(0x00000000, 0x00000000, 0x00900000, kStronglyOrdered, kShareable, kRWAccess); // ROM and peripherals - mmu_map_l1_range(0x00900000, 0x00900000, 0x00100000, kStronglyOrdered, kShareable, kRWAccess); // OCRAM - mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kStronglyOrdered, kShareable, kRWAccess); // More peripherals - - // Check whether SMP is enabled. If it is not, then we don't want to make SDRAM shareable. - uint32_t actlr = 0x0; - _ARM_MRC(15, 0, actlr, 1, 0, 1); - if (actlr & BM_ACTLR_SMP) - { - share_attr = kShareable; - } - else - { - share_attr = kNonshareable; - } - -#if defined(CHIP_MX6DQ) || defined(CHIP_MX6SDL) - mmu_map_l1_range(0x10000000, 0x10000000, 0x80000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 2GB DDR -#elif defined(CHIP_MX6SL) || defined(CHIP_MX6UL) - mmu_map_l1_range(0x80000000, 0x80000000, 0x40000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 1GB DDR -#else -#error Unknown chip type! -#endif -} - -void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access) -{ - register mmu_l1_section_t entry; - entry.u = 0; - - // Set constant attributes. - entry.id = kMMU_L1_Section_ID; - entry.xn = 0; // Allow execution - entry.domain = 0; // Domain 0 - entry.ng = 0; // Global - entry.ns = 0; // Secure - - // Set attributes based on the selected memory type. - switch (memoryType) - { - case kStronglyOrdered: - entry.c = 0; - entry.b = 0; - entry.tex = 0; - entry.s = 1; // Ignored - break; - case kDevice: - if (isShareable) - { - entry.c = 0; - entry.b = 1; - entry.tex = 0; - entry.s = 1; // Ignored - } - else - { - entry.c = 0; - entry.b = 0; - entry.tex = 2; - entry.s = 0; // Ignored - } - break; - case kOuterInner_WB_WA: - entry.c = 1; - entry.b = 1; - entry.tex = 1; - entry.s = isShareable; - break; - case kOuterInner_WT: - entry.c = 1; - entry.b = 0; - entry.tex = 0; - entry.s = isShareable; - break; - case kNoncacheable: - entry.c = 0; - entry.b = 0; - entry.tex = 1; - entry.s = isShareable; - break; - } - - // Set attributes from specified access mode. - switch (access) - { - case kNoAccess: - entry.ap2 = 0; - entry.ap1_0 = 0; - break; - case kROAccess: - entry.ap2 = 1; - entry.ap1_0 = 3; - break; - case kRWAccess: - entry.ap2 = 0; - entry.ap1_0 = 3; - break; - } - - // Get the L1 page table base address. - uint32_t * table = (uint32_t *)&__l1_page_table_start; - - // Convert addresses to 12-bit bases. - uint32_t vbase = va >> kMMU_L1_Section_Address_Shift; - uint32_t pbase = pa >> kMMU_L1_Section_Address_Shift; - uint32_t entries = length >> kMMU_L1_Section_Address_Shift; - - // Fill in L1 page table entries. - for (; entries > 0; ++pbase, ++vbase, --entries) - { - entry.address = pbase; - table[vbase] = entry.u; - } - - // Invalidate TLB - arm_unified_tlb_invalidate(); -} - -bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress) -{ - uint32_t pa = 0; - - // VA to PA translation with privileged read permission check - _ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 0); - - // Read PA register - _ARM_MRC(15, 0, pa, 7, 4, 0); - - // First bit of returned value is Result of conversion (0 is successful translation) - if (pa & 1) - { - // We can try write permission also - // VA to PA translation with privileged write permission check - _ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 1); - - // Read PA register - _ARM_MRC(15, 0, pa, 7, 4, 0); - - // First bit of returned value is Result of conversion (0 is successful translation) - if (pa & 1) - { - return false; - } - } - - if (physicalAddress) - { - // complete address returning base + offset - pa = (pa & 0xfffff000) | (virtualAddress & 0x00000fff); - *physicalAddress = pa; - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/cpu/mmu.h b/bsp/imx6ul/platform/cpu/mmu.h deleted file mode 100644 index 961c17f541..0000000000 --- a/bsp/imx6ul/platform/cpu/mmu.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2008-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//! @addtogroup diag_mmu -//! @{ - -/*! - * @file mmu.h - * @brief System memory arrangement. - */ - -#ifndef _MMU_H_ -#define _MMU_H_ - -#include "sdk.h" - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Memory region attributes. -typedef enum _mmu_memory_type -{ - kStronglyOrdered, - kDevice, - kOuterInner_WB_WA, - kOuterInner_WT, - kNoncacheable, -} mmu_memory_type_t; - -//! @brief Memory region shareability options. -typedef enum _mmu_shareability -{ - kShareable = 1, - kNonshareable = 0 -} mmu_shareability_t; - -//! @brief Access permissions for a memory region. -typedef enum _mmu_access -{ - kNoAccess, - kROAccess, - kRWAccess -} mmu_access_t; - -//////////////////////////////////////////////////////////////////////////////// -// Prototypes -//////////////////////////////////////////////////////////////////////////////// - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @brief Enable the MMU. - * - * The L1 page tables and MMU settings must have already been configured by - * calling mmu_init() before the MMU is enabled. - */ -void mmu_enable(); - -/*! - * @brief Disable the MMU. - */ -void mmu_disable(); - -/*! - * @brief Set up the default first-level page table. - * - * Initializes the L1 page table with the following regions: - * - 0x00000000...0x00900000 : ROM and peripherals, strongly-ordered - * - 0x00900000...0x00a00000 : OCRAM, strongly-ordered - * - For MX6DQ or MX6SDL: 0x10000000...0x90000000 : DDR, normal, outer inner, write-back, write-allocate - * - For MX6SL: 0x80000000...0xc0000000 : DDR, normal, outer inner, write-back, write-allocate - * - * If the CPU is participating in SMP, then the DDR regions are made shareable. Otherwise they - * are marked as non-shareable. - * - * The TTBR0 register is set to the base of the L1 table. - * - * All memory domains are configured to allow client access. However, note that only domain 0 is - * used by mmu_map_l1_range(). - */ -void mmu_init(); - -/*! - * @brief Maps a range of memory in the first-level page table. - * - * Entries in the first-level page table are filled in for the range of virtual addresses - * starting at @a va and continuing for @a length bytes. These virtual addreses are mapped - * to the physical addresses starting at @a pa and continuing for @a length bytes. All table - * entries for the range of mapped memory have the same attributes, which are selected with - * the @a memoryType, @a isShareable, and @a access parameters. - * - * @param pa The base physical address of the range to which the virtual address will be mapped. - * @param va The base virtual address of the range. - * @param length The size of the range to be mapped, in bytes. This value must be divisible by 1MB. - * @param memoryType The type of the memory region. This controls caching, buffering, ordering of - * memory accesses, and other attributes of the region. - * @param isShareable The shareability of the physical memory. Ignored for strongly-ordered memory. - * @param access Access permissions. - */ -void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access); - -/*! - * @brief Convert virtual address to physical. - * - * First attempts a priviledged read translation for the current security mode. If that fails, - * a priviledged write translation, also for the current security mode, is attempted. If this - * second attempt at translation fails, then false will be returned. - * - * @param virtualAddress Virtual address to convert to a physical address. - * @param[out] physicalAddress This parameter is filled in with the physical address corresponding - * to the virtual address passed in @a virtualAddress. - * @retval true The address returned through @a physicalAddress is valid. - * @retval false The conversion failed for some reason. - */ -bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress); - -#if defined(__cplusplus) -} -#endif - -//! @} - -#endif // _MMU_H_ -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// - diff --git a/bsp/imx6ul/platform/cpu/platform.h b/bsp/imx6ul/platform/cpu/platform.h new file mode 100644 index 0000000000..f6a3995bc5 --- /dev/null +++ b/bsp/imx6ul/platform/cpu/platform.h @@ -0,0 +1,96 @@ +/* + * 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 __PLATFORM_H__ +#define __PLATFORM_H__ + +#include +#include + +/* SOC-relative definitions */ +//#include "realview.h" +#include "gic_registers.h" +#include "irq_numbers.h" + +/* the maximum number of gic */ +# define ARM_GIC_MAX_NR 1 + +/* the maximum number of interrupts */ +#define ARM_GIC_NR_IRQS IMX_INTERRUPT_COUNT + +/* the maximum entries of the interrupt table */ +#define MAX_HANDLERS IMX_INTERRUPT_COUNT + +/* the basic constants needed by gic */ +rt_inline rt_uint32_t platform_get_gic_dist_base(void) +{ + rt_uint32_t gic_base; + asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base)); + return gic_base + kGICDBaseOffset; +} + +rt_inline rt_uint32_t platform_get_gic_cpu_base(void) +{ + rt_uint32_t gic_base; + asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base)); + return gic_base + kGICCBaseOffset; +} + +#define GIC_IRQ_START 0 + +#define GIC_ACK_INTID_MASK 0x000003ff + +/* the definition needed by gic.c */ +#define __REG32(x) (*((volatile unsigned int *)(x))) + +/* keep compatible with platform SDK */ +typedef enum { + CPU_0, + CPU_1, + CPU_2, + CPU_3, +} cpuid_e; + +enum _gicd_sgi_filter +{ + //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter. + kGicSgiFilter_UseTargetList = 0, + + //! Forward the interrupt to all CPU interfaces except that of the processor that requested + //! the interrupt. + kGicSgiFilter_AllOtherCPUs = 1, + + //! Forward the interrupt only to the CPU interface of the processor that requested the + //! interrupt. + kGicSgiFilter_OnlyThisCPU = 2 +}; + +typedef void (*irq_hdlr_t) (void); + +extern void rt_hw_interrupt_mask(int vector); +extern void rt_hw_interrupt_umask(int vector); +extern rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +rt_inline void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr) +{ + rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown"); +} + +rt_inline void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority) +{ + rt_hw_interrupt_umask(irq_id); +} + +rt_inline void disable_interrupt(uint32_t irq_id, uint32_t cpu_id) +{ + rt_hw_interrupt_mask(irq_id); +} + +#endif /* __PLATFORM_H__ */ diff --git a/bsp/imx6ul/platform/include/gic.h b/bsp/imx6ul/platform/include/gic.h deleted file mode 100644 index f3eee8499c..0000000000 --- a/bsp/imx6ul/platform/include/gic.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2011-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __GIC_H__ -#define __GIC_H__ - -#include "sdk_types.h" - -//! @addtogroup gic -//! @{ - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief Options for sending a software generated interrupt. -//! -//! These options are used for the @a filter_list parameter of the gic_send_sgi() -//! function. They control how to select which CPUs that the interrupt is -//! sent to. -enum _gicd_sgi_filter -{ - //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter. - kGicSgiFilter_UseTargetList = 0, - - //! Forward the interrupt to all CPU interfaces except that of the processor that requested - //! the interrupt. - kGicSgiFilter_AllOtherCPUs = 1, - - //! Forward the interrupt only to the CPU interface of the processor that requested the - //! interrupt. - kGicSgiFilter_OnlyThisCPU = 2 -}; - -//////////////////////////////////////////////////////////////////////////////// -// API -//////////////////////////////////////////////////////////////////////////////// - -#if defined(__cplusplus) -extern "C" { -#endif - -//! @name Initialization -//@{ -//! @brief Init interrupt handling. -//! -//! This function is intended to be called only by the primary CPU init code, so it will -//! only be called once during system bootup. -//! -//! Also inits the current CPU. You don't need to call gic_init_cpu() separately. -//! -//! @post The interrupt distributor and the current CPU interface are enabled. All interrupts -//! that were pending are cleared, and all interrupts are made secure (group 0). -void gic_init(void); - -//! @brief Init the current CPU's GIC interface. -//! -//! @post Enables the CPU interface and sets the priority mask to 255. Interrupt preemption -//! is disabled by setting the Binary Point to a value of 7. -void gic_init_cpu(void); -//@} - -//! @name GIC Interrupt Distributor Functions -//@{ -//! @brief Enable or disable the GIC Distributor. -//! -//! Enables or disables the GIC distributor passing both secure (group 0) and non-secure -//! (group 1) interrupts to the CPU interfaces. -//! -//! @param enableIt Pass true to enable or false to disable. -void gic_enable(bool enableIt); - -//! @brief Set the security mode for an interrupt. -//! -//! @param irqID The interrupt number. -//! @param isSecure Whether the interrupt is taken to secure mode. -void gic_set_irq_security(uint32_t irqID, bool isSecure); - -//! @brief Enable or disable an interrupt. -//! -//! @param irqID The number of the interrupt to control. -//! @param isEnabled Pass true to enable or false to disable. -void gic_enable_irq(uint32_t irqID, bool isEnabled); - -//! @brief Set whether a CPU will receive a particular interrupt. -//! -//! @param irqID The interrupt number. -//! @param cpuNumber The CPU number. The first CPU core is 0. -//! @param enableIt Whether to send the interrupt to the specified CPU. Pass true to enable -//! or false to disable. -void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt); - -//! @brief Set an interrupt's priority. -//! -//! @param irq_id The interrupt number. -//! @param priority The priority for the interrupt. In the range of 0 through 0xff, with -//! 0 being the highest priority. -void gic_set_irq_priority(uint32_t irq_id, uint32_t priority); - -//! @brief Send a software generated interrupt to a specific CPU. -//! -//! @param irq_id The interrupt number to send. -//! @param target_list Each bit indicates a CPU to which the interrupt will be forwarded. -//! Bit 0 is CPU 0, bit 1 is CPU 1, and so on. If the value is 0, then the interrupt -//! will not be forwarded to any CPUs. This parameter is only used if @a filter_list -//! is set to #kGicSgiFilter_UseTargetList. -//! @param filter_list One of the enums of the #_gicd_sgi_filter enumeration. The selected -//! option determines which CPUs the interrupt will be sent to. If the value -//! is #kGicSgiFilter_UseTargetList, then the @a target_list parameter is used. -void gic_send_sgi(uint32_t irq_id, uint32_t target_list, uint32_t filter_list); -//@} - -//! @name GIC CPU Interface Functions -//@{ -//! @brief Enable or disable the interface to the GIC for the current CPU. -//! -//! @param enableIt Pass true to enable or false to disable. -void gic_cpu_enable(bool enableIt); - -//! @brief Set the mask of which interrupt priorities the CPU will receive. -//! -//! @param priority The lowest priority that will be passed to the current CPU. Pass 0xff to -//! allow all priority interrupts to signal the CPU. -void gic_set_cpu_priority_mask(uint32_t priority); - -//! @brief Acknowledge starting of interrupt handling and get the interrupt number. -//! -//! Normally, this function is called at the beginning of the IRQ handler. It tells the GIC -//! that you are starting to handle an interupt, and returns the number of the interrupt you -//! need to handle. After the interrupt is handled, you should call gic_write_end_of_irq() -//! to signal that the interrupt is completely handled. -//! -//! In some cases, a spurious interrupt might happen. One possibility is if another CPU handles -//! the interrupt. When a spurious interrupt occurs, the end of the interrupt should be indicated -//! but nothing else. -//! -//! @return The number for the highest priority interrupt available for the calling CPU. If -//! the return value is 1022 or 1023, a spurious interrupt has occurred. -uint32_t gic_read_irq_ack(void); - -//! @brief Signal the end of handling an interrupt. -//! -//! @param irq_id The number of the interrupt for which handling has finished. -void gic_write_end_of_irq(uint32_t irq_id); -//@} - - -#if defined(__cplusplus) -} -#endif - -//! @} - -#endif // __GIC_H__ -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/include/interrupt.h b/bsp/imx6ul/platform/include/interrupt.h deleted file mode 100644 index 318e34f3bd..0000000000 --- a/bsp/imx6ul/platform/include/interrupt.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2009-2012, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ - -#include "sdk_types.h" -#include "irq_numbers.h" - -//! @addtogroup diag_interrupt -//! @{ - -/*! - * @file interrupt.h - * @brief Interface for the interrupt manager. - */ - -//////////////////////////////////////////////////////////////////////////////// -// Definitions -//////////////////////////////////////////////////////////////////////////////// - -//! @brief -typedef enum { - CPU_0, - CPU_1, - CPU_2, - CPU_3, -} cpuid_e; - -//! @brief Interrupt service routine. -typedef void (*irq_hdlr_t) (void); - -//////////////////////////////////////////////////////////////////////////////// -// API -//////////////////////////////////////////////////////////////////////////////// - -#if defined(__cplusplus) -extern "C" { -#endif - -//! @brief Enable an interrupt. -//! -//! Sets the interrupt priority and makes it non-secure. Then the interrupt is -//! enabled on the CPU specified by @a cpu_id. -//! -//! @param irq_id The interrupt number to enable. -//! @param cpu_id The index of the CPU for which the interrupt will be enabled. -//! @param priority The interrupt priority, from 0-255. Lower numbers have higher priority. -void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority); - -//! @brief Disable an interrupt on the specified CPU. -//! -//! @param irq_id The interrupt number to disabled. -//! @param cpu_id The index of the CPU for which the interrupt will be disabled. -void disable_interrupt(uint32_t irq_id, uint32_t cpu_id); - -//! @brief Set the interrupt service routine for the specified interrupt. -//! -//! @param irq_id The interrupt number. -//! @param isr Function that will be called to handle the interrupt. -void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr); - -//! @brief Interrupt handler that simply prints a message. -void default_interrupt_routine(void); - -#if defined(__cplusplus) -} -#endif - -//! @} - -#endif -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/rtconfig.py b/bsp/imx6ul/rtconfig.py index 2c08665920..0a9ea3dce3 100644 --- a/bsp/imx6ul/rtconfig.py +++ b/bsp/imx6ul/rtconfig.py @@ -10,7 +10,7 @@ if os.getenv('RTT_CC'): # only support GNU GCC compiler. PLATFORM = 'gcc' -EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin' +EXEC_PATH = '/usr/bin' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config index c8814d366a..6fde000858 100644 --- a/bsp/qemu-vexpress-a9/.config +++ b/bsp/qemu-vexpress-a9/.config @@ -322,6 +322,7 @@ CONFIG_RT_USING_LWP=y # 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_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set diff --git a/bsp/qemu-vexpress-a9/SConstruct b/bsp/qemu-vexpress-a9/SConstruct index 638311d697..d618790dec 100644 --- a/bsp/qemu-vexpress-a9/SConstruct +++ b/bsp/qemu-vexpress-a9/SConstruct @@ -5,7 +5,7 @@ import rtconfig if os.getenv('RTT_ROOT'): RTT_ROOT = os.getenv('RTT_ROOT') else: - RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + RTT_ROOT = os.path.join(os.getcwd(), '..', '..') sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] from building import * @@ -25,7 +25,7 @@ Export('RTT_ROOT') Export('rtconfig') # prepare building environment -objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True) +objs = PrepareBuilding(env, RTT_ROOT) # make a building DoBuilding(TARGET, objs) diff --git a/bsp/qemu-vexpress-a9/cpu/SConscript b/bsp/qemu-vexpress-a9/cpu/SConscript deleted file mode 100644 index b45f95cc1a..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -Import('rtconfig') -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') -CPPPATH = [cwd] - -if rtconfig.PLATFORM == 'iar': - src += Glob('*_iar.S') -elif rtconfig.PLATFORM == 'gcc': - src += Glob('*_gcc.S') -elif rtconfig.PLATFORM == 'armcc': - src += Glob('*_rvds.S') - -group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/qemu-vexpress-a9/cpu/armv7.h b/bsp/qemu-vexpress-a9/cpu/armv7.h deleted file mode 100644 index 69c556eb3c..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/armv7.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __ARMV7_H__ -#define __ARMV7_H__ - -/* the exception stack without VFP registers */ -struct rt_hw_exp_stack -{ - 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; -}; - -struct rt_hw_stack -{ - unsigned long cpsr; - 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 lr; - unsigned long pc; -}; - -#define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define MONITORMODE 0x16 -#define ABORTMODE 0x17 -#define HYPMODE 0x1b -#define UNDEFMODE 0x1b -#define MODEMASK 0x1f -#define NOINT 0xc0 - -#define T_Bit (1<<5) -#define F_Bit (1<<6) -#define I_Bit (1<<7) -#define A_Bit (1<<8) -#define E_Bit (1<<9) -#define J_Bit (1<<24) - -#endif diff --git a/bsp/qemu-vexpress-a9/cpu/context_gcc.S b/bsp/qemu-vexpress-a9/cpu/context_gcc.S deleted file mode 100644 index 0aad0200d5..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/context_gcc.S +++ /dev/null @@ -1,198 +0,0 @@ -/* - * File : context.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, 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 - * 2013-07-05 Bernard the first version - * 2018-11-22 Jesven in the smp version, using macro to - * define rt_hw_interrupt_enable and rt_hw_interrupt_disable - * rt_hw_context_switch_interrupt switches to the new thread directly - */ - -#include "rtconfig.h" -.section .text, "ax" - -#ifdef RT_USING_SMP -#define rt_hw_interrupt_disable rt_hw_local_irq_disable -#define rt_hw_interrupt_enable rt_hw_local_irq_enable -#endif - -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.globl rt_hw_interrupt_disable -rt_hw_interrupt_disable: - mrs r0, cpsr - cpsid i - bx lr - -/* - * void rt_hw_interrupt_enable(rt_base_t level); - */ -.globl rt_hw_interrupt_enable -rt_hw_interrupt_enable: - msr cpsr, r0 - bx lr - -/* - * void rt_hw_context_switch_to(rt_uint32 to); - * r0 --> to - */ -.globl rt_hw_context_switch_to -rt_hw_context_switch_to: - ldr sp, [r0] @ get new task stack pointer - -#ifdef RT_USING_SMP - mov r0, r1 - bl rt_cpus_lock_status_restore -#endif /*RT_USING_SMP*/ - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc - -.section .bss.share.isr -_guest_switch_lvl: - .word 0 - -.section .text.isr, "ax" -/* - * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); - * r0 --> from - * r1 --> to - */ -.globl rt_hw_context_switch -rt_hw_context_switch: - stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) - stmfd sp!, {r0-r12, lr} @ push lr & register file - - mrs r4, cpsr - tst lr, #0x01 - orrne r4, r4, #0x20 @ it's thumb code - - stmfd sp!, {r4} @ push cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13, r14}^ @ push usr_sp usr_lr - sub sp, #8 -#endif - - str sp, [r0] @ store sp in preempted tasks TCB - ldr sp, [r1] @ get new task stack pointer - -#ifdef RT_USING_SMP - mov r0, r2 - bl rt_cpus_lock_status_restore -#endif /*RT_USING_SMP*/ - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task cpsr to spsr - msr spsr_cxsf, r4 - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr - -/* - * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); - */ -.equ Mode_USR, 0x10 -.equ Mode_FIQ, 0x11 -.equ Mode_IRQ, 0x12 -.equ Mode_SVC, 0x13 -.equ Mode_ABT, 0x17 -.equ Mode_UND, 0x1B -.equ Mode_SYS, 0x1F - -.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled -.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled - -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_hw_context_switch_interrupt -rt_hw_context_switch_interrupt: -#ifdef RT_USING_SMP - /* r0 :irq_mod context - * r1 :addr of from_thread's sp - * r2 :addr of to_thread's sp - * r3 :to_thread's tcb - */ - - @ r0 point to {r0-r3} in stack - push {r1 - r3} - mov r1, r0 - add r0, r0, #4*4 - ldmfd r0!, {r4-r12,lr}@ reload saved registers - mrs r3, spsr @ get cpsr of interrupt thread - sub r2, lr, #4 @ save old task's pc to r2 - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - - stmfd sp!, {r2} @ push old task's pc - stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 - ldmfd r1, {r4-r7} @ restore r0-r3 of the interrupt thread - stmfd sp!, {r4-r7} @ push old task's r0-r3 - stmfd sp!, {r3} @ push old task's cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13,r14}^ @push usr_sp usr_lr - sub sp, #8 -#endif - - msr cpsr_c, #I_Bit|F_Bit|Mode_IRQ - pop {r1 - r3} - mov sp, r0 - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - str sp, [r1] - - ldr sp, [r2] - mov r0, r3 - bl rt_cpus_lock_status_restore - -#ifdef RT_USING_LWP - ldmfd sp, {r13,r14}^ @pop usr_sp usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task's cpsr to spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr - -#else /*RT_USING_SMP*/ - ldr r2, =rt_thread_switch_interrupt_flag - ldr r3, [r2] - cmp r3, #1 - beq _reswitch - ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread - mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 - str r0, [ip] - str r3, [r2] -_reswitch: - ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread - str r1, [r2] - bx lr -#endif /*RT_USING_SMP*/ diff --git a/bsp/qemu-vexpress-a9/cpu/cp15.h b/bsp/qemu-vexpress-a9/cpu/cp15.h deleted file mode 100644 index ebea3f0fe3..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/cp15.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __CP15_H__ -#define __CP15_H__ - -unsigned long rt_cpu_get_smp_id(void); - -void rt_cpu_mmu_disable(void); -void rt_cpu_mmu_enable(void); -void rt_cpu_tlb_set(volatile unsigned long*); - -void rt_cpu_vector_set_base(unsigned int addr); - -#endif diff --git a/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S b/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S deleted file mode 100644 index f1ed6492aa..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S +++ /dev/null @@ -1,140 +0,0 @@ -/* - * File : cp15_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * http://www.rt-thread.org - * - * 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-07-05 Bernard the first version - */ - -.globl rt_cpu_get_smp_id -rt_cpu_get_smp_id: - mrc p15, #0, r0, c0, c0, #5 - bx lr - -.globl rt_cpu_vector_set_base -rt_cpu_vector_set_base: - mcr p15, #0, r0, c12, c0, #0 - dsb - bx lr - -.globl rt_hw_cpu_dcache_enable -rt_hw_cpu_dcache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_hw_cpu_icache_enable -rt_hw_cpu_icache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -_FLD_MAX_WAY: - .word 0x3ff -_FLD_MAX_IDX: - .word 0x7ff - -.globl rt_cpu_dcache_clean_flush -rt_cpu_dcache_clean_flush: - push {r4-r11} - dmb - mrc p15, #1, r0, c0, c0, #1 @ read clid register - ands r3, r0, #0x7000000 @ get level of coherency - mov r3, r3, lsr #23 - beq finished - mov r10, #0 -loop1: - add r2, r10, r10, lsr #1 - mov r1, r0, lsr r2 - and r1, r1, #7 - cmp r1, #2 - blt skip - mcr p15, #2, r10, c0, c0, #0 - isb - mrc p15, #1, r1, c0, c0, #0 - and r2, r1, #7 - add r2, r2, #4 - ldr r4, _FLD_MAX_WAY - ands r4, r4, r1, lsr #3 - clz r5, r4 - ldr r7, _FLD_MAX_IDX - ands r7, r7, r1, lsr #13 -loop2: - mov r9, r4 -loop3: - orr r11, r10, r9, lsl r5 - orr r11, r11, r7, lsl r2 - mcr p15, #0, r11, c7, c14, #2 - subs r9, r9, #1 - bge loop3 - subs r7, r7, #1 - bge loop2 -skip: - add r10, r10, #2 - cmp r3, r10 - bgt loop1 - -finished: - dsb - isb - pop {r4-r11} - bx lr - -.globl rt_hw_cpu_dcache_disable -rt_hw_cpu_dcache_disable: - push {r4-r11, lr} - bl rt_cpu_dcache_clean_flush - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - pop {r4-r11, lr} - bx lr - -.globl rt_hw_cpu_icache_disable -rt_hw_cpu_icache_disable: - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_cpu_mmu_disable -rt_cpu_mmu_disable: - mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #1 - mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit - dsb - bx lr - -.globl rt_cpu_mmu_enable -rt_cpu_mmu_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x001 - mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit - dsb - bx lr - -.globl rt_cpu_tlb_set -rt_cpu_tlb_set: - mcr p15, #0, r0, c2, c0, #0 - dmb - bx lr diff --git a/bsp/qemu-vexpress-a9/cpu/cpuport.c b/bsp/qemu-vexpress-a9/cpu/cpuport.c deleted file mode 100644 index 6b129f89ee..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/cpuport.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-09-15 Bernard first version - * 2018-11-22 Jesven add rt_hw_cpu_id() - */ - -#include -#include -#include - -#ifdef RT_USING_SMP -int rt_hw_cpu_id(void) -{ - int cpu_id; - __asm__ volatile ( - "mrc p15, 0, %0, c0, c0, 5" - :"=r"(cpu_id) - ); - cpu_id &= 0xf; - return cpu_id; -}; - -void rt_hw_spin_lock(rt_hw_spinlock_t *lock) -{ - unsigned long tmp; - unsigned long newval; - rt_hw_spinlock_t lockval; - - __asm__ __volatile__( - "pld [%0]" - ::"r"(&lock->slock) - ); - - __asm__ __volatile__( - "1: ldrex %0, [%3]\n" - " add %1, %0, %4\n" - " strex %2, %1, [%3]\n" - " teq %2, #0\n" - " bne 1b" - : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) - : "r" (&lock->slock), "I" (1 << 16) - : "cc"); - - while (lockval.tickets.next != lockval.tickets.owner) { - __asm__ __volatile__("wfe":::"memory"); - lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); - } - - __asm__ volatile ("dmb":::"memory"); -} - -void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) -{ - __asm__ volatile ("dmb":::"memory"); - lock->tickets.owner++; - __asm__ volatile ("dsb ishst\nsev":::"memory"); -} -#endif /*RT_USING_SMP*/ - -/** - * @addtogroup ARM CPU - */ -/*@{*/ - -/** shutdown CPU */ -void rt_hw_cpu_shutdown() -{ - rt_uint32_t level; - rt_kprintf("shutdown...\n"); - - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } -} - -/*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/interrupt.c b/bsp/qemu-vexpress-a9/cpu/interrupt.c deleted file mode 100644 index d7e9ec08fa..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/interrupt.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * File : interrupt.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, 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 first version - * 2018-11-22 Jesven add smp support - */ - -#include -#include -#include "realview.h" -#include "gic.h" - -#define MAX_HANDLERS NR_IRQS_PBA8 - -/* exception and interrupt handler table */ -struct rt_irq_desc isr_table[MAX_HANDLERS]; - -#ifndef RT_USING_SMP -/* Those varibles will be accessed in ISR, so we need to share them. */ -rt_uint32_t rt_interrupt_from_thread = 0; -rt_uint32_t rt_interrupt_to_thread = 0; -rt_uint32_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; - -void rt_hw_vector_init(void) -{ - rt_cpu_vector_set_base((unsigned int)&system_vectors); -} - -/** - * This function will initialize hardware interrupt - */ -void rt_hw_interrupt_init(void) -{ - rt_uint32_t gic_cpu_base; - rt_uint32_t gic_dist_base; - - /* initialize vector table */ - rt_hw_vector_init(); - - /* initialize exceptions table */ - rt_memset(isr_table, 0x00, sizeof(isr_table)); - - /* initialize ARM GIC */ - gic_dist_base = REALVIEW_GIC_DIST_BASE; - gic_cpu_base = REALVIEW_GIC_CPU_BASE; - - arm_gic_dist_init(0, gic_dist_base, 0); - arm_gic_cpu_init(0, gic_cpu_base); -} - -/** - * 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 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; -} diff --git a/bsp/qemu-vexpress-a9/cpu/interrupt.h b/bsp/qemu-vexpress-a9/cpu/interrupt.h deleted file mode 100644 index 045246b21d..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/interrupt.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * File : interrupt.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, 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 first version - */ - -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ - -#define INT_IRQ 0x00 -#define INT_FIQ 0x01 - -void rt_hw_interrupt_control(int vector, int priority, int route); - -void rt_hw_interrupt_init(void); - -#endif diff --git a/bsp/qemu-vexpress-a9/cpu/mmu.c b/bsp/qemu-vexpress-a9/cpu/mmu.c deleted file mode 100644 index b2503e4260..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/mmu.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * File : mmu.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, 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 - * 2012-01-10 bernard porting to AM1808 - */ - -#include -#include -#include - -#include "cp15.h" - -#define DESC_SEC (0x2) -#define CB (3<<2) //cache_on, write_back -#define CNB (2<<2) //cache_on, write_through -#define NCB (1<<2) //cache_off,WR_BUF on -#define NCNB (0<<2) //cache_off,WR_BUF off -#define AP_RW (3<<10) //supervisor=RW, user=RW -#define AP_RO (2<<10) //supervisor=RW, user=RO -#define XN (1<<4) // eXecute Never - -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0<<5) -#define DOMAIN1 (0x1<<5) - -#define DOMAIN0_ATTR (DOMAIN_CHK<<0) -#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) - -/* Read/Write, cache, write back */ -#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) -/* Read/Write, cache, write through */ -#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) -/* Read/Write without cache and write buffer */ -#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) -/* Read/Write without cache and write buffer, no execute */ -#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN) -/* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) - -/* dump 2nd level page table */ -void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) -{ - int i; - int fcnt = 0; - - for (i = 0; i < 256; i++) - { - rt_uint32_t pte2 = ptb[i]; - if ((pte2 & 0x3) == 0) - { - if (fcnt == 0) - rt_kprintf(" "); - rt_kprintf("%04x: ", i); - fcnt++; - if (fcnt == 16) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - continue; - } - if (fcnt != 0) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - - rt_kprintf(" %04x: %x: ", i, pte2); - if ((pte2 & 0x3) == 0x1) - { - rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", - ((pte2 >> 7) | (pte2 >> 4))& 0xf, - (pte2 >> 15) & 0x1, - ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); - } - else - { - rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", - ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, - ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); - } - } -} - -void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) -{ - int i; - int fcnt = 0; - - rt_kprintf("page table@%p\n", ptb); - for (i = 0; i < 1024*4; i++) - { - rt_uint32_t pte1 = ptb[i]; - if ((pte1 & 0x3) == 0) - { - rt_kprintf("%03x: ", i); - fcnt++; - if (fcnt == 16) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - continue; - } - if (fcnt != 0) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - - rt_kprintf("%03x: %08x: ", i, pte1); - if ((pte1 & 0x3) == 0x3) - { - rt_kprintf("LPAE\n"); - } - else if ((pte1 & 0x3) == 0x1) - { - rt_kprintf("pte,ns:%d,domain:%d\n", - (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); - /* - *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) - * - 0x80000000 + 0xC0000000)); - */ - } - else if (pte1 & (1 << 18)) - { - rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", - (pte1 >> 19) & 0x1, - ((pte1 >> 13) | (pte1 >> 10))& 0xf, - (pte1 >> 4) & 0x1, - ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); - } - else - { - rt_kprintf("section,ns:%d,ap:%x," - "xn:%d,texcb:%02x,domain:%d\n", - (pte1 >> 19) & 0x1, - ((pte1 >> 13) | (pte1 >> 10))& 0xf, - (pte1 >> 4) & 0x1, - (((pte1 & (0x7 << 12)) >> 10) | - ((pte1 & 0x0c) >> 2)) & 0x1f, - (pte1 >> 5) & 0xf); - } - } -} - -/* level1 page table, each entry for 1MB memory. */ -volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); -void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, - rt_uint32_t vaddrEnd, - rt_uint32_t paddrStart, - rt_uint32_t attr) -{ - volatile rt_uint32_t *pTT; - volatile int i, nSec; - pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); - nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); - for(i = 0; i <= nSec; i++) - { - *pTT = attr | (((paddrStart >> 20) + i) << 20); - pTT++; - } -} - -unsigned long rt_hw_set_domain_register(unsigned long domain_val) -{ - unsigned long old_domain; - - asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); - asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); - - return old_domain; -} - -void rt_hw_mmu_init(void) -{ - rt_hw_cpu_dcache_disable(); - rt_hw_cpu_icache_disable(); - rt_cpu_mmu_disable(); - - /* set page table */ - /* 4G 1:1 memory */ - rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB); - /* IO memory region */ - rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN); - - /*rt_hw_cpu_dump_page_table(MMUTable);*/ - rt_hw_set_domain_register(0x55555555); - - rt_cpu_tlb_set(MMUTable); - - rt_cpu_mmu_enable(); - - rt_hw_cpu_icache_enable(); - rt_hw_cpu_dcache_enable(); -} - diff --git a/bsp/qemu-vexpress-a9/cpu/pmu.c b/bsp/qemu-vexpress-a9/cpu/pmu.c deleted file mode 100644 index 07911a2db7..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/pmu.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include "pmu.h" - -void rt_hw_pmu_dump_feature(void) -{ - unsigned long reg; - - reg = rt_hw_pmu_get_control(); - rt_kprintf("ARM PMU Implementor: %c, ID code: %02x, %d counters\n", - reg >> 24, (reg >> 16) & 0xff, (reg >> 11) & 0x1f); - RT_ASSERT(ARM_PMU_CNTER_NR == ((reg >> 11) & 0x1f)); -} diff --git a/bsp/qemu-vexpress-a9/cpu/pmu.h b/bsp/qemu-vexpress-a9/cpu/pmu.h deleted file mode 100644 index 05c1420dd8..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/pmu.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef __PMU_H__ -#define __PMU_H__ - -#include "board.h" - -/* Number of counters */ -#define ARM_PMU_CNTER_NR 4 - -enum rt_hw_pmu_event_type { - ARM_PMU_EVENT_PMNC_SW_INCR = 0x00, - ARM_PMU_EVENT_L1_ICACHE_REFILL = 0x01, - ARM_PMU_EVENT_ITLB_REFILL = 0x02, - ARM_PMU_EVENT_L1_DCACHE_REFILL = 0x03, - ARM_PMU_EVENT_L1_DCACHE_ACCESS = 0x04, - ARM_PMU_EVENT_DTLB_REFILL = 0x05, - ARM_PMU_EVENT_MEM_READ = 0x06, - ARM_PMU_EVENT_MEM_WRITE = 0x07, - ARM_PMU_EVENT_INSTR_EXECUTED = 0x08, - ARM_PMU_EVENT_EXC_TAKEN = 0x09, - ARM_PMU_EVENT_EXC_EXECUTED = 0x0A, - ARM_PMU_EVENT_CID_WRITE = 0x0B, -}; - -/* Enable bit */ -#define ARM_PMU_PMCR_E (0x01 << 0) -/* Event counter reset */ -#define ARM_PMU_PMCR_P (0x01 << 1) -/* Cycle counter reset */ -#define ARM_PMU_PMCR_C (0x01 << 2) -/* Cycle counter divider */ -#define ARM_PMU_PMCR_D (0x01 << 3) - -#ifdef __GNUC__ -rt_inline void rt_hw_pmu_enable_cnt(int divide64) -{ - unsigned long pmcr; - unsigned long pmcntenset; - - asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - pmcr |= ARM_PMU_PMCR_E | ARM_PMU_PMCR_P | ARM_PMU_PMCR_C; - if (divide64) - pmcr |= ARM_PMU_PMCR_D; - else - pmcr &= ~ARM_PMU_PMCR_D; - asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr)); - - /* enable all the counters */ - pmcntenset = ~0; - asm volatile ("mcr p15, 0, %0, c9, c12, 1" :: "r"(pmcntenset)); - /* clear overflows(just in case) */ - asm volatile ("mcr p15, 0, %0, c9, c12, 3" :: "r"(pmcntenset)); -} - -rt_inline unsigned long rt_hw_pmu_get_control(void) -{ - unsigned long pmcr; - asm ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - return pmcr; -} - -rt_inline unsigned long rt_hw_pmu_get_ceid(void) -{ - unsigned long reg; - /* only PMCEID0 is supported, PMCEID1 is RAZ. */ - asm ("mrc p15, 0, %0, c9, c12, 6" : "=r"(reg)); - return reg; -} - -rt_inline unsigned long rt_hw_pmu_get_cnten(void) -{ - unsigned long pmcnt; - asm ("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcnt)); - return pmcnt; -} - -rt_inline void rt_hw_pmu_reset_cycle(void) -{ - unsigned long pmcr; - - asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - pmcr |= ARM_PMU_PMCR_C; - asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr)); - asm volatile ("isb"); -} - -rt_inline void rt_hw_pmu_reset_event(void) -{ - unsigned long pmcr; - - asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr)); - pmcr |= ARM_PMU_PMCR_P; - asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr)); - asm volatile ("isb"); -} - -rt_inline unsigned long rt_hw_pmu_get_cycle(void) -{ - unsigned long cyc; - asm volatile ("isb"); - asm volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cyc)); - return cyc; -} - -rt_inline void rt_hw_pmu_select_counter(int idx) -{ - RT_ASSERT(idx < ARM_PMU_CNTER_NR); - - asm volatile ("mcr p15, 0, %0, c9, c12, 5" : : "r"(idx)); - /* Linux add an isb here, don't know why here. */ - asm volatile ("isb"); -} - -rt_inline void rt_hw_pmu_select_event(int idx, - enum rt_hw_pmu_event_type eve) -{ - RT_ASSERT(idx < ARM_PMU_CNTER_NR); - - rt_hw_pmu_select_counter(idx); - asm volatile ("mcr p15, 0, %0, c9, c13, 1" : : "r"(eve)); -} - -rt_inline unsigned long rt_hw_pmu_read_counter(int idx) -{ - unsigned long reg; - - rt_hw_pmu_select_counter(idx); - asm volatile ("isb"); - asm volatile ("mrc p15, 0, %0, c9, c13, 2" : "=r"(reg)); - return reg; -} - -rt_inline unsigned long rt_hw_pmu_get_ovsr(void) -{ - unsigned long reg; - asm volatile ("isb"); - asm ("mrc p15, 0, %0, c9, c12, 3" : "=r"(reg)); - return reg; -} - -rt_inline void rt_hw_pmu_clear_ovsr(unsigned long reg) -{ - asm ("mcr p15, 0, %0, c9, c12, 3" : : "r"(reg)); - asm volatile ("isb"); -} - -#endif - -void rt_hw_pmu_dump_feature(void); - -#endif /* end of include guard: __PMU_H__ */ - diff --git a/bsp/qemu-vexpress-a9/cpu/stack.c b/bsp/qemu-vexpress-a9/cpu/stack.c deleted file mode 100644 index dfb97557bc..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/stack.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * File : stack.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, 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 - * 2011-09-23 Bernard the first version - * 2011-10-05 Bernard add thumb mode - */ -#include -#include - -/** - * @addtogroup AM33xx - */ -/*@{*/ - -/** - * 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_uint32_t *stk; - - stack_addr += sizeof(rt_uint32_t); - stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); - stk = (rt_uint32_t*)stack_addr; - *(--stk) = (rt_uint32_t)tentry; /* entry point */ - *(--stk) = (rt_uint32_t)texit; /* lr */ - *(--stk) = 0; /* r12 */ - *(--stk) = 0; /* r11 */ - *(--stk) = 0; /* r10 */ - *(--stk) = 0; /* r9 */ - *(--stk) = 0; /* r8 */ - *(--stk) = 0; /* r7 */ - *(--stk) = 0; /* r6 */ - *(--stk) = 0; /* r5 */ - *(--stk) = 0; /* r4 */ - *(--stk) = 0; /* r3 */ - *(--stk) = 0; /* r2 */ - *(--stk) = 0; /* r1 */ - *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - /* cpsr */ - if ((rt_uint32_t)tentry & 0x01) - *(--stk) = SVCMODE | 0x20; /* thumb mode */ - else - *(--stk) = SVCMODE; /* arm mode */ - -#ifdef RT_USING_LWP - *(--stk) = 0; /* user lr */ - *(--stk) = 0; /* user sp*/ -#endif - - /* return task's current stack address */ - return (rt_uint8_t *)stk; -} - -/*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/start_gcc.S b/bsp/qemu-vexpress-a9/cpu/start_gcc.S deleted file mode 100644 index b71d8a1568..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/start_gcc.S +++ /dev/null @@ -1,447 +0,0 @@ -/* - * File : start_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, 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 - * 2013-07-05 Bernard the first version - * 2018-11-22 Jesven in the interrupt context, use rt_scheduler_do_irq_switch checks - * and switches to a new thread - */ - -#include "rtconfig.h" - -.equ Mode_USR, 0x10 -.equ Mode_FIQ, 0x11 -.equ Mode_IRQ, 0x12 -.equ Mode_SVC, 0x13 -.equ Mode_ABT, 0x17 -.equ Mode_UND, 0x1B -.equ Mode_SYS, 0x1F - -.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled -.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled - -.equ UND_Stack_Size, 0x00000000 -.equ SVC_Stack_Size, 0x00000400 -.equ ABT_Stack_Size, 0x00000000 -.equ RT_FIQ_STACK_PGSZ, 0x00000000 -.equ RT_IRQ_STACK_PGSZ, 0x00000800 -.equ USR_Stack_Size, 0x00000400 - -#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ - RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) - -.section .data.share.isr -/* stack */ -.globl stack_start -.globl stack_top - -stack_start: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top: - -.text -/* reset entry */ -.globl _reset -_reset: - /* set the cpu to SVC32 mode and disable interrupt */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0x13 - msr cpsr_c, r0 - - mrc p15, 0, r1, c1, c0, 1 - mov r0, #(1<<6) - orr r1, r0 - mcr p15, 0, r1, c1, c0, 1 //enable smp - - ldr lr, =after_enable_mmu - ldr r0, =mtbl - b enable_mmu - -after_enable_mmu: - - /* setup stack */ - bl stack_setup - - /* clear .bss */ - mov r0,#0 /* get a zero */ - ldr r1,=__bss_start /* bss start */ - ldr r2,=__bss_end /* bss end */ - -bss_loop: - cmp r1,r2 /* check if data to clear */ - strlo r0,[r1],#4 /* clear 4 bytes */ - blo bss_loop /* loop until done */ - - /* call C++ constructors of global objects */ - ldr r0, =__ctors_start__ - ldr r1, =__ctors_end__ - -ctor_loop: - cmp r0, r1 - beq ctor_end - ldr r2, [r0], #4 - stmfd sp!, {r0-r1} - mov lr, pc - bx r2 - ldmfd sp!, {r0-r1} - b ctor_loop -ctor_end: - - /* start RT-Thread Kernel */ - bl flush_cache_all - ldr pc, _rtthread_startup -_rtthread_startup: - .word rtthread_startup - -stack_setup: - ldr r0, =stack_top - - @ Set the startup stack for svc - mov sp, r0 - - @ Enter Undefined Instruction Mode and set its Stack Pointer - msr cpsr_c, #Mode_UND|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #UND_Stack_Size - - @ Enter Abort Mode and set its Stack Pointer - msr cpsr_c, #Mode_ABT|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #ABT_Stack_Size - - @ Enter FIQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_FIQ_STACK_PGSZ - - @ Enter IRQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_IRQ_STACK_PGSZ - - /* come back to SVC mode */ - msr cpsr_c, #Mode_SVC|I_Bit|F_Bit - bx lr - - .global enable_mmu -enable_mmu: - orr r0, #0x18 - mcr p15, 0, r0, c2, c0, 0 @ttbr0 - - mov r0, #(1 << 5) @PD1=1 - mcr p15, 0, r0, c2, c0, 2 @ttbcr - - mov r0, #1 - mcr p15, 0, r0, c3, c0, 0 @dacr - - mov r0, #0 - mcr p15, 0, r0, c8, c7, 0 - mcr p15, 0, r0, c7, c5, 0 @iciallu - mcr p15, 0, r0, c7, c5, 6 @bpiall - - mrc p15, 0, r0, c1, c0, 0 - orr r0, #(1 | 4) - orr r0, #(1 << 12) - mcr p15, 0, r0, c1, c0, 0 - dsb - isb - mov pc, lr - -.global flush_cache_all -flush_cache_all: - stmfd sp!, {r0-r12, lr} - bl v7_flush_dcache_all - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate - dsb - isb - ldmfd sp!, {r0-r12, lr} - mov pc, lr - - v7_flush_dcache_all: - dmb @ ensure ordering with previous memory accesses - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished @ if loc is 0, then no need to clean - mov r10, #0 @ start clean at cache level 0 -loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache level - mov r1, r0, lsr r2 @ extract cache type bits from clidr - and r1, r1, #7 @ mask of the bits for current cache only - cmp r1, #2 @ see what cache we have at this level - blt skip @ skip if no cache, or just i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - isb @ isb to sych the new cssr&csidr - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the way size - clz r5, r4 @ find bit position of way size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the index size -loop2: - mov r9, r4 @ create working copy of max way size -loop3: - orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 - orr r11, r11, r7, lsl r2 @ factor index number into r11 - mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge loop3 - subs r7, r7, #1 @ decrement the index - bge loop2 -skip: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt loop1 -finished: - mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - dsb - isb - mov pc, lr - -/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ -.section .text.isr, "ax" - .align 5 -.globl vector_fiq -vector_fiq: - stmfd sp!,{r0-r7,lr} - bl rt_hw_trap_fiq - ldmfd sp!,{r0-r7,lr} - subs pc, lr, #4 - -.globl rt_interrupt_enter -.globl rt_interrupt_leave -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread - - .align 5 -.globl vector_irq -vector_irq: -#ifdef RT_USING_SMP - clrex -#endif - stmfd sp!, {r0-r12,lr} - - bl rt_interrupt_enter - bl rt_hw_trap_irq - bl rt_interrupt_leave - -#ifdef RT_USING_SMP - mov r0, sp - bl rt_scheduler_do_irq_switch - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 -#else - @ if rt_thread_switch_interrupt_flag set, jump to - @ rt_hw_context_switch_interrupt_do and don't return - ldr r0, =rt_thread_switch_interrupt_flag - ldr r1, [r0] - cmp r1, #1 - beq rt_hw_context_switch_interrupt_do - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 - -rt_hw_context_switch_interrupt_do: - mov r1, #0 @ clear flag - str r1, [r0] - - mov r1, sp @ r1 point to {r0-r3} in stack - add sp, sp, #4*4 - ldmfd sp!, {r4-r12,lr}@ reload saved registers - mrs r0, spsr @ get cpsr of interrupt thread - sub r2, lr, #4 @ save old task's pc to r2 - - @ Switch to SVC mode with no interrupt. If the usr mode guest is - @ interrupted, this will just switch to the stack of kernel space. - @ save the registers in kernel space won't trigger data abort. - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - - stmfd sp!, {r2} @ push old task's pc - stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 - ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread - stmfd sp!, {r1-r4} @ push old task's r0-r3 - stmfd sp!, {r0} @ push old task's cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13, r14}^ @push usr_sp, usr_lr - sub sp, #8 -#endif - - ldr r4, =rt_interrupt_from_thread - ldr r5, [r4] - str sp, [r5] @ store sp in preempted tasks's TCB - - ldr r6, =rt_interrupt_to_thread - ldr r6, [r6] - ldr sp, [r6] @ get new task's stack pointer - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task's cpsr to spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr - -#endif - -.macro push_svc_reg - sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ - stmia sp, {r0 - r12} @/* Calling r0-r12 */ - mov r0, sp - mrs r6, spsr @/* Save CPSR */ - str lr, [r0, #15*4] @/* Push PC */ - str r6, [r0, #16*4] @/* Push CPSR */ - cps #Mode_SVC - str sp, [r0, #13*4] @/* Save calling SP */ - str lr, [r0, #14*4] @/* Save calling PC */ -.endm - - .align 5 - .globl vector_swi -.weak SVC_Handler -SVC_Handler: -vector_swi: - push_svc_reg - bl rt_hw_trap_swi - b . - - .align 5 - .globl vector_undef -vector_undef: - push_svc_reg - bl rt_hw_trap_undef - b . - - .align 5 - .globl vector_pabt -vector_pabt: - push_svc_reg - bl rt_hw_trap_pabt - b . - - .align 5 - .globl vector_dabt -vector_dabt: - push_svc_reg - bl rt_hw_trap_dabt - b . - - .align 5 - .globl vector_resv -vector_resv: - push_svc_reg - bl rt_hw_trap_resv - b . - -#ifdef RT_USING_SMP -.global set_secondary_cpu_boot_address -set_secondary_cpu_boot_address: - ldr r0, =secondary_cpu_start - - mvn r1, #0 //0xffffffff - ldr r2, =0x10000034 - str r1, [r2] - str r0, [r2, #-4] - mov pc, lr - -.global secondary_cpu_start -secondary_cpu_start: - mrc p15, 0, r1, c1, c0, 1 - mov r0, #(1<<6) - orr r1, r0 - mcr p15, 0, r1, c1, c0, 1 //enable smp - - ldr r0, =mtbl - ldr lr, =1f - - b enable_mmu -1: - mrc p15, 0, r0, c1, c0, 0 - bic r0, #(1<<13) - mcr p15, 0, r0, c1, c0, 0 - - cps #Mode_IRQ - ldr sp, =irq_stack_2_limit - - cps #Mode_FIQ - ldr sp, =irq_stack_2_limit - - cps #Mode_SVC - ldr sp, =svc_stack_2_limit - - b secondary_cpu_c_start -#endif - -.bss -.align 2 //align to 2~2=4 -svc_stack_2: - .space (1 << 10) -svc_stack_2_limit: - -irq_stack_2: - .space (1 << 10) -irq_stack_2_limit: - -.data -#define DEVICE_MEM 0x10c06 -#define NORMAL_MEM 0x11c0e -.align 14 -mtbl: - - //vaddr: 0x00000000 - .rept 0x100 - .word 0x0 - .endr - - //vaddr: 0x10000000 - .equ mmu_tbl_map_paddr, 0x10000000 - .rept 0x400 - .word mmu_tbl_map_paddr | DEVICE_MEM - .equ mmu_tbl_map_paddr, mmu_tbl_map_paddr + 0x100000 - .endr - - //vaddr: 0x50000000 - .rept 0x100 - .word 0x0 - .endr - - //vaddr: 0x60000000 - .equ mmu_tbl_map_paddr, 0x60000000 - .rept 0x800 - .word mmu_tbl_map_paddr | NORMAL_MEM - .equ mmu_tbl_map_paddr, mmu_tbl_map_paddr + 0x100000 - .endr - - //vaddr: 0xe0000000 - .rept 0x200 - .word 0x0 - .endr diff --git a/bsp/qemu-vexpress-a9/cpu/trap.c b/bsp/qemu-vexpress-a9/cpu/trap.c deleted file mode 100644 index a1f00d0075..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/trap.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * File : trap.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Develop 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-20 Bernard first version - */ - -#include -#include -#include - -#include "armv7.h" - -#include "gic.h" - -#ifdef RT_USING_FINSH -extern long list_thread(void); -#endif - -/** - * this function will show registers of CPU - * - * @param regs the registers point - */ -void rt_hw_show_register(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("Execption:\n"); - rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); - rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); - rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); - rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); - rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); - rt_kprintf("cpsr:0x%08x\n", regs->cpsr); -} - -/** - * 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_undef(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("undefined instruction:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * The software interrupt instruction (SWI) is used for entering - * Supervisor mode, usually to request a particular supervisor - * function. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("software interrupt:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * 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) -{ - rt_kprintf("prefetch abort:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during a data access. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("data abort:"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * Normally, system will never reach here - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("reserved trap:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -#define GIC_ACK_INTID_MASK 0x000003ff - -void rt_hw_trap_irq(void) -{ - void *param; - unsigned long ir; - unsigned long fullir; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - fullir = arm_gic_get_active_irq(0); - ir = fullir & GIC_ACK_INTID_MASK; - - 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 */ - arm_gic_ack(0, fullir); -} - -void rt_hw_trap_fiq(void) -{ - void *param; - unsigned long ir; - unsigned long fullir; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - fullir = arm_gic_get_active_irq(0); - ir = fullir & GIC_ACK_INTID_MASK; - - /* 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 */ - arm_gic_ack(0, fullir); -} - diff --git a/bsp/qemu-vexpress-a9/cpu/vector_gcc.S b/bsp/qemu-vexpress-a9/cpu/vector_gcc.S deleted file mode 100644 index 2473e1f850..0000000000 --- a/bsp/qemu-vexpress-a9/cpu/vector_gcc.S +++ /dev/null @@ -1,65 +0,0 @@ -/* - * File : vector_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, 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 - * 2013-07-05 Bernard the first version - */ - -.section .vectors, "ax" -.code 32 - -.globl system_vectors -system_vectors: - ldr pc, _vector_reset - ldr pc, _vector_undef - ldr pc, _vector_swi - ldr pc, _vector_pabt - ldr pc, _vector_dabt - ldr pc, _vector_resv - ldr pc, _vector_irq - ldr pc, _vector_fiq - -.globl _reset -.globl vector_undef -.globl vector_swi -.globl vector_pabt -.globl vector_dabt -.globl vector_resv -.globl vector_irq -.globl vector_fiq - -_vector_reset: - .word _reset -_vector_undef: - .word vector_undef -_vector_swi: - .word SVC_Handler -_vector_pabt: - .word vector_pabt -_vector_dabt: - .word vector_dabt -_vector_resv: - .word vector_resv -_vector_irq: - .word vector_irq -_vector_fiq: - .word vector_fiq - -.balignl 16,0xdeadbeef diff --git a/bsp/qemu-vexpress-a9/drivers/board.c b/bsp/qemu-vexpress-a9/drivers/board.c index 6ffac7efd7..e236c68b80 100644 --- a/bsp/qemu-vexpress-a9/drivers/board.c +++ b/bsp/qemu-vexpress-a9/drivers/board.c @@ -17,6 +17,15 @@ #include "board.h" #include "drv_timer.h" +#include + +struct mem_desc platform_mem_desc[] = { + {0x10000000, 0x50000000, 0x10000000, DEVICE_MEM}, + {0x60000000, 0xe0000000, 0x60000000, NORMAL_MEM} +}; + +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); diff --git a/bsp/qemu-vexpress-a9/platform/SConscript b/bsp/qemu-vexpress-a9/platform/SConscript new file mode 100644 index 0000000000..1b580929da --- /dev/null +++ b/bsp/qemu-vexpress-a9/platform/SConscript @@ -0,0 +1,13 @@ +from building import * + +cwd = GetCurrentDir() +src = Split(''' +''') + +CPPPATH = [ cwd + '/cpu', +cwd + '/include', +] + +group = DefineGroup('Platform', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/qemu-vexpress-a9/platform/cpu/platform.h b/bsp/qemu-vexpress-a9/platform/cpu/platform.h new file mode 100644 index 0000000000..2d5cc5f61b --- /dev/null +++ b/bsp/qemu-vexpress-a9/platform/cpu/platform.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 __PLATFORM_H__ +#define __PLATFORM_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_uint32_t platform_get_gic_dist_base(void) +{ + return REALVIEW_GIC_DIST_BASE; +} + +rt_inline rt_uint32_t platform_get_gic_cpu_base(void) +{ + return REALVIEW_GIC_CPU_BASE; +} + +#define GIC_IRQ_START 0 + +#define GIC_ACK_INTID_MASK 0x000003ff + +#endif /* __PLATFORM_H__ */ diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h index b6c3399da3..831d54c52f 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.h +++ b/bsp/qemu-vexpress-a9/rtconfig.h @@ -10,7 +10,9 @@ #define RT_USING_SMP #define RT_CPUS_NR 2 #define RT_ALIGN_SIZE 4 +/* RT_THREAD_PRIORITY_8 is not set */ #define RT_THREAD_PRIORITY_32 +/* RT_THREAD_PRIORITY_256 is not set */ #define RT_THREAD_PRIORITY_MAX 32 #define RT_TICK_PER_SECOND 100 #define RT_USING_OVERFLOW_CHECK @@ -37,7 +39,10 @@ #define RT_USING_MEMPOOL #define RT_USING_MEMHEAP +/* RT_USING_NOHEAP is not set */ #define RT_USING_SMALL_MEM +/* RT_USING_SLAB is not set */ +/* RT_USING_MEMHEAP_AS_HEAP is not set */ #define RT_USING_MEMTRACE #define RT_USING_HEAP @@ -53,6 +58,7 @@ #define ARCH_ARM #define ARCH_ARM_CORTEX_A #define ARCH_ARM_CORTEX_A9 +/* ARCH_CPU_STACK_GROWS_UPWARD is not set */ /* RT-Thread Components */ @@ -73,11 +79,14 @@ #define FINSH_HISTORY_LINES 5 #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION +/* FINSH_ECHO_DISABLE_DEFAULT is not set */ #define FINSH_THREAD_PRIORITY 20 #define FINSH_THREAD_STACK_SIZE 4096 #define FINSH_CMD_SIZE 80 +/* FINSH_USING_AUTH is not set */ #define FINSH_USING_MSH #define FINSH_USING_MSH_DEFAULT +/* FINSH_USING_MSH_ONLY is not set */ #define FINSH_ARG_MAX 10 /* Device virtual file system */ @@ -87,21 +96,29 @@ #define DFS_FILESYSTEMS_MAX 2 #define DFS_FILESYSTEM_TYPES_MAX 8 #define DFS_FD_MAX 16 +/* RT_USING_DFS_MNTTABLE is not set */ #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 +/* RT_DFS_ELM_USE_LFN_0 is not set */ +/* RT_DFS_ELM_USE_LFN_1 is not set */ +/* RT_DFS_ELM_USE_LFN_2 is not set */ #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 +/* RT_DFS_ELM_USE_ERASE is not set */ #define RT_DFS_ELM_REENTRANT #define RT_USING_DFS_DEVFS #define RT_USING_DFS_ROMFS #define RT_USING_DFS_RAMFS +/* RT_USING_DFS_UFFS is not set */ +/* RT_USING_DFS_JFFS2 is not set */ +/* RT_USING_DFS_NFS is not set */ /* Device Drivers */ @@ -110,12 +127,19 @@ #define RT_USING_SERIAL #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 +/* RT_USING_CAN is not set */ +/* RT_USING_HWTIMER is not set */ +/* RT_USING_CPUTIME is not set */ #define RT_USING_I2C #define RT_USING_I2C_BITOPS #define RT_USING_PIN +/* RT_USING_ADC is not set */ +/* RT_USING_PWM is not set */ #define RT_USING_MTD_NOR #define RT_USING_MTD_NAND #define RT_MTD_NAND_DEBUG +/* RT_USING_MTD is not set */ +/* RT_USING_PM is not set */ #define RT_USING_RTC #define RT_USING_SOFT_RTC #define RT_USING_SDIO @@ -124,18 +148,31 @@ #define RT_MMCSD_STACK_SIZE 1024 #define RT_MMCSD_THREAD_PREORITY 22 #define RT_MMCSD_MAX_PARTITION 16 +/* RT_SDIO_DEBUG is not set */ #define RT_USING_SPI +/* RT_USING_QSPI is not set */ #define RT_USING_SPI_MSD #define RT_USING_SFUD #define RT_SFUD_USING_SFDP #define RT_SFUD_USING_FLASH_INFO_TABLE +/* RT_SFUD_USING_QSPI is not set */ +/* RT_DEBUG_SFUD is not set */ +/* RT_USING_W25QXX is not set */ +/* RT_USING_GD is not set */ +/* RT_USING_ENC28J60 is not set */ +/* RT_USING_SPI_WIFI is not set */ #define RT_USING_WDT +/* RT_USING_AUDIO is not set */ +/* RT_USING_SENSOR is not set */ /* Using WiFi */ +/* RT_USING_WIFI is not set */ /* Using USB */ +/* RT_USING_USB_HOST is not set */ +/* RT_USING_USB_DEVICE is not set */ /* POSIX layer and C standard library */ @@ -145,6 +182,7 @@ #define RT_USING_POSIX_MMAP #define RT_USING_POSIX_TERMIOS #define RT_USING_POSIX_AIO +/* RT_USING_MODULE is not set */ /* Network */ @@ -161,9 +199,13 @@ /* light weight TCP/IP stack */ #define RT_USING_LWIP +/* RT_USING_LWIP141 is not set */ #define RT_USING_LWIP202 +/* RT_USING_LWIP210 is not set */ #define RT_USING_LWIP_IPV6 +/* RT_LWIP_IGMP is not set */ #define RT_LWIP_ICMP +/* RT_LWIP_SNMP is not set */ #define RT_LWIP_DNS #define RT_LWIP_DHCP #define IP_SOF_BROADCAST 1 @@ -176,6 +218,8 @@ #define RT_LWIP_MSKADDR "255.255.255.0" #define RT_LWIP_UDP #define RT_LWIP_TCP +/* RT_LWIP_RAW is not set */ +/* RT_LWIP_PPP is not set */ #define RT_MEMP_NUM_NETCONN 8 #define RT_LWIP_PBUF_NUM 16 #define RT_LWIP_RAW_PCB_NUM 4 @@ -187,6 +231,8 @@ #define RT_LWIP_TCPTHREAD_PRIORITY 10 #define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 #define RT_LWIP_TCPTHREAD_STACKSIZE 1024 +/* LWIP_NO_RX_THREAD is not set */ +/* LWIP_NO_TX_THREAD is not set */ #define RT_LWIP_ETHTHREAD_PRIORITY 12 #define RT_LWIP_ETHTHREAD_STACKSIZE 1024 #define RT_LWIP_ETHTHREAD_MBOX_SIZE 8 @@ -196,62 +242,164 @@ #define LWIP_SO_RCVTIMEO 1 #define LWIP_SO_SNDTIMEO 1 #define LWIP_SO_RCVBUF 1 +/* RT_LWIP_NETIF_LOOPBACK is not set */ #define LWIP_NETIF_LOOPBACK 0 +/* RT_LWIP_STATS is not set */ +/* RT_LWIP_DEBUG is not set */ /* Modbus master and slave stack */ +/* RT_USING_MODBUS is not set */ /* AT commands */ +/* RT_USING_AT is not set */ +/* LWIP_USING_DHCPD is not set */ /* VBUS(Virtual Software BUS) */ +/* RT_USING_VBUS is not set */ /* Utilities */ #define RT_USING_LOGTRACE #define LOG_TRACE_MAX_SESSION 16 +/* LOG_TRACE_USING_LEVEL_NOTRACE is not set */ +/* LOG_TRACE_USING_LEVEL_ERROR is not set */ +/* LOG_TRACE_USING_LEVEL_WARNING is not set */ #define LOG_TRACE_USING_LEVEL_INFO +/* LOG_TRACE_USING_LEVEL_VERBOSE is not set */ +/* LOG_TRACE_USING_LEVEL_DEBUG is not set */ +/* LOG_TRACE_USING_MEMLOG is not set */ +/* RT_USING_RYM is not set */ +/* RT_USING_ULOG is not set */ +/* RT_USING_UTEST is not set */ #define RT_USING_LWP /* RT-Thread online packages */ /* IoT - internet of things */ +/* PKG_USING_PAHOMQTT is not set */ +/* PKG_USING_WEBCLIENT is not set */ +/* PKG_USING_WEBNET is not set */ +/* PKG_USING_MONGOOSE is not set */ +/* PKG_USING_WEBTERMINAL is not set */ +/* PKG_USING_CJSON is not set */ +/* PKG_USING_JSMN is not set */ +/* PKG_USING_LIBMODBUS is not set */ +/* PKG_USING_LJSON is not set */ +/* PKG_USING_EZXML is not set */ +/* PKG_USING_NANOPB is not set */ /* Wi-Fi */ /* Marvell WiFi */ +/* PKG_USING_WLANMARVELL is not set */ /* Wiced WiFi */ +/* PKG_USING_WLAN_WICED is not set */ +/* PKG_USING_RW007 is not set */ +/* PKG_USING_COAP is not set */ +/* PKG_USING_NOPOLL is not set */ +/* PKG_USING_NETUTILS is not set */ +/* PKG_USING_AT_DEVICE is not set */ +/* PKG_USING_WIZNET is not set */ /* IoT Cloud */ +/* PKG_USING_ONENET is not set */ +/* PKG_USING_GAGENT_CLOUD is not set */ +/* PKG_USING_ALI_IOTKIT is not set */ +/* PKG_USING_AZURE is not set */ +/* PKG_USING_TENCENT_IOTKIT is not set */ +/* PKG_USING_NIMBLE is not set */ +/* PKG_USING_OTA_DOWNLOADER is not set */ /* security packages */ +/* PKG_USING_MBEDTLS is not set */ +/* PKG_USING_libsodium is not set */ +/* PKG_USING_TINYCRYPT is not set */ /* language packages */ +/* PKG_USING_LUA is not set */ +/* PKG_USING_JERRYSCRIPT is not set */ +/* PKG_USING_MICROPYTHON is not set */ /* multimedia packages */ +/* PKG_USING_OPENMV is not set */ +/* PKG_USING_MUPDF is not set */ /* tools packages */ +/* PKG_USING_CMBACKTRACE is not set */ +/* PKG_USING_EASYFLASH is not set */ +/* PKG_USING_EASYLOGGER is not set */ +/* PKG_USING_SYSTEMVIEW is not set */ +/* PKG_USING_RDB is not set */ +/* PKG_USING_QRCODE is not set */ +/* PKG_USING_ULOG_EASYFLASH is not set */ +/* PKG_USING_ADBD is not set */ /* system packages */ +/* PKG_USING_GUIENGINE is not set */ +/* PKG_USING_PERSIMMON is not set */ +/* PKG_USING_CAIRO is not set */ +/* PKG_USING_PIXMAN is not set */ +/* PKG_USING_LWEXT4 is not set */ +/* PKG_USING_PARTITION is not set */ +/* PKG_USING_FAL is not set */ +/* PKG_USING_SQLITE is not set */ +/* PKG_USING_RTI is not set */ +/* PKG_USING_LITTLEVGL2RTT is not set */ +/* PKG_USING_CMSIS is not set */ +/* PKG_USING_DFS_YAFFS is not set */ +/* PKG_USING_LITTLEFS is not set */ /* peripheral libraries and drivers */ /* sensors drivers */ +/* PKG_USING_LSM6DSL is not set */ +/* PKG_USING_LPS22HB is not set */ +/* PKG_USING_HTS221 is not set */ +/* PKG_USING_LSM303AGR is not set */ +/* PKG_USING_BME280 is not set */ +/* PKG_USING_BMA400 is not set */ +/* PKG_USING_BMI160_BMX160 is not set */ +/* PKG_USING_SPL0601 is not set */ +/* PKG_USING_REALTEK_AMEBA is not set */ +/* PKG_USING_SHT2X is not set */ +/* PKG_USING_AHT10 is not set */ +/* PKG_USING_AP3216C is not set */ +/* PKG_USING_STM32_SDIO is not set */ +/* PKG_USING_ICM20608 is not set */ +/* PKG_USING_U8G2 is not set */ +/* PKG_USING_BUTTON is not set */ +/* PKG_USING_MPU6XXX is not set */ +/* PKG_USING_PCF8574 is not set */ +/* PKG_USING_SX12XX is not set */ +/* PKG_USING_KENDRYTE_SDK is not set */ /* miscellaneous packages */ +/* PKG_USING_LIBCSV is not set */ +/* PKG_USING_OPTPARSE is not set */ +/* PKG_USING_FASTLZ is not set */ +/* PKG_USING_MINILZO is not set */ +/* PKG_USING_QUICKLZ is not set */ +/* PKG_USING_MULTIBUTTON is not set */ +/* PKG_USING_CANFESTIVAL is not set */ +/* PKG_USING_ZLIB is not set */ +/* PKG_USING_DSTR is not set */ +/* PKG_USING_TINYFRAME is not set */ +/* PKG_USING_KENDRYTE_DEMO is not set */ /* samples: kernel and components samples */ @@ -259,5 +407,6 @@ #define RT_USING_UART0 #define RT_USING_UART1 #define BSP_DRV_EMAC +/* BSP_DRV_AUDIO is not set */ #endif diff --git a/bsp/qemu-vexpress-a9/rtconfig.py b/bsp/qemu-vexpress-a9/rtconfig.py index 8ccd0227e4..d417673898 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.py +++ b/bsp/qemu-vexpress-a9/rtconfig.py @@ -2,14 +2,15 @@ import os # toolchains options ARCH='arm' -CPU='cortex-a9' +CPU='cortex-a' CROSS_TOOL='gcc' if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') +# only support GNU GCC compiler. PLATFORM = 'gcc' -EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin' +EXEC_PATH = '/usr/bin' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') diff --git a/components/lwp/SConscript b/components/lwp/SConscript index d3b799257b..f151f3b92e 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-a9"]} +support_arch = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7", "arm926", "cortex-a"]} platform_file = {'armcc': 'rvds.S', 'gcc': 'gcc.S', 'iar': 'iar.S'} if rtconfig.PLATFORM in platform_file.keys(): # support platforms diff --git a/components/lwp/arch/arm/cortex-a/lwp_gcc.S b/components/lwp/arch/arm/cortex-a/lwp_gcc.S new file mode 100644 index 0000000000..6c89152b0c --- /dev/null +++ b/components/lwp/arch/arm/cortex-a/lwp_gcc.S @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-12-10 Jesven first version + */ + +#define Mode_USR 0x10 +#define Mode_FIQ 0x11 +#define Mode_IRQ 0x12 +#define Mode_SVC 0x13 +#define Mode_MON 0x16 +#define Mode_ABT 0x17 +#define Mode_UDF 0x1B +#define Mode_SYS 0x1F + +#define A_Bit 0x100 +#define I_Bit 0x80 @; when I bit is set, IRQ is disabled +#define F_Bit 0x40 @; when F bit is set, FIQ is disabled +#define T_Bit 0x20 + +.cpu cortex-a9 +.syntax unified +.text + +/* + * void lwp_user_entry(args, text, data); + */ +.global lwp_user_entry +.type lwp_user_entry, % function +lwp_user_entry: + mrs r9, cpsr + bic r9, #0x1f + orr r9, #Mode_USR + cpsid i + msr spsr, r9 + + /* set data address. */ + mov r9, r2 + movs pc, r1 + +/* + * void SVC_Handler(void); + */ +.global SVC_Handler +.type SVC_Handler, % function +SVC_Handler: + push {lr} + mrs lr, spsr + push {r4, r5, lr} + cpsie i + + push {r0 - r3, r12} + and r0, r7, #0xff + bl lwp_get_sys_api + cmp r0, #0 /* r0 = api */ + mov lr, r0 + pop {r0 - r3, r12} + beq svc_exit + blx lr + +svc_exit: + cpsid i + pop {r4, r5, lr} + msr spsr_cxsf, lr + pop {lr} + movs pc, lr diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S index 97b3dbc447..b009630fa8 100644 --- a/libcpu/arm/cortex-a/context_gcc.S +++ b/libcpu/arm/cortex-a/context_gcc.S @@ -8,7 +8,14 @@ * 2013-07-05 Bernard the first version */ +#include "rtconfig.h" .section .text, "ax" + +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif + /* * rt_base_t rt_hw_interrupt_disable(); */ @@ -34,6 +41,16 @@ rt_hw_interrupt_enable: rt_hw_context_switch_to: ldr sp, [r0] @ get new task stack pointer +#ifdef RT_USING_SMP + mov r0, r1 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr + add sp, #8 +#endif + ldmfd sp!, {r4} @ pop new task spsr msr spsr_cxsf, r4 @@ -62,9 +79,24 @@ rt_hw_context_switch: stmfd sp!, {r4} @ push cpsr +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @ push usr_sp usr_lr + sub sp, #8 +#endif + str sp, [r0] @ store sp in preempted tasks TCB ldr sp, [r1] @ get new task stack pointer +#ifdef RT_USING_SMP + mov r0, r2 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @ pop usr_sp usr_lr + add sp, #8 +#endif + ldmfd sp!, {r4} @ pop new task cpsr to spsr msr spsr_cxsf, r4 ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr @@ -72,11 +104,70 @@ rt_hw_context_switch: /* * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); */ +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: +#ifdef RT_USING_SMP + /* r0 :irq_mod context + * r1 :addr of from_thread's sp + * r2 :addr of to_thread's sp + * r3 :to_thread's tcb + */ + + @ r0 point to {r0-r3} in stack + push {r1 - r3} + mov r1, r0 + add r0, r0, #4*4 + ldmfd r0!, {r4-r12,lr}@ reload saved registers + mrs r3, spsr @ get cpsr of interrupt thread + sub r2, lr, #4 @ save old task's pc to r2 + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 + ldmfd r1, {r4-r7} @ restore r0-r3 of the interrupt thread + stmfd sp!, {r4-r7} @ push old task's r0-r3 + stmfd sp!, {r3} @ push old task's cpsr + +#ifdef RT_USING_LWP + stmfd sp, {r13,r14}^ @push usr_sp usr_lr + sub sp, #8 +#endif + + msr cpsr_c, #I_Bit|F_Bit|Mode_IRQ + pop {r1 - r3} + mov sp, r0 + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + str sp, [r1] + + ldr sp, [r2] + mov r0, r3 + bl rt_cpus_lock_status_restore + +#ifdef RT_USING_LWP + ldmfd sp, {r13,r14}^ @pop usr_sp usr_lr + add sp, #8 +#endif + + ldmfd sp!, {r4} @ pop new task's cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr + +#else /*RT_USING_SMP*/ ldr r2, =rt_thread_switch_interrupt_flag ldr r3, [r2] cmp r3, #1 @@ -89,3 +180,4 @@ _reswitch: ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread str r1, [r2] bx lr +#endif /*RT_USING_SMP*/ diff --git a/libcpu/arm/cortex-a/cp15.h b/libcpu/arm/cortex-a/cp15.h index 486f38200d..97c5b93ad2 100644 --- a/libcpu/arm/cortex-a/cp15.h +++ b/libcpu/arm/cortex-a/cp15.h @@ -5,6 +5,7 @@ * * Change Logs: * Date Author Notes + * 2018-03-25 quanzhao the first version */ #ifndef __CP15_H__ #define __CP15_H__ @@ -15,6 +16,9 @@ void rt_cpu_mmu_disable(void); void rt_cpu_mmu_enable(void); void rt_cpu_tlb_set(volatile unsigned long*); +void rt_cpu_dcache_clean_flush(void); +void rt_cpu_icache_flush(void); + void rt_cpu_vector_set_base(unsigned int addr); #endif diff --git a/libcpu/arm/cortex-a/cp15_gcc.S b/libcpu/arm/cortex-a/cp15_gcc.S index 0e3e60655c..dd2436ffee 100644 --- a/libcpu/arm/cortex-a/cp15_gcc.S +++ b/libcpu/arm/cortex-a/cp15_gcc.S @@ -15,6 +15,11 @@ rt_cpu_get_smp_id: .globl rt_cpu_vector_set_base rt_cpu_vector_set_base: + /* clear SCTRL.V to customize the vector address */ + mrc p15, #0, r1, c1, c0, #0 + bic r1, #(1 << 13) + mcr p15, #0, r1, c1, c0, #0 + /* set up the vector address */ mcr p15, #0, r0, c12, c0, #0 dsb bx lr @@ -36,7 +41,7 @@ rt_hw_cpu_icache_enable: _FLD_MAX_WAY: .word 0x3ff _FLD_MAX_IDX: - .word 0x7ff + .word 0x7fff .globl rt_cpu_dcache_clean_flush rt_cpu_dcache_clean_flush: @@ -84,6 +89,14 @@ finished: pop {r4-r11} bx lr +.globl rt_cpu_icache_flush +rt_cpu_icache_flush: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + dsb + isb + bx lr + .globl rt_hw_cpu_dcache_disable rt_hw_cpu_dcache_disable: push {r4-r11, lr} diff --git a/libcpu/arm/cortex-a/cpu.c b/libcpu/arm/cortex-a/cpu.c index 2d78715011..6b129f89ee 100644 --- a/libcpu/arm/cortex-a/cpu.c +++ b/libcpu/arm/cortex-a/cpu.c @@ -6,28 +6,78 @@ * Change Logs: * Date Author Notes * 2011-09-15 Bernard first version + * 2018-11-22 Jesven add rt_hw_cpu_id() */ #include #include #include +#ifdef RT_USING_SMP +int rt_hw_cpu_id(void) +{ + int cpu_id; + __asm__ volatile ( + "mrc p15, 0, %0, c0, c0, 5" + :"=r"(cpu_id) + ); + cpu_id &= 0xf; + return cpu_id; +}; + +void rt_hw_spin_lock(rt_hw_spinlock_t *lock) +{ + unsigned long tmp; + unsigned long newval; + rt_hw_spinlock_t lockval; + + __asm__ __volatile__( + "pld [%0]" + ::"r"(&lock->slock) + ); + + __asm__ __volatile__( + "1: ldrex %0, [%3]\n" + " add %1, %0, %4\n" + " strex %2, %1, [%3]\n" + " teq %2, #0\n" + " bne 1b" + : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) + : "r" (&lock->slock), "I" (1 << 16) + : "cc"); + + while (lockval.tickets.next != lockval.tickets.owner) { + __asm__ __volatile__("wfe":::"memory"); + lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); + } + + __asm__ volatile ("dmb":::"memory"); +} + +void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) +{ + __asm__ volatile ("dmb":::"memory"); + lock->tickets.owner++; + __asm__ volatile ("dsb ishst\nsev":::"memory"); +} +#endif /*RT_USING_SMP*/ + /** - * @addtogroup AM33xx + * @addtogroup ARM CPU */ /*@{*/ /** shutdown CPU */ void rt_hw_cpu_shutdown() { - rt_uint32_t level; - rt_kprintf("shutdown...\n"); + rt_uint32_t level; + rt_kprintf("shutdown...\n"); - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } } /*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/gic.c b/libcpu/arm/cortex-a/gic.c similarity index 92% rename from bsp/qemu-vexpress-a9/cpu/gic.c rename to libcpu/arm/cortex-a/gic.c index 66876518ce..2a46142b54 100644 --- a/bsp/qemu-vexpress-a9/cpu/gic.c +++ b/libcpu/arm/cortex-a/gic.c @@ -1,11 +1,7 @@ /* - * File : gic.c, ARM Generic Interrupt Controller - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, RT-Thread Develop Team + * Copyright (c) 2006-2018, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes @@ -17,18 +13,19 @@ #include #include -#include #include "gic.h" #include "cp15.h" struct arm_gic { - rt_uint32_t offset; + rt_uint32_t offset; /* the first interrupt index in the vector table */ - rt_uint32_t dist_hw_base; - rt_uint32_t cpu_hw_base; + 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]; #define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00) @@ -118,6 +115,7 @@ void arm_gic_clear_active(rt_uint32_t index, int irq) 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; @@ -215,11 +213,12 @@ int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) */ if (_gic_max_irq > 1020) _gic_max_irq = 1020; - if (_gic_max_irq > ARM_GIC_NR_IRQS) + 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; @@ -244,9 +243,11 @@ int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) 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) = 0x03; + GIC_DIST_CTRL(dist_base) = 0x01; return 0; } @@ -258,6 +259,7 @@ int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base) _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; diff --git a/bsp/qemu-vexpress-a9/cpu/gic.h b/libcpu/arm/cortex-a/gic.h similarity index 67% rename from bsp/qemu-vexpress-a9/cpu/gic.h rename to libcpu/arm/cortex-a/gic.h index 9d0368ec94..6d86dd31e0 100644 --- a/bsp/qemu-vexpress-a9/cpu/gic.h +++ b/libcpu/arm/cortex-a/gic.h @@ -1,11 +1,7 @@ /* - * File : gic.h, ARM Generic Interrupt Controller - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Develop Team + * Copyright (c) 2006-2018, 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 + * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes @@ -15,6 +11,9 @@ #ifndef __GIC_H__ #define __GIC_H__ +#include +#include + 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); @@ -26,8 +25,11 @@ 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 rt_hw_vector_init(void); +void arm_gic_dump(rt_uint32_t index); #endif diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c index fb6e3ff3e0..b7a70719a9 100644 --- a/libcpu/arm/cortex-a/interrupt.c +++ b/libcpu/arm/cortex-a/interrupt.c @@ -6,68 +6,32 @@ * Change Logs: * Date Author Notes * 2013-07-06 Bernard first version - * 2014-04-03 Grissiom port to VMM + * 2018-11-22 Jesven add smp support */ #include #include +#include "interrupt.h" +#include "gic.h" -#include -#include - -#include -#include "cp15.h" - -#define MAX_HANDLERS IMX_INTERRUPT_COUNT - -extern volatile rt_uint8_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; -rt_uint32_t rt_interrupt_from_thread; -rt_uint32_t rt_interrupt_to_thread; -rt_uint32_t rt_thread_switch_interrupt_flag; +#ifndef RT_USING_SMP +/* Those varibles will be accessed in ISR, so we need to share them. */ +rt_uint32_t rt_interrupt_from_thread = 0; +rt_uint32_t rt_interrupt_to_thread = 0; +rt_uint32_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; -/* keep compatible with platform SDK */ -void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr) +void rt_hw_vector_init(void) { - rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown"); -} - -void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority) -{ - gic_set_irq_priority(irq_id, priority); - gic_set_irq_security(irq_id, false); // set IRQ as non-secure - gic_set_cpu_target(irq_id, cpu_id, true); - gic_enable_irq(irq_id, true); -} - -void disable_interrupt(uint32_t irq_id, uint32_t cpu_id) -{ - gic_enable_irq(irq_id, false); - gic_set_cpu_target(irq_id, cpu_id, false); -} - -static void rt_hw_vector_init(void) -{ - int sctrl; - unsigned int *src = (unsigned int *)&system_vectors; - - /* C12-C0 is only active when SCTLR.V = 0 */ - asm volatile ("mrc p15, #0, %0, c1, c0, #0" - :"=r" (sctrl)); - sctrl &= ~(1 << 13); - asm volatile ("mcr p15, #0, %0, c1, c0, #0" - : - :"r" (sctrl)); - - asm volatile ("mcr p15, #0, %0, c12, c0, #0" - : - :"r" (src)); + rt_cpu_vector_set_base((unsigned int)&system_vectors); } /** @@ -75,14 +39,24 @@ static void rt_hw_vector_init(void) */ void rt_hw_interrupt_init(void) { - rt_hw_vector_init(); - gic_init(); + rt_uint32_t gic_cpu_base; + rt_uint32_t gic_dist_base; + rt_uint32_t gic_irq_start; - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; + /* initialize vector table */ + rt_hw_vector_init(); + + /* initialize exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + + /* initialize ARM GIC */ + gic_dist_base = platform_get_gic_dist_base(); + gic_cpu_base = platform_get_gic_cpu_base(); + + gic_irq_start = GIC_IRQ_START; + + arm_gic_dist_init(0, gic_dist_base, gic_irq_start); + arm_gic_cpu_init(0, gic_cpu_base); } /** @@ -91,7 +65,7 @@ void rt_hw_interrupt_init(void) */ void rt_hw_interrupt_mask(int vector) { - disable_interrupt(vector, 0); + arm_gic_mask(0, vector); } /** @@ -100,9 +74,26 @@ void rt_hw_interrupt_mask(int vector) */ void rt_hw_interrupt_umask(int vector) { - enable_interrupt(vector, 0, 0); + 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); +} /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number @@ -126,23 +117,7 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, isr_table[vector].handler = handler; isr_table[vector].param = param; } - // arm_gic_set_cpu(0, vector, 1 << rt_cpu_get_smp_id()); } return old_handler; } - -/** - * Trigger a software IRQ - * - * Since we are running in single core, the target CPU are always CPU0. - */ -void rt_hw_interrupt_trigger(int vector) -{ - // arm_gic_trigger(0, 1, vector); -} - -void rt_hw_interrupt_clear(int vector) -{ - gic_write_end_of_irq(vector); -} diff --git a/libcpu/arm/cortex-a/interrupt.h b/libcpu/arm/cortex-a/interrupt.h new file mode 100644 index 0000000000..bff29d402d --- /dev/null +++ b/libcpu/arm/cortex-a/interrupt.h @@ -0,0 +1,32 @@ +/* + * 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 + +void rt_hw_interrupt_control(int vector, int priority, int route); + +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); + +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/arm/cortex-a/mmu.c b/libcpu/arm/cortex-a/mmu.c index 58acdd8145..1260f41fe5 100644 --- a/libcpu/arm/cortex-a/mmu.c +++ b/libcpu/arm/cortex-a/mmu.c @@ -13,35 +13,7 @@ #include #include "cp15.h" - -#define DESC_SEC (0x2) -#define CB (3<<2) //cache_on, write_back -#define CNB (2<<2) //cache_on, write_through -#define NCB (1<<2) //cache_off,WR_BUF on -#define NCNB (0<<2) //cache_off,WR_BUF off -#define AP_RW (3<<10) //supervisor=RW, user=RW -#define AP_RO (2<<10) //supervisor=RW, user=RO -#define XN (1<<4) // eXecute Never - -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0<<5) -#define DOMAIN1 (0x1<<5) - -#define DOMAIN0_ATTR (DOMAIN_CHK<<0) -#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) - -/* Read/Write, cache, write back */ -#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) -/* Read/Write, cache, write through */ -#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) -/* Read/Write without cache and write buffer */ -#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) -/* Read/Write without cache and write buffer, no execute */ -#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN) -/* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) +#include "mmu.h" /* dump 2nd level page table */ void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) @@ -178,18 +150,25 @@ unsigned long rt_hw_set_domain_register(unsigned long domain_val) return old_domain; } +void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size) +{ + /* set page table */ + for(; size > 0; size--) + { + rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end, + mdesc->paddr_start, mdesc->attr); + mdesc++; + } +} + void rt_hw_mmu_init(void) { + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); rt_hw_cpu_dcache_disable(); rt_hw_cpu_icache_disable(); rt_cpu_mmu_disable(); - /* set page table */ - /* 4G 1:1 memory */ - rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB); - /* IO memory region */ - rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN); - /*rt_hw_cpu_dump_page_table(MMUTable);*/ rt_hw_set_domain_register(0x55555555); diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h new file mode 100644 index 0000000000..deec690c69 --- /dev/null +++ b/libcpu/arm/cortex-a/mmu.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-25 quanzhao the first version + */ +#ifndef __MMU_H_ +#define __MMU_H_ + +#include + +#define DESC_SEC (0x2) +#define MEMWB (3<<2) /* write back, no write allocate */ +#define MEMWT (2<<2) /* write through, no write allocate */ +#define SHAREDEVICE (1<<2) /* shared device */ +#define STRONGORDER (0<<2) /* strong ordered */ +#define XN (1<<4) /* eXecute Never */ +#define AP_RW (3<<10) /* supervisor=RW, user=RW */ +#define AP_RO (2<<10) /* supervisor=RW, user=RO */ +#define SHARED (1<<16) /* shareable */ + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) + +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) + +/* device mapping type */ +#define DEVICE_MEM (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN) +/* normal memory mapping type */ +#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWB|DESC_SEC) + +struct mem_desc +{ + rt_uint32_t vaddr_start; + rt_uint32_t vaddr_end; + rt_uint32_t paddr_start; + rt_uint32_t attr; +}; + + +#endif diff --git a/libcpu/arm/cortex-a/stack.c b/libcpu/arm/cortex-a/stack.c index 1d3ebcb9e6..d76b8a428a 100644 --- a/libcpu/arm/cortex-a/stack.c +++ b/libcpu/arm/cortex-a/stack.c @@ -50,13 +50,17 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, *(--stk) = 0xdeadbeef; /* r2 */ *(--stk) = 0xdeadbeef; /* r1 */ *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - /* cpsr */ if ((rt_uint32_t)tentry & 0x01) *(--stk) = SVCMODE | 0x20; /* thumb mode */ else *(--stk) = SVCMODE; /* arm mode */ +#ifdef RT_USING_LWP + *(--stk) = 0; /* user lr */ + *(--stk) = 0; /* user sp*/ +#endif + /* return task's current stack address */ return (rt_uint8_t *)stk; } diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 2f16d16807..0f4ff58364 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/libcpu/arm/cortex-a/start_gcc.S @@ -6,8 +6,12 @@ * Change Logs: * Date Author Notes * 2013-07-05 Bernard the first version + * 2018-11-22 Jesven in the interrupt context, use rt_scheduler_do_irq_switch checks + * and switches to a new thread */ +#include "rtconfig.h" + .equ Mode_USR, 0x10 .equ Mode_FIQ, 0x11 .equ Mode_IRQ, 0x12 @@ -20,11 +24,11 @@ .equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled .equ UND_Stack_Size, 0x00000000 -.equ SVC_Stack_Size, 0x00000100 +.equ SVC_Stack_Size, 0x00000400 .equ ABT_Stack_Size, 0x00000000 .equ RT_FIQ_STACK_PGSZ, 0x00000000 -.equ RT_IRQ_STACK_PGSZ, 0x00000100 -.equ USR_Stack_Size, 0x00000100 +.equ RT_IRQ_STACK_PGSZ, 0x00000800 +.equ USR_Stack_Size, 0x00000400 #define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) @@ -44,12 +48,8 @@ stack_top: /* reset entry */ .globl _reset _reset: - bl rt_cpu_mmu_disable /* set the cpu to SVC32 mode and disable interrupt */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0x13 - msr cpsr_c, r0 + cps #Mode_SVC /* setup stack */ bl stack_setup @@ -64,6 +64,20 @@ bss_loop: strlo r0,[r1],#4 /* clear 4 bytes */ blo bss_loop /* loop until done */ +#ifdef RT_USING_SMP + mrc p15, 0, r1, c1, c0, 1 + mov r0, #(1<<6) + orr r1, r0 + mcr p15, 0, r1, c1, c0, 1 //enable smp +#endif + + /* initialize the mmu table and enable mmu */ + ldr r0, =platform_mem_desc + ldr r1, =platform_mem_desc_size + ldr r1, [r1] + bl rt_hw_init_mmu_table + bl rt_hw_mmu_init + /* call C++ constructors of global objects */ ldr r0, =__ctors_start__ ldr r1, =__ctors_end__ @@ -137,12 +151,22 @@ vector_fiq: .align 5 .globl vector_irq vector_irq: +#ifdef RT_USING_SMP + clrex +#endif stmfd sp!, {r0-r12,lr} bl rt_interrupt_enter bl rt_hw_trap_irq bl rt_interrupt_leave +#ifdef RT_USING_SMP + mov r0, sp + bl rt_scheduler_do_irq_switch + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 +#else @ if rt_thread_switch_interrupt_flag set, jump to @ rt_hw_context_switch_interrupt_do and don't return ldr r0, =rt_thread_switch_interrupt_flag @@ -174,6 +198,11 @@ rt_hw_context_switch_interrupt_do: stmfd sp!, {r1-r4} @ push old task's r0-r3 stmfd sp!, {r0} @ push old task's cpsr +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @push usr_sp, usr_lr + sub sp, #8 +#endif + ldr r4, =rt_interrupt_from_thread ldr r5, [r4] str sp, [r5] @ store sp in preempted tasks's TCB @@ -182,11 +211,18 @@ rt_hw_context_switch_interrupt_do: ldr r6, [r6] ldr sp, [r6] @ get new task's stack pointer +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr + add sp, #8 +#endif + ldmfd sp!, {r4} @ pop new task's cpsr to spsr msr spsr_cxsf, r4 ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr +#endif + .macro push_svc_reg sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ stmia sp, {r0 - r12} @/* Calling r0-r12 */ @@ -200,36 +236,86 @@ rt_hw_context_switch_interrupt_do: .endm .align 5 - .globl vector_swi + .globl vector_swi +.weak SVC_Handler +SVC_Handler: vector_swi: push_svc_reg bl rt_hw_trap_swi b . .align 5 - .globl vector_undef + .globl vector_undef vector_undef: push_svc_reg bl rt_hw_trap_undef b . .align 5 - .globl vector_pabt + .globl vector_pabt vector_pabt: push_svc_reg bl rt_hw_trap_pabt b . .align 5 - .globl vector_dabt + .globl vector_dabt vector_dabt: push_svc_reg bl rt_hw_trap_dabt b . .align 5 - .globl vector_resv + .globl vector_resv vector_resv: push_svc_reg bl rt_hw_trap_resv b . + +#ifdef RT_USING_SMP +.global set_secondary_cpu_boot_address +set_secondary_cpu_boot_address: + ldr r0, =secondary_cpu_start + + mvn r1, #0 //0xffffffff + ldr r2, =0x10000034 + str r1, [r2] + str r0, [r2, #-4] + mov pc, lr + +.global secondary_cpu_start +secondary_cpu_start: + mrc p15, 0, r1, c1, c0, 1 + mov r0, #(1<<6) + orr r1, r0 + mcr p15, 0, r1, c1, c0, 1 //enable smp + + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1<<13) + mcr p15, 0, r0, c1, c0, 0 + + cps #Mode_IRQ + ldr sp, =irq_stack_2_limit + + cps #Mode_FIQ + ldr sp, =irq_stack_2_limit + + cps #Mode_SVC + ldr sp, =svc_stack_2_limit + + /* initialize the mmu table and enable mmu */ + bl rt_hw_mmu_init + + b secondary_cpu_c_start +#endif + +.bss +.align 2 //align to 2~2=4 +svc_stack_2: + .space (1 << 10) +svc_stack_2_limit: + +irq_stack_2: + .space (1 << 10) +irq_stack_2_limit: + diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c index f3b2c26e6d..54628933ff 100644 --- a/libcpu/arm/cortex-a/trap.c +++ b/libcpu/arm/cortex-a/trap.c @@ -10,13 +10,11 @@ #include #include -#include +#include #include "armv7.h" +#include "interrupt.h" -#include "gic.h" - -extern struct rt_thread *rt_current_thread; #ifdef RT_USING_FINSH extern long list_thread(void); #endif @@ -130,48 +128,52 @@ void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) void rt_hw_trap_irq(void) { void *param; + int ir; rt_isr_handler_t isr_func; extern struct rt_irq_desc isr_table[]; - // vectNum = RESERVED[31:13] | CPUID[12:10] | INTERRUPT_ID[9:0] - // send ack and get ID source - uint32_t vectNum = gic_read_irq_ack(); + ir = rt_hw_interrupt_get_irq(); - // Check that INT_ID isn't 1023 or 1022 (spurious interrupt) - if (vectNum & 0x0200) + if (ir == 1023) { - gic_write_end_of_irq(vectNum); // send end of irq + /* Spurious interrupt */ + return; } - else - { - // copy the local value to the global image of CPUID - unsigned cpu = (vectNum >> 10) & 0x7; - unsigned irq = vectNum & 0x1FF; - /* skip warning */ - cpu = cpu; - - // Call the service routine stored in the handlers array. If there isn't - // one for this IRQ, then call the default handler. - /* get interrupt service routine */ - isr_func = isr_table[irq].handler; + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; #ifdef RT_USING_INTERRUPT_INFO - isr_table[irq].counter++; + isr_table[ir].counter++; #endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[irq].param; - /* turn to interrupt service routine */ - isr_func(irq, param); - } - - // Signal the end of the irq. - gic_write_end_of_irq(vectNum); + 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) { - /* TODO */ + 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); } +