From 4b730f7df50191ee1c4c5b2680eef875e40f8ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=80=99=E9=B9=8F=E9=A3=9E?= <2597457485@qq.com> Date: Fri, 15 Jan 2021 20:02:31 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0qemu=E5=B7=A5=E7=A8=8B?= =?UTF-8?q?=E6=89=80=E9=9C=80=E7=9A=84gcc=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arm/cortex-m4/qemu_gcc/los_arch_atomic.h | 161 ++++ .../arm/cortex-m4/qemu_gcc/los_arch_context.h | 132 +++ .../cortex-m4/qemu_gcc/los_arch_interrupt.h | 782 ++++++++++++++++++ .../arm/cortex-m4/qemu_gcc/los_arch_timer.h | 54 ++ .../arch/arm/cortex-m4/qemu_gcc/los_context.c | 175 ++++ .../arm/cortex-m4/qemu_gcc/los_dispatch.S | 180 ++++ kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S | 378 +++++++++ .../arm/cortex-m4/qemu_gcc/los_interrupt.c | 398 +++++++++ .../arch/arm/cortex-m4/qemu_gcc/los_timer.c | 235 ++++++ 9 files changed, 2495 insertions(+) create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_atomic.h create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_context.h create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_interrupt.h create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_timer.h create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_context.c create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_dispatch.S create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_interrupt.c create mode 100644 kernel/arch/arm/cortex-m4/qemu_gcc/los_timer.c diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_atomic.h b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_atomic.h new file mode 100644 index 00000000..9cb48162 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_atomic.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 LOS_ATOMIC_H +#define LOS_ATOMIC_H + +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable and return the previous value of the atomic variable. + * @attention + * + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + * + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) +{ + INT32 prevVal = 0; + UINT32 status = 0; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "strex %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic auto-decrement and return the result of auto-decrement. + * @attention + * + * + * @param v [IN] The addSelf variable pointer. + * + * @retval #INT32 The return value of variable auto-decrement. + * @par Dependency: + * + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) +{ + INT32 val = 0; + UINT32 status = 0; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to oldVal. + * @attention + * + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + * + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE BOOL HalAtomicCmpXchg32bits(volatile INT32 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal = 0; + UINT32 status = 0; + + do { + __asm__ __volatile__("1: ldrex %0, %2\n" + " mov %1, #0\n" + " cmp %0, %3\n" + " bne 2f\n" + " strex %1, %4, %2\n" + "2:" + : "=&r"(prevVal), "=&r"(status), "+Q"(*v) + : "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* LOS_ATOMIC_H */ + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_context.h b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_context.h new file mode 100644 index 00000000..62ece273 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_context.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 _LOS_ARCH_CONTEXT_H +#define _LOS_ARCH_CONTEXT_H + +#include "los_config.h" +#include "los_compiler.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +typedef struct tagTskContext { +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + UINT32 S16; + UINT32 S17; + UINT32 S18; + UINT32 S19; + UINT32 S20; + UINT32 S21; + UINT32 S22; + UINT32 S23; + UINT32 S24; + UINT32 S25; + UINT32 S26; + UINT32 S27; + UINT32 S28; + UINT32 S29; + UINT32 S30; + UINT32 S31; +#endif + UINT32 uwR4; + UINT32 uwR5; + UINT32 uwR6; + UINT32 uwR7; + UINT32 uwR8; + UINT32 uwR9; + UINT32 uwR10; + UINT32 uwR11; + UINT32 uwPriMask; + UINT32 uwR0; + UINT32 uwR1; + UINT32 uwR2; + UINT32 uwR3; + UINT32 uwR12; + UINT32 uwLR; + UINT32 uwPC; + UINT32 uwxPSR; +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + UINT32 S0; + UINT32 S1; + UINT32 S2; + UINT32 S3; + UINT32 S4; + UINT32 S5; + UINT32 S6; + UINT32 S7; + UINT32 S8; + UINT32 S9; + UINT32 S10; + UINT32 S11; + UINT32 S12; + UINT32 S13; + UINT32 S14; + UINT32 S15; + UINT32 FPSCR; + UINT32 NO_NAME; +#endif +} TaskContext; + +/** + * @ingroup los_config + * @brief: Task start running function. + * + * @par Description: + * This API is used to start a task. + * + * @attention: + * + * + * @param: None. + * + * @retval None. + * + * @par Dependency: + * + * @see None. + */ +extern VOID HalStartToRun(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_ARCH_CONTEXT_H */ + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_interrupt.h b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_interrupt.h new file mode 100644 index 00000000..280a5fa4 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_interrupt.h @@ -0,0 +1,782 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 _LOS_EXC_H +#define _LOS_EXC_H + +#include "los_config.h" +#include "los_compiler.h" +#include "los_interrupt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +/* * + * @ingroup los_hwi + * Maximum number of used hardware interrupts. + */ +#ifndef OS_HWI_MAX_NUM +#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT +#endif + +/* * + * @ingroup los_hwi + * Highest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_HIGHEST +#define OS_HWI_PRIO_HIGHEST 0 +#endif + +/* * + * @ingroup los_hwi + * Lowest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_LOWEST +#define OS_HWI_PRIO_LOWEST 7 +#endif + + +/* * + * @ingroup los_hwi + * Define the type of a hardware interrupt vector table function. + */ +typedef VOID (**HWI_VECTOR_FUNC)(void); + +/* * + * @ingroup los_hwi + * Count of interrupts. + */ +extern UINT32 g_intCount; + +/* * + * @ingroup los_hwi + * Count of M-Core system interrupt vector. + */ +#define OS_SYS_VECTOR_CNT 16 + +/* * + * @ingroup los_hwi + * Count of M-Core interrupt vector. + */ +#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) + +/* * + * @ingroup los_hwi + * AIRCR register priority group parameter . + */ +#define OS_NVIC_AIRCR_PRIGROUP 7 + +/* * + * @ingroup los_hwi + * Boot interrupt vector table. + */ +extern UINT32 _BootVectors[]; + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable for a Cortex-A7 platform is [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. + */ +#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Null hardware interrupt handling function. + * + * Value: 0x02000901 + * + * Solution: Pass in a valid non-null hardware interrupt handling function. + */ +#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation. + * + * Value: 0x02000902 + * + * Solution: Increase the configured maximum number of supported hardware interrupts. + */ +#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient memory for hardware interrupt initialization. + * + * Value: 0x02000903 + * + * Solution: Expand the configured memory. + */ +#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created. + * + * Value: 0x02000904 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt priority. + * + * Value: 0x02000905 + * + * Solution: Ensure that the interrupt priority is valid. The value range of the interrupt priority applicable for a Cortex-A7 platform is [0,15]. + */ +#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Incorrect interrupt creation mode. + * + * Value: 0x02000906 + * + * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of which the value can be 0 or 1. + */ +#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created as a fast interrupt. + * + * Value: 0x02000907 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) + +/* * + * @ingroup los_hwi + * SysTick control and status register. + */ +#define OS_SYSTICK_CONTROL_REG 0xE000E010 + +/* * + * @ingroup los_hw + * SysTick current value register. + */ +#define OS_SYSTICK_CURRENT_REG 0xE000E018 + +/* * + * @ingroup los_hwi + * Interrupt Priority-Level Registers. + */ +#define OS_NVIC_PRI_BASE 0xE000E400 + +/* * + * @ingroup los_hwi + * Interrupt enable register for 0-31. + */ +#define OS_NVIC_SETENA_BASE 0xE000E100 + +/* * + * @ingroup los_hwi + * interrupt pending register. + */ +#define OS_NVIC_SETPEND_BASE 0xE000E200 + +/* * + * @ingroup los_hwi + * Interrupt active register. + */ +#define OS_NVIC_INT_ACT_BASE 0xE000E300 + +/* * + * @ingroup los_hwi + * Interrupt disable register for 0-31. + */ +#define OS_NVIC_CLRENA_BASE 0xE000E180 + +/* * + * @ingroup los_hwi + * Interrupt control and status register. + */ +#define OS_NVIC_INT_CTRL 0xE000ED04 + +/* * + * @ingroup los_hwi + * Vector table offset register. + */ +#define OS_NVIC_VTOR 0xE000ED08 + +/* * + * @ingroup los_hwi + * Application interrupt and reset control register + */ +#define OS_NVIC_AIRCR 0xE000ED0C + +/* * + * @ingroup los_hwi + * System exception priority register. + */ +#define OS_NVIC_EXCPRI_BASE 0xE000ED18 + +/* * + * @ingroup los_hwi + * Interrupt No. 1 :reset. + */ +#define OS_EXC_RESET 1 + +/* * + * @ingroup los_hwi + * Interrupt No. 2 :Non-Maskable Interrupt. + */ +#define OS_EXC_NMI 2 + +/* * + * @ingroup los_hwi + * Interrupt No. 3 :(hard)fault. + */ +#define OS_EXC_HARD_FAULT 3 + +/* * + * @ingroup los_hwi + * Interrupt No. 4 :MemManage fault. + */ +#define OS_EXC_MPU_FAULT 4 + +/* * + * @ingroup los_hwi + * Interrupt No. 5 :Bus fault. + */ +#define OS_EXC_BUS_FAULT 5 + +/* * + * @ingroup los_hwi + * Interrupt No. 6 :Usage fault. + */ +#define OS_EXC_USAGE_FAULT 6 + +/* * + * @ingroup los_hwi + * Interrupt No. 11 :SVCall. + */ +#define OS_EXC_SVC_CALL 11 + +/* * + * @ingroup los_hwi + * Interrupt No. 12 :Debug monitor. + */ +#define OS_EXC_DBG_MONITOR 12 + +/* * + * @ingroup los_hwi + * Interrupt No. 14 :PendSV. + */ +#define OS_EXC_PEND_SV 14 + +/* * + * @ingroup los_hwi + * Interrupt No. 15 :SysTick. + */ +#define OS_EXC_SYS_TICK 15 + +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT]; + +#if (OS_HWI_WITH_ARG == 1) +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVectonr(num, vector, arg) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pParm = (VOID *)arg; \ + } while(0) +#else +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVector(num, vector) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT] = vector; \ + } while(0) +#endif + +/* * + * @ingroup los_hwi + * @brief: Hardware interrupt entry function. + * + * @par Description: + * This API is used as all hardware interrupt handling function entry. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID HalInterrupt(VOID); + +/* * + * @ingroup los_hwi + * @brief: Get a interrupt number. + * + * @par Description: + * This API is used to get the current interrupt number. + * + * @attention: + * + * + * @param: None. + * + * @retval: Interrupt Indexes number. + * @par Dependency: + * + * @see None. + */ +extern UINT32 HalIntNumGet(VOID); + +/* * + * @ingroup los_hwi + * @brief: Default vector handling function. + * + * @par Description: + * This API is used to configure interrupt for null function. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID HalHwiDefaultHandler(VOID); + +/* * + * @ingroup los_hwi + * @brief: Reset the vector table. + * + * @par Description: + * This API is used to reset the vector table. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID Reset_Handler(VOID); + +/* * + * @ingroup los_hwi + * @brief: Pended System Call. + * + * @par Description: + * PendSV can be pended and is useful for an OS to pend an exception + * so that an action can be performed after other important tasks are completed. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID HalPendSV(VOID); + + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +#define OS_EXC_MAX_BUF_LEN 25 +#define OS_EXC_MAX_NEST_DEPTH 1 + +#define OS_NVIC_SHCSR 0xE000ED24 +#define OS_NVIC_CCR 0xE000ED14 + +#define OS_NVIC_INT_ENABLE_SIZE 0x20 +#define OS_NVIC_INT_PRI_SIZE 0xF0 +#define OS_NVIC_EXCPRI_SIZE 0xC + +#define OS_NVIC_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE +#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE + +#define OS_EXC_FLAG_NO_FLOAT 0x10000000 +#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 +#define OS_EXC_FLAG_IN_HWI 0x02 + +#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB + +#define OS_EXC_EVENT 0x00000001 + +/** + *@ingroup los_exc + * the struct of register files + * + * description: the register files that saved when exception triggered + * + * notes:the following register with prefix 'uw' correspond to the registers in the cpu data sheet. + */ +typedef struct tagExcContext { + //handler save +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + UINT32 S16; + UINT32 S17; + UINT32 S18; + UINT32 S19; + UINT32 S20; + UINT32 S21; + UINT32 S22; + UINT32 S23; + UINT32 S24; + UINT32 S25; + UINT32 S26; + UINT32 S27; + UINT32 S28; + UINT32 S29; + UINT32 S30; + UINT32 S31; +#endif + UINT32 uwR4; + UINT32 uwR5; + UINT32 uwR6; + UINT32 uwR7; + UINT32 uwR8; + UINT32 uwR9; + UINT32 uwR10; + UINT32 uwR11; + UINT32 uwPriMask; + //auto save + UINT32 uwSP; + UINT32 uwR0; + UINT32 uwR1; + UINT32 uwR2; + UINT32 uwR3; + UINT32 uwR12; + UINT32 uwLR; + UINT32 uwPC; + UINT32 uwxPSR; +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED) && (__FPU_USED== 1U))) + UINT32 S0; + UINT32 S1; + UINT32 S2; + UINT32 S3; + UINT32 S4; + UINT32 S5; + UINT32 S6; + UINT32 S7; + UINT32 S8; + UINT32 S9; + UINT32 S10; + UINT32 S11; + UINT32 S12; + UINT32 S13; + UINT32 S14; + UINT32 S15; + UINT32 FPSCR; + UINT32 NO_NAME; +#endif +}EXC_CONTEXT_S; + +typedef VOID (*EXC_PROC_FUNC)(UINT32, EXC_CONTEXT_S *); +VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr); + +/** + * @ingroup los_hwi + * @brief: Exception initialization. + * + * @par Description: + * This API is used to configure the exception function vector table. + * + * @attention: + * + * + *@param uwArraySize [IN] Memory size of exception. + * + * @retval: None + * @par Dependency: + * + * @see None. + */ +VOID OsExcInit(VOID); + +VOID HalExcNMI(VOID); +VOID HalExcHardFault(VOID); +VOID HalExcMemFault(VOID); +VOID HalExcBusFault(VOID); +VOID HalExcUsageFault(VOID); +VOID HalExcSvcCall(VOID); +VOID HalHwiInit(); + + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器入栈时发生错误 + */ +#define OS_EXC_BF_STKERR 1 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器出栈时发生错误 + */ +#define OS_EXC_BF_UNSTKERR 2 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器不精确的数据访问违例 + */ +#define OS_EXC_BF_IMPRECISERR 3 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器精确的数据访问违例 + */ +#define OS_EXC_BF_PRECISERR 4 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器取指时的访问违例 + */ +#define OS_EXC_BF_IBUSERR 5 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器入栈时发生错误 + */ +#define OS_EXC_MF_MSTKERR 6 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器出栈时发生错误 + */ +#define OS_EXC_MF_MUNSTKERR 7 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器数据访问违例 + */ +#define OS_EXC_MF_DACCVIOL 8 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器取指访问违例 + */ +#define OS_EXC_MF_IACCVIOL 9 + + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,表示除法运算时除数为零 + */ +#define OS_EXC_UF_DIVBYZERO 10 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,未对齐访问导致的错误 + */ +#define OS_EXC_UF_UNALIGNED 11 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图执行协处理器相关指令 + */ +#define OS_EXC_UF_NOCP 12 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,在异常返回时试图非法地加载EXC_RETURN到PC + */ +#define OS_EXC_UF_INVPC 13 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图切入ARM状态 + */ +#define OS_EXC_UF_INVSTATE 14 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,执行的指令其编码是未定义的——解码不能 + */ +#define OS_EXC_UF_UNDEFINSTR 15 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:NMI中断 + */ + +#define OS_EXC_CAUSE_NMI 16 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:硬fault + */ +#define OS_EXC_CAUSE_HARDFAULT 17 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:任务处理函数退出 + */ +#define OS_EXC_CAUSE_TASK_EXIT 18 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:致命错误 + */ +#define OS_EXC_CAUSE_FATAL_ERR 19 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:调试事件导致的硬fault + */ +#define OS_EXC_CAUSE_DEBUGEVT 20 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:取向量时发生的硬fault + */ +#define OS_EXC_CAUSE_VECTBL 21 + +/** + *@ingroup los_exc + * 异常信息结构体 + * + * 描述:M4平台下的异常触发时保存的异常信息 + * + */ +typedef struct tagExcInfo { + /**< 异常发生阶段: 0表示异常发生在初始化中,1表示异常发生在任务中,2表示异常发生在中断中 */ + UINT16 phase; + /**< 异常类型,出异常时对照上面列出的1-19号 */ + UINT16 type; + /**< 若为精确地址访问错误表示异常发生时的错误访问地址 */ + UINT32 faultAddr; + /**< 在中断中发生异常,表示中断号。在任务中发生异常,表示任务id,如果发生在初始化中,则为0xffffffff */ + UINT32 thrdPid; + /**< 异常嵌套个数,目前仅支持第一次进入异常时执行注册的钩子函数 */ + UINT16 nestCnt; + /**< 保留 */ + UINT16 reserved; + /**< 自动压栈浮点寄存器的异常发生时刻的硬件上下文 */ + EXC_CONTEXT_S * context; +} ExcInfo; + +extern UINT32 g_curNestCount; +extern UINT32 g_intCount; + +static VOID OsExcSave2DDR(VOID); +VOID OsExcInfoDisplay(ExcInfo *exc); + +extern UINT8 g_uwExcTbl[32]; + + + +typedef struct tagExcInfoCallBackArray { + ExcInfoType uwType; + UINT32 uwValid; + EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; + VOID* pArg; +} ExcInfoArray; + + + +#define MAX_SCENE_INFO_SIZE (8 + sizeof(ExcInfo) - 4 + sizeof(EXC_CONTEXT_S)) +#define MAX_TSK_INFO_SIZE (8 + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) +#define MAX_INT_INFO_SIZE (8 + 0x164) + +#if (LOSCFG_BASE_IPC_QUEUE == 1) +#define MAX_QUEUE_INFO_SIZE (8 + sizeof(QUEUE_INFO_S) * LOSCFG_BASE_IPC_QUEUE_LIMIT) +#else +#define MAX_QUEUE_INFO_SIZE (0) +#endif + +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1) +#define MAX_SWITCH_INFO_SIZE (8 + (sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN) * OS_TASK_SWITCH_INFO_COUNT) +#else +#define MAX_SWITCH_INFO_SIZE (0) +#endif + +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) +#define MAX_MEM_INFO_SIZE (8 + sizeof(MEM_INFO_S) * OS_SYS_MEM_NUM) +#else +#define MAX_MEM_INFO_SIZE (0) +#endif + +#define MAX_EXC_MEM_SIZE ( 4 + MAX_SCENE_INFO_SIZE + MAX_TSK_INFO_SIZE + MAX_QUEUE_INFO_SIZE + MAX_INT_INFO_SIZE + MAX_SWITCH_INFO_SIZE + MAX_MEM_INFO_SIZE + 4) + + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_EXC_H */ + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_timer.h b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_timer.h new file mode 100644 index 00000000..2f38c220 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_timer.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 _LOS_ARCH_TIMER_H +#define _LOS_ARCH_TIMER_H + +#include "los_config.h" +#include "los_compiler.h" +#include "los_context.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT32 HalTickStart(OS_TICK_HANDLER handler); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_ARCH_TIMER_H */ + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_context.c b/kernel/arch/arm/cortex-m4/qemu_gcc/los_context.c new file mode 100644 index 00000000..30fb7885 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_context.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "los_config.h" +#include "los_task.h" +#include "securec.h" +#include "los_interrupt.h" +#include "los_arch_context.h" +#include "los_arch_interrupt.h" +#include "los_arch_timer.h" +#include "los_context.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* **************************************************************************** + Function : HalArchInit + Description : arch init function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalArchInit() +{ + HalHwiInit(); +} + +/* **************************************************************************** + Function : HalSysExit + Description : Task exit function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) +{ + LOS_IntLock(); + for(;;); +} + +/* **************************************************************************** + Function : HalTskStackInit + Description : Task stack initialization function + Input : taskID --- TaskID + stackSize --- Total size of the stack + topStack --- Top of task's stack + Output : None + Return : Context pointer + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) +{ + TaskContext *context = NULL; + errno_t result; + + /* initialize the task stack, write magic num to stack top */ + result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); + if (result != EOK) { + printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); + } + *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; + + context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + context->S16 = 0xAA000010; + context->S17 = 0xAA000011; + context->S18 = 0xAA000012; + context->S19 = 0xAA000013; + context->S20 = 0xAA000014; + context->S21 = 0xAA000015; + context->S22 = 0xAA000016; + context->S23 = 0xAA000017; + context->S24 = 0xAA000018; + context->S25 = 0xAA000019; + context->S26 = 0xAA00001A; + context->S27 = 0xAA00001B; + context->S28 = 0xAA00001C; + context->S29 = 0xAA00001D; + context->S30 = 0xAA00001E; + context->S31 = 0xAA00001F; + context->S0 = 0xAA000000; + context->S1 = 0xAA000001; + context->S2 = 0xAA000002; + context->S3 = 0xAA000003; + context->S4 = 0xAA000004; + context->S5 = 0xAA000005; + context->S6 = 0xAA000006; + context->S7 = 0xAA000007; + context->S8 = 0xAA000008; + context->S9 = 0xAA000009; + context->S10 = 0xAA00000A; + context->S11 = 0xAA00000B; + context->S12 = 0xAA00000C; + context->S13 = 0xAA00000D; + context->S14 = 0xAA00000E; + context->S15 = 0xAA00000F; + context->FPSCR = 0x00000000; + context->NO_NAME = 0xAA000011; +#endif + + context->uwR4 = 0x04040404L; + context->uwR5 = 0x05050505L; + context->uwR6 = 0x06060606L; + context->uwR7 = 0x07070707L; + context->uwR8 = 0x08080808L; + context->uwR9 = 0x09090909L; + context->uwR10 = 0x10101010L; + context->uwR11 = 0x11111111L; + context->uwPriMask = 0; + context->uwR0 = taskID; + context->uwR1 = 0x01010101L; + context->uwR2 = 0x02020202L; + context->uwR3 = 0x03030303L; + context->uwR12 = 0x12121212L; + context->uwLR = (UINT32)(UINTPTR)HalSysExit; + context->uwPC = (UINT32)(UINTPTR)OsTaskEntry; + context->uwxPSR = 0x01000000L; + + return (VOID *)context; +} + +void HalBackTrace() +{ + +} + +LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) +{ + UINT32 ret; + ret = HalTickStart(handler); + if (ret != LOS_OK) { + return ret; + } + HalStartToRun(); + return LOS_OK; /* never return */ +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_dispatch.S b/kernel/arch/arm/cortex-m4/qemu_gcc/los_dispatch.S new file mode 100644 index 00000000..313a9fc7 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_dispatch.S @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + +.syntax unified +.arch armv7e-m +.thumb + +.equ OS_NVIC_INT_CTRL, 0xE000ED04 +.equ OS_NVIC_SYSPRI2, 0xE000ED20 +.equ OS_NVIC_PENDSV_PRI, 0xF0F00000 +.equ OS_NVIC_PENDSVSET, 0x10000000 +.equ OS_TASK_STATUS_RUNNING, 0x0010 + + .section .text + .thumb + + .type HalStartToRun, %function + .global HalStartToRun +HalStartToRun: + .fnstart + .cantunwind + + ldr r4, =OS_NVIC_SYSPRI2 + ldr r5, =OS_NVIC_PENDSV_PRI + str r5, [r4] + + ldr r0, =g_taskScheduled + mov r1, #1 + str r1, [r0] + + mov r0, #2 + msr CONTROL, r0 + + + ldr r0, =g_losTask + ldr r2, [r0, #4] + ldr r0, =g_losTask + str r2, [r0] + + ldr r3, =g_losTask + ldr r0, [r3] + ldrh r7, [r0 , #4] + mov r8, #OS_TASK_STATUS_RUNNING + orr r7, r7, r8 + strh r7, [r0 , #4] + + ldr r12, [r0] + add r12, r12, #36 + + ldmfd r12!, {r0-r7} + msr psp, r12 + mov lr, r5 + + cpsie I + bx r6 + + .fnend + + + .type HalIntLock, %function + .global HalIntLock +HalIntLock: + .fnstart + .cantunwind + + MRS R0, PRIMASK + CPSID I + BX LR + .fnend + + .type HalIntUnLock, %function + .global HalIntUnLock +HalIntUnLock: + .fnstart + .cantunwind + + MRS R0, PRIMASK + CPSIE I + BX LR + .fnend + + .type HalIntRestore, %function + .global HalIntRestore +HalIntRestore: + .fnstart + .cantunwind + + MSR PRIMASK, R0 + BX LR + .fnend + + .type HalTaskSchedule, %function + .global HalTaskSchedule +HalTaskSchedule: + .fnstart + .cantunwind + + ldr r0, =OS_NVIC_INT_CTRL + ldr r1, =OS_NVIC_PENDSVSET + str r1, [r0] + bx lr + .fnend + + + + + .type HalPendSV, %function + .global HalPendSV +HalPendSV: + .fnstart + .cantunwind + + mrs r12, PRIMASK + cpsid I + +HalTaskSwitch: + + mrs r0, psp + + stmfd r0!, {r4-r12} + + ldr r5, =g_losTask + ldr r6, [r5] + str r0, [r6] + + + ldrh r7, [r6 , #4] + mov r8,#OS_TASK_STATUS_RUNNING + bic r7, r7, r8 + strh r7, [r6 , #4] + + + ldr r0, =g_losTask + ldr r0, [r0, #4] + str r0, [r5] + + + ldrh r7, [r0 , #4] + mov r8, #OS_TASK_STATUS_RUNNING + orr r7, r7, r8 + strh r7, [r0 , #4] + + ldr r1, [r0] + + ldmfd r1!, {r4-r12} + msr psp, r1 + + msr PRIMASK, r12 + + + bx lr + .fnend diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S b/kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S new file mode 100644 index 00000000..37d3ec28 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + + .syntax unified + .arch armv7e-m + .thumb +.section .text + + + .global HalExcNMI + .global HalExcHardFault + .global HalExcMemFault + .global HalExcBusFault + .global HalExcUsageFault + .global HalExcSvcCall + + .extern HalExcHandleEntry + .extern g_uwExcTbl + .extern g_taskScheduled + +.equ OS_FLG_BGD_ACTIVE, 0x0002 + +.equ OS_EXC_CAUSE_NMI, 16 +.equ OS_EXC_CAUSE_HARDFAULT, 17 + +.equ HF_DEBUGEVT, 20 +.equ HF_VECTBL, 21 + +.equ FLAG_ADDR_VALID, 0x10000 +.equ FLAG_HWI_ACTIVE, 0x20000 +.equ FLAG_NO_FLOAT, 0x10000000 + +.equ OS_NVIC_FSR , 0xE000ED28 //include BusFault/MemFault/UsageFault State Regeister +.equ OS_NVIC_HFSR , 0xE000ED2C //HardFault State Regeister +.equ OS_NVIC_BFAR , 0xE000ED38 +.equ OS_NVIC_MMAR , 0xE000ED34 +.equ OS_NVIC_ACT_BASE , 0xE000E300 +.equ OS_NVIC_SHCSRS , 0xE000ED24 +.equ OS_NVIC_SHCSR_MASK , 0xC00 + + .type HalExcNMI, %function + .global HalExcNMI +HalExcNMI: + .fnstart + .cantunwind + MOV R0, #OS_EXC_CAUSE_NMI + MOV R1, #0 + B osExcDispatch + .fnend + + .type HalExcHardFault, %function + .global HalExcHardFault +HalExcHardFault: + .fnstart + .cantunwind + MOV R0, #OS_EXC_CAUSE_HARDFAULT + LDR R2, =OS_NVIC_HFSR + LDR R2, [R2] + + MOV R1, #HF_DEBUGEVT + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x80000000 + BNE osExcDispatch // DEBUGEVT + + AND R0, R0 , #0x000000FF + MOV R1, #HF_VECTBL + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x00000002 + BNE osExcDispatch // VECTBL + + //if not DEBUGEVT and VECTBL then is FORCED + AND R0, R0, #0x000000FF + + LDR R2, =OS_NVIC_FSR + LDR R2, [R2] + + TST R2, #0x8000 // BFARVALID + BNE _HFBusFault // BusFault + + TST R2, #0x80 // MMARVALID + BNE _HFMemFault // MemFault + + MOV R12,#0 + B osHFExcCommonBMU + .fnend + + .type _HFBusFault, %function + +_HFBusFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + B osHFExcCommonBMU + .fnend + + .type _HFMemFault, %function + +_HFMemFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + .fnend + + .type osHFExcCommonBMU, %function + .global osHFExcCommonBMU +osHFExcCommonBMU: + .fnstart + .cantunwind + CLZ R2, R2 + LDR R3, =g_uwExcTbl + ADD R3, R3, R2 + LDRB R2, [R3] + ORR R0, R0, R2, LSL #0x8 + ORR R0, R0 ,R12 + B osExcDispatch + .fnend + + .type HalExcSvcCall, %function + .global HalExcSvcCall +HalExcSvcCall: + .fnstart + .cantunwind + TST LR, #0x4 + ITE EQ + MRSEQ R0, MSP + MRSNE R0, PSP + LDR R1, [R0,#24] + LDRB R0, [R1,#-2] + MOV R1, #0 + B osExcDispatch + .fnend + + .type HalExcBusFault, %function + .global HalExcBusFault +HalExcBusFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x8000 // BFARVALID + BEQ _ExcBusNoADDR + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1F00 + + B osExcCommonBMU + .fnend + + .type _ExcBusNoADDR, %function + .global _ExcBusNoADDR +_ExcBusNoADDR: + .fnstart + .cantunwind + MOV R12,#0 + B osExcCommonBMU + .fnend + + .type HalExcMemFault, %function + .global HalExcMemFault +HalExcMemFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x80 // MMARVALID + BEQ _ExcMemNoADDR + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1B + + B osExcCommonBMU + .fnend + + .type _ExcMemNoADDR, %function + .global _ExcMemNoADDR +_ExcMemNoADDR: + .fnstart + .cantunwind + MOV R12,#0 + B osExcCommonBMU + .fnend + + .type HalExcUsageFault, %function + .global HalExcUsageFault +HalExcUsageFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + MOV R1, #0x030F + LSL R1, R1, #16 + AND R0, R0, R1 + MOV R12, #0 + + .fnend + + .type osExcCommonBMU, %function + .global osExcCommonBMU +osExcCommonBMU: + .fnstart + .cantunwind + CLZ R0, R0 + LDR R3, =g_uwExcTbl + ADD R3, R3, R0 + LDRB R0, [R3] + ORR R0, R0, R12 + .fnend +// R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR + + .type osExcDispatch, %function + .global osExcDispatch +osExcDispatch: + .fnstart + .cantunwind + LDR R2, =OS_NVIC_ACT_BASE + MOV R12, #8 // R12 is hwi check loop counter + .fnend + + .type _hwiActiveCheck, %function + .global _hwiActiveCheck +_hwiActiveCheck: + .fnstart + .cantunwind + LDR R3, [R2] // R3 store active hwi register when exc + CMP R3, #0 + BEQ _hwiActiveCheckNext + + // exc occured in IRQ + ORR R0, R0, #FLAG_HWI_ACTIVE + RBIT R2, R3 + CLZ R2, R2 + AND R12, R12, #1 + ADD R2, R2, R12, LSL #5 // calculate R2 (hwi number) as uwPid + .fnend + + .type _ExcInMSP, %function + .global _ExcInMSP +_ExcInMSP: + .fnstart + .cantunwind + CMP LR, #0XFFFFFFED + BNE _NoFloatInMsp + ADD R3, R13, #104 + PUSH {R3} + MRS R12, PRIMASK // store message-->exc: disable int? + PUSH {R4-R12} // store message-->exc: {R4-R12} + B _handleEntry + .fnend + + .type _NoFloatInMsp, %function + .global _NoFloatInMsp +_NoFloatInMsp: + .fnstart + .cantunwind + ADD R3, R13, #32 + PUSH {R3} // save IRQ SP // store message-->exc: MSP(R13) + + MRS R12, PRIMASK // store message-->exc: disable int? + PUSH {R4-R12} // store message-->exc: {R4-R12} + ORR R0, R0, #FLAG_NO_FLOAT + B _handleEntry + .fnend + + .type _hwiActiveCheckNext, %function + .global _hwiActiveCheckNext +_hwiActiveCheckNext: + .fnstart + .cantunwind + ADD R2, R2, #4 // next NVIC ACT ADDR + SUBS R12, R12, #1 + BNE _hwiActiveCheck + + /*NMI interrupt excption*/ + LDR R2, =OS_NVIC_SHCSRS + LDRH R2,[R2] + LDR R3,=OS_NVIC_SHCSR_MASK + AND R2, R2,R3 + CMP R2,#0 + BNE _ExcInMSP + // exc occured in Task or Init or exc + // reserved for register info from task stack + + LDR R2, =g_taskScheduled + LDR R2, [R2] + TST R2, #1 // OS_FLG_BGD_ACTIVE + BEQ _ExcInMSP // if exc occured in Init then branch + + + CMP LR, #0xFFFFFFED //auto push floating registers + BNE _NoFloatInPsp + + // exc occured in Task + MOV R2, R13 + SUB R13, #96 // add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #104 + PUSH {R12} // save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + + // copy auto saved task register + + LDMFD R3!, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) + STMFD R2!, {R4-R11} + B _handleEntry + .fnend + + .type _NoFloatInPsp, %function + .global _NoFloatInPsp +_NoFloatInPsp: + .fnstart + .cantunwind + MOV R2, R13 //no auto push floating registers + SUB R13, #32 // add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #32 + PUSH {R12} // save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + + LDMFD R3, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) + STMFD R2!, {R4-R11} + ORR R0, R0, #FLAG_NO_FLOAT + .fnend + + .type _handleEntry, %function + .global _handleEntry +_handleEntry: + .fnstart + .cantunwind + MOV R3, R13 // R13:the 4th param + CPSID I + CPSID F + B HalExcHandleEntry + + NOP + .fnend diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_interrupt.c b/kernel/arch/arm/cortex-m4/qemu_gcc/los_interrupt.c new file mode 100644 index 00000000..3dc41549 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_interrupt.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "los_interrupt.h" +#include "los_context.h" +#include "los_arch_interrupt.h" +#include +#include "los_debug.h" +#include "los_task.h" +#include "los_tick.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/*lint -save -e40 -e522 -e533*/ + +UINT32 g_intCount = 0; +/*lint -restore*/ +#ifdef __ICCARM__ +#pragma location = ".data.vector" +#pragma data_alignment=0x100 +#elif defined(__CC_ARM) || defined(__GNUC__) +LITE_OS_SEC_VEC +#endif +HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; + +#if (OS_HWI_WITH_ARG == 1) +HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; +#else +HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +#endif + +/* **************************************************************************** + Function : HalIntNumGet + Description : Get a interrupt number + Input : None + Output : None + Return : Interrupt Indexes number + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 HalIntNumGet(VOID) +{ + return __get_IPSR(); +} + +inline UINT32 HalIsIntAcvive(VOID) +{ + return (g_intCount > 0); +} +/* **************************************************************************** + Function : HalHwiDefaultHandler + Description : default handler of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +/*lint -e529*/ +LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) +{ + UINT32 irqNum = HalIntNumGet(); + PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, irqNum); + while (1) {} +} + +/* **************************************************************************** + Function : HalInterrupt + Description : Hardware interrupt entry function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) +{ + UINT32 hwiIndex; + UINT32 intSave; + +#if (LOSCFG_KERNEL_RUNSTOP == 1) + SCB->SCR &= (UINT32) ~((UINT32)SCB_SCR_SLEEPDEEP_Msk); +#endif + + intSave = LOS_IntLock(); + + g_intCount++; + + LOS_IntRestore(intSave); + + hwiIndex = HalIntNumGet(); + +#if (OS_HWI_WITH_ARG == 1) + if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { + g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + } +#else + if (g_hwiSlaveForm[hwiIndex] != 0) { + g_hwiSlaveForm[hwiIndex](); + } +#endif + intSave = LOS_IntLock(); + g_intCount--; + LOS_IntRestore(intSave); +} + +/* **************************************************************************** + Function : HalHwiCreate + Description : create hardware interrupt + Input : hwiNum --- hwi num to create + hwiPrio --- priority of the hwi + mode --- unused + handler --- hwi handler + arg --- param of the hwi handler + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg) +{ + UINTPTR intSave; + + if (handler == NULL) { + return OS_ERRNO_HWI_PROC_FUNC_NULL; + } + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)HalHwiDefaultHandler) { + return OS_ERRNO_HWI_ALREADY_CREATED; + } + + if (hwiPrio > OS_HWI_PRIO_LOWEST) { + return OS_ERRNO_HWI_PRIO_INVALID; + } + + intSave = LOS_IntLock(); +#if (OS_HWI_WITH_ARG == 1) + OsSetVector(hwiNum, handler, arg); +#else + OsSetVector(hwiNum, handler); +#endif + NVIC_EnableIRQ((IRQn_Type)hwiNum); + NVIC_SetPriority((IRQn_Type)hwiNum, hwiPrio); + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +/* **************************************************************************** + Function : HalHwiDelete + Description : Delete hardware interrupt + Input : hwiNum --- hwi num to delete + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) +{ + UINT32 intSave; + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + NVIC_DisableIRQ((IRQn_Type)hwiNum); + + intSave = LOS_IntLock(); + + g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler; + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +#define OS_NVIC_INT_CTRL_SIZE 4 +#define OS_NVIC_SHCSR_SIZE 4 +#define FAULT_STATUS_REG_BIT 32 +#define USGFAULT (1 << 18) +#define BUSFAULT (1 << 17) +#define MEMFAULT (1 << 16) +#define DIV0FAULT (1 << 4) +#define HARDFAULT_IRQN (-13) + +static ExcInfoArray g_excArray[OS_EXC_TYPE_MAX]; + +static ExcInfo g_excInfo = {0}; + +UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { + 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, + 0, 0, 0, 0, OS_EXC_UF_NOCP, OS_EXC_UF_INVPC, OS_EXC_UF_INVSTATE, OS_EXC_UF_UNDEFINSTR, + 0, 0, 0, OS_EXC_BF_STKERR, OS_EXC_BF_UNSTKERR, OS_EXC_BF_IMPRECISERR, OS_EXC_BF_PRECISERR, OS_EXC_BF_IBUSERR, + 0, 0, 0, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL +}; + +UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) +{ + UINT32 *base = NULL; + UINT32 len = 0, i, j; +#define OS_NR_NVIC_EXC_DUMP_Types 7 + UINT32 rgNvicBases[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_SETENA_BASE, OS_NVIC_SETPEND_BASE, + OS_NVIC_INT_ACT_BASE, OS_NVIC_PRI_BASE, OS_NVIC_EXCPRI_BASE, OS_NVIC_SHCSR, OS_NVIC_INT_CTRL}; + UINT32 rgNvicLens[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_INT_ENABLE_SIZE, OS_NVIC_INT_PEND_SIZE, + OS_NVIC_INT_ACT_SIZE, OS_NVIC_INT_PRI_SIZE, OS_NVIC_EXCPRI_SIZE, OS_NVIC_SHCSR_SIZE, OS_NVIC_INT_CTRL_SIZE}; + char strRgEnable[] = "enable"; + char strRgPending[] = "pending"; + char strRgActive[] = "active"; + char strRgPriority[] = "priority"; + char strRgException[] = "exception"; + char strRgShcsr[] = "shcsr"; + char strRgIntCtrl[] = "control"; + char *strRgs[] = {strRgEnable, strRgPending, strRgActive, strRgPriority, strRgException, strRgShcsr, strRgIntCtrl}; + (VOID)index; + (VOID)excContent; + + PRINTK("OS exception NVIC dump: \n"); + for (i = 0; i < OS_NR_NVIC_EXC_DUMP_Types; i++) { + base = (UINT32 *)rgNvicBases[i]; + len = rgNvicLens[i]; + PRINTK("interrupt %s register, base address: 0x%x, size: 0x%x\n", strRgs[i], base, len); + len = (len >> 2); + for (j = 0; j < len; j++) { + PRINTK("0x%x ", *(base + j)); + } + PRINTK("\n"); + } + return 0; +} + +UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) +{ + (VOID)index; + (VOID)excContent; + PRINTK("OS exception context dump:\n"); + PRINTK("Phase = 0x%x\n", g_excInfo.phase); + PRINTK("Type = 0x%x\n", g_excInfo.type); + PRINTK("FaultAddr = 0x%x\n", g_excInfo.faultAddr); + PRINTK("ThrdPid = 0x%x\n", g_excInfo.thrdPid); + PRINTK("R0 = 0x%x\n", g_excInfo.context->uwR0); + PRINTK("R1 = 0x%x\n", g_excInfo.context->uwR1); + PRINTK("R2 = 0x%x\n", g_excInfo.context->uwR2); + PRINTK("R3 = 0x%x\n", g_excInfo.context->uwR3); + PRINTK("R4 = 0x%x\n", g_excInfo.context->uwR4); + PRINTK("R5 = 0x%x\n", g_excInfo.context->uwR5); + PRINTK("R6 = 0x%x\n", g_excInfo.context->uwR6); + PRINTK("R7 = 0x%x\n", g_excInfo.context->uwR7); + PRINTK("R8 = 0x%x\n", g_excInfo.context->uwR8); + PRINTK("R9 = 0x%x\n", g_excInfo.context->uwR9); + PRINTK("R10 = 0x%x\n", g_excInfo.context->uwR10); + PRINTK("R11 = 0x%x\n", g_excInfo.context->uwR11); + PRINTK("R12 = 0x%x\n", g_excInfo.context->uwR12); + PRINTK("PriMask = 0x%x\n", g_excInfo.context->uwPriMask); + PRINTK("SP = 0x%x\n", g_excInfo.context->uwSP); + PRINTK("LR = 0x%x\n", g_excInfo.context->uwLR); + PRINTK("PC = 0x%x\n", g_excInfo.context->uwPC); + PRINTK("xPSR = 0x%x\n", g_excInfo.context->uwxPSR); + return 0; +} + +VOID HalDumpMsg(VOID) +{ + UINT32 index = 0; + for (index = 0; index < (OS_EXC_TYPE_MAX - 1); index++) { + if (g_excArray[index].uwValid == FALSE) { + continue; + } + g_excArray[index].pFnExcInfoCb(index, g_excArray[index].pArg); + } +} + +LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) +{ + UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; + g_intCount++; + g_excInfo.nestCnt++; + + g_excInfo.type = excType & OS_NULL_SHORT; + + if (tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) { + g_excInfo.faultAddr = faultAddr; + } else { + g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; + } + if (g_losTask.runTask != NULL) { + if (tmpFlag & OS_EXC_FLAG_IN_HWI) { + g_excInfo.phase = OS_EXC_IN_HWI; + g_excInfo.thrdPid = pid; + } else { + g_excInfo.phase = OS_EXC_IN_TASK; + g_excInfo.thrdPid = g_losTask.runTask->taskID; + } + } else { + g_excInfo.phase = OS_EXC_IN_INIT; + g_excInfo.thrdPid = OS_NULL_INT; + } + if (excType & OS_EXC_FLAG_NO_FLOAT) { + g_excInfo.context = (EXC_CONTEXT_S *)((CHAR *)excBufAddr - LOS_OFF_SET_OF(EXC_CONTEXT_S, uwR4)); + } else { + g_excInfo.context = excBufAddr; + } + HalDumpMsg(); + HalSysExit(); +} + +VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) +{ + ExcInfoArray *excInfo = NULL; + if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { + PRINT_ERR("HalExcRegister ERROR!\n"); + return; + } + excInfo = &(g_excArray[type]); + excInfo->uwType = type; + excInfo->pFnExcInfoCb = func; + excInfo->pArg = arg; + excInfo->uwValid = TRUE; +} + +/* **************************************************************************** + Function : HalHwiInit + Description : initialization of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() +{ +#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) + UINT32 index; + g_hwiForm[0] = 0; /* [0] Top of Stack */ + g_hwiForm[1] = Reset_Handler; /* [1] reset */ + for (index = 2; index < OS_VECTOR_CNT; index++) { + g_hwiForm[index] = (HWI_PROC_FUNC)HalHwiDefaultHandler; + } + /* Exception handler register */ + g_hwiForm[NonMaskableInt_IRQn + OS_SYS_VECTOR_CNT] = HalExcNMI; + g_hwiForm[HARDFAULT_IRQN + OS_SYS_VECTOR_CNT] = HalExcHardFault; + g_hwiForm[MemoryManagement_IRQn + OS_SYS_VECTOR_CNT] = HalExcMemFault; + g_hwiForm[BusFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcBusFault; + g_hwiForm[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcUsageFault; + g_hwiForm[SVCall_IRQn + OS_SYS_VECTOR_CNT] = HalExcSvcCall; + g_hwiForm[PendSV_IRQn + OS_SYS_VECTOR_CNT] = HalPendSV; + + /* Interrupt vector table location */ + SCB->VTOR = (UINT32)(UINTPTR)g_hwiForm; +#endif + +#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */ + NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP); +#endif + + /* Enable USGFAULT, BUSFAULT, MEMFAULT */ + *(volatile UINT32 *)OS_NVIC_SHCSR |= (USGFAULT | BUSFAULT | MEMFAULT); + /* Enable DIV 0 and unaligned exception */ + *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; + + HalExcRegister(OS_EXC_TYPE_CONTEXT, (EXC_INFO_SAVE_CALLBACK)HalExcContextDump, NULL); + HalExcRegister(OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)HalExcNvicDump, NULL); + + return; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_timer.c b/kernel/arch/arm/cortex-m4/qemu_gcc/los_timer.c new file mode 100644 index 00000000..1bd385b5 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/qemu_gcc/los_timer.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "los_config.h" +#include "los_tick.h" +#include "los_arch_interrupt.h" +#include "los_timer.h" +#include "los_context.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + + +/* **************************************************************************** +Function : HalTickStart +Description : Configure Tick Interrupt Start +Input : none +output : none +return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed +**************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) +{ + UINT32 ret; + + if ((OS_SYS_CLOCK == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) { + return LOS_ERRNO_TICK_CFG_INVALID; + } +#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) +#if (OS_HWI_WITH_ARG == 1) + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler, NULL); +#else + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler); +#endif +#endif + + g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; + g_ullTickCount = 0; + + ret = SysTick_Config(g_cyclesPerTick); + if (ret == 1) { + return LOS_ERRNO_TICK_PER_SEC_TOO_SMALL; + } + + return LOS_OK; +} + +/* **************************************************************************** +Function : HalSysTickCurrCycleGet +Description : Get System cycle count +Input : none +output : none +return : hwCycle --- the system cycle count +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 HalSysTickCurrCycleGet(VOID) +{ + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + hwCycle += g_cyclesPerTick; + } + + LOS_IntRestore(intSave); + + return hwCycle; +} + +/* **************************************************************************** +Function : HalGetCpuCycle +Description : Get System cycle count +Input : none +output : cntHi --- CpuTick High 4 byte + cntLo --- CpuTick Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + swTick++; + } + + cycle = (((swTick) * g_cyclesPerTick) + (g_cyclesPerTick - hwCycle)); + + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} + +/* **************************************************************************** +Function : HalGetSystickCycle +Description : Get Sys tick cycle count +Input : none +output : cntHi --- SysTick count High 4 byte + cntLo --- SysTick count Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalGetSystickCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + UINT32 systickLoad; + UINT32 systickCur; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + + systickLoad = SysTick->LOAD; + systickCur = SysTick->VAL; + if (systickLoad < systickCur) { + LOS_IntRestore(intSave); + return; + } + hwCycle = systickLoad - systickCur; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = systickLoad - systickCur; + swTick++; + } + + cycle = hwCycle + swTick * systickLoad; + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} + +static BOOL g_sysSleepFlag = FALSE; + +VOID HalTickLock(VOID) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; +} + +VOID HalTickUnlock(VOID) +{ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +BOOL HalGetSysSleepFlag(VOID) +{ + return g_sysSleepFlag; +} + +VOID HalClearSysSleepFlag(VOID) +{ + g_sysSleepFlag = FALSE; +} + +VOID HalEnterSleep(LOS_SysSleepEnum sleep) +{ + __DSB(); + __WFI(); + __ISB(); +} + +//extern unsigned int SystemCoreClock; +void HalDelay(UINT32 ticks) +{ +#if 0 + UINT32 delayTimes; + /* there are 4 machine cycle in loop */ + if ((ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES)) >= 0xffffffff) { + delayTimes = 0xffffffff; + } else { + delayTimes = ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES); + } + while (delayTimes) { + delayTimes = delayTimes - 1; + } +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ -- Gitee From 4b2473add6fe207fe8032cd95138c56e864b5dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=80=99=E9=B9=8F=E9=A3=9E?= <2597457485@qq.com> Date: Thu, 28 Jan 2021 15:58:48 +0800 Subject: [PATCH 2/2] add cortex-m4 gcc --- .../{qemu_gcc => gcc}/los_arch_atomic.h | 322 ++-- .../{qemu_gcc => gcc}/los_arch_context.h | 1 - .../{qemu_gcc => gcc}/los_arch_interrupt.h | 1564 ++++++++--------- .../{qemu_gcc => gcc}/los_arch_timer.h | 0 .../cortex-m4/{qemu_gcc => gcc}/los_context.c | 349 ++-- .../{qemu_gcc => gcc}/los_dispatch.S | 329 ++-- .../arm/cortex-m4/{qemu_gcc => gcc}/los_exc.S | 759 ++++---- .../{qemu_gcc => gcc}/los_interrupt.c | 795 +++++---- .../cortex-m4/{qemu_gcc => gcc}/los_timer.c | 470 ++--- 9 files changed, 2279 insertions(+), 2310 deletions(-) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_arch_atomic.h (97%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_arch_context.h (99%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_arch_interrupt.h (96%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_arch_timer.h (100%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_context.c (97%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_dispatch.S (59%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_exc.S (95%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_interrupt.c (97%) rename kernel/arch/arm/cortex-m4/{qemu_gcc => gcc}/los_timer.c (96%) diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_atomic.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_atomic.h similarity index 97% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_atomic.h rename to kernel/arch/arm/cortex-m4/gcc/los_arch_atomic.h index 9cb48162..2e6121c3 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_atomic.h +++ b/kernel/arch/arm/cortex-m4/gcc/los_arch_atomic.h @@ -1,161 +1,161 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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 LOS_ATOMIC_H -#define LOS_ATOMIC_H - -#include "los_compiler.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/** - * @ingroup los_atomic - * @brief Atomic exchange for 32-bit variable. - * - * @par Description: - * This API is used to implement the atomic exchange for 32-bit variable and return the previous value of the atomic variable. - * @attention - * - * - * @param v [IN] The variable pointer. - * @param val [IN] The exchange value. - * - * @retval #INT32 The previous value of the atomic variable - * @par Dependency: - * - * @see - * @since Huawei LiteOS V100R001C00 - */ -STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) -{ - INT32 prevVal = 0; - UINT32 status = 0; - - do { - __asm__ __volatile__("ldrex %0, [%3]\n" - "strex %1, %4, [%3]" - : "=&r"(prevVal), "=&r"(status), "+m"(*v) - : "r"(v), "r"(val) - : "cc"); - } while (__builtin_expect(status != 0, 0)); - - return prevVal; -} - -/** - * @ingroup los_atomic - * @brief Atomic auto-decrement. - * - * @par Description: - * This API is used to implementating the atomic auto-decrement and return the result of auto-decrement. - * @attention - * - * - * @param v [IN] The addSelf variable pointer. - * - * @retval #INT32 The return value of variable auto-decrement. - * @par Dependency: - * - * @see - * @since Huawei LiteOS V100R001C00 - */ -STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) -{ - INT32 val = 0; - UINT32 status = 0; - - do { - __asm__ __volatile__("ldrex %0, [%3]\n" - "sub %0, %0, #1\n" - "strex %1, %0, [%3]" - : "=&r"(val), "=&r"(status), "+m"(*v) - : "r"(v) - : "cc"); - } while (__builtin_expect(status != 0, 0)); - - return val; -} - -/** - * @ingroup los_atomic - * @brief Atomic exchange for 32-bit variable with compare. - * - * @par Description: - * This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to oldVal. - * @attention - * - * - * @param v [IN] The variable pointer. - * @param val [IN] The new value. - * @param oldVal [IN] The old value. - * - * @retval TRUE The previous value of the atomic variable is not equal to oldVal. - * @retval FALSE The previous value of the atomic variable is equal to oldVal. - * @par Dependency: - * - * @see - * @since Huawei LiteOS V100R001C00 - */ -STATIC INLINE BOOL HalAtomicCmpXchg32bits(volatile INT32 *v, INT32 val, INT32 oldVal) -{ - INT32 prevVal = 0; - UINT32 status = 0; - - do { - __asm__ __volatile__("1: ldrex %0, %2\n" - " mov %1, #0\n" - " cmp %0, %3\n" - " bne 2f\n" - " strex %1, %4, %2\n" - "2:" - : "=&r"(prevVal), "=&r"(status), "+Q"(*v) - : "r"(oldVal), "r"(val) - : "cc"); - } while (__builtin_expect(status != 0, 0)); - - return prevVal != oldVal; -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* LOS_ATOMIC_H */ - +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 LOS_ATOMIC_H +#define LOS_ATOMIC_H + +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable and return the previous value of the atomic variable. + * @attention + * + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + * + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) +{ + INT32 prevVal = 0; + UINT32 status = 0; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "strex %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic auto-decrement and return the result of auto-decrement. + * @attention + * + * + * @param v [IN] The addSelf variable pointer. + * + * @retval #INT32 The return value of variable auto-decrement. + * @par Dependency: + * + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) +{ + INT32 val = 0; + UINT32 status = 0; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to oldVal. + * @attention + * + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + * + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE BOOL HalAtomicCmpXchg32bits(volatile INT32 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal = 0; + UINT32 status = 0; + + do { + __asm__ __volatile__("1: ldrex %0, %2\n" + " mov %1, #0\n" + " cmp %0, %3\n" + " bne 2f\n" + " strex %1, %4, %2\n" + "2:" + : "=&r"(prevVal), "=&r"(status), "+Q"(*v) + : "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* LOS_ATOMIC_H */ + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_context.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_context.h similarity index 99% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_context.h rename to kernel/arch/arm/cortex-m4/gcc/los_arch_context.h index 62ece273..4759cb69 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_context.h +++ b/kernel/arch/arm/cortex-m4/gcc/los_arch_context.h @@ -35,7 +35,6 @@ #include "los_config.h" #include "los_compiler.h" - #ifdef __cplusplus #if __cplusplus extern "C" { diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_interrupt.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_interrupt.h similarity index 96% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_interrupt.h rename to kernel/arch/arm/cortex-m4/gcc/los_arch_interrupt.h index 280a5fa4..6a271023 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m4/gcc/los_arch_interrupt.h @@ -1,782 +1,782 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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 _LOS_EXC_H -#define _LOS_EXC_H - -#include "los_config.h" -#include "los_compiler.h" -#include "los_interrupt.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -/* * - * @ingroup los_hwi - * Maximum number of used hardware interrupts. - */ -#ifndef OS_HWI_MAX_NUM -#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT -#endif - -/* * - * @ingroup los_hwi - * Highest priority of a hardware interrupt. - */ -#ifndef OS_HWI_PRIO_HIGHEST -#define OS_HWI_PRIO_HIGHEST 0 -#endif - -/* * - * @ingroup los_hwi - * Lowest priority of a hardware interrupt. - */ -#ifndef OS_HWI_PRIO_LOWEST -#define OS_HWI_PRIO_LOWEST 7 -#endif - - -/* * - * @ingroup los_hwi - * Define the type of a hardware interrupt vector table function. - */ -typedef VOID (**HWI_VECTOR_FUNC)(void); - -/* * - * @ingroup los_hwi - * Count of interrupts. - */ -extern UINT32 g_intCount; - -/* * - * @ingroup los_hwi - * Count of M-Core system interrupt vector. - */ -#define OS_SYS_VECTOR_CNT 16 - -/* * - * @ingroup los_hwi - * Count of M-Core interrupt vector. - */ -#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) - -/* * - * @ingroup los_hwi - * AIRCR register priority group parameter . - */ -#define OS_NVIC_AIRCR_PRIGROUP 7 - -/* * - * @ingroup los_hwi - * Boot interrupt vector table. - */ -extern UINT32 _BootVectors[]; - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: Invalid interrupt number. - * - * Value: 0x02000900 - * - * Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable for a Cortex-A7 platform is [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. - */ -#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: Null hardware interrupt handling function. - * - * Value: 0x02000901 - * - * Solution: Pass in a valid non-null hardware interrupt handling function. - */ -#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation. - * - * Value: 0x02000902 - * - * Solution: Increase the configured maximum number of supported hardware interrupts. - */ -#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: Insufficient memory for hardware interrupt initialization. - * - * Value: 0x02000903 - * - * Solution: Expand the configured memory. - */ -#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: The interrupt has already been created. - * - * Value: 0x02000904 - * - * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. - */ -#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: Invalid interrupt priority. - * - * Value: 0x02000905 - * - * Solution: Ensure that the interrupt priority is valid. The value range of the interrupt priority applicable for a Cortex-A7 platform is [0,15]. - */ -#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: Incorrect interrupt creation mode. - * - * Value: 0x02000906 - * - * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of which the value can be 0 or 1. - */ -#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) - -/* * - * @ingroup los_hwi - * Hardware interrupt error code: The interrupt has already been created as a fast interrupt. - * - * Value: 0x02000907 - * - * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. - */ -#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) - -/* * - * @ingroup los_hwi - * SysTick control and status register. - */ -#define OS_SYSTICK_CONTROL_REG 0xE000E010 - -/* * - * @ingroup los_hw - * SysTick current value register. - */ -#define OS_SYSTICK_CURRENT_REG 0xE000E018 - -/* * - * @ingroup los_hwi - * Interrupt Priority-Level Registers. - */ -#define OS_NVIC_PRI_BASE 0xE000E400 - -/* * - * @ingroup los_hwi - * Interrupt enable register for 0-31. - */ -#define OS_NVIC_SETENA_BASE 0xE000E100 - -/* * - * @ingroup los_hwi - * interrupt pending register. - */ -#define OS_NVIC_SETPEND_BASE 0xE000E200 - -/* * - * @ingroup los_hwi - * Interrupt active register. - */ -#define OS_NVIC_INT_ACT_BASE 0xE000E300 - -/* * - * @ingroup los_hwi - * Interrupt disable register for 0-31. - */ -#define OS_NVIC_CLRENA_BASE 0xE000E180 - -/* * - * @ingroup los_hwi - * Interrupt control and status register. - */ -#define OS_NVIC_INT_CTRL 0xE000ED04 - -/* * - * @ingroup los_hwi - * Vector table offset register. - */ -#define OS_NVIC_VTOR 0xE000ED08 - -/* * - * @ingroup los_hwi - * Application interrupt and reset control register - */ -#define OS_NVIC_AIRCR 0xE000ED0C - -/* * - * @ingroup los_hwi - * System exception priority register. - */ -#define OS_NVIC_EXCPRI_BASE 0xE000ED18 - -/* * - * @ingroup los_hwi - * Interrupt No. 1 :reset. - */ -#define OS_EXC_RESET 1 - -/* * - * @ingroup los_hwi - * Interrupt No. 2 :Non-Maskable Interrupt. - */ -#define OS_EXC_NMI 2 - -/* * - * @ingroup los_hwi - * Interrupt No. 3 :(hard)fault. - */ -#define OS_EXC_HARD_FAULT 3 - -/* * - * @ingroup los_hwi - * Interrupt No. 4 :MemManage fault. - */ -#define OS_EXC_MPU_FAULT 4 - -/* * - * @ingroup los_hwi - * Interrupt No. 5 :Bus fault. - */ -#define OS_EXC_BUS_FAULT 5 - -/* * - * @ingroup los_hwi - * Interrupt No. 6 :Usage fault. - */ -#define OS_EXC_USAGE_FAULT 6 - -/* * - * @ingroup los_hwi - * Interrupt No. 11 :SVCall. - */ -#define OS_EXC_SVC_CALL 11 - -/* * - * @ingroup los_hwi - * Interrupt No. 12 :Debug monitor. - */ -#define OS_EXC_DBG_MONITOR 12 - -/* * - * @ingroup los_hwi - * Interrupt No. 14 :PendSV. - */ -#define OS_EXC_PEND_SV 14 - -/* * - * @ingroup los_hwi - * Interrupt No. 15 :SysTick. - */ -#define OS_EXC_SYS_TICK 15 - -/* * - * @ingroup los_hwi - * hardware interrupt form mapping handling function array. - */ -extern HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT]; - -#if (OS_HWI_WITH_ARG == 1) -/* * - * @ingroup los_hwi - * hardware interrupt Slave form mapping handling function array. - */ -extern HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; - -/* * - * @ingroup los_hwi - * Set interrupt vector table. - */ -#define OsSetVectonr(num, vector, arg) \ - do { \ - g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; \ - g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; \ - g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pParm = (VOID *)arg; \ - } while(0) -#else -/* * - * @ingroup los_hwi - * hardware interrupt Slave form mapping handling function array. - */ -extern HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; - -/* * - * @ingroup los_hwi - * Set interrupt vector table. - */ -#define OsSetVector(num, vector) \ - do { \ - g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; \ - g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT] = vector; \ - } while(0) -#endif - -/* * - * @ingroup los_hwi - * @brief: Hardware interrupt entry function. - * - * @par Description: - * This API is used as all hardware interrupt handling function entry. - * - * @attention: - * - * - * @param:None. - * - * @retval:None. - * @par Dependency: - * - * @see None. - */ -extern VOID HalInterrupt(VOID); - -/* * - * @ingroup los_hwi - * @brief: Get a interrupt number. - * - * @par Description: - * This API is used to get the current interrupt number. - * - * @attention: - * - * - * @param: None. - * - * @retval: Interrupt Indexes number. - * @par Dependency: - * - * @see None. - */ -extern UINT32 HalIntNumGet(VOID); - -/* * - * @ingroup los_hwi - * @brief: Default vector handling function. - * - * @par Description: - * This API is used to configure interrupt for null function. - * - * @attention: - * - * - * @param:None. - * - * @retval:None. - * @par Dependency: - * - * @see None. - */ -extern VOID HalHwiDefaultHandler(VOID); - -/* * - * @ingroup los_hwi - * @brief: Reset the vector table. - * - * @par Description: - * This API is used to reset the vector table. - * - * @attention: - * - * - * @param:None. - * - * @retval:None. - * @par Dependency: - * - * @see None. - */ -extern VOID Reset_Handler(VOID); - -/* * - * @ingroup los_hwi - * @brief: Pended System Call. - * - * @par Description: - * PendSV can be pended and is useful for an OS to pend an exception - * so that an action can be performed after other important tasks are completed. - * - * @attention: - * - * - * @param:None. - * - * @retval:None. - * @par Dependency: - * - * @see None. - */ -extern VOID HalPendSV(VOID); - - -#define OS_EXC_IN_INIT 0 -#define OS_EXC_IN_TASK 1 -#define OS_EXC_IN_HWI 2 - -#define OS_EXC_MAX_BUF_LEN 25 -#define OS_EXC_MAX_NEST_DEPTH 1 - -#define OS_NVIC_SHCSR 0xE000ED24 -#define OS_NVIC_CCR 0xE000ED14 - -#define OS_NVIC_INT_ENABLE_SIZE 0x20 -#define OS_NVIC_INT_PRI_SIZE 0xF0 -#define OS_NVIC_EXCPRI_SIZE 0xC - -#define OS_NVIC_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE -#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE - -#define OS_EXC_FLAG_NO_FLOAT 0x10000000 -#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 -#define OS_EXC_FLAG_IN_HWI 0x02 - -#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB - -#define OS_EXC_EVENT 0x00000001 - -/** - *@ingroup los_exc - * the struct of register files - * - * description: the register files that saved when exception triggered - * - * notes:the following register with prefix 'uw' correspond to the registers in the cpu data sheet. - */ -typedef struct tagExcContext { - //handler save -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - UINT32 S16; - UINT32 S17; - UINT32 S18; - UINT32 S19; - UINT32 S20; - UINT32 S21; - UINT32 S22; - UINT32 S23; - UINT32 S24; - UINT32 S25; - UINT32 S26; - UINT32 S27; - UINT32 S28; - UINT32 S29; - UINT32 S30; - UINT32 S31; -#endif - UINT32 uwR4; - UINT32 uwR5; - UINT32 uwR6; - UINT32 uwR7; - UINT32 uwR8; - UINT32 uwR9; - UINT32 uwR10; - UINT32 uwR11; - UINT32 uwPriMask; - //auto save - UINT32 uwSP; - UINT32 uwR0; - UINT32 uwR1; - UINT32 uwR2; - UINT32 uwR3; - UINT32 uwR12; - UINT32 uwLR; - UINT32 uwPC; - UINT32 uwxPSR; -#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined (__FPU_USED) && (__FPU_USED== 1U))) - UINT32 S0; - UINT32 S1; - UINT32 S2; - UINT32 S3; - UINT32 S4; - UINT32 S5; - UINT32 S6; - UINT32 S7; - UINT32 S8; - UINT32 S9; - UINT32 S10; - UINT32 S11; - UINT32 S12; - UINT32 S13; - UINT32 S14; - UINT32 S15; - UINT32 FPSCR; - UINT32 NO_NAME; -#endif -}EXC_CONTEXT_S; - -typedef VOID (*EXC_PROC_FUNC)(UINT32, EXC_CONTEXT_S *); -VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr); - -/** - * @ingroup los_hwi - * @brief: Exception initialization. - * - * @par Description: - * This API is used to configure the exception function vector table. - * - * @attention: - * - * - *@param uwArraySize [IN] Memory size of exception. - * - * @retval: None - * @par Dependency: - * - * @see None. - */ -VOID OsExcInit(VOID); - -VOID HalExcNMI(VOID); -VOID HalExcHardFault(VOID); -VOID HalExcMemFault(VOID); -VOID HalExcBusFault(VOID); -VOID HalExcUsageFault(VOID); -VOID HalExcSvcCall(VOID); -VOID HalHwiInit(); - - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器入栈时发生错误 - */ -#define OS_EXC_BF_STKERR 1 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器出栈时发生错误 - */ -#define OS_EXC_BF_UNSTKERR 2 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器不精确的数据访问违例 - */ -#define OS_EXC_BF_IMPRECISERR 3 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器精确的数据访问违例 - */ -#define OS_EXC_BF_PRECISERR 4 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器取指时的访问违例 - */ -#define OS_EXC_BF_IBUSERR 5 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器入栈时发生错误 - */ -#define OS_EXC_MF_MSTKERR 6 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器出栈时发生错误 - */ -#define OS_EXC_MF_MUNSTKERR 7 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器数据访问违例 - */ -#define OS_EXC_MF_DACCVIOL 8 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器取指访问违例 - */ -#define OS_EXC_MF_IACCVIOL 9 - - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,表示除法运算时除数为零 - */ -#define OS_EXC_UF_DIVBYZERO 10 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,未对齐访问导致的错误 - */ -#define OS_EXC_UF_UNALIGNED 11 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,试图执行协处理器相关指令 - */ -#define OS_EXC_UF_NOCP 12 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,在异常返回时试图非法地加载EXC_RETURN到PC - */ -#define OS_EXC_UF_INVPC 13 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,试图切入ARM状态 - */ -#define OS_EXC_UF_INVSTATE 14 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,执行的指令其编码是未定义的——解码不能 - */ -#define OS_EXC_UF_UNDEFINSTR 15 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:NMI中断 - */ - -#define OS_EXC_CAUSE_NMI 16 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:硬fault - */ -#define OS_EXC_CAUSE_HARDFAULT 17 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:任务处理函数退出 - */ -#define OS_EXC_CAUSE_TASK_EXIT 18 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:致命错误 - */ -#define OS_EXC_CAUSE_FATAL_ERR 19 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:调试事件导致的硬fault - */ -#define OS_EXC_CAUSE_DEBUGEVT 20 - -/** - *@ingroup los_exc - *Cortex-M3异常具体类型:取向量时发生的硬fault - */ -#define OS_EXC_CAUSE_VECTBL 21 - -/** - *@ingroup los_exc - * 异常信息结构体 - * - * 描述:M4平台下的异常触发时保存的异常信息 - * - */ -typedef struct tagExcInfo { - /**< 异常发生阶段: 0表示异常发生在初始化中,1表示异常发生在任务中,2表示异常发生在中断中 */ - UINT16 phase; - /**< 异常类型,出异常时对照上面列出的1-19号 */ - UINT16 type; - /**< 若为精确地址访问错误表示异常发生时的错误访问地址 */ - UINT32 faultAddr; - /**< 在中断中发生异常,表示中断号。在任务中发生异常,表示任务id,如果发生在初始化中,则为0xffffffff */ - UINT32 thrdPid; - /**< 异常嵌套个数,目前仅支持第一次进入异常时执行注册的钩子函数 */ - UINT16 nestCnt; - /**< 保留 */ - UINT16 reserved; - /**< 自动压栈浮点寄存器的异常发生时刻的硬件上下文 */ - EXC_CONTEXT_S * context; -} ExcInfo; - -extern UINT32 g_curNestCount; -extern UINT32 g_intCount; - -static VOID OsExcSave2DDR(VOID); -VOID OsExcInfoDisplay(ExcInfo *exc); - -extern UINT8 g_uwExcTbl[32]; - - - -typedef struct tagExcInfoCallBackArray { - ExcInfoType uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -} ExcInfoArray; - - - -#define MAX_SCENE_INFO_SIZE (8 + sizeof(ExcInfo) - 4 + sizeof(EXC_CONTEXT_S)) -#define MAX_TSK_INFO_SIZE (8 + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) -#define MAX_INT_INFO_SIZE (8 + 0x164) - -#if (LOSCFG_BASE_IPC_QUEUE == 1) -#define MAX_QUEUE_INFO_SIZE (8 + sizeof(QUEUE_INFO_S) * LOSCFG_BASE_IPC_QUEUE_LIMIT) -#else -#define MAX_QUEUE_INFO_SIZE (0) -#endif - -#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1) -#define MAX_SWITCH_INFO_SIZE (8 + (sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN) * OS_TASK_SWITCH_INFO_COUNT) -#else -#define MAX_SWITCH_INFO_SIZE (0) -#endif - -#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) -#define MAX_MEM_INFO_SIZE (8 + sizeof(MEM_INFO_S) * OS_SYS_MEM_NUM) -#else -#define MAX_MEM_INFO_SIZE (0) -#endif - -#define MAX_EXC_MEM_SIZE ( 4 + MAX_SCENE_INFO_SIZE + MAX_TSK_INFO_SIZE + MAX_QUEUE_INFO_SIZE + MAX_INT_INFO_SIZE + MAX_SWITCH_INFO_SIZE + MAX_MEM_INFO_SIZE + 4) - - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#endif /* _LOS_EXC_H */ - +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 _LOS_EXC_H +#define _LOS_EXC_H + +#include "los_config.h" +#include "los_compiler.h" +#include "los_interrupt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +/* * + * @ingroup los_hwi + * Maximum number of used hardware interrupts. + */ +#ifndef OS_HWI_MAX_NUM +#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT +#endif + +/* * + * @ingroup los_hwi + * Highest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_HIGHEST +#define OS_HWI_PRIO_HIGHEST 0 +#endif + +/* * + * @ingroup los_hwi + * Lowest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_LOWEST +#define OS_HWI_PRIO_LOWEST 7 +#endif + + +/* * + * @ingroup los_hwi + * Define the type of a hardware interrupt vector table function. + */ +typedef VOID (**HWI_VECTOR_FUNC)(void); + +/* * + * @ingroup los_hwi + * Count of interrupts. + */ +extern UINT32 g_intCount; + +/* * + * @ingroup los_hwi + * Count of M-Core system interrupt vector. + */ +#define OS_SYS_VECTOR_CNT 16 + +/* * + * @ingroup los_hwi + * Count of M-Core interrupt vector. + */ +#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) + +/* * + * @ingroup los_hwi + * AIRCR register priority group parameter . + */ +#define OS_NVIC_AIRCR_PRIGROUP 7 + +/* * + * @ingroup los_hwi + * Boot interrupt vector table. + */ +extern UINT32 _BootVectors[]; + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable for a Cortex-A7 platform is [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. + */ +#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Null hardware interrupt handling function. + * + * Value: 0x02000901 + * + * Solution: Pass in a valid non-null hardware interrupt handling function. + */ +#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation. + * + * Value: 0x02000902 + * + * Solution: Increase the configured maximum number of supported hardware interrupts. + */ +#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient memory for hardware interrupt initialization. + * + * Value: 0x02000903 + * + * Solution: Expand the configured memory. + */ +#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created. + * + * Value: 0x02000904 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt priority. + * + * Value: 0x02000905 + * + * Solution: Ensure that the interrupt priority is valid. The value range of the interrupt priority applicable for a Cortex-A7 platform is [0,15]. + */ +#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Incorrect interrupt creation mode. + * + * Value: 0x02000906 + * + * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of which the value can be 0 or 1. + */ +#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created as a fast interrupt. + * + * Value: 0x02000907 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) + +/* * + * @ingroup los_hwi + * SysTick control and status register. + */ +#define OS_SYSTICK_CONTROL_REG 0xE000E010 + +/* * + * @ingroup los_hw + * SysTick current value register. + */ +#define OS_SYSTICK_CURRENT_REG 0xE000E018 + +/* * + * @ingroup los_hwi + * Interrupt Priority-Level Registers. + */ +#define OS_NVIC_PRI_BASE 0xE000E400 + +/* * + * @ingroup los_hwi + * Interrupt enable register for 0-31. + */ +#define OS_NVIC_SETENA_BASE 0xE000E100 + +/* * + * @ingroup los_hwi + * interrupt pending register. + */ +#define OS_NVIC_SETPEND_BASE 0xE000E200 + +/* * + * @ingroup los_hwi + * Interrupt active register. + */ +#define OS_NVIC_INT_ACT_BASE 0xE000E300 + +/* * + * @ingroup los_hwi + * Interrupt disable register for 0-31. + */ +#define OS_NVIC_CLRENA_BASE 0xE000E180 + +/* * + * @ingroup los_hwi + * Interrupt control and status register. + */ +#define OS_NVIC_INT_CTRL 0xE000ED04 + +/* * + * @ingroup los_hwi + * Vector table offset register. + */ +#define OS_NVIC_VTOR 0xE000ED08 + +/* * + * @ingroup los_hwi + * Application interrupt and reset control register + */ +#define OS_NVIC_AIRCR 0xE000ED0C + +/* * + * @ingroup los_hwi + * System exception priority register. + */ +#define OS_NVIC_EXCPRI_BASE 0xE000ED18 + +/* * + * @ingroup los_hwi + * Interrupt No. 1 :reset. + */ +#define OS_EXC_RESET 1 + +/* * + * @ingroup los_hwi + * Interrupt No. 2 :Non-Maskable Interrupt. + */ +#define OS_EXC_NMI 2 + +/* * + * @ingroup los_hwi + * Interrupt No. 3 :(hard)fault. + */ +#define OS_EXC_HARD_FAULT 3 + +/* * + * @ingroup los_hwi + * Interrupt No. 4 :MemManage fault. + */ +#define OS_EXC_MPU_FAULT 4 + +/* * + * @ingroup los_hwi + * Interrupt No. 5 :Bus fault. + */ +#define OS_EXC_BUS_FAULT 5 + +/* * + * @ingroup los_hwi + * Interrupt No. 6 :Usage fault. + */ +#define OS_EXC_USAGE_FAULT 6 + +/* * + * @ingroup los_hwi + * Interrupt No. 11 :SVCall. + */ +#define OS_EXC_SVC_CALL 11 + +/* * + * @ingroup los_hwi + * Interrupt No. 12 :Debug monitor. + */ +#define OS_EXC_DBG_MONITOR 12 + +/* * + * @ingroup los_hwi + * Interrupt No. 14 :PendSV. + */ +#define OS_EXC_PEND_SV 14 + +/* * + * @ingroup los_hwi + * Interrupt No. 15 :SysTick. + */ +#define OS_EXC_SYS_TICK 15 + +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT]; + +#if (OS_HWI_WITH_ARG == 1) +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVectonr(num, vector, arg) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pParm = (VOID *)arg; \ + } while(0) +#else +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVector(num, vector) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT] = vector; \ + } while(0) +#endif + +/* * + * @ingroup los_hwi + * @brief: Hardware interrupt entry function. + * + * @par Description: + * This API is used as all hardware interrupt handling function entry. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID HalInterrupt(VOID); + +/* * + * @ingroup los_hwi + * @brief: Get a interrupt number. + * + * @par Description: + * This API is used to get the current interrupt number. + * + * @attention: + * + * + * @param: None. + * + * @retval: Interrupt Indexes number. + * @par Dependency: + * + * @see None. + */ +extern UINT32 HalIntNumGet(VOID); + +/* * + * @ingroup los_hwi + * @brief: Default vector handling function. + * + * @par Description: + * This API is used to configure interrupt for null function. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID HalHwiDefaultHandler(VOID); + +/* * + * @ingroup los_hwi + * @brief: Reset the vector table. + * + * @par Description: + * This API is used to reset the vector table. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID Reset_Handler(VOID); + +/* * + * @ingroup los_hwi + * @brief: Pended System Call. + * + * @par Description: + * PendSV can be pended and is useful for an OS to pend an exception + * so that an action can be performed after other important tasks are completed. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID HalPendSV(VOID); + + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +#define OS_EXC_MAX_BUF_LEN 25 +#define OS_EXC_MAX_NEST_DEPTH 1 + +#define OS_NVIC_SHCSR 0xE000ED24 +#define OS_NVIC_CCR 0xE000ED14 + +#define OS_NVIC_INT_ENABLE_SIZE 0x20 +#define OS_NVIC_INT_PRI_SIZE 0xF0 +#define OS_NVIC_EXCPRI_SIZE 0xC + +#define OS_NVIC_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE +#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE + +#define OS_EXC_FLAG_NO_FLOAT 0x10000000 +#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 +#define OS_EXC_FLAG_IN_HWI 0x02 + +#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB + +#define OS_EXC_EVENT 0x00000001 + +/** + *@ingroup los_exc + * the struct of register files + * + * description: the register files that saved when exception triggered + * + * notes:the following register with prefix 'uw' correspond to the registers in the cpu data sheet. + */ +typedef struct tagExcContext { + //handler save +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + UINT32 S16; + UINT32 S17; + UINT32 S18; + UINT32 S19; + UINT32 S20; + UINT32 S21; + UINT32 S22; + UINT32 S23; + UINT32 S24; + UINT32 S25; + UINT32 S26; + UINT32 S27; + UINT32 S28; + UINT32 S29; + UINT32 S30; + UINT32 S31; +#endif + UINT32 uwR4; + UINT32 uwR5; + UINT32 uwR6; + UINT32 uwR7; + UINT32 uwR8; + UINT32 uwR9; + UINT32 uwR10; + UINT32 uwR11; + UINT32 uwPriMask; + //auto save + UINT32 uwSP; + UINT32 uwR0; + UINT32 uwR1; + UINT32 uwR2; + UINT32 uwR3; + UINT32 uwR12; + UINT32 uwLR; + UINT32 uwPC; + UINT32 uwxPSR; +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED) && (__FPU_USED== 1U))) + UINT32 S0; + UINT32 S1; + UINT32 S2; + UINT32 S3; + UINT32 S4; + UINT32 S5; + UINT32 S6; + UINT32 S7; + UINT32 S8; + UINT32 S9; + UINT32 S10; + UINT32 S11; + UINT32 S12; + UINT32 S13; + UINT32 S14; + UINT32 S15; + UINT32 FPSCR; + UINT32 NO_NAME; +#endif +}EXC_CONTEXT_S; + +typedef VOID (*EXC_PROC_FUNC)(UINT32, EXC_CONTEXT_S *); +VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr); + +/** + * @ingroup los_hwi + * @brief: Exception initialization. + * + * @par Description: + * This API is used to configure the exception function vector table. + * + * @attention: + * + * + *@param uwArraySize [IN] Memory size of exception. + * + * @retval: None + * @par Dependency: + * + * @see None. + */ +VOID OsExcInit(VOID); + +VOID HalExcNMI(VOID); +VOID HalExcHardFault(VOID); +VOID HalExcMemFault(VOID); +VOID HalExcBusFault(VOID); +VOID HalExcUsageFault(VOID); +VOID HalExcSvcCall(VOID); +VOID HalHwiInit(); + + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器入栈时发生错误 + */ +#define OS_EXC_BF_STKERR 1 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器出栈时发生错误 + */ +#define OS_EXC_BF_UNSTKERR 2 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器不精确的数据访问违例 + */ +#define OS_EXC_BF_IMPRECISERR 3 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器精确的数据访问违例 + */ +#define OS_EXC_BF_PRECISERR 4 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器取指时的访问违例 + */ +#define OS_EXC_BF_IBUSERR 5 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器入栈时发生错误 + */ +#define OS_EXC_MF_MSTKERR 6 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器出栈时发生错误 + */ +#define OS_EXC_MF_MUNSTKERR 7 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器数据访问违例 + */ +#define OS_EXC_MF_DACCVIOL 8 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器取指访问违例 + */ +#define OS_EXC_MF_IACCVIOL 9 + + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,表示除法运算时除数为零 + */ +#define OS_EXC_UF_DIVBYZERO 10 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,未对齐访问导致的错误 + */ +#define OS_EXC_UF_UNALIGNED 11 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图执行协处理器相关指令 + */ +#define OS_EXC_UF_NOCP 12 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,在异常返回时试图非法地加载EXC_RETURN到PC + */ +#define OS_EXC_UF_INVPC 13 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图切入ARM状态 + */ +#define OS_EXC_UF_INVSTATE 14 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,执行的指令其编码是未定义的——解码不能 + */ +#define OS_EXC_UF_UNDEFINSTR 15 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:NMI中断 + */ + +#define OS_EXC_CAUSE_NMI 16 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:硬fault + */ +#define OS_EXC_CAUSE_HARDFAULT 17 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:任务处理函数退出 + */ +#define OS_EXC_CAUSE_TASK_EXIT 18 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:致命错误 + */ +#define OS_EXC_CAUSE_FATAL_ERR 19 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:调试事件导致的硬fault + */ +#define OS_EXC_CAUSE_DEBUGEVT 20 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:取向量时发生的硬fault + */ +#define OS_EXC_CAUSE_VECTBL 21 + +/** + *@ingroup los_exc + * 异常信息结构体 + * + * 描述:M4平台下的异常触发时保存的异常信息 + * + */ +typedef struct tagExcInfo { + /**< 异常发生阶段: 0表示异常发生在初始化中,1表示异常发生在任务中,2表示异常发生在中断中 */ + UINT16 phase; + /**< 异常类型,出异常时对照上面列出的1-19号 */ + UINT16 type; + /**< 若为精确地址访问错误表示异常发生时的错误访问地址 */ + UINT32 faultAddr; + /**< 在中断中发生异常,表示中断号。在任务中发生异常,表示任务id,如果发生在初始化中,则为0xffffffff */ + UINT32 thrdPid; + /**< 异常嵌套个数,目前仅支持第一次进入异常时执行注册的钩子函数 */ + UINT16 nestCnt; + /**< 保留 */ + UINT16 reserved; + /**< 自动压栈浮点寄存器的异常发生时刻的硬件上下文 */ + EXC_CONTEXT_S * context; +} ExcInfo; + +extern UINT32 g_curNestCount; +extern UINT32 g_intCount; + +static VOID OsExcSave2DDR(VOID); +VOID OsExcInfoDisplay(ExcInfo *exc); + +extern UINT8 g_uwExcTbl[32]; + + + +typedef struct tagExcInfoCallBackArray { + ExcInfoType uwType; + UINT32 uwValid; + EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; + VOID* pArg; +} ExcInfoArray; + + + +#define MAX_SCENE_INFO_SIZE (8 + sizeof(ExcInfo) - 4 + sizeof(EXC_CONTEXT_S)) +#define MAX_TSK_INFO_SIZE (8 + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) +#define MAX_INT_INFO_SIZE (8 + 0x164) + +#if (LOSCFG_BASE_IPC_QUEUE == 1) +#define MAX_QUEUE_INFO_SIZE (8 + sizeof(QUEUE_INFO_S) * LOSCFG_BASE_IPC_QUEUE_LIMIT) +#else +#define MAX_QUEUE_INFO_SIZE (0) +#endif + +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1) +#define MAX_SWITCH_INFO_SIZE (8 + (sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN) * OS_TASK_SWITCH_INFO_COUNT) +#else +#define MAX_SWITCH_INFO_SIZE (0) +#endif + +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) +#define MAX_MEM_INFO_SIZE (8 + sizeof(MEM_INFO_S) * OS_SYS_MEM_NUM) +#else +#define MAX_MEM_INFO_SIZE (0) +#endif + +#define MAX_EXC_MEM_SIZE ( 4 + MAX_SCENE_INFO_SIZE + MAX_TSK_INFO_SIZE + MAX_QUEUE_INFO_SIZE + MAX_INT_INFO_SIZE + MAX_SWITCH_INFO_SIZE + MAX_MEM_INFO_SIZE + 4) + + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_EXC_H */ + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_timer.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_timer.h similarity index 100% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_arch_timer.h rename to kernel/arch/arm/cortex-m4/gcc/los_arch_timer.h diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_context.c b/kernel/arch/arm/cortex-m4/gcc/los_context.c similarity index 97% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_context.c rename to kernel/arch/arm/cortex-m4/gcc/los_context.c index 30fb7885..f15654fa 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_context.c +++ b/kernel/arch/arm/cortex-m4/gcc/los_context.c @@ -1,175 +1,174 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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 "los_config.h" -#include "los_task.h" -#include "securec.h" -#include "los_interrupt.h" -#include "los_arch_context.h" -#include "los_arch_interrupt.h" -#include "los_arch_timer.h" -#include "los_context.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* **************************************************************************** - Function : HalArchInit - Description : arch init function - Input : None - Output : None - Return : None - **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT VOID HalArchInit() -{ - HalHwiInit(); -} - -/* **************************************************************************** - Function : HalSysExit - Description : Task exit function - Input : None - Output : None - Return : None - **************************************************************************** */ -LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) -{ - LOS_IntLock(); - for(;;); -} - -/* **************************************************************************** - Function : HalTskStackInit - Description : Task stack initialization function - Input : taskID --- TaskID - stackSize --- Total size of the stack - topStack --- Top of task's stack - Output : None - Return : Context pointer - **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) -{ - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); - -#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ - (defined(__FPU_USED) && (__FPU_USED == 1U))) - context->S16 = 0xAA000010; - context->S17 = 0xAA000011; - context->S18 = 0xAA000012; - context->S19 = 0xAA000013; - context->S20 = 0xAA000014; - context->S21 = 0xAA000015; - context->S22 = 0xAA000016; - context->S23 = 0xAA000017; - context->S24 = 0xAA000018; - context->S25 = 0xAA000019; - context->S26 = 0xAA00001A; - context->S27 = 0xAA00001B; - context->S28 = 0xAA00001C; - context->S29 = 0xAA00001D; - context->S30 = 0xAA00001E; - context->S31 = 0xAA00001F; - context->S0 = 0xAA000000; - context->S1 = 0xAA000001; - context->S2 = 0xAA000002; - context->S3 = 0xAA000003; - context->S4 = 0xAA000004; - context->S5 = 0xAA000005; - context->S6 = 0xAA000006; - context->S7 = 0xAA000007; - context->S8 = 0xAA000008; - context->S9 = 0xAA000009; - context->S10 = 0xAA00000A; - context->S11 = 0xAA00000B; - context->S12 = 0xAA00000C; - context->S13 = 0xAA00000D; - context->S14 = 0xAA00000E; - context->S15 = 0xAA00000F; - context->FPSCR = 0x00000000; - context->NO_NAME = 0xAA000011; -#endif - - context->uwR4 = 0x04040404L; - context->uwR5 = 0x05050505L; - context->uwR6 = 0x06060606L; - context->uwR7 = 0x07070707L; - context->uwR8 = 0x08080808L; - context->uwR9 = 0x09090909L; - context->uwR10 = 0x10101010L; - context->uwR11 = 0x11111111L; - context->uwPriMask = 0; - context->uwR0 = taskID; - context->uwR1 = 0x01010101L; - context->uwR2 = 0x02020202L; - context->uwR3 = 0x03030303L; - context->uwR12 = 0x12121212L; - context->uwLR = (UINT32)(UINTPTR)HalSysExit; - context->uwPC = (UINT32)(UINTPTR)OsTaskEntry; - context->uwxPSR = 0x01000000L; - - return (VOID *)context; -} - -void HalBackTrace() -{ - -} - -LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) -{ - UINT32 ret; - ret = HalTickStart(handler); - if (ret != LOS_OK) { - return ret; - } - HalStartToRun(); - return LOS_OK; /* never return */ -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "los_config.h" +#include "los_task.h" +#include "securec.h" +#include "los_interrupt.h" +#include "los_arch_context.h" +#include "los_arch_interrupt.h" +#include "los_arch_timer.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* **************************************************************************** + Function : HalArchInit + Description : arch init function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalArchInit() +{ + HalHwiInit(); +} + +/* **************************************************************************** + Function : HalSysExit + Description : Task exit function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) +{ + LOS_IntLock(); + for(;;); +} + +/* **************************************************************************** + Function : HalTskStackInit + Description : Task stack initialization function + Input : taskID --- TaskID + stackSize --- Total size of the stack + topStack --- Top of task's stack + Output : None + Return : Context pointer + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) +{ + TaskContext *context = NULL; + errno_t result; + + /* initialize the task stack, write magic num to stack top */ + result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); + if (result != EOK) { + printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); + } + *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; + + context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + context->S16 = 0xAA000010; + context->S17 = 0xAA000011; + context->S18 = 0xAA000012; + context->S19 = 0xAA000013; + context->S20 = 0xAA000014; + context->S21 = 0xAA000015; + context->S22 = 0xAA000016; + context->S23 = 0xAA000017; + context->S24 = 0xAA000018; + context->S25 = 0xAA000019; + context->S26 = 0xAA00001A; + context->S27 = 0xAA00001B; + context->S28 = 0xAA00001C; + context->S29 = 0xAA00001D; + context->S30 = 0xAA00001E; + context->S31 = 0xAA00001F; + context->S0 = 0xAA000000; + context->S1 = 0xAA000001; + context->S2 = 0xAA000002; + context->S3 = 0xAA000003; + context->S4 = 0xAA000004; + context->S5 = 0xAA000005; + context->S6 = 0xAA000006; + context->S7 = 0xAA000007; + context->S8 = 0xAA000008; + context->S9 = 0xAA000009; + context->S10 = 0xAA00000A; + context->S11 = 0xAA00000B; + context->S12 = 0xAA00000C; + context->S13 = 0xAA00000D; + context->S14 = 0xAA00000E; + context->S15 = 0xAA00000F; + context->FPSCR = 0x00000000; + context->NO_NAME = 0xAA000011; +#endif + + context->uwR4 = 0x04040404L; + context->uwR5 = 0x05050505L; + context->uwR6 = 0x06060606L; + context->uwR7 = 0x07070707L; + context->uwR8 = 0x08080808L; + context->uwR9 = 0x09090909L; + context->uwR10 = 0x10101010L; + context->uwR11 = 0x11111111L; + context->uwPriMask = 0; + context->uwR0 = taskID; + context->uwR1 = 0x01010101L; + context->uwR2 = 0x02020202L; + context->uwR3 = 0x03030303L; + context->uwR12 = 0x12121212L; + context->uwLR = (UINT32)(UINTPTR)HalSysExit; + context->uwPC = (UINT32)(UINTPTR)OsTaskEntry; + context->uwxPSR = 0x01000000L; + + return (VOID *)context; +} + +void HalBackTrace() +{ + +} + +LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) +{ + UINT32 ret; + ret = HalTickStart(handler); + if (ret != LOS_OK) { + return ret; + } + HalStartToRun(); + return LOS_OK; /* never return */ +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_dispatch.S b/kernel/arch/arm/cortex-m4/gcc/los_dispatch.S similarity index 59% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_dispatch.S rename to kernel/arch/arm/cortex-m4/gcc/los_dispatch.S index 313a9fc7..78523d94 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_dispatch.S +++ b/kernel/arch/arm/cortex-m4/gcc/los_dispatch.S @@ -1,180 +1,149 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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. - */ - -.syntax unified -.arch armv7e-m -.thumb - -.equ OS_NVIC_INT_CTRL, 0xE000ED04 -.equ OS_NVIC_SYSPRI2, 0xE000ED20 -.equ OS_NVIC_PENDSV_PRI, 0xF0F00000 -.equ OS_NVIC_PENDSVSET, 0x10000000 -.equ OS_TASK_STATUS_RUNNING, 0x0010 - - .section .text - .thumb - - .type HalStartToRun, %function - .global HalStartToRun -HalStartToRun: - .fnstart - .cantunwind - - ldr r4, =OS_NVIC_SYSPRI2 - ldr r5, =OS_NVIC_PENDSV_PRI - str r5, [r4] - - ldr r0, =g_taskScheduled - mov r1, #1 - str r1, [r0] - - mov r0, #2 - msr CONTROL, r0 - - - ldr r0, =g_losTask - ldr r2, [r0, #4] - ldr r0, =g_losTask - str r2, [r0] - - ldr r3, =g_losTask - ldr r0, [r3] - ldrh r7, [r0 , #4] - mov r8, #OS_TASK_STATUS_RUNNING - orr r7, r7, r8 - strh r7, [r0 , #4] - - ldr r12, [r0] - add r12, r12, #36 - - ldmfd r12!, {r0-r7} - msr psp, r12 - mov lr, r5 - - cpsie I - bx r6 - - .fnend - - - .type HalIntLock, %function - .global HalIntLock -HalIntLock: - .fnstart - .cantunwind - - MRS R0, PRIMASK - CPSID I - BX LR - .fnend - - .type HalIntUnLock, %function - .global HalIntUnLock -HalIntUnLock: - .fnstart - .cantunwind - - MRS R0, PRIMASK - CPSIE I - BX LR - .fnend - - .type HalIntRestore, %function - .global HalIntRestore -HalIntRestore: - .fnstart - .cantunwind - - MSR PRIMASK, R0 - BX LR - .fnend - - .type HalTaskSchedule, %function - .global HalTaskSchedule -HalTaskSchedule: - .fnstart - .cantunwind - - ldr r0, =OS_NVIC_INT_CTRL - ldr r1, =OS_NVIC_PENDSVSET - str r1, [r0] - bx lr - .fnend - - - - - .type HalPendSV, %function - .global HalPendSV -HalPendSV: - .fnstart - .cantunwind - - mrs r12, PRIMASK - cpsid I - -HalTaskSwitch: - - mrs r0, psp - - stmfd r0!, {r4-r12} - - ldr r5, =g_losTask - ldr r6, [r5] - str r0, [r6] - - - ldrh r7, [r6 , #4] - mov r8,#OS_TASK_STATUS_RUNNING - bic r7, r7, r8 - strh r7, [r6 , #4] - - - ldr r0, =g_losTask - ldr r0, [r0, #4] - str r0, [r5] - - - ldrh r7, [r0 , #4] - mov r8, #OS_TASK_STATUS_RUNNING - orr r7, r7, r8 - strh r7, [r0 , #4] - - ldr r1, [r0] - - ldmfd r1!, {r4-r12} - msr psp, r1 - - msr PRIMASK, r12 - - - bx lr - .fnend +.syntax unified +.arch armv7e-m +.thumb + +.equ OS_NVIC_INT_CTRL, 0xE000ED04 +.equ OS_NVIC_SYSPRI2, 0xE000ED20 +.equ OS_NVIC_PENDSV_PRI, 0xF0F00000 +.equ OS_NVIC_PENDSVSET, 0x10000000 +.equ OS_TASK_STATUS_RUNNING, 0x0010 + + .section .text + .thumb + + .type HalStartToRun, %function + .global HalStartToRun +HalStartToRun: + .fnstart + .cantunwind + + ldr r4, =OS_NVIC_SYSPRI2 + ldr r5, =OS_NVIC_PENDSV_PRI + str r5, [r4] + + ldr r0, =g_taskScheduled + mov r1, #1 + str r1, [r0] + + mov r0, #2 + msr CONTROL, r0 + + + ldr r0, =g_losTask + ldr r2, [r0, #4] + ldr r0, =g_losTask + str r2, [r0] + + ldr r3, =g_losTask + ldr r0, [r3] + ldrh r7, [r0 , #4] + mov r8, #OS_TASK_STATUS_RUNNING + orr r7, r7, r8 + strh r7, [r0 , #4] + + ldr r12, [r0] + add r12, r12, #36 + + ldmfd r12!, {r0-r7} + msr psp, r12 + mov lr, r5 + + cpsie I + bx r6 + + .fnend + + + .type HalIntLock, %function + .global HalIntLock +HalIntLock: + .fnstart + .cantunwind + + MRS R0, PRIMASK + CPSID I + BX LR + .fnend + + .type HalIntUnLock, %function + .global HalIntUnLock +HalIntUnLock: + .fnstart + .cantunwind + + MRS R0, PRIMASK + CPSIE I + BX LR + .fnend + + .type HalIntRestore, %function + .global HalIntRestore +HalIntRestore: + .fnstart + .cantunwind + + MSR PRIMASK, R0 + BX LR + .fnend + + .type HalTaskSchedule, %function + .global HalTaskSchedule +HalTaskSchedule: + .fnstart + .cantunwind + + ldr r0, =OS_NVIC_INT_CTRL + ldr r1, =OS_NVIC_PENDSVSET + str r1, [r0] + bx lr + .fnend + + + + + .type HalPendSV, %function + .global HalPendSV +HalPendSV: + .fnstart + .cantunwind + + mrs r12, PRIMASK + cpsid I + +HalTaskSwitch: + + mrs r0, psp + + stmfd r0!, {r4-r12} + + ldr r5, =g_losTask + ldr r6, [r5] + str r0, [r6] + + + ldrh r7, [r6 , #4] + mov r8,#OS_TASK_STATUS_RUNNING + bic r7, r7, r8 + strh r7, [r6 , #4] + + + ldr r0, =g_losTask + ldr r0, [r0, #4] + str r0, [r5] + + + ldrh r7, [r0 , #4] + mov r8, #OS_TASK_STATUS_RUNNING + orr r7, r7, r8 + strh r7, [r0 , #4] + + ldr r1, [r0] + + ldmfd r1!, {r4-r12} + msr psp, r1 + + msr PRIMASK, r12 + + + bx lr + .fnend diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S b/kernel/arch/arm/cortex-m4/gcc/los_exc.S similarity index 95% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S rename to kernel/arch/arm/cortex-m4/gcc/los_exc.S index 37d3ec28..2b6df84e 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_exc.S +++ b/kernel/arch/arm/cortex-m4/gcc/los_exc.S @@ -1,378 +1,381 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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. - */ - - .syntax unified - .arch armv7e-m - .thumb -.section .text - - - .global HalExcNMI - .global HalExcHardFault - .global HalExcMemFault - .global HalExcBusFault - .global HalExcUsageFault - .global HalExcSvcCall - - .extern HalExcHandleEntry - .extern g_uwExcTbl - .extern g_taskScheduled - -.equ OS_FLG_BGD_ACTIVE, 0x0002 - -.equ OS_EXC_CAUSE_NMI, 16 -.equ OS_EXC_CAUSE_HARDFAULT, 17 - -.equ HF_DEBUGEVT, 20 -.equ HF_VECTBL, 21 - -.equ FLAG_ADDR_VALID, 0x10000 -.equ FLAG_HWI_ACTIVE, 0x20000 -.equ FLAG_NO_FLOAT, 0x10000000 - -.equ OS_NVIC_FSR , 0xE000ED28 //include BusFault/MemFault/UsageFault State Regeister -.equ OS_NVIC_HFSR , 0xE000ED2C //HardFault State Regeister -.equ OS_NVIC_BFAR , 0xE000ED38 -.equ OS_NVIC_MMAR , 0xE000ED34 -.equ OS_NVIC_ACT_BASE , 0xE000E300 -.equ OS_NVIC_SHCSRS , 0xE000ED24 -.equ OS_NVIC_SHCSR_MASK , 0xC00 - - .type HalExcNMI, %function - .global HalExcNMI -HalExcNMI: - .fnstart - .cantunwind - MOV R0, #OS_EXC_CAUSE_NMI - MOV R1, #0 - B osExcDispatch - .fnend - - .type HalExcHardFault, %function - .global HalExcHardFault -HalExcHardFault: - .fnstart - .cantunwind - MOV R0, #OS_EXC_CAUSE_HARDFAULT - LDR R2, =OS_NVIC_HFSR - LDR R2, [R2] - - MOV R1, #HF_DEBUGEVT - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x80000000 - BNE osExcDispatch // DEBUGEVT - - AND R0, R0 , #0x000000FF - MOV R1, #HF_VECTBL - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x00000002 - BNE osExcDispatch // VECTBL - - //if not DEBUGEVT and VECTBL then is FORCED - AND R0, R0, #0x000000FF - - LDR R2, =OS_NVIC_FSR - LDR R2, [R2] - - TST R2, #0x8000 // BFARVALID - BNE _HFBusFault // BusFault - - TST R2, #0x80 // MMARVALID - BNE _HFMemFault // MemFault - - MOV R12,#0 - B osHFExcCommonBMU - .fnend - - .type _HFBusFault, %function - -_HFBusFault: - .fnstart - .cantunwind - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - B osHFExcCommonBMU - .fnend - - .type _HFMemFault, %function - -_HFMemFault: - .fnstart - .cantunwind - LDR R1, =OS_NVIC_MMAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - .fnend - - .type osHFExcCommonBMU, %function - .global osHFExcCommonBMU -osHFExcCommonBMU: - .fnstart - .cantunwind - CLZ R2, R2 - LDR R3, =g_uwExcTbl - ADD R3, R3, R2 - LDRB R2, [R3] - ORR R0, R0, R2, LSL #0x8 - ORR R0, R0 ,R12 - B osExcDispatch - .fnend - - .type HalExcSvcCall, %function - .global HalExcSvcCall -HalExcSvcCall: - .fnstart - .cantunwind - TST LR, #0x4 - ITE EQ - MRSEQ R0, MSP - MRSNE R0, PSP - LDR R1, [R0,#24] - LDRB R0, [R1,#-2] - MOV R1, #0 - B osExcDispatch - .fnend - - .type HalExcBusFault, %function - .global HalExcBusFault -HalExcBusFault: - .fnstart - .cantunwind - LDR R0, =OS_NVIC_FSR - LDR R0, [R0] - - TST R0, #0x8000 // BFARVALID - BEQ _ExcBusNoADDR - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - AND R0, R0, #0x1F00 - - B osExcCommonBMU - .fnend - - .type _ExcBusNoADDR, %function - .global _ExcBusNoADDR -_ExcBusNoADDR: - .fnstart - .cantunwind - MOV R12,#0 - B osExcCommonBMU - .fnend - - .type HalExcMemFault, %function - .global HalExcMemFault -HalExcMemFault: - .fnstart - .cantunwind - LDR R0, =OS_NVIC_FSR - LDR R0, [R0] - - TST R0, #0x80 // MMARVALID - BEQ _ExcMemNoADDR - LDR R1, =OS_NVIC_MMAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - AND R0, R0, #0x1B - - B osExcCommonBMU - .fnend - - .type _ExcMemNoADDR, %function - .global _ExcMemNoADDR -_ExcMemNoADDR: - .fnstart - .cantunwind - MOV R12,#0 - B osExcCommonBMU - .fnend - - .type HalExcUsageFault, %function - .global HalExcUsageFault -HalExcUsageFault: - .fnstart - .cantunwind - LDR R0, =OS_NVIC_FSR - LDR R0, [R0] - - MOV R1, #0x030F - LSL R1, R1, #16 - AND R0, R0, R1 - MOV R12, #0 - - .fnend - - .type osExcCommonBMU, %function - .global osExcCommonBMU -osExcCommonBMU: - .fnstart - .cantunwind - CLZ R0, R0 - LDR R3, =g_uwExcTbl - ADD R3, R3, R0 - LDRB R0, [R3] - ORR R0, R0, R12 - .fnend -// R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR - - .type osExcDispatch, %function - .global osExcDispatch -osExcDispatch: - .fnstart - .cantunwind - LDR R2, =OS_NVIC_ACT_BASE - MOV R12, #8 // R12 is hwi check loop counter - .fnend - - .type _hwiActiveCheck, %function - .global _hwiActiveCheck -_hwiActiveCheck: - .fnstart - .cantunwind - LDR R3, [R2] // R3 store active hwi register when exc - CMP R3, #0 - BEQ _hwiActiveCheckNext - - // exc occured in IRQ - ORR R0, R0, #FLAG_HWI_ACTIVE - RBIT R2, R3 - CLZ R2, R2 - AND R12, R12, #1 - ADD R2, R2, R12, LSL #5 // calculate R2 (hwi number) as uwPid - .fnend - - .type _ExcInMSP, %function - .global _ExcInMSP -_ExcInMSP: - .fnstart - .cantunwind - CMP LR, #0XFFFFFFED - BNE _NoFloatInMsp - ADD R3, R13, #104 - PUSH {R3} - MRS R12, PRIMASK // store message-->exc: disable int? - PUSH {R4-R12} // store message-->exc: {R4-R12} - B _handleEntry - .fnend - - .type _NoFloatInMsp, %function - .global _NoFloatInMsp -_NoFloatInMsp: - .fnstart - .cantunwind - ADD R3, R13, #32 - PUSH {R3} // save IRQ SP // store message-->exc: MSP(R13) - - MRS R12, PRIMASK // store message-->exc: disable int? - PUSH {R4-R12} // store message-->exc: {R4-R12} - ORR R0, R0, #FLAG_NO_FLOAT - B _handleEntry - .fnend - - .type _hwiActiveCheckNext, %function - .global _hwiActiveCheckNext -_hwiActiveCheckNext: - .fnstart - .cantunwind - ADD R2, R2, #4 // next NVIC ACT ADDR - SUBS R12, R12, #1 - BNE _hwiActiveCheck - - /*NMI interrupt excption*/ - LDR R2, =OS_NVIC_SHCSRS - LDRH R2,[R2] - LDR R3,=OS_NVIC_SHCSR_MASK - AND R2, R2,R3 - CMP R2,#0 - BNE _ExcInMSP - // exc occured in Task or Init or exc - // reserved for register info from task stack - - LDR R2, =g_taskScheduled - LDR R2, [R2] - TST R2, #1 // OS_FLG_BGD_ACTIVE - BEQ _ExcInMSP // if exc occured in Init then branch - - - CMP LR, #0xFFFFFFED //auto push floating registers - BNE _NoFloatInPsp - - // exc occured in Task - MOV R2, R13 - SUB R13, #96 // add 8 Bytes reg(for STMFD) - - MRS R3, PSP - ADD R12, R3, #104 - PUSH {R12} // save task SP - - MRS R12, PRIMASK - PUSH {R4-R12} - - // copy auto saved task register - - LDMFD R3!, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) - STMFD R2!, {R4-R11} - B _handleEntry - .fnend - - .type _NoFloatInPsp, %function - .global _NoFloatInPsp -_NoFloatInPsp: - .fnstart - .cantunwind - MOV R2, R13 //no auto push floating registers - SUB R13, #32 // add 8 Bytes reg(for STMFD) - - MRS R3, PSP - ADD R12, R3, #32 - PUSH {R12} // save task SP - - MRS R12, PRIMASK - PUSH {R4-R12} - - LDMFD R3, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) - STMFD R2!, {R4-R11} - ORR R0, R0, #FLAG_NO_FLOAT - .fnend - - .type _handleEntry, %function - .global _handleEntry -_handleEntry: - .fnstart - .cantunwind - MOV R3, R13 // R13:the 4th param - CPSID I - CPSID F - B HalExcHandleEntry - - NOP - .fnend +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ + + .syntax unified + .arch armv7e-m + .thumb +.section .text + + + .global HalExcNMI + .global HalExcHardFault + .global HalExcMemFault + .global HalExcBusFault + .global HalExcUsageFault + .global HalExcSvcCall + + .extern HalExcHandleEntry + .extern g_uwExcTbl + .extern g_taskScheduled + +.equ OS_FLG_BGD_ACTIVE, 0x0002 + +.equ OS_EXC_CAUSE_NMI, 16 +.equ OS_EXC_CAUSE_HARDFAULT, 17 + +.equ HF_DEBUGEVT, 20 +.equ HF_VECTBL, 21 + +.equ FLAG_ADDR_VALID, 0x10000 +.equ FLAG_HWI_ACTIVE, 0x20000 +.equ FLAG_NO_FLOAT, 0x10000000 + +.equ OS_NVIC_FSR , 0xE000ED28 //include BusFault/MemFault/UsageFault State Regeister +.equ OS_NVIC_HFSR , 0xE000ED2C //HardFault State Regeister +.equ OS_NVIC_BFAR , 0xE000ED38 +.equ OS_NVIC_MMAR , 0xE000ED34 +.equ OS_NVIC_ACT_BASE , 0xE000E300 +.equ OS_NVIC_SHCSRS , 0xE000ED24 +.equ OS_NVIC_SHCSR_MASK , 0xC00 + + .type HalExcNMI, %function + .global HalExcNMI +HalExcNMI: + .fnstart + .cantunwind + MOV R0, #OS_EXC_CAUSE_NMI + MOV R1, #0 + B osExcDispatch + .fnend + + .type HalExcHardFault, %function + .global HalExcHardFault +HalExcHardFault: + .fnstart + .cantunwind + MOV R0, #OS_EXC_CAUSE_HARDFAULT + LDR R2, =OS_NVIC_HFSR + LDR R2, [R2] + + MOV R1, #HF_DEBUGEVT + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x80000000 + BNE osExcDispatch // DEBUGEVT + + AND R0, R0 , #0x000000FF + MOV R1, #HF_VECTBL + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x00000002 + BNE osExcDispatch // VECTBL + + //if not DEBUGEVT and VECTBL then is FORCED + AND R0, R0, #0x000000FF + + LDR R2, =OS_NVIC_FSR + LDR R2, [R2] + + TST R2, #0x8000 // BFARVALID + BNE _HFBusFault // BusFault + + TST R2, #0x80 // MMARVALID + BNE _HFMemFault // MemFault + + MOV R12,#0 + B osHFExcCommonBMU + .fnend + + .type _HFBusFault, %function + +_HFBusFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + B osHFExcCommonBMU + .fnend + + .type _HFMemFault, %function + +_HFMemFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + .fnend + + .type osHFExcCommonBMU, %function + .global osHFExcCommonBMU +osHFExcCommonBMU: + .fnstart + .cantunwind + CLZ R2, R2 + LDR R3, =g_uwExcTbl + ADD R3, R3, R2 + LDRB R2, [R3] + ORR R0, R0, R2, LSL #0x8 + ORR R0, R0 ,R12 + B osExcDispatch + .fnend + + .type HalExcSvcCall, %function + .global HalExcSvcCall +HalExcSvcCall: + .fnstart + .cantunwind + TST LR, #0x4 + ITE EQ + MRSEQ R0, MSP + MRSNE R0, PSP + LDR R1, [R0,#24] + LDRB R0, [R1,#-2] + MOV R1, #0 + B osExcDispatch + .fnend + + .type HalExcBusFault, %function + .global HalExcBusFault +HalExcBusFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x8000 // BFARVALID + BEQ _ExcBusNoADDR + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1F00 + + B osExcCommonBMU + .fnend + + .type _ExcBusNoADDR, %function + .global _ExcBusNoADDR +_ExcBusNoADDR: + .fnstart + .cantunwind + MOV R12,#0 + B osExcCommonBMU + .fnend + + .type HalExcMemFault, %function + .global HalExcMemFault +HalExcMemFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x80 // MMARVALID + BEQ _ExcMemNoADDR + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1B + + B osExcCommonBMU + .fnend + + .type _ExcMemNoADDR, %function + .global _ExcMemNoADDR +_ExcMemNoADDR: + .fnstart + .cantunwind + MOV R12,#0 + B osExcCommonBMU + .fnend + + .type HalExcUsageFault, %function + .global HalExcUsageFault +HalExcUsageFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + MOV R1, #0x030F + LSL R1, R1, #16 + AND R0, R0, R1 + MOV R12, #0 + + .fnend + + .type osExcCommonBMU, %function + .global osExcCommonBMU +osExcCommonBMU: + .fnstart + .cantunwind + CLZ R0, R0 + LDR R3, =g_uwExcTbl + ADD R3, R3, R0 + LDRB R0, [R3] + ORR R0, R0, R12 + .fnend +// R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR + + .type osExcDispatch, %function + .global osExcDispatch +osExcDispatch: + .fnstart + .cantunwind + LDR R2, =OS_NVIC_ACT_BASE + MOV R12, #8 // R12 is hwi check loop counter + .fnend + + .type _hwiActiveCheck, %function + .global _hwiActiveCheck +_hwiActiveCheck: + .fnstart + .cantunwind + LDR R3, [R2] // R3 store active hwi register when exc + CMP R3, #0 + BEQ _hwiActiveCheckNext + + // exc occured in IRQ + ORR R0, R0, #FLAG_HWI_ACTIVE + RBIT R2, R3 + CLZ R2, R2 + AND R12, R12, #1 + ADD R2, R2, R12, LSL #5 // calculate R2 (hwi number) as uwPid + .fnend + + .type _ExcInMSP, %function + .global _ExcInMSP +_ExcInMSP: + .fnstart + .cantunwind + CMP LR, #0XFFFFFFED + BNE _NoFloatInMsp + ADD R3, R13, #104 + PUSH {R3} + MRS R12, PRIMASK // store message-->exc: disable int? + PUSH {R4-R12} // store message-->exc: {R4-R12} + #VPUSH {D8-D15} // FPU + B _handleEntry + .fnend + + .type _NoFloatInMsp, %function + .global _NoFloatInMsp +_NoFloatInMsp: + .fnstart + .cantunwind + ADD R3, R13, #32 + PUSH {R3} // save IRQ SP // store message-->exc: MSP(R13) + + MRS R12, PRIMASK // store message-->exc: disable int? + PUSH {R4-R12} // store message-->exc: {R4-R12} + ORR R0, R0, #FLAG_NO_FLOAT + B _handleEntry + .fnend + + .type _hwiActiveCheckNext, %function + .global _hwiActiveCheckNext +_hwiActiveCheckNext: + .fnstart + .cantunwind + ADD R2, R2, #4 // next NVIC ACT ADDR + SUBS R12, R12, #1 + BNE _hwiActiveCheck + + /*NMI interrupt excption*/ + LDR R2, =OS_NVIC_SHCSRS + LDRH R2,[R2] + LDR R3,=OS_NVIC_SHCSR_MASK + AND R2, R2,R3 + CMP R2,#0 + BNE _ExcInMSP + // exc occured in Task or Init or exc + // reserved for register info from task stack + + LDR R2, =g_taskScheduled + LDR R2, [R2] + TST R2, #1 // OS_FLG_BGD_ACTIVE + BEQ _ExcInMSP // if exc occured in Init then branch + + + CMP LR, #0xFFFFFFED //auto push floating registers + BNE _NoFloatInPsp + + // exc occured in Task + MOV R2, R13 + SUB R13, #96 // add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #104 + PUSH {R12} // save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + + // copy auto saved task register + + LDMFD R3!, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) + #VLDMIA R3!, {D8-D15} // FPU + #VSTMDB R2!, {D8-D15} // FPU + STMFD R2!, {R4-R11} + B _handleEntry + .fnend + + .type _NoFloatInPsp, %function + .global _NoFloatInPsp +_NoFloatInPsp: + .fnstart + .cantunwind + MOV R2, R13 //no auto push floating registers + SUB R13, #32 // add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #32 + PUSH {R12} // save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + + LDMFD R3, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) + STMFD R2!, {R4-R11} + ORR R0, R0, #FLAG_NO_FLOAT + .fnend + + .type _handleEntry, %function + .global _handleEntry +_handleEntry: + .fnstart + .cantunwind + MOV R3, R13 // R13:the 4th param + CPSID I + CPSID F + B HalExcHandleEntry + + NOP + .fnend diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_interrupt.c b/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c similarity index 97% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_interrupt.c rename to kernel/arch/arm/cortex-m4/gcc/los_interrupt.c index 3dc41549..132c00c8 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_interrupt.c +++ b/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c @@ -1,398 +1,397 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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 "los_interrupt.h" -#include "los_context.h" -#include "los_arch_interrupt.h" -#include -#include "los_debug.h" -#include "los_task.h" -#include "los_tick.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/*lint -save -e40 -e522 -e533*/ - -UINT32 g_intCount = 0; -/*lint -restore*/ -#ifdef __ICCARM__ -#pragma location = ".data.vector" -#pragma data_alignment=0x100 -#elif defined(__CC_ARM) || defined(__GNUC__) -LITE_OS_SEC_VEC -#endif -HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; - -#if (OS_HWI_WITH_ARG == 1) -HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; -#else -HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; -#endif - -/* **************************************************************************** - Function : HalIntNumGet - Description : Get a interrupt number - Input : None - Output : None - Return : Interrupt Indexes number - **************************************************************************** */ -LITE_OS_SEC_TEXT_MINOR UINT32 HalIntNumGet(VOID) -{ - return __get_IPSR(); -} - -inline UINT32 HalIsIntAcvive(VOID) -{ - return (g_intCount > 0); -} -/* **************************************************************************** - Function : HalHwiDefaultHandler - Description : default handler of the hardware interrupt - Input : None - Output : None - Return : None - **************************************************************************** */ -/*lint -e529*/ -LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) -{ - UINT32 irqNum = HalIntNumGet(); - PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, irqNum); - while (1) {} -} - -/* **************************************************************************** - Function : HalInterrupt - Description : Hardware interrupt entry function - Input : None - Output : None - Return : None - **************************************************************************** */ -LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) -{ - UINT32 hwiIndex; - UINT32 intSave; - -#if (LOSCFG_KERNEL_RUNSTOP == 1) - SCB->SCR &= (UINT32) ~((UINT32)SCB_SCR_SLEEPDEEP_Msk); -#endif - - intSave = LOS_IntLock(); - - g_intCount++; - - LOS_IntRestore(intSave); - - hwiIndex = HalIntNumGet(); - -#if (OS_HWI_WITH_ARG == 1) - if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { - g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); - } -#else - if (g_hwiSlaveForm[hwiIndex] != 0) { - g_hwiSlaveForm[hwiIndex](); - } -#endif - intSave = LOS_IntLock(); - g_intCount--; - LOS_IntRestore(intSave); -} - -/* **************************************************************************** - Function : HalHwiCreate - Description : create hardware interrupt - Input : hwiNum --- hwi num to create - hwiPrio --- priority of the hwi - mode --- unused - handler --- hwi handler - arg --- param of the hwi handler - Output : None - Return : LOS_OK on success or error code on failure - **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum, - HWI_PRIOR_T hwiPrio, - HWI_MODE_T mode, - HWI_PROC_FUNC handler, - HWI_ARG_T arg) -{ - UINTPTR intSave; - - if (handler == NULL) { - return OS_ERRNO_HWI_PROC_FUNC_NULL; - } - - if (hwiNum >= OS_HWI_MAX_NUM) { - return OS_ERRNO_HWI_NUM_INVALID; - } - - if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)HalHwiDefaultHandler) { - return OS_ERRNO_HWI_ALREADY_CREATED; - } - - if (hwiPrio > OS_HWI_PRIO_LOWEST) { - return OS_ERRNO_HWI_PRIO_INVALID; - } - - intSave = LOS_IntLock(); -#if (OS_HWI_WITH_ARG == 1) - OsSetVector(hwiNum, handler, arg); -#else - OsSetVector(hwiNum, handler); -#endif - NVIC_EnableIRQ((IRQn_Type)hwiNum); - NVIC_SetPriority((IRQn_Type)hwiNum, hwiPrio); - - LOS_IntRestore(intSave); - - return LOS_OK; -} - -/* **************************************************************************** - Function : HalHwiDelete - Description : Delete hardware interrupt - Input : hwiNum --- hwi num to delete - Output : None - Return : LOS_OK on success or error code on failure - **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) -{ - UINT32 intSave; - - if (hwiNum >= OS_HWI_MAX_NUM) { - return OS_ERRNO_HWI_NUM_INVALID; - } - - NVIC_DisableIRQ((IRQn_Type)hwiNum); - - intSave = LOS_IntLock(); - - g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler; - - LOS_IntRestore(intSave); - - return LOS_OK; -} - -#define OS_NVIC_INT_CTRL_SIZE 4 -#define OS_NVIC_SHCSR_SIZE 4 -#define FAULT_STATUS_REG_BIT 32 -#define USGFAULT (1 << 18) -#define BUSFAULT (1 << 17) -#define MEMFAULT (1 << 16) -#define DIV0FAULT (1 << 4) -#define HARDFAULT_IRQN (-13) - -static ExcInfoArray g_excArray[OS_EXC_TYPE_MAX]; - -static ExcInfo g_excInfo = {0}; - -UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { - 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, - 0, 0, 0, 0, OS_EXC_UF_NOCP, OS_EXC_UF_INVPC, OS_EXC_UF_INVSTATE, OS_EXC_UF_UNDEFINSTR, - 0, 0, 0, OS_EXC_BF_STKERR, OS_EXC_BF_UNSTKERR, OS_EXC_BF_IMPRECISERR, OS_EXC_BF_PRECISERR, OS_EXC_BF_IBUSERR, - 0, 0, 0, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL -}; - -UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) -{ - UINT32 *base = NULL; - UINT32 len = 0, i, j; -#define OS_NR_NVIC_EXC_DUMP_Types 7 - UINT32 rgNvicBases[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_SETENA_BASE, OS_NVIC_SETPEND_BASE, - OS_NVIC_INT_ACT_BASE, OS_NVIC_PRI_BASE, OS_NVIC_EXCPRI_BASE, OS_NVIC_SHCSR, OS_NVIC_INT_CTRL}; - UINT32 rgNvicLens[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_INT_ENABLE_SIZE, OS_NVIC_INT_PEND_SIZE, - OS_NVIC_INT_ACT_SIZE, OS_NVIC_INT_PRI_SIZE, OS_NVIC_EXCPRI_SIZE, OS_NVIC_SHCSR_SIZE, OS_NVIC_INT_CTRL_SIZE}; - char strRgEnable[] = "enable"; - char strRgPending[] = "pending"; - char strRgActive[] = "active"; - char strRgPriority[] = "priority"; - char strRgException[] = "exception"; - char strRgShcsr[] = "shcsr"; - char strRgIntCtrl[] = "control"; - char *strRgs[] = {strRgEnable, strRgPending, strRgActive, strRgPriority, strRgException, strRgShcsr, strRgIntCtrl}; - (VOID)index; - (VOID)excContent; - - PRINTK("OS exception NVIC dump: \n"); - for (i = 0; i < OS_NR_NVIC_EXC_DUMP_Types; i++) { - base = (UINT32 *)rgNvicBases[i]; - len = rgNvicLens[i]; - PRINTK("interrupt %s register, base address: 0x%x, size: 0x%x\n", strRgs[i], base, len); - len = (len >> 2); - for (j = 0; j < len; j++) { - PRINTK("0x%x ", *(base + j)); - } - PRINTK("\n"); - } - return 0; -} - -UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) -{ - (VOID)index; - (VOID)excContent; - PRINTK("OS exception context dump:\n"); - PRINTK("Phase = 0x%x\n", g_excInfo.phase); - PRINTK("Type = 0x%x\n", g_excInfo.type); - PRINTK("FaultAddr = 0x%x\n", g_excInfo.faultAddr); - PRINTK("ThrdPid = 0x%x\n", g_excInfo.thrdPid); - PRINTK("R0 = 0x%x\n", g_excInfo.context->uwR0); - PRINTK("R1 = 0x%x\n", g_excInfo.context->uwR1); - PRINTK("R2 = 0x%x\n", g_excInfo.context->uwR2); - PRINTK("R3 = 0x%x\n", g_excInfo.context->uwR3); - PRINTK("R4 = 0x%x\n", g_excInfo.context->uwR4); - PRINTK("R5 = 0x%x\n", g_excInfo.context->uwR5); - PRINTK("R6 = 0x%x\n", g_excInfo.context->uwR6); - PRINTK("R7 = 0x%x\n", g_excInfo.context->uwR7); - PRINTK("R8 = 0x%x\n", g_excInfo.context->uwR8); - PRINTK("R9 = 0x%x\n", g_excInfo.context->uwR9); - PRINTK("R10 = 0x%x\n", g_excInfo.context->uwR10); - PRINTK("R11 = 0x%x\n", g_excInfo.context->uwR11); - PRINTK("R12 = 0x%x\n", g_excInfo.context->uwR12); - PRINTK("PriMask = 0x%x\n", g_excInfo.context->uwPriMask); - PRINTK("SP = 0x%x\n", g_excInfo.context->uwSP); - PRINTK("LR = 0x%x\n", g_excInfo.context->uwLR); - PRINTK("PC = 0x%x\n", g_excInfo.context->uwPC); - PRINTK("xPSR = 0x%x\n", g_excInfo.context->uwxPSR); - return 0; -} - -VOID HalDumpMsg(VOID) -{ - UINT32 index = 0; - for (index = 0; index < (OS_EXC_TYPE_MAX - 1); index++) { - if (g_excArray[index].uwValid == FALSE) { - continue; - } - g_excArray[index].pFnExcInfoCb(index, g_excArray[index].pArg); - } -} - -LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) -{ - UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; - g_intCount++; - g_excInfo.nestCnt++; - - g_excInfo.type = excType & OS_NULL_SHORT; - - if (tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) { - g_excInfo.faultAddr = faultAddr; - } else { - g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; - } - if (g_losTask.runTask != NULL) { - if (tmpFlag & OS_EXC_FLAG_IN_HWI) { - g_excInfo.phase = OS_EXC_IN_HWI; - g_excInfo.thrdPid = pid; - } else { - g_excInfo.phase = OS_EXC_IN_TASK; - g_excInfo.thrdPid = g_losTask.runTask->taskID; - } - } else { - g_excInfo.phase = OS_EXC_IN_INIT; - g_excInfo.thrdPid = OS_NULL_INT; - } - if (excType & OS_EXC_FLAG_NO_FLOAT) { - g_excInfo.context = (EXC_CONTEXT_S *)((CHAR *)excBufAddr - LOS_OFF_SET_OF(EXC_CONTEXT_S, uwR4)); - } else { - g_excInfo.context = excBufAddr; - } - HalDumpMsg(); - HalSysExit(); -} - -VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) -{ - ExcInfoArray *excInfo = NULL; - if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { - PRINT_ERR("HalExcRegister ERROR!\n"); - return; - } - excInfo = &(g_excArray[type]); - excInfo->uwType = type; - excInfo->pFnExcInfoCb = func; - excInfo->pArg = arg; - excInfo->uwValid = TRUE; -} - -/* **************************************************************************** - Function : HalHwiInit - Description : initialization of the hardware interrupt - Input : None - Output : None - Return : None - **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() -{ -#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) - UINT32 index; - g_hwiForm[0] = 0; /* [0] Top of Stack */ - g_hwiForm[1] = Reset_Handler; /* [1] reset */ - for (index = 2; index < OS_VECTOR_CNT; index++) { - g_hwiForm[index] = (HWI_PROC_FUNC)HalHwiDefaultHandler; - } - /* Exception handler register */ - g_hwiForm[NonMaskableInt_IRQn + OS_SYS_VECTOR_CNT] = HalExcNMI; - g_hwiForm[HARDFAULT_IRQN + OS_SYS_VECTOR_CNT] = HalExcHardFault; - g_hwiForm[MemoryManagement_IRQn + OS_SYS_VECTOR_CNT] = HalExcMemFault; - g_hwiForm[BusFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcBusFault; - g_hwiForm[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcUsageFault; - g_hwiForm[SVCall_IRQn + OS_SYS_VECTOR_CNT] = HalExcSvcCall; - g_hwiForm[PendSV_IRQn + OS_SYS_VECTOR_CNT] = HalPendSV; - - /* Interrupt vector table location */ - SCB->VTOR = (UINT32)(UINTPTR)g_hwiForm; -#endif - -#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */ - NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP); -#endif - - /* Enable USGFAULT, BUSFAULT, MEMFAULT */ - *(volatile UINT32 *)OS_NVIC_SHCSR |= (USGFAULT | BUSFAULT | MEMFAULT); - /* Enable DIV 0 and unaligned exception */ - *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; - - HalExcRegister(OS_EXC_TYPE_CONTEXT, (EXC_INFO_SAVE_CALLBACK)HalExcContextDump, NULL); - HalExcRegister(OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)HalExcNvicDump, NULL); - - return; -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "los_interrupt.h" +#include "los_context.h" +#include "los_arch_interrupt.h" +#include +#include "los_debug.h" +#include "los_task.h" +#include "los_tick.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/*lint -save -e40 -e522 -e533*/ + +UINT32 g_intCount = 0; +/*lint -restore*/ +#ifdef __ICCARM__ +#pragma location = ".data.vector" +#pragma data_alignment=0x100 +#elif defined(__CC_ARM) || defined(__GNUC__) +LITE_OS_SEC_VEC +#endif +HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; + +#if (OS_HWI_WITH_ARG == 1) +HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; +#else +HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +#endif + +/* **************************************************************************** + Function : HalIntNumGet + Description : Get a interrupt number + Input : None + Output : None + Return : Interrupt Indexes number + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 HalIntNumGet(VOID) +{ + return __get_IPSR(); +} + +inline UINT32 HalIsIntAcvive(VOID) +{ + return (g_intCount > 0); +} +/* **************************************************************************** + Function : HalHwiDefaultHandler + Description : default handler of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +/*lint -e529*/ +LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) +{ + UINT32 irqNum = HalIntNumGet(); + PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, irqNum); + while (1) {} +} + +/* **************************************************************************** + Function : HalInterrupt + Description : Hardware interrupt entry function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) +{ + UINT32 hwiIndex; + UINT32 intSave; + +#if (LOSCFG_KERNEL_RUNSTOP == 1) + SCB->SCR &= (UINT32) ~((UINT32)SCB_SCR_SLEEPDEEP_Msk); +#endif + + intSave = LOS_IntLock(); + + g_intCount++; + + LOS_IntRestore(intSave); + + hwiIndex = HalIntNumGet(); + +#if (OS_HWI_WITH_ARG == 1) + if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { + g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + } +#else + if (g_hwiSlaveForm[hwiIndex] != 0) { + g_hwiSlaveForm[hwiIndex](); + } +#endif + intSave = LOS_IntLock(); + g_intCount--; + LOS_IntRestore(intSave); +} + +/* **************************************************************************** + Function : HalHwiCreate + Description : create hardware interrupt + Input : hwiNum --- hwi num to create + hwiPrio --- priority of the hwi + mode --- unused + handler --- hwi handler + arg --- param of the hwi handler + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg) +{ + UINTPTR intSave; + + if (handler == NULL) { + return OS_ERRNO_HWI_PROC_FUNC_NULL; + } + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)HalHwiDefaultHandler) { + return OS_ERRNO_HWI_ALREADY_CREATED; + } + + if (hwiPrio > OS_HWI_PRIO_LOWEST) { + return OS_ERRNO_HWI_PRIO_INVALID; + } + + intSave = LOS_IntLock(); +#if (OS_HWI_WITH_ARG == 1) + OsSetVector(hwiNum, handler, arg); +#else + OsSetVector(hwiNum, handler); +#endif + NVIC_EnableIRQ((IRQn_Type)hwiNum); + NVIC_SetPriority((IRQn_Type)hwiNum, hwiPrio); + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +/* **************************************************************************** + Function : HalHwiDelete + Description : Delete hardware interrupt + Input : hwiNum --- hwi num to delete + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) +{ + UINT32 intSave; + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + NVIC_DisableIRQ((IRQn_Type)hwiNum); + + intSave = LOS_IntLock(); + + g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler; + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +#define OS_NVIC_INT_CTRL_SIZE 4 +#define OS_NVIC_SHCSR_SIZE 4 +#define FAULT_STATUS_REG_BIT 32 +#define USGFAULT (1 << 18) +#define BUSFAULT (1 << 17) +#define MEMFAULT (1 << 16) +#define DIV0FAULT (1 << 4) +#define HARDFAULT_IRQN (-13) + +static ExcInfoArray g_excArray[OS_EXC_TYPE_MAX]; + +static ExcInfo g_excInfo = {0}; + +UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { + 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, + 0, 0, 0, 0, OS_EXC_UF_NOCP, OS_EXC_UF_INVPC, OS_EXC_UF_INVSTATE, OS_EXC_UF_UNDEFINSTR, + 0, 0, 0, OS_EXC_BF_STKERR, OS_EXC_BF_UNSTKERR, OS_EXC_BF_IMPRECISERR, OS_EXC_BF_PRECISERR, OS_EXC_BF_IBUSERR, + 0, 0, 0, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL +}; + +UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) +{ + UINT32 *base = NULL; + UINT32 len = 0, i, j; +#define OS_NR_NVIC_EXC_DUMP_Types 7 + UINT32 rgNvicBases[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_SETENA_BASE, OS_NVIC_SETPEND_BASE, + OS_NVIC_INT_ACT_BASE, OS_NVIC_PRI_BASE, OS_NVIC_EXCPRI_BASE, OS_NVIC_SHCSR, OS_NVIC_INT_CTRL}; + UINT32 rgNvicLens[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_INT_ENABLE_SIZE, OS_NVIC_INT_PEND_SIZE, + OS_NVIC_INT_ACT_SIZE, OS_NVIC_INT_PRI_SIZE, OS_NVIC_EXCPRI_SIZE, OS_NVIC_SHCSR_SIZE, OS_NVIC_INT_CTRL_SIZE}; + char strRgEnable[] = "enable"; + char strRgPending[] = "pending"; + char strRgActive[] = "active"; + char strRgPriority[] = "priority"; + char strRgException[] = "exception"; + char strRgShcsr[] = "shcsr"; + char strRgIntCtrl[] = "control"; + char *strRgs[] = {strRgEnable, strRgPending, strRgActive, strRgPriority, strRgException, strRgShcsr, strRgIntCtrl}; + (VOID)index; + (VOID)excContent; + + PRINTK("OS exception NVIC dump: \n"); + for (i = 0; i < OS_NR_NVIC_EXC_DUMP_Types; i++) { + base = (UINT32 *)rgNvicBases[i]; + len = rgNvicLens[i]; + PRINTK("interrupt %s register, base address: 0x%x, size: 0x%x\n", strRgs[i], base, len); + len = (len >> 2); + for (j = 0; j < len; j++) { + PRINTK("0x%x ", *(base + j)); + } + PRINTK("\n"); + } + return 0; +} + +UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) +{ + (VOID)index; + (VOID)excContent; + PRINTK("OS exception context dump:\n"); + PRINTK("Phase = 0x%x\n", g_excInfo.phase); + PRINTK("Type = 0x%x\n", g_excInfo.type); + PRINTK("FaultAddr = 0x%x\n", g_excInfo.faultAddr); + PRINTK("ThrdPid = 0x%x\n", g_excInfo.thrdPid); + PRINTK("R0 = 0x%x\n", g_excInfo.context->uwR0); + PRINTK("R1 = 0x%x\n", g_excInfo.context->uwR1); + PRINTK("R2 = 0x%x\n", g_excInfo.context->uwR2); + PRINTK("R3 = 0x%x\n", g_excInfo.context->uwR3); + PRINTK("R4 = 0x%x\n", g_excInfo.context->uwR4); + PRINTK("R5 = 0x%x\n", g_excInfo.context->uwR5); + PRINTK("R6 = 0x%x\n", g_excInfo.context->uwR6); + PRINTK("R7 = 0x%x\n", g_excInfo.context->uwR7); + PRINTK("R8 = 0x%x\n", g_excInfo.context->uwR8); + PRINTK("R9 = 0x%x\n", g_excInfo.context->uwR9); + PRINTK("R10 = 0x%x\n", g_excInfo.context->uwR10); + PRINTK("R11 = 0x%x\n", g_excInfo.context->uwR11); + PRINTK("R12 = 0x%x\n", g_excInfo.context->uwR12); + PRINTK("PriMask = 0x%x\n", g_excInfo.context->uwPriMask); + PRINTK("SP = 0x%x\n", g_excInfo.context->uwSP); + PRINTK("LR = 0x%x\n", g_excInfo.context->uwLR); + PRINTK("PC = 0x%x\n", g_excInfo.context->uwPC); + PRINTK("xPSR = 0x%x\n", g_excInfo.context->uwxPSR); + return 0; +} + +VOID HalDumpMsg(VOID) +{ + UINT32 index = 0; + for (index = 0; index < (OS_EXC_TYPE_MAX - 1); index++) { + if (g_excArray[index].uwValid == FALSE) { + continue; + } + g_excArray[index].pFnExcInfoCb(index, g_excArray[index].pArg); + } +} + +LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) +{ + UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; + g_intCount++; + g_excInfo.nestCnt++; + + g_excInfo.type = excType & OS_NULL_SHORT; + + if (tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) { + g_excInfo.faultAddr = faultAddr; + } else { + g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; + } + if (g_losTask.runTask != NULL) { + if (tmpFlag & OS_EXC_FLAG_IN_HWI) { + g_excInfo.phase = OS_EXC_IN_HWI; + g_excInfo.thrdPid = pid; + } else { + g_excInfo.phase = OS_EXC_IN_TASK; + g_excInfo.thrdPid = g_losTask.runTask->taskID; + } + } else { + g_excInfo.phase = OS_EXC_IN_INIT; + g_excInfo.thrdPid = OS_NULL_INT; + } + if (excType & OS_EXC_FLAG_NO_FLOAT) { + g_excInfo.context = (EXC_CONTEXT_S *)((CHAR *)excBufAddr - LOS_OFF_SET_OF(EXC_CONTEXT_S, uwR4)); + } else { + g_excInfo.context = excBufAddr; + } + HalDumpMsg(); + HalSysExit(); +} + +VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) +{ + ExcInfoArray *excInfo = NULL; + if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { + PRINT_ERR("HalExcRegister ERROR!\n"); + return; + } + excInfo = &(g_excArray[type]); + excInfo->uwType = type; + excInfo->pFnExcInfoCb = func; + excInfo->pArg = arg; + excInfo->uwValid = TRUE; +} + +/* **************************************************************************** + Function : HalHwiInit + Description : initialization of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() +{ +#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) + UINT32 index; + g_hwiForm[0] = 0; /* [0] Top of Stack */ + g_hwiForm[1] = Reset_Handler; /* [1] reset */ + for (index = 2; index < OS_VECTOR_CNT; index++) { + g_hwiForm[index] = (HWI_PROC_FUNC)HalHwiDefaultHandler; + } + /* Exception handler register */ + g_hwiForm[NonMaskableInt_IRQn + OS_SYS_VECTOR_CNT] = HalExcNMI; + g_hwiForm[HARDFAULT_IRQN + OS_SYS_VECTOR_CNT] = HalExcHardFault; + g_hwiForm[MemoryManagement_IRQn + OS_SYS_VECTOR_CNT] = HalExcMemFault; + g_hwiForm[BusFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcBusFault; + g_hwiForm[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcUsageFault; + g_hwiForm[SVCall_IRQn + OS_SYS_VECTOR_CNT] = HalExcSvcCall; + g_hwiForm[PendSV_IRQn + OS_SYS_VECTOR_CNT] = HalPendSV; + + /* Interrupt vector table location */ + SCB->VTOR = (UINT32)(UINTPTR)g_hwiForm; +#endif +#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */ + NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP); +#endif + + /* Enable USGFAULT, BUSFAULT, MEMFAULT */ + *(volatile UINT32 *)OS_NVIC_SHCSR |= (USGFAULT | BUSFAULT | MEMFAULT); + /* Enable DIV 0 and unaligned exception */ + *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; + + HalExcRegister(OS_EXC_TYPE_CONTEXT, (EXC_INFO_SAVE_CALLBACK)HalExcContextDump, NULL); + HalExcRegister(OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)HalExcNvicDump, NULL); + + return; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/arch/arm/cortex-m4/qemu_gcc/los_timer.c b/kernel/arch/arm/cortex-m4/gcc/los_timer.c similarity index 96% rename from kernel/arch/arm/cortex-m4/qemu_gcc/los_timer.c rename to kernel/arch/arm/cortex-m4/gcc/los_timer.c index 1bd385b5..2486a29e 100644 --- a/kernel/arch/arm/cortex-m4/qemu_gcc/los_timer.c +++ b/kernel/arch/arm/cortex-m4/gcc/los_timer.c @@ -1,235 +1,235 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of the copyright holder 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 "los_config.h" -#include "los_tick.h" -#include "los_arch_interrupt.h" -#include "los_timer.h" -#include "los_context.h" -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - - - -/* **************************************************************************** -Function : HalTickStart -Description : Configure Tick Interrupt Start -Input : none -output : none -return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed -**************************************************************************** */ -LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) -{ - UINT32 ret; - - if ((OS_SYS_CLOCK == 0) || - (LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) || - (LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) { - return LOS_ERRNO_TICK_CFG_INVALID; - } -#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) -#if (OS_HWI_WITH_ARG == 1) - OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler, NULL); -#else - OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler); -#endif -#endif - - g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; - g_ullTickCount = 0; - - ret = SysTick_Config(g_cyclesPerTick); - if (ret == 1) { - return LOS_ERRNO_TICK_PER_SEC_TOO_SMALL; - } - - return LOS_OK; -} - -/* **************************************************************************** -Function : HalSysTickCurrCycleGet -Description : Get System cycle count -Input : none -output : none -return : hwCycle --- the system cycle count -**************************************************************************** */ -LITE_OS_SEC_TEXT_MINOR UINT32 HalSysTickCurrCycleGet(VOID) -{ - UINT32 hwCycle; - UINTPTR intSave; - - intSave = LOS_IntLock(); - hwCycle = SysTick->VAL; - - /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ - if ((SCB->ICSR & TICK_CHECK) != 0) { - hwCycle = SysTick->VAL; - hwCycle += g_cyclesPerTick; - } - - LOS_IntRestore(intSave); - - return hwCycle; -} - -/* **************************************************************************** -Function : HalGetCpuCycle -Description : Get System cycle count -Input : none -output : cntHi --- CpuTick High 4 byte - cntLo --- CpuTick Low 4 byte -return : none -**************************************************************************** */ -LITE_OS_SEC_TEXT_MINOR VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo) -{ - UINT64 swTick; - UINT64 cycle; - UINT32 hwCycle; - UINTPTR intSave; - - intSave = LOS_IntLock(); - - swTick = g_ullTickCount; - hwCycle = SysTick->VAL; - - /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ - if ((SCB->ICSR & TICK_CHECK) != 0) { - hwCycle = SysTick->VAL; - swTick++; - } - - cycle = (((swTick) * g_cyclesPerTick) + (g_cyclesPerTick - hwCycle)); - - *cntHi = cycle >> SHIFT_32_BIT; - *cntLo = cycle & CYCLE_CHECK; - - LOS_IntRestore(intSave); - - return; -} - -/* **************************************************************************** -Function : HalGetSystickCycle -Description : Get Sys tick cycle count -Input : none -output : cntHi --- SysTick count High 4 byte - cntLo --- SysTick count Low 4 byte -return : none -**************************************************************************** */ -LITE_OS_SEC_TEXT_MINOR VOID HalGetSystickCycle(UINT32 *cntHi, UINT32 *cntLo) -{ - UINT64 swTick; - UINT64 cycle; - UINT32 hwCycle; - UINTPTR intSave; - UINT32 systickLoad; - UINT32 systickCur; - - intSave = LOS_IntLock(); - - swTick = g_ullTickCount; - - systickLoad = SysTick->LOAD; - systickCur = SysTick->VAL; - if (systickLoad < systickCur) { - LOS_IntRestore(intSave); - return; - } - hwCycle = systickLoad - systickCur; - - /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ - if ((SCB->ICSR & TICK_CHECK) != 0) { - hwCycle = systickLoad - systickCur; - swTick++; - } - - cycle = hwCycle + swTick * systickLoad; - *cntHi = cycle >> SHIFT_32_BIT; - *cntLo = cycle & CYCLE_CHECK; - - LOS_IntRestore(intSave); - - return; -} - -static BOOL g_sysSleepFlag = FALSE; - -VOID HalTickLock(VOID) -{ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; -} - -VOID HalTickUnlock(VOID) -{ - SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; -} - -BOOL HalGetSysSleepFlag(VOID) -{ - return g_sysSleepFlag; -} - -VOID HalClearSysSleepFlag(VOID) -{ - g_sysSleepFlag = FALSE; -} - -VOID HalEnterSleep(LOS_SysSleepEnum sleep) -{ - __DSB(); - __WFI(); - __ISB(); -} - -//extern unsigned int SystemCoreClock; -void HalDelay(UINT32 ticks) -{ -#if 0 - UINT32 delayTimes; - /* there are 4 machine cycle in loop */ - if ((ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES)) >= 0xffffffff) { - delayTimes = 0xffffffff; - } else { - delayTimes = ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES); - } - while (delayTimes) { - delayTimes = delayTimes - 1; - } -#endif -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "los_config.h" +#include "los_tick.h" +#include "los_arch_interrupt.h" +#include "los_timer.h" +#include "los_context.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + + +/* **************************************************************************** +Function : HalTickStart +Description : Configure Tick Interrupt Start +Input : none +output : none +return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed +**************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) +{ + UINT32 ret; + + if ((OS_SYS_CLOCK == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) { + return LOS_ERRNO_TICK_CFG_INVALID; + } + +#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) +#if (OS_HWI_WITH_ARG == 1) + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler, NULL); +#else + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler); +#endif +#endif + g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; + g_ullTickCount = 0; + + ret = SysTick_Config(g_cyclesPerTick); + if (ret == 1) { + return LOS_ERRNO_TICK_PER_SEC_TOO_SMALL; + } + + return LOS_OK; +} + +/* **************************************************************************** +Function : HalSysTickCurrCycleGet +Description : Get System cycle count +Input : none +output : none +return : hwCycle --- the system cycle count +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 HalSysTickCurrCycleGet(VOID) +{ + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + hwCycle += g_cyclesPerTick; + } + + LOS_IntRestore(intSave); + + return hwCycle; +} + +/* **************************************************************************** +Function : HalGetCpuCycle +Description : Get System cycle count +Input : none +output : cntHi --- CpuTick High 4 byte + cntLo --- CpuTick Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + swTick++; + } + + cycle = (((swTick) * g_cyclesPerTick) + (g_cyclesPerTick - hwCycle)); + + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} + +/* **************************************************************************** +Function : HalGetSystickCycle +Description : Get Sys tick cycle count +Input : none +output : cntHi --- SysTick count High 4 byte + cntLo --- SysTick count Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalGetSystickCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + UINT32 systickLoad; + UINT32 systickCur; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + + systickLoad = SysTick->LOAD; + systickCur = SysTick->VAL; + if (systickLoad < systickCur) { + LOS_IntRestore(intSave); + return; + } + hwCycle = systickLoad - systickCur; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = systickLoad - systickCur; + swTick++; + } + + cycle = hwCycle + swTick * systickLoad; + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} + +static BOOL g_sysSleepFlag = FALSE; + +VOID HalTickLock(VOID) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; +} + +VOID HalTickUnlock(VOID) +{ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +BOOL HalGetSysSleepFlag(VOID) +{ + return g_sysSleepFlag; +} + +VOID HalClearSysSleepFlag(VOID) +{ + g_sysSleepFlag = FALSE; +} + +VOID HalEnterSleep(LOS_SysSleepEnum sleep) +{ + __DSB(); + __WFI(); + __ISB(); +} + +//extern unsigned int SystemCoreClock; +void HalDelay(UINT32 ticks) +{ +#if 0 + UINT32 delayTimes; + /* there are 4 machine cycle in loop */ + if ((ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES)) >= 0xffffffff) { + delayTimes = 0xffffffff; + } else { + delayTimes = ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES); + } + while (delayTimes) { + delayTimes = delayTimes - 1; + } +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ -- Gitee