diff --git a/components/backtrace/los_backtrace.c b/components/backtrace/los_backtrace.c old mode 100644 new mode 100755 index 05538f13..b1df4f70 --- a/components/backtrace/los_backtrace.c +++ b/components/backtrace/los_backtrace.c @@ -351,6 +351,242 @@ STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp) return pc; } + +#elif (LOSCFG_BACKTRACE_TYPE == 4) +#define OS_BACKTRACE_START 0 +#define ALIGN_MASK (4 - 1) +#define OS_REG_LR_OFFSET 136 + +UINT32 IsFpAligned(UINT32 value) +{ + return (value & (UINT32)(ALIGN_MASK)) == 0; +} + +STATIC INLINE UINTPTR HalGetLr(VOID) +{ + UINTPTR regLr; + + __asm__ __volatile__("mov %0, a0" : "=r"(regLr)); + + return regLr; +} + +/* This function is used to check fp address. */ +BOOL IsValidFP(UINTPTR regFP, UINTPTR start, UINTPTR end) +{ + return (regFP > start) && (regFP <= end) && IsFpAligned(regFP); +} + +/* This function is used to check return address. */ +BOOL IsValidRa(UINTPTR regRA) +{ + regRA &= ~VIR_TEXT_ADDR_MASK; + regRA |= TEXT_ADDR_MASK; + + return OsStackDataIsCodeAddr(regRA); +} + +BOOL FindSuitableStack(UINTPTR regSP, UINTPTR *start, UINTPTR *end) +{ + UINT32 index; + UINT32 stackStart; + UINT32 stackEnd; + BOOL found = FALSE; + LosTaskCB *taskCB = NULL; + + /* Search in the task stacks */ + for (index = 0; index < g_taskMaxNum; index++) { + taskCB = OS_TCB_FROM_TID(index); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + + stackStart = taskCB->topOfStack; + stackEnd = taskCB->topOfStack + taskCB->stackSize; + if (IsValidFP(regSP, stackStart, stackEnd)) { + found = TRUE; + goto FOUND; + } + } + + if (IsValidFP(regSP, CSTACK_START_ADDR, CSTACK_END_ADDR)) { + stackStart = CSTACK_START_ADDR; + stackEnd = CSTACK_END_ADDR; + found = TRUE; + goto FOUND; + } + +FOUND: + if (found == TRUE) { + *start = stackStart; + *end = stackEnd; + } + + return found; +} + +UINT32 HalBackTraceGet(UINTPTR sp, UINT32 retAddr, UINTPTR *callChain, UINT32 maxDepth, UINT32 jumpCount) +{ + UINTPTR tmpSp; + UINT32 tmpRa; + UINTPTR backRa = retAddr; + UINTPTR backSp = sp; + UINTPTR stackStart; + UINT32 stackEnd; + UINT32 count = 0; + UINT32 index = 0; + + if (FindSuitableStack(sp, &stackStart, &stackEnd) == FALSE) { + PRINTK("sp:0x%x error, backtrace failed!\n", sp); + return 0; + } + + while (IsValidFP(backSp, stackStart, stackEnd)) { + if (callChain == NULL) { + PRINTK("trace%u ra:0x%x sp:0x%x\n", count, (backRa << WINDOW_INCREMENT_SHIFT) >> + WINDOW_INCREMENT_SHIFT, backSp); + } else { + if (index++ < jumpCount) { + continue; + } + backRa &= ~VIR_TEXT_ADDR_MASK; + backRa |= TEXT_ADDR_MASK; + callChain[count++] = backRa; + } + + tmpRa = backRa; + tmpSp = backSp; + backRa = *((UINT32 *)(UINTPTR)(tmpSp - RA_OFFSET)); + backSp = *((UINT32 *)(UINTPTR)(tmpSp - SP_OFFSET)); + + if ((tmpRa == backRa) || (backSp == tmpSp) || (count == maxDepth) || !IsValidRa(backRa)) { + break; + } + } + + return count; +} + +VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP) +{ + UINTPTR reglr; + if (LR == NULL) { + return; + } + + if (SP == 0) { + __asm__ __volatile__("mov %0, sp" : "=a"(SP) : :); + __asm__ __volatile__("mov %0, a0" : "=a"(reglr) : :); + } else { + reglr = *(UINT32 *)(SP - OS_REG_LR_OFFSET); + } + HakSpillWindow(); + HalBackTraceGet(SP, reglr, LR, LRSize, jumpCount); +} +#elif (LOSCFG_BACKTRACE_TYPE == 5) +#define OS_BACKTRACE_START 0 + +UINT32 IsAligned(UINT32 val, UINT32 align) +{ + return ((val & (align - 1)) == 0); +} + +STATIC INLINE UINTPTR OsSpGet(VOID) +{ + UINTPTR regSp; + + __asm__ __volatile__("mov %0, sp" : "=r"(regSp)); + + return regSp; +} + +/* This function is used to check sp. */ +BOOL IsValidSP(UINTPTR regSP, UINTPTR start, UINTPTR end) +{ + return (regSP > start) && (regSP < end); +} + +STATIC INLINE BOOL FindSuitableStack(UINTPTR *regSP, UINTPTR *start, UINTPTR *end) +{ + UINT32 index; + UINT32 topOfStack; + UINT32 stackBottom; + BOOL found = FALSE; + LosTaskCB *taskCB = NULL; + + /* Search in the task stacks */ + for (index = 0; index < g_taskMaxNum; index++) { + taskCB = &g_taskCBArray[index]; + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + topOfStack = taskCB->topOfStack; + stackBottom = taskCB->topOfStack + taskCB->stackSize; + + if (IsValidSP(*regSP, topOfStack, stackBottom)) { + found = TRUE; + goto FOUND; + } + } + +FOUND: + if (found == TRUE) { + *start = topOfStack; + *end = stackBottom; + } else if (*regSP < CSTACK_END_ADDR) { + *start = *regSP; + *end = CSTACK_END_ADDR; + found = TRUE; + } + + return found; +} + +VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP) +{ + UINTPTR stackPointer = SP; + UINTPTR topOfStack; + UINTPTR tmpStack = 0; + UINTPTR stackBottom; + UINTPTR checkBL; + UINT32 count = 0; + UINT32 index = 0; + + if (LR == NULL) { + return; + } + + if (SP == 0) { + SP = OsSpGet(); + } + + if (FindSuitableStack(&stackPointer, &topOfStack, &stackBottom) == FALSE) { + return; + } + + while ((stackPointer < stackBottom) && (count < LRSize)) { + if (IsValidSP(*(UINT32 *)stackPointer, topOfStack, stackBottom) + && OsStackDataIsCodeAddr(*(UINT32 *)(stackPointer + STACK_OFFSET)) + && IsAligned(*(UINT32 *)stackPointer, ALGIN_CODE)) { + if (tmpStack == *(UINT32 *)stackPointer) { + break; + } + tmpStack = *(UINT32 *)stackPointer; + checkBL = *(UINT32 *)(stackPointer + STACK_OFFSET); + if (count++ < jumpCount) { + continue; + } + stackPointer = tmpStack; + LR[index++] = checkBL; + continue; + } + stackPointer += STACK_OFFSET; + } + + if (index < LRSize) { + LR[index] = 0; + } +} #else #error Unknown backtrace type. #endif @@ -424,4 +660,3 @@ VOID OSBackTraceInit(VOID) } #endif - diff --git a/components/backtrace/los_backtrace.h b/components/backtrace/los_backtrace.h index 8cdde9d5..fabeb2db 100644 --- a/components/backtrace/los_backtrace.h +++ b/components/backtrace/los_backtrace.h @@ -138,6 +138,51 @@ extern CHAR *CSTACK_SECTION_END; #else #error Unknown compiler. #endif +#elif (LOSCFG_BACKTRACE_TYPE == 4) +/* The default code section start address */ +#define CODE_SECTION_START __text_start +/* The default code section end address */ +#define CODE_SECTION_END __text_end +/* The default C stack section start address */ +#define CSTACK_SECTION_START __init_stack_s +/* The default C stack section end address */ +#define CSTACK_SECTION_END __init_stack_e + +extern CHAR *CODE_SECTION_START; +extern CHAR *CODE_SECTION_END; +extern CHAR *CSTACK_SECTION_START; +extern CHAR *CSTACK_SECTION_END; + +#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) +#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) +#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START) +#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) + +#define VIR_TEXT_ADDR_MASK 0x80000000 +#define TEXT_ADDR_MASK 0x40000000 +#define RA_OFFSET 16 +#define SP_OFFSET 12 +#define WINDOW_INCREMENT_SHIFT 2 + +UINT32 HalBackTraceGet(UINTPTR sp, UINT32 retAddr, UINTPTR *callChain, UINT32 maxDepth, UINT32 jumpCount); +#elif (LOSCFG_BACKTRACE_TYPE == 5) +/* The default code section start address */ +#define CODE_SECTION_START __text_start +/* The default code section end address */ +#define CODE_SECTION_END __text_end +/* The default C stack section end address */ +#define CSTACK_SECTION_END __ram_end + +extern CHAR *CODE_SECTION_START; +extern CHAR *CODE_SECTION_END; +extern CHAR *CSTACK_SECTION_END; + +#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) +#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) +#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) + +#define ALGIN_CODE 2 +#define STACK_OFFSET 4 #endif /* This function is currently used to register the memory leak check hook, diff --git a/kernel/BUILD.gn b/kernel/BUILD.gn index 043adac4..edfde289 100644 --- a/kernel/BUILD.gn +++ b/kernel/BUILD.gn @@ -69,9 +69,13 @@ static_library("kernel") { } else { deps = [ "arch/arm/cortex-m33/gcc/NTZ:arch" ] } + } else if ("$board_cpu" == "ck802") { + deps = [ "arch/csky/v2/gcc:arch" ] } else if ("$board_cpu" == "") { if ("$board_arch" == "rv32imac" || "$board_arch" == "rv32imafdc") { deps = [ "arch/risc-v/riscv32/gcc:arch" ] + } else if ("$board" == "esp32") { + deps = [ "arch/xtensa/lx6/gcc:arch" ] } } } diff --git a/kernel/arch/csky/v2/gcc/BUILD.gn b/kernel/arch/csky/v2/gcc/BUILD.gn new file mode 100644 index 00000000..97e5000c --- /dev/null +++ b/kernel/arch/csky/v2/gcc/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 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. + +static_library("arch") { + sources = [ + "los_context.c", + "los_dispatch.S", + "los_exc.S", + "los_interrupt.c", + "los_timer.c", + ] + + include_dirs = [ + ".", + "../../../../../kernel/arch/include", + "../../../../../kernel/include", + "../../../../../utils", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/kernel/arch/csky/v2/gcc/los_arch_atomic.h b/kernel/arch/csky/v2/gcc/los_arch_atomic.h new file mode 100644 index 00000000..b86b038d --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_arch_atomic.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_ATOMIC_H +#define _LOS_ARCH_ATOMIC_H + +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_arch_atomic + * @brief Atomic exchange for 32-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit 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 + */ +STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) +{ + INT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + prevVal = *v; + *v = val; + LOS_IntRestore(intSave); + + return prevVal; +} + +/** + * @ingroup los_arch_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implement 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 + */ +STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) +{ + INT32 val; + UINT32 intSave; + + intSave = LOS_IntLock(); + *v -= 1; + val = *v; + LOS_IntRestore(intSave); + + return val; +} + +/** + * @ingroup los_arch_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 + */ +STATIC INLINE BOOL HalAtomicCmpXchg32bits(volatile INT32 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + prevVal = *v; + if (prevVal == oldVal) { + *v = val; + } + LOS_IntRestore(intSave); + + return prevVal != oldVal; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_ATOMIC_H */ + diff --git a/kernel/arch/csky/v2/gcc/los_arch_context.h b/kernel/arch/csky/v2/gcc/los_arch_context.h new file mode 100644 index 00000000..ce72465d --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_arch_context.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_TRAP_STACK_SIZE 500 + +typedef struct TagTskContext { + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + UINT32 R12; + UINT32 R13; + UINT32 R15; + UINT32 EPSR; + UINT32 EPC; +} TaskContext; + +VOID HalStartToRun(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_CONTEXT_H */ diff --git a/kernel/arch/csky/v2/gcc/los_arch_interrupt.h b/kernel/arch/csky/v2/gcc/los_arch_interrupt.h new file mode 100644 index 00000000..67f47863 --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_arch_interrupt.h @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_INTERRUPT_H +#define _LOS_ARCH_INTERRUPT_H + +#include "los_config.h" +#include "los_compiler.h" +#include "los_interrupt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* * + * @ingroup los_arch_interrupt + * Maximum number of used hardware interrupts. + */ +#ifndef OS_HWI_MAX_NUM +#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT +#endif + +/* * + * @ingroup los_arch_interrupt + * Highest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_HIGHEST +#define OS_HWI_PRIO_HIGHEST 0 +#endif + +/* * + * @ingroup los_arch_interrupt + * Lowest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_LOWEST +#define OS_HWI_PRIO_LOWEST 3 +#endif + +/* * + * @ingroup los_arch_interrupt + * Check the interrupt priority. + */ +#define HWI_PRI_VALID(pri) (((pri) >= OS_HWI_PRIO_HIGHEST) && ((pri) <= OS_HWI_PRIO_LOWEST)) + +/* * + * @ingroup los_arch_interrupt + * Define the type of a hardware interrupt vector table function. + */ +typedef VOID (**HWI_VECTOR_FUNC)(VOID); + +/* * + * @ingroup los_arch_interrupt + * Count of interrupts. + */ +extern UINT32 g_intCount; + +/* * + * @ingroup los_arch_interrupt + * Count of C-sky system interrupt vector. + */ +#define OS_SYS_VECTOR_CNT 32 + +/* * + * @ingroup los_arch_interrupt + * Count of C-sky interrupt vector. + */ +#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) + +#define PSR_VEC_OFFSET 16U +#define VIC_REG_BASE 0xE000E100UL + +typedef struct { + UINT32 ISER[4U]; + UINT32 RESERVED0[12U]; + UINT32 IWER[4U]; + UINT32 RESERVED1[12U]; + UINT32 ICER[4U]; + UINT32 RESERVED2[12U]; + UINT32 IWDR[4U]; + UINT32 RESERVED3[12U]; + UINT32 ISPR[4U]; + UINT32 RESERVED4[12U]; + UINT32 ISSR[4U]; + UINT32 RESERVED5[12U]; + UINT32 ICPR[4U]; + UINT32 RESERVED6[12U]; + UINT32 ICSR[4U]; + UINT32 RESERVED7[12U]; + UINT32 IABR[4U]; + UINT32 RESERVED8[60U]; + UINT32 IPR[32U]; + UINT32 RESERVED9[480U]; + UINT32 ISR; + UINT32 IPTR; + UINT32 TSPEND; + UINT32 TSABR; + UINT32 TSPR; +} VIC_TYPE; + +extern VIC_TYPE *VIC_REG; +/* * + * @ingroup los_arch_interrupt + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. + */ +#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) + +/* * + * @ingroup los_arch_interrupt + * 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_arch_interrupt + * 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_arch_interrupt + * 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_arch_interrupt + * 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_arch_interrupt + * Hardware interrupt error code: Invalid interrupt priority. + * + * Value: 0x02000905 + * + * Solution: Ensure that the interrupt priority is valid. + */ +#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) + +/* * + * @ingroup los_arch_interrupt + * 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. + */ +#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) + +/* * + * @ingroup los_arch_interrupt + * 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_arch_interrupt + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. + */ +#define LOS_ERRNO_HWI_NUM_INVALID OS_ERRNO_HWI_NUM_INVALID + +#if (OS_HWI_WITH_ARG == 1) +/* * + * @ingroup los_arch_interrupt + * Set interrupt vector table. + */ +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); +#else +/* * + * @ingroup los_arch_interrupt + * Set interrupt vector table. + */ +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); +#endif + +/* * + * @ingroup los_arch_interrupt + * @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_arch_interrupt + * @brief: Get an 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_arch_interrupt + * @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); + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +#define OS_VIC_INT_ENABLE_SIZE 0x4 +#define OS_VIC_INT_WAKER_SIZE 0x4 +#define OS_VIC_INT_ICER_SIZE 0x4 +#define OS_VIC_INT_ISPR_SIZE 0x4 +#define OS_VIC_INT_IABR_SIZE 0x4 +#define OS_VIC_INT_IPR_SIZE 0x4 +#define OS_VIC_INT_ISR_SIZE 0x4 +#define OS_VIC_INT_IPTR_SIZE 0x4 + +#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 + +#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB + +/** + * @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 { + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + UINT32 R12; + UINT32 R13; + UINT32 R14; + UINT32 R15; + UINT32 EPSR; + UINT32 EPC; +} EXC_CONTEXT_S; + +/* * + * @ingroup los_arch_interrupt + * @brief: Exception handler function. + * + * @par Description: + * This API is used to handle Exception. + * + * @attention: + * + * + * @param excBufAddr [IN] The address of stack pointer at which the error occurred. + * @param faultAddr [IN] The address at which the error occurred. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(EXC_CONTEXT_S *excBufAddr, UINT32 faultAddr); + +VOID IrqEntry(VOID); + +VOID HandleEntry(VOID); + +VOID HalHwiInit(VOID); + +/** + * @ingroup los_exc + * Exception information structure + * + * Description: Exception information saved when an exception is triggered on the Csky platform. + * + */ +typedef struct TagExcInfo { + UINT16 phase; + UINT16 type; + UINT32 faultAddr; + UINT32 thrdPid; + UINT16 nestCnt; + UINT16 reserved; + EXC_CONTEXT_S *context; +} ExcInfo; + +extern ExcInfo g_excInfo; + +#define MAX_INT_INFO_SIZE (8 + 0x164) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_INTERRUPT_H */ diff --git a/kernel/arch/csky/v2/gcc/los_arch_timer.h b/kernel/arch/csky/v2/gcc/los_arch_timer.h new file mode 100644 index 00000000..97ec28d1 --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_arch_timer.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 /* __cplusplus */ +#endif /* __cplusplus */ + +UINT32 HalTickStart(OS_TICK_HANDLER handler); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_TIMER_H */ diff --git a/kernel/arch/csky/v2/gcc/los_context.c b/kernel/arch/csky/v2/gcc/los_context.c new file mode 100644 index 00000000..7bbd75ad --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_context.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_context.h" +#include "securec.h" +#include "los_arch_context.h" +#include "los_arch_interrupt.h" +#include "los_task.h" +#include "los_sched.h" +#include "los_interrupt.h" +#include "los_arch_timer.h" +#include "los_debug.h" + +STATIC UINT32 g_sysNeedSched = FALSE; + +/* **************************************************************************** + Function : HalArchInit + Description : arch init function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalArchInit(VOID) +{ + UINT32 ret; + HalHwiInit(); + + ret = HalTickStart(OsTickHandler); + if (ret != LOS_OK) { + PRINT_ERR("Tick start failed!\n"); + } +} + +/* **************************************************************************** + Function : HalSysExit + Description : Task exit function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) +{ + LOS_IntLock(); + while (1) { + } +} + +/* **************************************************************************** + 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)); + + context->R0 = taskID; + context->R1 = 0x01010101L; + context->R2 = 0x02020202L; + context->R3 = 0x03030303L; + context->R4 = 0x04040404L; + context->R5 = 0x05050505L; + context->R6 = 0x06060606L; + context->R7 = 0x07070707L; + context->R8 = 0x08080808L; + context->R9 = 0x09090909L; + context->R10 = 0x10101010L; + context->R11 = 0x11111111L; + context->R12 = 0x12121212L; + context->R13 = 0x13131313L; + context->R15 = (UINT32)HalSysExit; + context->EPSR = 0xe0000144L; + context->EPC = (UINT32)OsTaskEntry; + return (VOID *)context; +} + +LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(VOID) +{ + (VOID)LOS_IntLock(); + OsSchedStart(); + HalStartToRun(); + return LOS_OK; /* never return */ +} + +VOID HalIrqEndCheckNeedSched(VOID) +{ + if (g_sysNeedSched && g_taskScheduled && LOS_CHECK_SCHEDULE) { + HalTaskSchedule(); + } +} + +VOID HalTaskSchedule(VOID) +{ + UINT32 intSave; + + if (OS_INT_ACTIVE) { + g_sysNeedSched = TRUE; + return; + } + + intSave = LOS_IntLock(); + g_sysNeedSched = FALSE; + BOOL isSwitch = OsSchedTaskSwitch(); + if (isSwitch) { + HalTaskContextSwitch(); + return; + } + LOS_IntRestore(intSave); + return; +} diff --git a/kernel/arch/csky/v2/gcc/los_dispatch.S b/kernel/arch/csky/v2/gcc/los_dispatch.S new file mode 100644 index 00000000..3ce7bb07 --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_dispatch.S @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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. + */ + +#define OS_TASK_STATUS_RUNNING 0x0010 +#define VIC_TSPDR 0XE000EC08 + +.section .text +.align 2 +.type HalStartToRun, %function +.global HalStartToRun +HalStartToRun: + lrw r1, g_losTask + lrw r2, g_losTask + 4 + + ldw r0, (r2) + + st.w r0, (r1) + st.w r0, (r2) + + ldw sp, (r0) + + ldw r0, (sp, 64) + mtcr r0, epc + ldw r0, (sp, 60) + mtcr r0, epsr + ldw r15, (sp, 56) + ldm r0-r13, (sp) + + rte + +.align 2 +.type HalTaskContextSwitch, %function +.global HalTaskContextSwitch +HalTaskContextSwitch: + + subi sp, 68 + stm r0-r13, (sp) + stw r15, (sp, 56) + mfcr r1, psr + stw r1, (sp, 60) + stw r15, (sp, 64) + lrw r2, g_losTask + ldw r0, (r2) + stw sp, (r0) + + lrw r3, g_losTask + 4 + ldw r0, (r3) + stw r0, (r2) + + ldw sp, (r0) + ldw r0, (sp, 64) + mtcr r0, epc + ldw r0, (sp, 60) + mtcr r0, epsr + ldw r15, (sp, 56) + ldm r0-r13, (sp) + + addi sp, 68 + + rte + diff --git a/kernel/arch/csky/v2/gcc/los_exc.S b/kernel/arch/csky/v2/gcc/los_exc.S new file mode 100644 index 00000000..7a59c1f6 --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_exc.S @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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. + */ + +.import HalExcHandleEntry +.extern g_trapStackBase + +.section .text +.align 2 +.global HandleEntry +HandleEntry: + mov r10, sp + lrw r14, g_trapStackBase + + stm r0-r15, (sp) + stw r10, (sp, 56) + mfcr r0, epsr + stw r0, (sp, 64) + mfcr r0, epc + stw r0, (sp, 68) + mov r0, sp + + mfcr r1, epc + + mov sp, r10 + lrw r2, HalExcHandleEntry + jmp r2 + diff --git a/kernel/arch/csky/v2/gcc/los_interrupt.c b/kernel/arch/csky/v2/gcc/los_interrupt.c new file mode 100644 index 00000000..d0128c02 --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_interrupt.c @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 +#include "securec.h" +#include "los_context.h" +#include "los_arch_context.h" +#include "los_arch_interrupt.h" +#include "los_debug.h" +#include "los_hook.h" +#include "los_task.h" +#include "los_sched.h" +#include "los_memory.h" +#include "los_membox.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define INT_OFFSET 6 +#define PRI_OFF_PER_INT 8 +#define PRI_PER_REG 4 +#define PRI_OFF_IN_REG 6 +#define PRI_BITS 2 +#define PRI_HI 0 +#define PRI_LOW 7 +#define MASK_8_BITS 0xFF +#define MASK_32_BITS 0xFFFFFFFF +#define BYTES_OF_128_INT 4 +#define TIM_INT_NUM 1 + +#define OS_USER_HWI_MIN 0 +#define OS_USER_HWI_MAX (LOSCFG_PLATFORM_HWI_LIMIT - 1) + +UINT32 g_intCount = 0; +CHAR g_trapStackBase[OS_TRAP_STACK_SIZE]; + +VIC_TYPE *VIC_REG = (VIC_TYPE *)VIC_REG_BASE; + +UINT32 HwiNumValid(UINT32 num) +{ + return ((num) >= OS_USER_HWI_MIN) && ((num) <= OS_USER_HWI_MAX); +} + +UINT32 HalGetPsr(VOID) +{ + UINT32 intSave; + __asm__ volatile("mfcr %0, psr" : "=r" (intSave) : : "memory"); + return intSave; +} + +UINT32 HalSetVbr(UINT32 intSave) +{ + __asm__ volatile("mtcr %0, vbr" : : "r"(intSave) : "memory"); + return intSave; +} + +UINT32 HalIntLock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mfcr %0, psr \n" + "psrclr ie" + : "=r"(intSave) + : + : "memory"); + return intSave; +} + +UINT32 HalIntUnlock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mfcr %0, psr \n" + "psrset ie" + : "=r"(intSave) + : + : "memory"); + return intSave; +} + +VOID HalIntRestore(UINT32 intSave) +{ + __asm__ __volatile__("mtcr %0, psr" : : "r"(intSave)); +} + +UINT32 HalIntLocked(VOID) +{ + UINT32 intSave; + __asm__ volatile("mfcr %0, psr" : "=r" (intSave) : : "memory"); + return !(intSave & (1 << INT_OFFSET)); +} + +UINT32 HalIrqUnmask(UINT32 hwiNum) +{ + UINT32 intSave; + if (!HwiNumValid(hwiNum)) { + return LOS_ERRNO_HWI_NUM_INVALID; + } + intSave = LOS_IntLock(); + VIC_REG->ISER[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT)); + VIC_REG->ISSR[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT)); + LOS_IntRestore(intSave); + return LOS_OK; +} + +UINT32 HalIrqSetPriority(UINT32 hwiNum, UINT8 priority) +{ + UINT32 intSave; + if (!HwiNumValid(hwiNum)) { + return LOS_ERRNO_HWI_NUM_INVALID; + } + if (!HWI_PRI_VALID(priority)) { + return OS_ERRNO_HWI_PRIO_INVALID; + } + intSave = LOS_IntLock(); + VIC_REG->IPR[hwiNum / PRI_PER_REG] |= (((priority << PRI_OFF_IN_REG) << (hwiNum % PRI_PER_REG)) * PRI_OFF_PER_INT); + LOS_IntRestore(intSave); + return LOS_OK; +} + +UINT32 HalIrqMask(HWI_HANDLE_T hwiNum) +{ + UINT32 intSave; + if (!HwiNumValid(hwiNum)) { + return LOS_ERRNO_HWI_NUM_INVALID; + } + intSave = LOS_IntLock(); + VIC_REG->ICER[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT)); + LOS_IntRestore(intSave); + return LOS_OK; +} + +UINT32 HalIrqPending(UINT32 hwiNum) +{ + UINT32 intSave; + if (!HwiNumValid(hwiNum)) { + return LOS_ERRNO_HWI_NUM_INVALID; + } + intSave = LOS_IntLock(); + VIC_REG->ISPR[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT)); + LOS_IntRestore(intSave); + return LOS_OK; +} + +UINT32 HalIrqClear(UINT32 hwiNum) +{ + if (!HwiNumValid(hwiNum)) { + return LOS_ERRNO_HWI_NUM_INVALID; + } + VIC_REG->ICPR[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT)); + return LOS_OK; +} + +/* * + * @ingroup los_hwi + * Hardware interrupt form mapping handling function array. + */ +STATIC HWI_PROC_FUNC __attribute__((aligned(0x100))) g_hwiForm[OS_VECTOR_CNT] = {0}; + +#if (OS_HWI_WITH_ARG == 1) + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * Hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)IrqEntry; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + HalIrqUnmask(num); + } +} + +#else +/* * + * @ingroup los_hwi + * Hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = IrqEntry; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + HalIrqUnmask(num); + } +} +#endif + +/* **************************************************************************** + Function : HalIntNumGet + Description : Get an interrupt number + Input : None + Output : None + Return : Interrupt Indexes number + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 HalIntNumGet(VOID) +{ + return HalGetPsr(); +} + +inline UINT32 HalIsIntActive(VOID) +{ + return (g_intCount > 0); +} + +/* **************************************************************************** + Function : HalHwiDefaultHandler + Description : default handler of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) +{ + UINT32 irqNum = HalIntNumGet(); + irqNum = (irqNum >> PSR_VEC_OFFSET) & MASK_8_BITS; + PRINT_ERR("%s irqnum:%x\n", __FUNCTION__, irqNum); + while (1) {} +} + +WEAK VOID HalPreInterruptHandler(UINT32 arg) +{ + return; +} + +WEAK VOID HalAftInterruptHandler(UINT32 arg) +{ + return; +} + +/* **************************************************************************** + Function : HalInterrupt + Description : Hardware interrupt entry function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) +{ + UINT32 hwiIndex; + UINT32 intSave; + + intSave = LOS_IntLock(); + g_intCount = TRUE; + LOS_IntRestore(intSave); + + hwiIndex = HalIntNumGet(); + hwiIndex = (hwiIndex >> PSR_VEC_OFFSET) & MASK_8_BITS; + OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex); + + HalPreInterruptHandler(hwiIndex); +#if (OS_HWI_WITH_ARG == 1) + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); + } +#else + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); + } +#endif + + HalAftInterruptHandler(hwiIndex); + + OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, hwiIndex); + + intSave = LOS_IntLock(); + g_intCount = FALSE; + HalIrqEndCheckNeedSched(); + 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) +{ + UINT32 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_hwiHandlerForm[hwiNum + OS_SYS_VECTOR_CNT] != 0) { + return OS_ERRNO_HWI_ALREADY_CREATED; + } + if (g_hwiHandlerForm[hwiNum + OS_SYS_VECTOR_CNT] != 0) { + 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 + HalIrqUnmask(hwiNum); + (VOID)HalIrqSetPriority(hwiNum, (UINT8)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; + } + HalIrqMask(hwiNum); + intSave = LOS_IntLock(); + g_hwiHandlerForm[hwiNum + OS_SYS_VECTOR_CNT] = 0; + LOS_IntRestore(intSave); + + return LOS_OK; +} + +ExcInfo g_excInfo = {0}; + +#if (LOSCFG_KERNEL_PRINTF != 0) +STATIC VOID OsExcTypeInfo(const ExcInfo *excInfo) +{ + CHAR *phaseStr[] = {"exc in init", "exc in task", "exc in hwi"}; + + PRINTK("Type = %d\n", excInfo->type); + PRINTK("ThrdPid = %d\n", excInfo->thrdPid); + PRINTK("Phase = %s\n", phaseStr[excInfo->phase]); + PRINTK("FaultAddr = 0x%x\n", excInfo->faultAddr); +} + +STATIC VOID OsExcCurTaskInfo(const ExcInfo *excInfo) +{ + PRINTK("Current task info:\n"); + if (excInfo->phase == OS_EXC_IN_TASK) { + LosTaskCB *taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet()); + PRINTK("Task name = %s\n", taskCB->taskName); + PRINTK("Task ID = %d\n", taskCB->taskID); + PRINTK("Task SP = 0x%x\n", (UINTPTR)taskCB->stackPointer); + PRINTK("Task ST = 0x%x\n", taskCB->topOfStack); + PRINTK("Task SS = 0x%x\n", taskCB->stackSize); + } else if (excInfo->phase == OS_EXC_IN_HWI) { + PRINTK("Exception occur in interrupt phase!\n"); + } else { + PRINTK("Exception occur in system init phase!\n"); + } +} + +STATIC VOID OsExcRegInfo(const ExcInfo *excInfo) +{ + EXC_CONTEXT_S *excContext = excInfo->context; + PRINTK("Exception reg dump:\n"); + PRINTK("R0 = 0x%x\n" + "R1 = 0x%x\n" + "R2 = 0x%x\n" + "R3 = 0x%x\n" + "R4 = 0x%x\n" + "R5 = 0x%x\n" + "R6 = 0x%x\n" + "R7 = 0x%x\n" + "R8 = 0x%x\n" + "R9 = 0x%x\n" + "R10 = 0x%x\n" + "R11 = 0x%x\n" + "R12 = 0x%x\n" + "R13 = 0x%x\n" + "R14 = 0x%x\n" + "R15 = 0x%x\n" + "EPSR = 0x%x\n" + "EPC = 0x%x\n", + excContext->R0, excContext->R1, excContext->R2, excContext->R3, excContext->R4, excContext->R5, + excContext->R6, excContext->R7, excContext->R8, excContext->R9, excContext->R10, excContext->R11, + excContext->R12, excContext->R13, excContext->R14, excContext->R15, excContext->EPSR, + excContext->EPC); +} + +STATIC VOID OsExcBackTraceInfo(const ExcInfo *excInfo) +{ + UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = {0}; + UINT32 index; + + OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, excInfo->context->R14); + + PRINTK("----- backtrace start -----\n"); + for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) { + if (LR[index] == 0) { + break; + } + PRINTK("backtrace %d -- lr = 0x%x\n", index, LR[index]); + } + PRINTK("----- backtrace end -----\n"); +} + +STATIC VOID OsExcMemPoolCheckInfo(VOID) +{ + PRINTK("\r\nmemory pools check:\n"); +#if (LOSCFG_PLATFORM_EXC == 1) + MemInfoCB memExcInfo[OS_SYS_MEM_NUM]; + UINT32 errCnt; + UINT32 i; + + (VOID)memset_s(memExcInfo, sizeof(memExcInfo), 0, sizeof(memExcInfo)); + + errCnt = OsMemExcInfoGet(OS_SYS_MEM_NUM, memExcInfo); + if (errCnt < OS_SYS_MEM_NUM) { + errCnt += OsMemboxExcInfoGet(OS_SYS_MEM_NUM - errCnt, memExcInfo + errCnt); + } + + if (errCnt == 0) { + PRINTK("all memory pool check passed!\n"); + return; + } + + for (i = 0; i < errCnt; i++) { + PRINTK("pool num = %d\n", i); + PRINTK("pool type = %d\n", memExcInfo[i].type); + PRINTK("pool addr = 0x%x\n", memExcInfo[i].startAddr); + PRINTK("pool size = 0x%x\n", memExcInfo[i].size); + PRINTK("pool free = 0x%x\n", memExcInfo[i].free); + PRINTK("pool blkNum = %d\n", memExcInfo[i].blockSize); + PRINTK("pool error node addr = 0x%x\n", memExcInfo[i].errorAddr); + PRINTK("pool error node len = 0x%x\n", memExcInfo[i].errorLen); + PRINTK("pool error node owner = %d\n", memExcInfo[i].errorOwner); + } +#endif + UINT32 ret = LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR); + if (ret == LOS_OK) { + PRINTK("system heap memcheck over, all passed!\n"); + } + + PRINTK("memory pool check end!\n"); +} +#endif + +STATIC VOID OsExcInfoDisplay(const ExcInfo *excInfo) +{ +#if (LOSCFG_KERNEL_PRINTF != 0) + PRINTK("*************Exception Information**************\n"); + OsExcTypeInfo(excInfo); + OsExcCurTaskInfo(excInfo); + OsExcRegInfo(excInfo); + OsExcBackTraceInfo(excInfo); + OsGetAllTskInfo(); + OsExcMemPoolCheckInfo(); +#endif +} + +LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(EXC_CONTEXT_S *excBufAddr, UINT32 faultAddr) +{ + UINT16 tmpFlag = ((excBufAddr->EPSR >> PSR_VEC_OFFSET) & MASK_8_BITS); + g_excInfo.nestCnt++; + UINT32 excType = (HalGetPsr() >> PSR_VEC_OFFSET) & MASK_8_BITS; + g_excInfo.type = excType; + + g_excInfo.faultAddr = faultAddr; + + if (g_losTask.runTask != NULL) { + if (tmpFlag >= 0) { + g_excInfo.phase = OS_EXC_IN_HWI; + g_excInfo.thrdPid = tmpFlag; + } 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; + } + g_excInfo.context = excBufAddr; + + OsDoExcHook(EXC_INTERRUPT); + OsExcInfoDisplay(&g_excInfo); + HalSysExit(); +} + +/* stack protector */ +WEAK UINT32 __stack_chk_guard = 0xd00a0dff; + +WEAK VOID __stack_chk_fail(VOID) +{ + /* __builtin_return_address is a builtin function, building in gcc */ + LOS_Panic("stack-protector: Kernel stack is corrupted in: %x\n", + __builtin_return_address(0)); +} + +/* **************************************************************************** + Function : HalHwiInit + Description : initialization of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalHwiInit(VOID) +{ + UINT32 i; + + for (i = 1; i < OS_SYS_VECTOR_CNT; i++) { + g_hwiForm[i] = (HWI_PROC_FUNC)HandleEntry; + } + + for (i = OS_SYS_VECTOR_CNT; i < (LOSCFG_PLATFORM_HWI_LIMIT + OS_SYS_VECTOR_CNT); i++) { + g_hwiForm[i] = (HWI_PROC_FUNC)IrqEntry; + } + + HalSetVbr((UINT32)&g_hwiForm); + for (int i = 0; i < BYTES_OF_128_INT; i++) { + VIC_REG->IABR[i] = 0x0; + VIC_REG->ICPR[i] = MASK_32_BITS; + } + return; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/arch/csky/v2/gcc/los_timer.c b/kernel/arch/csky/v2/gcc/los_timer.c new file mode 100644 index 00000000..c38de171 --- /dev/null +++ b/kernel/arch/csky/v2/gcc/los_timer.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_timer.h" +#include "los_config.h" +#include "los_tick.h" +#include "los_arch_interrupt.h" +#include "los_context.h" +#include "los_sched.h" +#include "los_debug.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + UINT32 CTRL; + UINT32 LOAD; + UINT32 VAL; + UINT32 CALIB; +} CORE_TIM_TYPE; + +#define OS_CYCLE_PER_TICK (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +#define CORE_TIM_BASE (0xE000E010UL) +#define SysTick ((CORE_TIM_TYPE *)CORE_TIM_BASE) + +#define CORETIM_ENABLE (1UL << 0) +#define CORETIM_INTMASK (1UL << 1) +#define CORETIM_SOURCE (1UL << 2) +#define CORETIM_MODE (1UL << 16) + +#define TIM_INT_NUM 1 + +/* **************************************************************************** +Function : HalTickStart +Description : Configure Tick Interrupt Start +Input : none +output : none +return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed +**************************************************************************** */ +WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) +{ + 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; + } + + g_sysClock = OS_SYS_CLOCK; + g_cyclesPerTick = OS_CYCLE_PER_TICK; + SysTick->LOAD = (OS_CYCLE_PER_TICK - 1); + SysTick->VAL = 0; + SysTick->CTRL |= (CORETIM_SOURCE | CORETIM_ENABLE | CORETIM_INTMASK); + + VIC_REG->IWER[0] = 0x1 << TIM_INT_NUM; + +#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) +#if (OS_HWI_WITH_ARG == 1) + OsSetVector(TIM_INT_NUM, (HWI_PROC_FUNC)handler, NULL); +#else + OsSetVector(TIM_INT_NUM, (HWI_PROC_FUNC)handler); +#endif +#endif + return LOS_OK; +} + +WEAK VOID HalSysTickReload(UINT64 nextResponseTime) +{ + SysTick->CTRL &= ~CORETIM_ENABLE; + SysTick->LOAD = (UINT32)(nextResponseTime - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL |= CORETIM_ENABLE; +} + +WEAK UINT64 HalGetTickCycle(UINT32 *period) +{ + UINT32 hwCycle; + UINT32 intSave = LOS_IntLock(); + *period = SysTick->LOAD; + hwCycle = *period - SysTick->VAL; + LOS_IntRestore(intSave); + return (UINT64)hwCycle; +} + +WEAK VOID HalTickLock(VOID) +{ + SysTick->CTRL &= ~CORETIM_ENABLE; +} + +WEAK VOID HalTickUnlock(VOID) +{ + SysTick->CTRL |= CORETIM_ENABLE; +} + +VOID Wfi(VOID) +{ + __asm__ volatile("wait"); +} + +VOID Dsb(VOID) +{ + __asm__ volatile("sync" : : : "memory"); +} + +UINT32 HalEnterSleep(VOID) +{ + Dsb(); + Wfi(); + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/arch/xtensa/lx6/gcc/BUILD.gn b/kernel/arch/xtensa/lx6/gcc/BUILD.gn new file mode 100644 index 00000000..a2bfb9b5 --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021 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. + +static_library("arch") { + sources = [ + "los_context.c", + "los_dispatch.S", + "los_exc.S", + "los_interrupt.c", + "los_timer.c", + "los_window.S", + ] + + include_dirs = [ + ".", + "../../../../../kernel/arch/include", + "../../../../../kernel/include", + "../../../../../utils", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/kernel/arch/xtensa/lx6/gcc/los_arch_atomic.h b/kernel/arch/xtensa/lx6/gcc/los_arch_atomic.h new file mode 100644 index 00000000..e2e51143 --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_arch_atomic.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_ATOMIC_H +#define _LOS_ARCH_ATOMIC_H + +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_arch_atomic + * @brief Atomic exchange for 32-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit 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 + */ +STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) +{ + UINT32 intSave; + INT32 prevVal; + + intSave = LOS_IntLock(); + prevVal = *v; + *v = val; + LOS_IntRestore(intSave); + + return prevVal; +} + +/** + * @ingroup los_arch_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implement 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 + */ +STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) +{ + UINT32 intSave; + + intSave = LOS_IntLock(); + *v -= 1; + LOS_IntRestore(intSave); + + return intSave; +} + +/** + * @ingroup los_arch_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 + */ +STATIC INLINE BOOL HalAtomicCmpXchg32bits(volatile INT32 *v, INT32 val, INT32 oldVal) +{ + UINT32 intSave; + INT32 prevVal; + + intSave = LOS_IntLock(); + prevVal = *v; + if (prevVal == oldVal) { + *v = val; + } + LOS_IntRestore(intSave); + + return (prevVal != oldVal); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_ATOMIC_H */ diff --git a/kernel/arch/xtensa/lx6/gcc/los_arch_context.h b/kernel/arch/xtensa/lx6/gcc/los_arch_context.h new file mode 100644 index 00000000..c6814594 --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_arch_context.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define LOSCFG_STACK_POINT_ALIGN_SIZE 16 +#define SAVED_REG_NUM 8 +#define SPILL_WINDOW_SIZE 8 + +typedef struct { + UINT32 pc; + UINT32 ps; + UINT32 regA[16]; + UINT32 sar; + UINT32 excCause; + UINT32 excVaddr; + UINT32 lbeg; + UINT32 lend; + UINT32 lcount; + UINT32 temp[4]; + UINT32 res[8]; +} TaskContext; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_CONTEXT_H */ diff --git a/kernel/arch/xtensa/lx6/gcc/los_arch_interrupt.h b/kernel/arch/xtensa/lx6/gcc/los_arch_interrupt.h new file mode 100644 index 00000000..fb7f50be --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_arch_interrupt.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_INTERRUPT_H +#define _LOS_ARCH_INTERRUPT_H + +#include "los_config.h" +#include "los_compiler.h" +#include "los_interrupt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + UINT32 pc; + UINT32 ps; + UINT32 regA[16]; + UINT32 sar; + UINT32 excCause; + UINT32 excVaddr; + UINT32 lbeg; + UINT32 lend; + UINT32 lcount; + UINT32 temp[4]; + UINT32 res[8]; +} EXC_CONTEXT_S; + +#define VECTOR_START _init_start +extern CHAR *VECTOR_START; +#define INIT_VECTOR_START ((UINTPTR)&VECTOR_START) + +/* * + * @ingroup los_arch_interrupt + * Maximum number of used hardware interrupts. + */ +#ifndef OS_HWI_MAX_NUM +#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT +#endif + +/* * + * @ingroup los_arch_interrupt + * Highest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_HIGHEST +#define OS_HWI_PRIO_HIGHEST 0 +#endif + +/* * + * @ingroup los_arch_interrupt + * Lowest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_LOWEST +#define OS_HWI_PRIO_LOWEST 7 +#endif + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +/* * + * @ingroup los_arch_interrupt + * Define the type of a hardware interrupt vector table function. + */ +typedef VOID (**HWI_VECTOR_FUNC)(VOID); + +/* * + * @ingroup los_arch_interrupt + * Count of interrupts. + */ +extern UINT32 g_intCount; + +/* * + * @ingroup los_arch_interrupt + * Count of Xtensa system interrupt vector. + */ +#define OS_SYS_VECTOR_CNT 0 + +/* * + * @ingroup los_arch_interrupt + * Count of Xtensa interrupt vector. + */ +#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) + +/* * + * @ingroup los_arch_interrupt + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. + */ +#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) + +/* * + * @ingroup los_arch_interrupt + * 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_arch_interrupt + * 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_arch_interrupt + * 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_arch_interrupt + * 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_arch_interrupt + * Hardware interrupt error code: Invalid interrupt priority. + * + * Value: 0x02000905 + * + * Solution: Ensure that the interrupt priority is valid. + */ +#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) + +/* * + * @ingroup los_arch_interrupt + * 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. + */ +#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) + +/* * + * @ingroup los_arch_interrupt + * 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) + +#if (OS_HWI_WITH_ARG == 1) +/* * + * @ingroup los_arch_interrupt + * Set interrupt vector table. + */ +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); +#else +/* * + * @ingroup los_arch_interrupt + * Set interrupt vector table. + */ +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); +#endif + +VOID HalInterrupt(VOID); +UINT32 HalIntNumGet(VOID); +VOID HalHwiDefaultHandler(VOID); +VOID HalExcHandleEntry(UINTPTR faultAddr, EXC_CONTEXT_S *excBufAddr, UINT32 type); +VOID HalHwiInit(VOID); + +/** + * @ingroup los_exc + * Exception information structure + * + * Description: Exception information saved when an exception is triggered on the Xtensa platform. + * + */ +typedef struct TagExcInfo { + UINT16 phase; + UINT16 type; + UINT32 faultAddr; + UINT32 thrdPid; + UINT16 nestCnt; + UINT16 reserved; + EXC_CONTEXT_S *context; +} ExcInfo; + +extern UINT32 g_curNestCount; +extern ExcInfo g_excInfo; + +#define MAX_INT_INFO_SIZE (8 + 0x164) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_INTERRUPT_H */ diff --git a/kernel/arch/xtensa/lx6/gcc/los_arch_macro.h b/kernel/arch/xtensa/lx6/gcc/los_arch_macro.h new file mode 100644 index 00000000..e95b9a69 --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_arch_macro.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_MACRO_H +#define _LOS_ARCH_MACRO_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +.macro POP_ALL_REG SP + l32i a3, \SP, CONTEXT_OFF_LBEG + l32i a4, \SP, CONTEXT_OFF_LEND + wsr a3, LBEG + l32i a3, \SP, CONTEXT_OFF_LCOUNT + wsr a4, LEND + wsr a3, LCOUNT + l32i a3, \SP, CONTEXT_OFF_SAR + l32i a1, \SP, CONTEXT_OFF_A1 + wsr a3, SAR + l32i a3, \SP, CONTEXT_OFF_A3 + l32i a4, \SP, CONTEXT_OFF_A4 + l32i a5, \SP, CONTEXT_OFF_A5 + l32i a6, \SP, CONTEXT_OFF_A6 + l32i a7, \SP, CONTEXT_OFF_A7 + l32i a8, \SP, CONTEXT_OFF_A8 + l32i a9, \SP, CONTEXT_OFF_A9 + l32i a10, \SP, CONTEXT_OFF_A10 + l32i a11, \SP, CONTEXT_OFF_A11 + l32i a12, \SP, CONTEXT_OFF_A12 + l32i a13, \SP, CONTEXT_OFF_A13 + l32i a14, \SP, CONTEXT_OFF_A14 + l32i a15, \SP, CONTEXT_OFF_A15 + l32i a0, \SP, CONTEXT_OFF_PS + wsr a0, PS + l32i a0, \SP, CONTEXT_OFF_PC + wsr a0, EPC1 + l32i a0, \SP, CONTEXT_OFF_A0 + l32i a2, \SP, CONTEXT_OFF_A2 + rsync +.endm + +.macro PUSH_ALL_REG SP + s32i a0, \SP, CONTEXT_OFF_A0 + s32i a1, \SP, CONTEXT_OFF_A1 + s32i a2, \SP, CONTEXT_OFF_A2 + s32i a3, \SP, CONTEXT_OFF_A3 + s32i a4, \SP, CONTEXT_OFF_A4 + s32i a5, \SP, CONTEXT_OFF_A5 + s32i a6, \SP, CONTEXT_OFF_A6 + s32i a7, \SP, CONTEXT_OFF_A7 + s32i a8, \SP, CONTEXT_OFF_A8 + s32i a9, \SP, CONTEXT_OFF_A9 + s32i a10, \SP, CONTEXT_OFF_A10 + s32i a11, \SP, CONTEXT_OFF_A11 + s32i a12, \SP, CONTEXT_OFF_A12 + s32i a13, \SP, CONTEXT_OFF_A13 + s32i a14, \SP, CONTEXT_OFF_A14 + s32i a15, \SP, CONTEXT_OFF_A15 + rsr a3, SAR + s32i a3, \SP, CONTEXT_OFF_SAR + rsr a3, LBEG + s32i a3, \SP, CONTEXT_OFF_LBEG + rsr a3, LEND + s32i a3, \SP, CONTEXT_OFF_LEND + rsr a3, LCOUNT + s32i a3, \SP, CONTEXT_OFF_LCOUNT + rsr a3, PS + s32i a3, \SP, CONTEXT_OFF_PS +.endm + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_MACRO_H */ + diff --git a/kernel/arch/xtensa/lx6/gcc/los_arch_regs.h b/kernel/arch/xtensa/lx6/gcc/los_arch_regs.h new file mode 100644 index 00000000..1b1350b4 --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_arch_regs.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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. + */ + +/** + * @defgroup Special Register Fields and Values + * @ingroup kernel + */ + +#ifndef _ARCH_REGS_H +#define _ARCH_REGS_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* PS register -- imprecise exception */ +#define SPREG_PS_DEPC_SHIFT 4 +#define SPREG_PS_DEPC_MASK 0x00000004 +#define SPREG_PS_DEPC SPREG_PS_DEPC_MASK +/* PS register -- interrupt part */ +#define SPREG_PS_DI_SHIFT 3 +#define SPREG_PS_DI_MASK 0x00000008 +#define SPREG_PS_DI SPREG_PS_DI_MASK +#define SPREG_PS_DI_DEPC 0x0000000C +/* PS register -- stack part */ +#define SPREG_PS_STACK_SHIFT 5 +#define SPREG_PS_STACK_MASK 0x000000E0 +#define SPREG_PS_STACK_INTERRUPT 0x00000000 +#define SPREG_PS_STACK_CROSS 0x00000020 +#define SPREG_PS_STACK_IDLE 0x00000040 +#define SPREG_PS_STACK_KERNEL 0x00000060 +#define SPREG_PS_STACK_PAGE 0x000000E0 +#define SPREG_PS_STACK_FIRSTINT 0x00000080 +#define SPREG_PS_STACK_FIRSTKER 0x000000A0 +/* PS register -- entry no rotate */ +#define SPREG_PS_ENTRYNR_SHIFT 22 +#define SPREG_PS_ENTRYNR_MASK 0x00400000 +#define SPREG_PS_ENTRYNR SPREG_PS_ENTRYNR_MASK + +/* Exccause Register -- cause */ +#define SPREG_EXCCAUSE_CAUSE_SHIFT 0 +#define SPREG_EXCCAUSE_CAUSE_BITS 4 +#define SPREG_EXCCAUSE_CAUSE_MASK 0x0000000F + +/** + * @ingroup Execute level of core + */ +#define EXEC_LEVEL_APPLICATION_CODE 2 +#define EXEC_LEVEL_EXCEPTION_HANDLER 3 +#define EXEC_LEVEL_INTERRUPT_HANDLER 4 +#define EXEC_LEVEL_NON_INTERRUPTIBLE 5 + +/** + * @ingroup Schedule Flag stored on Task Context + */ +#define OS_SCHED_FLAG_TASKPREEMT 4 /* Task Preemted through LOS_Schedule */ + +/** + * @ingroup Context Fields Define + */ +#define CONTEXT_OFF_EPC 0 +#define CONTEXT_OFF_PC 0 /* reuse with EPC */ +#define CONTEXT_OFF_PS 4 +#define CONTEXT_OFF_A0 8 +#define CONTEXT_OFF_A1 12 +#define CONTEXT_OFF_A2 16 +#define CONTEXT_OFF_A3 20 +#define CONTEXT_OFF_A4 24 +#define CONTEXT_OFF_A5 28 +#define CONTEXT_OFF_A6 32 +#define CONTEXT_OFF_A7 36 +#define CONTEXT_OFF_A8 40 +#define CONTEXT_OFF_A9 44 +#define CONTEXT_OFF_A10 48 +#define CONTEXT_OFF_A11 52 +#define CONTEXT_OFF_A12 56 +#define CONTEXT_OFF_A13 60 +#define CONTEXT_OFF_A14 64 +#define CONTEXT_OFF_A15 68 +#define CONTEXT_OFF_RESERVED 72 +#define CONTEXT_OFF_SAR 72 +#define CONTEXT_OFF_SCHED_FLAG 76 /* reuse with exccause */ +#define CONTEXT_OFF_EXCCAUSE 76 +#define CONTEXT_OFF_EXCVADDR 80 +#define CONTEXT_OFF_LBEG 84 +#define CONTEXT_OFF_LEND 88 +#define CONTEXT_OFF_LCOUNT 92 +#define CONTEXT_OFF_TMP0 96 +#define CONTEXT_OFF_TMP1 100 +#define CONTEXT_OFF_TMP2 104 +#define CONTEXT_OFF_EXIT 108 +#define CONTEXT_SIZE 144 +#define EXCCAUSE_LEVEL1INTERRUPT 4 +#define XTENSA_LOGREG_NUM 16 +#define INDEX_OF_SP 1 +#define INDEX_OF_ARGS0 6 + +#define WINDOWSTARTBITS 16 +#define WINDOWBASEBITS 4 +#define WINDOWSTARTMASK ((1 << WINDOWSTARTBITS) - 1) + +#define WOE_ENABLE 0x40000 +#define BIT_CALLINC 16 +#define LEVEL_MASK 0xf +#define INT_MASK 5 +#define LEVEL1_INT_MASK 1 +#define USER_VECTOR_MODE 0x20 +#define LEVEL1 1 +#define LEVEL2 2 +#define LEVEL3 3 +#define LEVEL4 4 +#define LEVEL5 5 + +#ifdef YES +#undef YES +#endif +#define YES 1 + +#ifdef NO +#undef NO +#endif +#define NO 0 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _ARCH_REGS_H */ diff --git a/kernel/arch/xtensa/lx6/gcc/los_arch_timer.h b/kernel/arch/xtensa/lx6/gcc/los_arch_timer.h new file mode 100644 index 00000000..2b63c8ce --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_arch_timer.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 /* __cplusplus */ +#endif /* __cplusplus */ + +VOID SysTick_Handler(VOID); +UINT32 HalTickStart(OS_TICK_HANDLER handler); + +#define TIM0_GROUP0 0x3FF5F000 +#define TIM0_GROUP1 0x3FF60000 +#define TIM1_GROUP0 0x3FF5F024 +#define TIM1_GROUP1 0x3FF60024 + +#define TIM0_INT_ENABLE_GROUP0 0x3FF5F098 +#define TIM0_INT_ENABLE_GROUP1 0x3FF60098 +#define TIM0_INT_CLEAR_GROUP0 0x3FF5F0A4 +#define TIM0_INT_CLEAR_GROUP1 0x3FF600A4 + +typedef struct { + UINT32 CTRL; + UINT64 VAL; + UINT32 UPDATE; + UINT64 ALARM; + UINT64 LOAD; + UINT32 LOAD_TRI; +} Systick_t; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ARCH_TIMER_H */ diff --git a/kernel/arch/xtensa/lx6/gcc/los_context.c b/kernel/arch/xtensa/lx6/gcc/los_context.c new file mode 100644 index 00000000..c5764c4e --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_context.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_context.h" +#include "securec.h" +#include "los_arch_regs.h" +#include "los_arch_context.h" +#include "los_arch_interrupt.h" +#include "los_task.h" +#include "los_sched.h" +#include "los_interrupt.h" +#include "los_arch_timer.h" +#include "los_timer.h" +#include "los_debug.h" + +STATIC UINT32 g_sysNeedSched = FALSE; + +UINT32 g_stackDefault[] = { + 0x00000000, /* REG_OFF_PC */ + 0x00000000, /* REG_OFF_PS */ + 0x00000A00, /* REG_OFF_AR00 */ + 0x00000A01, /* REG_OFF_AR01 */ + 0x00000A02, /* REG_OFF_AR02 */ + 0x00000A03, /* REG_OFF_AR03 */ + 0x00000A04, /* REG_OFF_AR04 */ + 0x00000A05, /* REG_OFF_AR05 */ + 0x00000A06, /* REG_OFF_AR06 */ + 0x00000A07, /* REG_OFF_AR07 */ + 0x00000A08, /* REG_OFF_AR08 */ + 0x00000A09, /* REG_OFF_AR09 */ + 0x00000A10, /* REG_OFF_AR10 */ + 0x00000A11, /* REG_OFF_AR11 */ + 0x00000A12, /* REG_OFF_AR12 */ + 0x00000A13, /* REG_OFF_AR13 */ + 0x00000A14, /* REG_OFF_AR14 */ + 0x00000A15, /* REG_OFF_AR15 */ + 0x00000000, /* REG_OFF_RESERVED */ + 0x00000000, /* REG_OFF_EXCCAUSE */ + 0x00000000, /* REG_OFF_EXCVASSR */ + 0x00000000, /* REG_OFF_LCOUNT */ + 0x00000000, /* REG_OFF_LEND */ + 0x00000000, /* REG_OFF_LBEG */ + 0x00000000, /* REG_OFF_TMP */ + 0x00000000, /* REG_OFF_TMP */ + 0x00000000, /* REG_OFF_TMP */ + 0x00000000, /* REG_OFF_TMP */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ + 0x00000000, /* REG_OFF_SPILL_RESERVED */ +}; + +LITE_OS_SEC_TEXT_INIT VOID HalArchInit(VOID) +{ + HalHwiInit(); +} + +LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) +{ + LOS_IntLock(); + while (1) { + } +} + +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))); + + /* initialize the task context */ + result = memcpy_s(context, sizeof(TaskContext), g_stackDefault, sizeof(TaskContext)); + if (result != EOK) { + PRINT_ERR("[%s] memcpy_s failed!\n", __func__); + } + + context->pc = (UINT32)(UINTPTR)OsTaskEntry; + context->regA[INDEX_OF_SP] = (UINTPTR)topStack + stackSize; /* endStack */ + context->regA[INDEX_OF_ARGS0] = taskID; /* argument1 */ + context->ps = SPREG_PS_STACK_CROSS | WOE_ENABLE | 1 << BIT_CALLINC; /* set to kernel stack */ + + return (VOID *)context; +} + +VOID HalStartToRun(VOID) +{ + __asm__ volatile ("call0 OsStartToRun"); +} + +LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(VOID) +{ + UINT32 ret; + + (VOID)LOS_IntLock(); + + ret = HalTickStart(OsTickHandler); + if (ret != LOS_OK) { + PRINT_ERR("Tick start failed!\n"); + } + + OsSchedStart(); + HalStartToRun(); + return LOS_OK; +} + +VOID HalTaskSchedule(VOID) +{ + UINT32 intSave; + + if (OS_INT_ACTIVE) { + g_sysNeedSched = TRUE; + return; + } + + intSave = LOS_IntLock(); + g_sysNeedSched = FALSE; + BOOL isSwitch = OsSchedTaskSwitch(); + if (isSwitch) { + HalTaskContextSwitch(); + return; + } + + LOS_IntRestore(intSave); + return; +} + +VOID HalIrqEndCheckNeedSched(VOID) +{ + if (g_sysNeedSched && g_taskScheduled && LOS_CHECK_SCHEDULE) { + HalTaskSchedule(); + } +} diff --git a/kernel/arch/xtensa/lx6/gcc/los_dispatch.S b/kernel/arch/xtensa/lx6/gcc/los_dispatch.S new file mode 100644 index 00000000..c07adfcc --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_dispatch.S @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_arch_regs.h" +#include "los_arch_macro.h" + +.section .text +.literal_position +.align 4 +.type HalTaskContextSwitch, %function +.global HalTaskContextSwitch +HalTaskContextSwitch: + + entry sp, 16 + addi a2, sp, -CONTEXT_SIZE + PUSH_ALL_REG a2 + call0 SaveRetAddr + beqi a3, 1, .switchdone + movi a4, g_losTask + l32i a5, a4, 0 /* get run task */ + s32i a2, a5, 0 /* store sp */ + l32i a5, a4, 4 /* get new task */ + s32i a5, a4, 0 /* run task = new task */ + l32i a4, a5, 0 /* get new sp */ + rsr a5, PS + movi a3, ~(WOE_ENABLE | LEVEL_MASK) + and a2, a5, a3 + addi a2, a2, 3 + wsr a2, PS + rsync + call0 SpillWindow + mov a2, a4 + POP_ALL_REG a2 + rfe + +.switchdone: + retw + +.type HakSpillWindow, %function +.global HakSpillWindow +HakSpillWindow: + + entry sp, 16 + + addi a2, sp, -CONTEXT_SIZE + PUSH_ALL_REG a2 + + rsr a5, PS + movi a3, ~(WOE_ENABLE | LEVEL_MASK) /* disable woe and int */ + and a3, a5, a3 + addi a3, a3, LEVEL3 + wsr a3, PS + rsync + + mov a4, a2 + call0 SpillWindow + + l32i a5, a4, CONTEXT_OFF_PS /* restroe PS */ + wsr a5, PS + rsync + l32i a0, a4, CONTEXT_OFF_A0 + l32i a1, a4, CONTEXT_OFF_A1 + + retw + +.type OsStartToRun, %function +.global OsStartToRun +OsStartToRun: + + movi a2, g_losTask + l32i a3, a2, 4 /* get new task */ + l32i sp, a3, 0 /* get sp */ + + rsr a4, PS + movi a3, ~(WOE_ENABLE | LEVEL_MASK) + and a2, a4, a3 + addi a2, a2, LEVEL3 + wsr a2, PS + rsync + + mov a5, a1 + l32i a1, a1, CONTEXT_OFF_A1 + call0 SpillWindow + + mov a2, a5 + POP_ALL_REG a2 + rfe + +.global SaveRetAddr +.type SaveRetAddr, @function +.literal_position +.align 4 + +SaveRetAddr: + + movi a3, 1 + s32i a3, a2, CONTEXT_OFF_A3 + s32i a0, a2, CONTEXT_OFF_PC /* save pc */ + movi a3, 0 + ret diff --git a/kernel/arch/xtensa/lx6/gcc/los_exc.S b/kernel/arch/xtensa/lx6/gcc/los_exc.S new file mode 100644 index 00000000..e9e61510 --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_exc.S @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_arch_regs.h" +#include "los_arch_macro.h" + +.extern HalInterrupt +.extern UserException + +.section .iram,"ax" +.literal_position +.type HandleEntry,@function +.align 4 +HandleEntry: + + mov a0, sp + addi sp, sp, -CONTEXT_SIZE + + PUSH_ALL_REG a1 + s32i a0, sp, CONTEXT_OFF_A1 + rsr a0, EPC1 + s32i a0, sp, CONTEXT_OFF_PC + rsr a0, EXCSAVE1 + s32i a0, sp, CONTEXT_OFF_A0 + + wsr a1, EXCSAVE1 + l32i a1, a1, CONTEXT_OFF_A1 + call0 SpillWindow + rsr a1, EXCSAVE1 + rsr a0, EXCCAUSE + s32i a0, sp, CONTEXT_OFF_EXCCAUSE + rsr a0, EXCVADDR + s32i a0, sp, CONTEXT_OFF_EXCVADDR + movi a0, INT_MASK | USER_VECTOR_MODE | WOE_ENABLE + wsr a0, PS + + rsr a6, EPC1 + mov a7, sp + rsr a8, EXCCAUSE + call4 HalExcHandleEntry +1: + j 1b + +.begin literal_prefix .DebugExceptionHandler +.section .DebugExceptionHandler.text, "ax" +.global DebugExceptionHandler +.align 4 +.literal_position +DebugExceptionHandler: + + call0 UserException + +.end literal_prefix + +.begin literal_prefix .NMIExceptionHandler +.section .NMIExceptionHandler.text, "ax" +.global NMIExceptionHandler +.align 4 +.literal_position +NMIExceptionHandler: + + call0 UserException + +.end literal_prefix + +.begin literal_prefix .DoubleExceptionHandler +.section .DoubleExceptionHandler.text, "ax" +.global DoubleExceptionHandler +.align 4 +.literal_position +DoubleExceptionHandler: + + movi a0, INT_MASK | USER_VECTOR_MODE | WOE_ENABLE + wsr a0, PS + rsr a2, EXCCAUSE + call0 UserException + +.end literal_prefix + +.begin literal_prefix .KernelExceptionHandler +.section .KernelExceptionHandler.text, "ax" +.global KernelExceptionHandler +.align 4 +.literal_position +KernelExceptionHandler: + + wsr a0, EXCSAVE1 + call0 KernelException + +.end literal_prefix + +.section .iram,"ax" +.align 4 +KernelException: + + movi a0,5 + wsr a0,EXCCAUSE + call0 UserException + rfe + +.begin literal_prefix .UserExceptionHandler +.section .UserExceptionHandler.text, "ax" +.global UserExceptionHandler +.type UserExceptionHandler,@function +.align 4 +.literal_position +UserExceptionHandler: + + wsr a0, EXCSAVE1 + call0 UserException + +.end literal_prefix + +.section .iram,"ax" +.type UserException,@function +.align 4 +UserException: + + rsr a0, EXCCAUSE + beqi a0, 4, InterruptEntry1 + call0 HandleEntry +1: + j 1b + +.section .iram,"ax" +.type InterruptEntry1,@function +.align 4 +InterruptEntry1: + + mov a0, sp + addi sp, sp, -CONTEXT_SIZE + + PUSH_ALL_REG a1 + + s32i a0, sp, CONTEXT_OFF_A1 + rsr a0, EPC1 + s32i a0, sp, CONTEXT_OFF_PC + rsr a0, EXCSAVE1 + s32i a0, sp, CONTEXT_OFF_A0 + + wsr a1, EXCSAVE1 + l32i a1, a1, CONTEXT_OFF_A1 + call0 SpillWindow + rsr a1, EXCSAVE1 + + movi a0, LEVEL1_INT_MASK | USER_VECTOR_MODE | WOE_ENABLE + wsr a0, PS + rsync + + call4 HalInterrupt + mov a2, a1 + POP_ALL_REG a2 + rfe + +.begin literal_prefix .InterruptEntry2 +.section .InterruptEntry2.text, "ax" +.global InterruptEntry2 +.type InterruptEntry2,@function +.align 4 +.literal_position +InterruptEntry2: + + wsr a0, EXCSAVE2 + movi a4, LEVEL2 + call0 HandleEntry + +.end literal_prefix + +.begin literal_prefix .InterruptEntry3 +.section .InterruptEntry3.text, "ax" +.global InterruptEntry3 +.type InterruptEntry3,@function +.align 4 +.literal_position +InterruptEntry3: + + wsr a0, EXCSAVE3 + movi a4, LEVEL3 + call0 HandleEntry + +.end literal_prefix + +.begin literal_prefix .InterruptEntry4 +.section .InterruptEntry4.text, "ax" +.global InterruptEntry4 +.type InterruptEntry4,@function +.align 4 +.literal_position +InterruptEntry4: + + wsr a0, EXCSAVE4 + movi a4, LEVEL4 + call0 HandleEntry + +.end literal_prefix + +.begin literal_prefix .InterruptEntry5 +.section .InterruptEntry5.text, "ax" +.global InterruptEntry5 +.type InterruptEntry5,@function +.align 4 +.literal_position +InterruptEntry5: + + wsr a0, EXCSAVE5 + movi a4, LEVEL5 + call0 HandleEntry + +.end literal_prefix + +.section .WindowVectors.text, "ax" + +.org 0x0 +.global OverFlowGroup1 +OverFlowGroup1: + + addi a5, a5, -16 + s32i a3, a5, 12 + s32i a2, a5, 8 + s32i a1, a5, 4 + s32i a0, a5, 0 + addi a5, a5, 16 + rfwo + +.org 0x40 +.global UnderFlowGroup1 +UnderFlowGroup1: + + addi a5, a5, -16 + l32i a3, a5, 12 + l32i a2, a5, 8 + l32i a1, a5, 4 + l32i a0, a5, 0 + addi a5, a5, 16 + rfwu + +.org 0x80 +.global OverFlowGroup2 +OverFlowGroup2: + + addi a9, a9, -16 + s32i a3, a9, 12 + s32i a2, a9, 8 + s32i a1, a9, 4 + s32i a0, a9, 0 + addi a9, a9, 16 + + addi a1, a1, -12 + l32i a0, a1, 0 + addi a1, a1, 12 + + addi a0, a0, -32 + + s32i a7, a0, 12 + s32i a6, a0, 8 + s32i a5, a0, 4 + s32i a4, a0, 0 + + rfwo + +.org 0xC0 +.global UnderFlowGroup2 +UnderFlowGroup2: + + addi a9, a9, -16 + l32i a3, a9, 12 + l32i a2, a9, 8 + l32i a1, a9, 4 + l32i a0, a9, 0 + addi a9, a9, 16 + + addi a1, a1, -12 + l32i a4, a1, 0 + addi a1, a1, 12 + + addi a4, a4, -32 + l32i a7, a4, 12 + l32i a6, a4, 8 + l32i a5, a4, 4 + l32i a4, a4, 0 + rfwu + +.org 0x100 +.global OverFlowGroup3 +OverFlowGroup3: + + addi a13, a13, -16 + s32i a3, a13, 12 + s32i a2, a13, 8 + s32i a1, a13, 4 + s32i a0, a13, 0 + addi a13, a13, 16 + + addi a1, a1, -12 + l32i a0, a1, 0 + addi a1, a1, 12 + + addi a0, a0, -48 + + s32i a11, a0, 28 + s32i a10, a0, 24 + s32i a9, a0, 20 + s32i a8, a0, 16 + s32i a7, a0, 12 + s32i a6, a0, 8 + s32i a5, a0, 4 + s32i a4, a0, 0 + rfwo + +.org 0x140 +.global UnderFlowGroup3 +UnderFlowGroup3: + + addi a13, a13, -16 + l32i a3, a13, 12 + l32i a2, a13, 8 + l32i a1, a13, 4 + l32i a0, a13, 0 + addi a13, a13, 16 + + addi a1, a1, -12 + l32i a4, a1, 0 + addi a1, a1, 12 + + addi a4, a4, -48 + l32i a11, a0, 28 + l32i a10, a0, 24 + l32i a9, a0, 20 + l32i a8, a0, 16 + l32i a7, a4, 12 + l32i a6, a4, 8 + l32i a5, a4, 4 + l32i a4, a4, 0 + rfwu diff --git a/kernel/arch/xtensa/lx6/gcc/los_interrupt.c b/kernel/arch/xtensa/lx6/gcc/los_interrupt.c new file mode 100644 index 00000000..493e64fa --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_interrupt.c @@ -0,0 +1,554 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 +#include "securec.h" +#include "los_context.h" +#include "los_arch_interrupt.h" +#include "los_debug.h" +#include "los_hook.h" +#include "los_task.h" +#include "los_sched.h" +#include "los_memory.h" +#include "los_membox.h" +#include "los_arch_regs.h" + +UINT32 g_intCount = FALSE; + +/* * + * @ingroup los_hwi + * Hardware interrupt form mapping handling function array. + */ +STATIC HWI_PROC_FUNC __attribute__((aligned(0x100))) g_hwiForm[OS_VECTOR_CNT] = {0}; + +#if (OS_HWI_WITH_ARG == 1) + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + } +} + +#else +/* * + * @ingroup los_hwi + * Hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + } +} +#endif + +UINT32 HwiNumValid(UINT32 num) +{ + return (num >= OS_SYS_VECTOR_CNT) && (num <= OS_VECTOR_CNT); +} + +/* * + * @ingroup los_hwi + * Lock all interrupt. + */ +UINT32 HalIntLock(VOID) +{ + UINT32 ret; + + __asm__ volatile("rsil %0, %1" : "=r"(ret) : "i"(INT_MASK) : "memory"); + return ret; +} + +/* * + * @ingroup los_hwi + * Restore interrupt status. + */ +VOID HalIntRestore(UINT32 intSave) +{ + __asm__ volatile("wsr.ps %0; rsync" : : "r"(intSave) : "memory"); +} + +/* * + * @ingroup los_hwi + * Unlock interrupt. + */ +UINT32 HalIntUnLock(VOID) +{ + UINT32 intSave; + + __asm__ volatile("rsil %0, %1" : "=r"(intSave) : "i"(0) : "memory"); + + return intSave; +} + +/* * + * @ingroup los_hwi + * Determine if the interrupt is locked + */ +STATIC INLINE UINT32 HalIntLocked(VOID) +{ + UINT32 intSave; + __asm__ volatile("rsr %0, ps " : "=r"(intSave) : : "memory"); + + return (intSave & SPREG_PS_DI_MASK); +} + +/* * + * @ingroup los_hwi + * Trigger the interrupt + */ +UINT32 HalIrqPending(HWI_HANDLE_T hwiNum) +{ + if (!HwiNumValid(hwiNum)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + __asm__ __volatile__("wsr %0, intset; rsync" : : "a"(0x1U << hwiNum)); + + return LOS_OK; +} + +/* * + * @ingroup los_hwi + * Unmask the interrupt + */ +UINT32 HalIrqUnmask(HWI_HANDLE_T hwiNum) +{ + UINT32 ier; + + if (!HwiNumValid(hwiNum)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + __asm__ __volatile__("rsr %0, intenable" : "=a"(ier) : : "memory"); + __asm__ __volatile__("wsr %0, intenable; rsync" : : "a"(ier | ((UINT32)0x1U << hwiNum))); + + return LOS_OK; +} + +/* * + * @ingroup los_hwi + * Mask the interrupt + */ +UINT32 HalIrqMask(HWI_HANDLE_T hwiNum) +{ + UINT32 ier; + + if (!HwiNumValid(hwiNum)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + __asm__ __volatile__("rsr %0, intenable" : "=a"(ier) : : "memory"); + __asm__ __volatile__("wsr %0, intenable; rsync" : : "a"(ier & ~((UINT32)0x1U << hwiNum))); + + return LOS_OK; +} + +/* **************************************************************************** + Function : HalIntNumGet + Description : Get an interrupt number + Input : None + Output : None + Return : Interrupt Indexes number + **************************************************************************** */ +UINT32 HalIntNumGet(VOID) +{ + UINT32 ier; + UINT32 intenable; + UINT32 intSave; + + __asm__ __volatile__("rsr %0, interrupt" : "=a"(ier) : : "memory"); + __asm__ __volatile__("rsr %0, intenable" : "=a"(intenable) : : "memory"); + + intSave = ier & intenable; + + return __builtin_ffs(intSave) - 1; +} + +/* * + * @ingroup los_hwi + * Clear the interrupt + */ +UINT32 HalIrqClear(HWI_HANDLE_T vector) +{ + if (!HwiNumValid(vector)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + __asm__ __volatile__("wsr %0, intclear; rsync" : : "a"(0x1U << vector)); + + return LOS_OK; +} + +INLINE UINT32 HalIsIntActive(VOID) +{ + return (g_intCount == TRUE); +} + +/* **************************************************************************** + Function : HalHwiDefaultHandler + Description : default handler of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +VOID HalHwiDefaultHandler(VOID) +{ + UINT32 irqNum = HalIntNumGet(); + PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, irqNum); + while (1) {} +} + +WEAK VOID HalPreInterruptHandler(UINT32 arg) +{ + return; +} + +WEAK VOID HalAftInterruptHandler(UINT32 arg) +{ + return; +} + +/* **************************************************************************** + Function : HalInterrupt + Description : Hardware interrupt entry function + Input : None + Output : None + Return : None + **************************************************************************** */ +VOID HalInterrupt(VOID) +{ + UINT32 hwiIndex; + UINT32 intSave; + + intSave = LOS_IntLock(); + g_intCount = TRUE; + LOS_IntRestore(intSave); + + hwiIndex = HalIntNumGet(); + HalIrqClear(hwiIndex); + + OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex); + + HalPreInterruptHandler(hwiIndex); + +#if (OS_HWI_WITH_ARG == 1) + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); + } +#else + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); + } +#endif + + HalAftInterruptHandler(hwiIndex); + + OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, hwiIndex); + + intSave = LOS_IntLock(); + g_intCount = FALSE; + LOS_IntRestore(intSave); + HalIrqEndCheckNeedSched(); +} + +/* **************************************************************************** + 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 + **************************************************************************** */ +UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg) +{ + UINT32 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 + HalIrqUnmask(hwiNum); + + 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; + } + + HalIrqMask(hwiNum); + + intSave = LOS_IntLock(); + + g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler; + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +ExcInfo g_excInfo = {0}; + +#if (LOSCFG_KERNEL_PRINTF != 0) + +STATIC VOID OsExcTypeInfo(const ExcInfo *excInfo) +{ + CHAR *phaseStr[] = {"exc in init", "exc in task", "exc in hwi"}; + + PRINTK("Type = %d\n", excInfo->type); + PRINTK("ThrdPid = %d\n", excInfo->thrdPid); + PRINTK("Phase = %s\n", phaseStr[excInfo->phase]); + PRINTK("FaultAddr = 0x%x\n", excInfo->faultAddr); +} + +STATIC VOID OsExcCurTaskInfo(const ExcInfo *excInfo) +{ + PRINTK("Current task info:\n"); + if (excInfo->phase == OS_EXC_IN_TASK) { + LosTaskCB *taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet()); + PRINTK("Task name = %s\n", taskCB->taskName); + PRINTK("Task ID = %d\n", taskCB->taskID); + PRINTK("Task SP = 0x%x\n", (UINTPTR)taskCB->stackPointer); + PRINTK("Task ST = 0x%x\n", taskCB->topOfStack); + PRINTK("Task SS = 0x%x\n", taskCB->stackSize); + } else if (excInfo->phase == OS_EXC_IN_HWI) { + PRINTK("Exception occur in interrupt phase!\n"); + } else { + PRINTK("Exception occur in system init phase!\n"); + } +} + +STATIC VOID OsExcRegInfo(const ExcInfo *excInfo) +{ + INT32 index; + PRINTK("Exception reg dump:\n"); + PRINTK("sar = 0x%x\n", excInfo->context->sar); + PRINTK("excCause = 0x%x\n", excInfo->context->excCause); + PRINTK("excVaddr = 0x%x\n", excInfo->context->excVaddr); + PRINTK("lbeg = 0x%x\n", excInfo->context->lbeg); + PRINTK("lend = 0x%x\n", excInfo->context->lend); + PRINTK("lcount = 0x%x\n", excInfo->context->lcount); + PRINTK("pc = 0x%x\n", excInfo->context->pc); + PRINTK("ps = 0x%x\n", excInfo->context->ps); + for (index = 0; index < XTENSA_LOGREG_NUM; index++) { + PRINTK("regA%d = 0x%x\n", index, excInfo->context->regA[index]); + } +} + +STATIC VOID OsExcBackTraceInfo(const ExcInfo *excInfo) +{ + UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = {0}; + UINT32 index; + + OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, excInfo->context->regA[1]); + + PRINTK("----- backtrace start -----\n"); + for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) { + if (LR[index] == 0) { + break; + } + PRINTK("backtrace %d -- lr = 0x%x\n", index, LR[index]); + } + PRINTK("----- backtrace end -----\n"); +} + +STATIC VOID OsExcMemPoolCheckInfo(VOID) +{ + PRINTK("\r\nmemory pools check:\n"); +#if (LOSCFG_PLATFORM_EXC == 1) + MemInfoCB memExcInfo[OS_SYS_MEM_NUM]; + UINT32 errCnt; + UINT32 i; + + (VOID)memset_s(memExcInfo, sizeof(memExcInfo), 0, sizeof(memExcInfo)); + + errCnt = OsMemExcInfoGet(OS_SYS_MEM_NUM, memExcInfo); + if (errCnt < OS_SYS_MEM_NUM) { + errCnt += OsMemboxExcInfoGet(OS_SYS_MEM_NUM - errCnt, memExcInfo + errCnt); + } + + if (errCnt == 0) { + PRINTK("all memory pool check passed!\n"); + return; + } + + for (i = 0; i < errCnt; i++) { + PRINTK("pool num = %d\n", i); + PRINTK("pool type = %d\n", memExcInfo[i].type); + PRINTK("pool addr = 0x%x\n", memExcInfo[i].startAddr); + PRINTK("pool size = 0x%x\n", memExcInfo[i].size); + PRINTK("pool free = 0x%x\n", memExcInfo[i].free); + PRINTK("pool blkNum = %d\n", memExcInfo[i].blockSize); + PRINTK("pool error node addr = 0x%x\n", memExcInfo[i].errorAddr); + PRINTK("pool error node len = 0x%x\n", memExcInfo[i].errorLen); + PRINTK("pool error node owner = %d\n", memExcInfo[i].errorOwner); + } +#endif + UINT32 ret = LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR); + if (ret == LOS_OK) { + PRINTK("system heap memcheck over, all passed!\n"); + } + + PRINTK("memory pool check end!\n"); +} +#endif + +STATIC VOID OsExcInfoDisplay(const ExcInfo *excInfo) +{ +#if (LOSCFG_KERNEL_PRINTF != 0) + PRINTK("*************Exception Information**************\n"); + OsExcTypeInfo(excInfo); + OsExcCurTaskInfo(excInfo); + OsExcRegInfo(excInfo); + OsExcBackTraceInfo(excInfo); + OsGetAllTskInfo(); + OsExcMemPoolCheckInfo(); +#endif +} + +VOID HalExcHandleEntry(UINTPTR faultAddr, EXC_CONTEXT_S *excBufAddr, UINT32 type) +{ + g_excInfo.nestCnt++; + g_excInfo.faultAddr = faultAddr; + g_excInfo.type = type; + + LosTaskCB *taskCB = g_losTask.runTask; + + if ((taskCB == NULL) || (taskCB == OS_TCB_FROM_TID(g_taskMaxNum))) { + g_excInfo.phase = OS_EXC_IN_INIT; + g_excInfo.thrdPid = OS_NULL_INT; + } else if (HalIntNumGet() != OS_NULL_INT) { + g_excInfo.phase = OS_EXC_IN_HWI; + g_excInfo.thrdPid = HalIntNumGet(); + } else { + g_excInfo.phase = OS_EXC_IN_TASK; + g_excInfo.thrdPid = g_losTask.runTask->taskID; + } + + g_excInfo.context = excBufAddr; + + OsDoExcHook(EXC_INTERRUPT); + OsExcInfoDisplay(&g_excInfo); + HalSysExit(); +} + +/* Stack protector */ +WEAK UINT32 __stack_chk_guard = 0xd00a0dff; + +WEAK VOID __stack_chk_fail(VOID) +{ + /* __builtin_return_address is a builtin function, building in gcc */ + LOS_Panic("stack-protector: Kernel stack is corrupted in: 0x%x\n", + __builtin_return_address(0)); +} + +/* **************************************************************************** + Function : HalHwiInit + Description : initialization of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +VOID HalHwiInit(VOID) +{ + for (UINT32 i = 0; i < OS_HWI_MAX_NUM; i++) { + g_hwiForm[i + OS_SYS_VECTOR_CNT] = HalHwiDefaultHandler; + HalIrqMask(i); + } + asm volatile ("wsr %0, vecbase" : : "r"(INIT_VECTOR_START)); + return; +} + diff --git a/kernel/arch/xtensa/lx6/gcc/los_timer.c b/kernel/arch/xtensa/lx6/gcc/los_timer.c new file mode 100644 index 00000000..dd623bb1 --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_timer.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_timer.h" +#include "los_config.h" +#include "los_tick.h" +#include "los_arch_interrupt.h" +#include "los_arch_timer.h" +#include "los_context.h" +#include "los_sched.h" +#include "los_debug.h" + +#define OVERFLOW_MAX 0xFFFFFFFF + +UINT32 GetCcount(VOID) +{ + UINT32 intSave; + + __asm__ __volatile__("rsr %0, ccount" : "=a"(intSave) :); + + return intSave; +} + +VOID ResetCcount(VOID) +{ + __asm__ __volatile__("wsr %0, ccount; rsync" : :"a"(0)); +} + +UINT32 GetCcompare(VOID) +{ + UINT32 intSave; + + __asm__ __volatile__("rsr %0, ccompare0" : "=a"(intSave) :); + + return intSave; +} + +VOID SetCcompare(UINT32 newCompareVal) +{ + __asm__ __volatile__("wsr %0, ccompare0; rsync" : : "a"(newCompareVal)); +} + +VOID HalUpdateTimerCmpVal(UINT32 newCompareVal) +{ + SetCcompare(newCompareVal); + ResetCcount(); +} + +/* **************************************************************************** +Function : HalTickStart +Description : Configure Tick Interrupt Start +Input : none +output : none +return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed +**************************************************************************** */ +WEAK UINT32 HalTickStart(OS_TICK_HANDLER handler) +{ + UINT32 ret; + UINT32 ccount; + UINT32 nextTickCycles; + + 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(OS_TICK_INT_NUM, (HWI_PROC_FUNC)handler, NULL); +#else + OsSetVector(OS_TICK_INT_NUM, (HWI_PROC_FUNC)handler); +#endif +#endif + + g_sysClock = OS_SYS_CLOCK; + g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; + + SetCcompare(g_cyclesPerTick); + ResetCcount(); + + __asm__ __volatile__("wsr %0, ccompare1; rsync" : : "a"(0)); + __asm__ __volatile__("wsr %0, ccompare2; rsync" : : "a"(0)); + + HalIrqUnmask(OS_TICK_INT_NUM); + return LOS_OK; +} + +WEAK VOID HalSysTickReload(UINT64 nextResponseTime) +{ + HalUpdateTimerCmpVal(nextResponseTime); +} + +WEAK UINT64 HalGetTickCycle(UINT32 *period) +{ + UINT32 ccount; + UINT32 intSave = LOS_IntLock(); + + ccount = GetCcount(); + *period = g_cyclesPerTick; + + LOS_IntRestore(intSave); + + return ccount; +} + +WEAK VOID HalTickLock(VOID) +{ + HalIrqMask(OS_TICK_INT_NUM); +} + +WEAK VOID HalTickUnlock(VOID) +{ + HalIrqUnmask(OS_TICK_INT_NUM); +} + +VOID Wfi(VOID) +{ + __asm__ volatile("waiti 0" : : : "memory"); +} + +VOID Dsb(VOID) +{ + __asm__ volatile("dsync" : : : "memory"); +} + +UINT32 HalEnterSleep(VOID) +{ + Dsb(); + Wfi(); + + return LOS_OK; +} diff --git a/kernel/arch/xtensa/lx6/gcc/los_window.S b/kernel/arch/xtensa/lx6/gcc/los_window.S new file mode 100644 index 00000000..6a94dfca --- /dev/null +++ b/kernel/arch/xtensa/lx6/gcc/los_window.S @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_arch_regs.h" + +.text +.align 4 +.literal_position +.global SpillWindow +SpillWindow: + + rsr a2, WINDOWBASE /* read windowbase reg */ + + movi a3, WINDOWSTARTBITS + sub a3, a3, a2 /* get the num of high bits */ + addi a3, a3, -1 + + ssl a3 /* set left shift bit */ + rsr a3, WINDOWSTART /* read windowstart reg */ + sll a3, a3 + movi a2, WINDOWSTARTMASK + and a3, a3, a2 + + beqi a3, 0, .Linvalidwindowstart /* if a3 == 0 goto Linvalidwindowstart */ + + rsr a2, WINDOWBASE /* read windowbase reg */ + + addi a2, a2, 1 + ssr a2 + rsr a2, WINDOWSTART + srl a2, a2 + or a2, a2, a3 + movi a3, 0 + +.bitclear0: + bbsi.l a2, 0, .bitcleardone + srli a2, a2, 1 + addi a3, a3, 1 + j .bitclear0 + +.bitcleardone: + srli a2, a2, 1 /* drop the first bit */ + + wsr a2, WINDOWSTART + rsr a2, WINDOWBASE + + add a2, a2, a3 + wsr a2, WINDOWBASE + rsync + + rsr a2, WINDOWSTART + +.Lspillstart: + beqi a2, 0, .Ldone + bbsi.l a2, 0, .Lspill4 + bbsi.l a2, 1, .Lspill8 + bbsi.l a2, 2, .Lspill12 + j .Linvalidwindow + +.Lspill4: + s32e a4, a9, -16 + s32e a5, a9, -12 + s32e a6, a9, -8 + s32e a7, a9, -4 + + srli a6, a2, 1 + rotw 1 + j .Lspillstart + +.Lspill8: + s32e a4, a13, -16 + s32e a5, a13, -12 + s32e a6, a13, -8 + s32e a7, a13, -4 + + l32i a3, a5, -12 /* call[i - 1]'s sp */ + addi a3, a3, -16 /* base area */ + + s32e a8, a3, -16 + s32e a9, a3, -12 + s32e a10, a3, -8 + s32e a11, a3, -4 + + srli a10, a2, 2 + rotw 2 + j .Lspillstart + +.Lspill12: + rotw 1 + s32e a0, a13, -16 + s32e a1, a13, -12 + s32e a2, a13, -8 + s32e a3, a13, -4 + + l32i a3, a1, -12 /* call[i - 1]'s sp */ + addi a3, a3, -16 /* base area */ + + s32e a4, a3, -32 + s32e a5, a3, -28 + s32e a6, a3, -24 + s32e a7, a3, -20 + s32e a8, a3, -16 + s32e a9, a3, -12 + s32e a10, a3, -8 + s32e a11, a3, -4 + + rotw -1 + srli a14, a2, 3 + rotw 3 + j .Lspillstart + +.Ldone: + rotw 1 + rsr a2, WINDOWBASE + ssl a2 + movi a2, 1 + sll a2, a2 + wsr a2, WINDOWSTART + rsync + movi a2, 0 + ret + +.Linvalidwindowstart: + movi a2, 1 + ret + +.Linvalidwindow: + movi a3, 1 + slli a2, a2, 1 + or a2, a2, a3 + rsr a3, WINDOWBASE + +1: + bbsi.l a2, WINDOWSTARTBITS-1, 2f + slli a2, a2, 1 + addi a3, a3, -1 + j 1b + +2: + extui a3, a3, 0, WINDOWSTARTBITS /* the original bit */ + + addi a3, a3, 1 + ssl a3 + sll a3, a2 + slli a2, a2, 32 - WINDOWSTARTBITS + srl a2, a2 + + or a2, a2, a3 + extui a2, a2, 0, WINDOWSTARTBITS + wsr a2, WINDOWSTART + + movi a3, 31 + rsr a2, SAR + sub a2, a3, a2 + wsr a2, WINDOWBASE + rsync + + movi a2, 2 + ret diff --git a/kernel/include/los_config.h b/kernel/include/los_config.h index c08bc8c2..9c9b6bfb 100644 --- a/kernel/include/los_config.h +++ b/kernel/include/los_config.h @@ -739,6 +739,8 @@ extern UINT8 *m_aucSysMem0; * 1: Call stack analysis for cortex-m series by scanning the stack. * 2: Call stack analysis for risc-v by using frame pointer. * 3: Call stack analysis for risc-v by scanning the stack. + * 4: Call stack analysis for xtensa by scanning the stack. + * 5: Call stack analysis for c-sky by scanning the stack. * others: Not currently supported. */ #ifndef LOSCFG_BACKTRACE_TYPE