From b548a03df425d627195098bd672c0461832fe5fe Mon Sep 17 00:00:00 2001 From: Grey Huang <102242739@qq.com> Date: Fri, 25 Oct 2019 16:28:16 +0800 Subject: [PATCH] add fold arm-v8m/ m23 --- arch/arm/arm-v8m/common/include/tos_cpu.h | 141 +++++++++ arch/arm/arm-v8m/common/include/tos_cpu_def.h | 34 ++ .../arm-v8m/common/include/tos_cpu_types.h | 57 ++++ arch/arm/arm-v8m/common/include/tos_fault.h | 236 ++++++++++++++ arch/arm/arm-v8m/common/tos_cpu.c | 293 ++++++++++++++++++ arch/arm/arm-v8m/common/tos_fault.c | 268 ++++++++++++++++ arch/arm/arm-v8m/cortex-m23/armcc/port.h | 73 +++++ arch/arm/arm-v8m/cortex-m23/armcc/port_c.c | 145 +++++++++ .../arm-v8m/cortex-m23/armcc/port_config.h | 29 ++ arch/arm/arm-v8m/cortex-m23/armcc/port_s.S | 137 ++++++++ arch/arm/arm-v8m/cortex-m23/gcc/port.h | 73 +++++ arch/arm/arm-v8m/cortex-m23/gcc/port_c.c | 145 +++++++++ arch/arm/arm-v8m/cortex-m23/gcc/port_config.h | 29 ++ arch/arm/arm-v8m/cortex-m23/gcc/port_s.S | 143 +++++++++ arch/arm/arm-v8m/cortex-m23/iccarm/port.h | 73 +++++ arch/arm/arm-v8m/cortex-m23/iccarm/port_c.c | 145 +++++++++ .../arm-v8m/cortex-m23/iccarm/port_config.h | 29 ++ arch/arm/arm-v8m/cortex-m23/iccarm/port_s.S | 126 ++++++++ 18 files changed, 2176 insertions(+) create mode 100644 arch/arm/arm-v8m/common/include/tos_cpu.h create mode 100644 arch/arm/arm-v8m/common/include/tos_cpu_def.h create mode 100644 arch/arm/arm-v8m/common/include/tos_cpu_types.h create mode 100644 arch/arm/arm-v8m/common/include/tos_fault.h create mode 100644 arch/arm/arm-v8m/common/tos_cpu.c create mode 100644 arch/arm/arm-v8m/common/tos_fault.c create mode 100644 arch/arm/arm-v8m/cortex-m23/armcc/port.h create mode 100644 arch/arm/arm-v8m/cortex-m23/armcc/port_c.c create mode 100644 arch/arm/arm-v8m/cortex-m23/armcc/port_config.h create mode 100644 arch/arm/arm-v8m/cortex-m23/armcc/port_s.S create mode 100644 arch/arm/arm-v8m/cortex-m23/gcc/port.h create mode 100644 arch/arm/arm-v8m/cortex-m23/gcc/port_c.c create mode 100644 arch/arm/arm-v8m/cortex-m23/gcc/port_config.h create mode 100644 arch/arm/arm-v8m/cortex-m23/gcc/port_s.S create mode 100644 arch/arm/arm-v8m/cortex-m23/iccarm/port.h create mode 100644 arch/arm/arm-v8m/cortex-m23/iccarm/port_c.c create mode 100644 arch/arm/arm-v8m/cortex-m23/iccarm/port_config.h create mode 100644 arch/arm/arm-v8m/cortex-m23/iccarm/port_s.S diff --git a/arch/arm/arm-v8m/common/include/tos_cpu.h b/arch/arm/arm-v8m/common/include/tos_cpu.h new file mode 100644 index 00000000..2ad847fb --- /dev/null +++ b/arch/arm/arm-v8m/common/include/tos_cpu.h @@ -0,0 +1,141 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _TOS_CPU_H_ +#define _TOS_CPU_H_ + +typedef struct cpu_context_st { + cpu_data_t _R4; + cpu_data_t _R5; + cpu_data_t _R6; + cpu_data_t _R7; + cpu_data_t _R8; + cpu_data_t _R9; + cpu_data_t _R10; + cpu_data_t _R11; +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + cpu_data_t EXC_RETURN; +#endif + cpu_data_t _R0; + cpu_data_t _R1; + cpu_data_t _R2; + cpu_data_t _R3; + cpu_data_t _R12; + cpu_data_t _R14; + cpu_data_t _PC; + cpu_data_t _xPSR; +} cpu_context_t; + +__API__ uint32_t tos_cpu_clz(uint32_t val); + +__API__ void tos_cpu_int_disable(void); + +__API__ void tos_cpu_int_enable(void); + +__API__ cpu_cpsr_t tos_cpu_cpsr_save(void); + +__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr); + +#if (TOS_CFG_CPU_HRTIMER_EN > 0u) + +__API__ void tos_cpu_hrtimer_init(void); + +__API__ cpu_hrtimer_t tos_cpu_hrtimer_read(void); + +#endif + +__KERNEL__ void cpu_init(void); + +__KERNEL__ void cpu_reset(void); + +__KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick); + +__KERNEL__ void cpu_sched_start(void); + +__KERNEL__ void cpu_context_switch(void); + +__KERNEL__ void cpu_irq_context_switch(void); + +#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u + +__KERNEL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth); + +#endif + +__KERNEL__ k_stack_t *cpu_task_stk_init(void *entry, + void *arg, + void *exit, + k_stack_t *stk_base, + size_t stk_size); + +#if TOS_CFG_TICKLESS_EN > 0u + +__KERNEL__ void cpu_systick_resume(void); + +__KERNEL__ void cpu_systick_suspend(void); + +__KERNEL__ void cpu_systick_reload_reset(void); + +__KERNEL__ void cpu_systick_pending_reset(void); + +__KERNEL__ k_time_t cpu_systick_max_delay_millisecond(void); + +__KERNEL__ void cpu_systick_expires_set(k_time_t millisecond); + +__KERNEL__ void cpu_systick_reset(void); + +#endif + +#if TOS_CFG_PWR_MGR_EN > 0u + +__KERNEL__ void cpu_sleep_mode_enter(void); + +__KERNEL__ void cpu_stop_mode_enter(void); + +__KERNEL__ void cpu_standby_mode_enter(void); + +#endif + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + +__KERNEL__ void cpu_flush_fpu(void); + +#endif /* TOS_CFG_CPU_ARM_FPU_EN */ + +__KERNEL__ void cpu_fault_diagnosis(void); + +#endif + +/* Allocates CPU status register word. */ +#define TOS_CPU_CPSR_ALLOC() cpu_cpsr_t cpu_cpsr = (cpu_cpsr_t)0u + +/* Save CPU status word & disable interrupts.*/ +#define TOS_CPU_INT_DISABLE() \ + do { \ + cpu_cpsr = tos_cpu_cpsr_save(); \ + } while (0) + +/* Restore CPU status word. */ +#define TOS_CPU_INT_ENABLE() \ + do { \ + tos_cpu_cpsr_restore(cpu_cpsr); \ + } while (0) + +#endif /* _TOS_CPU_H_ */ + diff --git a/arch/arm/arm-v8m/common/include/tos_cpu_def.h b/arch/arm/arm-v8m/common/include/tos_cpu_def.h new file mode 100644 index 00000000..f71d7c8e --- /dev/null +++ b/arch/arm/arm-v8m/common/include/tos_cpu_def.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _TOS_CPU_DEF_H_ +#define _TOS_CPU_DEF_H_ + +enum CPU_WORD_SIZE { + CPU_WORD_SIZE_08, + CPU_WORD_SIZE_16, + CPU_WORD_SIZE_32, + CPU_WORD_SIZE_64, +}; + +enum CPU_STK_GROWTH { + CPU_STK_GROWTH_ASCENDING, + CPU_STK_GROWTH_DESCENDING, +}; + +#endif /* _TOS_CPU_DEF_H_ */ + diff --git a/arch/arm/arm-v8m/common/include/tos_cpu_types.h b/arch/arm/arm-v8m/common/include/tos_cpu_types.h new file mode 100644 index 00000000..62d9e014 --- /dev/null +++ b/arch/arm/arm-v8m/common/include/tos_cpu_types.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _TOS_CPU_TYPES_H_ +#define _TOS_CPU_TYPES_H_ + +/* CPU address type based on address bus size. */ +#if (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef uint32_t cpu_addr_t; +#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef uint16_t cpu_addr_t; +#else +typedef uint8_t cpu_addr_t; +#endif + +/* CPU data type based on data bus size. */ +#if (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_32) +typedef uint32_t cpu_data_t; +#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_16) +typedef uint16_t cpu_data_t; +#else +typedef uint8_t cpu_data_t; +#endif + +#if (TOS_CFG_CPU_HRTIMER_EN > 0) +#if (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_08) +typedef uint8_t cpu_hrtimer_t; +#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_16) +typedef uint16_t cpu_hrtimer_t; +#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_64) +typedef uint64_t cpu_hrtimer_t; +#else +typedef uint32_t cpu_hrtimer_t; +#endif +#else +typedef uint32_t cpu_hrtimer_t; +#endif + +//typedef cpu_addr_t size_t; +typedef cpu_addr_t cpu_cpsr_t; + +#endif + diff --git a/arch/arm/arm-v8m/common/include/tos_fault.h b/arch/arm/arm-v8m/common/include/tos_fault.h new file mode 100644 index 00000000..784c5f9d --- /dev/null +++ b/arch/arm/arm-v8m/common/include/tos_fault.h @@ -0,0 +1,236 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _TOS_FAULT_H_ +#define _TOS_FAULT_H_ + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u + +typedef int (*k_fault_log_writer_t)(const char *format, ...); + +#define K_FAULT_STACK_DUMP_DEPTH 10u + +#define K_FAULT_CALL_STACK_BACKTRACE_DEPTH 5u + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) +typedef struct fault_fpu_frame_st { + cpu_data_t s0; + cpu_data_t s1; + cpu_data_t s2; + cpu_data_t s3; + cpu_data_t s4; + cpu_data_t s5; + cpu_data_t s6; + cpu_data_t s7; + cpu_data_t s8; + cpu_data_t s9; + cpu_data_t s10; + cpu_data_t s11; + cpu_data_t s12; + cpu_data_t s13; + cpu_data_t s14; + cpu_data_t s15; + cpu_data_t fpscr; +} fault_fpu_frame_t; +#endif + +typedef struct fault_cpu_frame_st { + cpu_data_t r0; + cpu_data_t r1; + cpu_data_t r2; + cpu_data_t r3; + cpu_data_t r12; + cpu_data_t lr; + cpu_data_t pc; + cpu_data_t spsr; +} fault_cpu_frame_t; + +typedef struct fault_exc_frame_st { + fault_cpu_frame_t cpu_frame; + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + fault_fpu_frame_t fpu_frame; +#endif +} fault_exc_frame_t; + +/** + * information we need to do fault backtrace + */ +typedef struct fault_information_st { + int is_thumb : 1; /**< whether it is thumb we use when we fall into fault? */ + int is_on_task : 1; /**< whether we are on a task when fall into fault? */ + int is_stk_ovrf : 1; /**< whether we get a stack overflow */ + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + int is_ext_stk_frm : 1; /**< whether it is a extended stack frame?(whether the cpu has pushed fpu registers onto the stack) */ +#endif + + cpu_addr_t pc; /**< just where fault happens */ + + cpu_addr_t sp_before_fault; /**< original sp just before the cpu push the fault exception frame */ + + /** + * we need main_stack_start & main_stack_limit to do call stack backtrace + * when we fall into fault during a task, we should do the call stack backtrace on the task's stack + * but if not, which means we are in kernel, we should do the call stack backtrace on the main stack + * in arm v7-m, this should be the MSP's start and limit + * in arm v7-a, call stack backtrace is another story(much more elegant because we have FP). + */ + cpu_addr_t stack_start; /**< current sp start address we use. if on task, it'll be the task's stack, otherwise it'll be the msp */ + cpu_addr_t stack_limit; /**< current sp limit address */ + cpu_addr_t code_start; /**< current code start address */ + cpu_addr_t code_limit; /**< current code limit address */ +} fault_info_t; + +#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + +#define DEFAULT_CODE_SECTION_NAME ER_IROM1 +#define DEFAULT_CSTACK_SECTION_NAME STACK + +#define SECTION_START(_name_) _name_##$$Base +#define SECTION_END(_name_) _name_##$$Limit +#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base +#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit +#define CSTACK_BLOCK_START(_name_) SECTION_START(_name_) +#define CSTACK_BLOCK_END(_name_) SECTION_END(_name_) +#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_) +#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_) + +extern const int CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME); +extern const int CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME); +extern const int CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME); +extern const int CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME); + +__STATIC_INLINE__ cpu_addr_t fault_code_start(void) +{ + return (cpu_addr_t)&CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME); +} + +__STATIC_INLINE__ cpu_addr_t fault_code_limit(void) +{ + return (cpu_addr_t)&CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME); +} + +__STATIC_INLINE__ cpu_addr_t fault_msp_start(void) +{ + return (cpu_addr_t)&CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME); +} + +__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void) +{ + return (cpu_addr_t)&CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME); +} + +#elif defined(__ICCARM__) + +#define DEFAULT_CODE_SECTION_NAME ".text" +#define DEFAULT_CSTACK_SECTION_NAME "CSTACK" + +#pragma section=DEFAULT_CSTACK_SECTION_NAME +#pragma section=DEFAULT_CODE_SECTION_NAME + +__STATIC_INLINE__ cpu_addr_t fault_code_start(void) +{ + return (cpu_addr_t)__section_begin(DEFAULT_CODE_SECTION_NAME); +} + +__STATIC_INLINE__ cpu_addr_t fault_code_limit(void) +{ + return (cpu_addr_t)__section_end(DEFAULT_CODE_SECTION_NAME); +} + +__STATIC_INLINE__ cpu_addr_t fault_msp_start(void) +{ + return (cpu_addr_t)__section_begin(DEFAULT_CSTACK_SECTION_NAME); +} + +__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void) +{ + return (cpu_addr_t)__section_end(DEFAULT_CSTACK_SECTION_NAME); +} + +#elif defined(__GNUC__) + +/** + * if we are using keil(armcc) or mdk(iccarm), we probably use the defult link script supplied by the IDE. + * the way to locate the text/stack section start and limit is to find them in default link script. + * but if we build our project by makefile(or something like scons, cmake, etc), we probably need to write + * our own link scrpit, if so, we should do like this(just a demo): + * + _stext = .; + .text : { + *(.text.startup) + *(.text) + *(.text.*) + } + _etext = .; + + __bss_start = .; + .bss : { + *(.bss) + *(.bss.*) + *(COMMON) + _sstack = .; + *(.cstack) + _estack = .; + } + __bss_end = .; + * by this, we can locate text/stack section start and limit by _stext/_etext and _sstack/_estack + */ +#define DEFAULT_CODE_SECTION_START _stext +#define DEFAULT_CODE_SECTION_END _etext +#define DEFAULT_CSTACK_SECTION_START _sstack +#define DEFAULT_CSTACK_SECTION_END _estack + +extern const int DEFAULT_CODE_SECTION_START; +extern const int DEFAULT_CODE_SECTION_END; + +extern const int DEFAULT_CSTACK_SECTION_START; +extern const int DEFAULT_CSTACK_SECTION_END; + +__STATIC_INLINE__ cpu_addr_t fault_code_start(void) +{ + return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_START)); +} + +__STATIC_INLINE__ cpu_addr_t fault_code_limit(void) +{ + return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_END)); +} + +__STATIC_INLINE__ cpu_addr_t fault_msp_start(void) +{ + return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_START)); +} + +__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void) +{ + return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_END)); +} + +#endif + +__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer); + +__KERNEL__ int fault_default_log_writer(const char *format, ...); + +__KERNEL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame); + +#endif + +#endif /* _TOS_FAULT_H_ */ + diff --git a/arch/arm/arm-v8m/common/tos_cpu.c b/arch/arm/arm-v8m/common/tos_cpu.c new file mode 100644 index 00000000..4c854c15 --- /dev/null +++ b/arch/arm/arm-v8m/common/tos_cpu.c @@ -0,0 +1,293 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include + +__API__ uint32_t tos_cpu_clz(uint32_t val) +{ +#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 0u) + uint32_t nbr_lead_zeros = 0; + + if (!(val & 0XFFFF0000)) { + val <<= 16; + nbr_lead_zeros += 16; + } + + if (!(val & 0XFF000000)) { + val <<= 8; + nbr_lead_zeros += 8; + } + + if (!(val & 0XF0000000)) { + val <<= 4; + nbr_lead_zeros += 4; + } + + if (!(val & 0XC0000000)) { + val <<= 2; + nbr_lead_zeros += 2; + } + + if (!(val & 0X80000000)) { + nbr_lead_zeros += 1; + } + + if (!val) { + nbr_lead_zeros += 1; + } + + return (nbr_lead_zeros); +#else + return port_clz(val); +#endif +} + +__API__ void tos_cpu_int_disable(void) +{ + port_int_disable(); +} + +__API__ void tos_cpu_int_enable(void) +{ + port_int_enable(); +} + +__API__ cpu_cpsr_t tos_cpu_cpsr_save(void) +{ + return port_cpsr_save(); +} + +__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr) +{ + port_cpsr_restore(cpsr); +} + +__KERNEL__ void cpu_init(void) +{ + k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second; + cpu_systick_init(k_cpu_cycle_per_tick); + +#if (TOS_CFG_CPU_HRTIMER_EN > 0) + tos_cpu_hrtimer_init(); +#endif +} + +__KERNEL__ void cpu_reset(void) +{ + port_cpu_reset(); +} + +__KERNEL__ void cpu_sched_start(void) +{ + port_sched_start(); +} + +__KERNEL__ void cpu_context_switch(void) +{ + port_context_switch(); +} + +__KERNEL__ void cpu_irq_context_switch(void) +{ + port_irq_context_switch(); +} + +__KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick) +{ + port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO); + port_systick_config(cycle_per_tick); +} + +#if TOS_CFG_TICKLESS_EN > 0u + +/** + * @brief Set value to systick reload value register + * + * @param cycles The value set to register + * + * @return None + */ +__STATIC_INLINE__ void cpu_systick_reload(k_cycle_t cycle_per_tick) +{ + port_systick_reload(cycle_per_tick); +} + +/** + * @brief Enable systick interrupt + * + * @return None + */ +__KERNEL__ void cpu_systick_resume(void) +{ + port_systick_resume(); +} + +/** + * @brief Disable systick interrupt + * + * @return None + */ +__KERNEL__ void cpu_systick_suspend(void) +{ + port_systick_suspend(); +} + +__KERNEL__ k_time_t cpu_systick_max_delay_millisecond(void) +{ + return port_systick_max_delay_millisecond(); +} + +__KERNEL__ void cpu_systick_expires_set(k_time_t millisecond) +{ + k_cycle_t cycles; + + cycles = (k_cycle_t)((uint64_t)millisecond * TOS_CFG_CPU_CLOCK / K_TIME_MILLISEC_PER_SEC); /* CLOCK means cycle per second */ + + cpu_systick_reload(cycles - 12); /* interrupt delay */ +} + +__KERNEL__ void cpu_systick_pending_reset(void) +{ + port_systick_pending_reset(); +} + +__KERNEL__ void cpu_systick_reset(void) +{ + cpu_systick_reload(k_cpu_cycle_per_tick); +} + +#endif /* TOS_CFG_TICKLESS_EN */ + +#if TOS_CFG_PWR_MGR_EN > 0u + +__KERNEL__ void cpu_sleep_mode_enter(void) +{ + port_sleep_mode_enter(); +} + +__KERNEL__ void cpu_stop_mode_enter(void) +{ + port_stop_mode_enter(); +} + +__KERNEL__ void cpu_standby_mode_enter(void) +{ + port_standby_mode_enter(); +} + +#endif /* TOS_CFG_PWR_MGR_EN */ + +__KERNEL__ k_stack_t *cpu_task_stk_init(void *entry, + void *arg, + void *exit, + k_stack_t *stk_base, + size_t stk_size) +{ + cpu_data_t *sp; + + sp = (cpu_data_t *)&stk_base[stk_size]; + sp = (cpu_data_t *)((cpu_addr_t)sp & 0xFFFFFFF8); + +#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u + uint8_t *slot = (uint8_t *)&stk_base[0]; + for (; slot < (uint8_t *)sp; ++slot) { + *slot = 0xCC; + } +#endif + + /* auto-saved on exception(pendSV) by hardware */ + *--sp = (cpu_data_t)0x01000000u; /* xPSR */ + *--sp = (cpu_data_t)entry; /* entry */ + *--sp = (cpu_data_t)exit; /* R14 (LR) */ + *--sp = (cpu_data_t)0x12121212u; /* R12 */ + *--sp = (cpu_data_t)0x03030303u; /* R3 */ + *--sp = (cpu_data_t)0x02020202u; /* R2 */ + *--sp = (cpu_data_t)0x01010101u; /* R1 */ + *--sp = (cpu_data_t)arg; /* R0: arg */ + + /* Remaining registers saved on process stack */ + /* EXC_RETURN = 0xFFFFFFFDL + Initial state: Thread mode + non-floating-point state + PSP + 31 - 28 : EXC_RETURN flag, 0xF + 27 - 5 : reserved, 0xFFFFFE + 4 : 1, basic stack frame; 0, extended stack frame + 3 : 1, return to Thread mode; 0, return to Handler mode + 2 : 1, return to PSP; 0, return to MSP + 1 : reserved, 0 + 0 : reserved, 1 + */ +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + *--sp = (cpu_data_t)0xFFFFFFFDL; +#endif + + *--sp = (cpu_data_t)0x11111111u; /* R11 */ + *--sp = (cpu_data_t)0x10101010u; /* R10 */ + *--sp = (cpu_data_t)0x09090909u; /* R9 */ + *--sp = (cpu_data_t)0x08080808u; /* R8 */ + *--sp = (cpu_data_t)0x07070707u; /* R7 */ + *--sp = (cpu_data_t)0x06060606u; /* R6 */ + *--sp = (cpu_data_t)0x05050505u; /* R5 */ + *--sp = (cpu_data_t)0x04040404u; /* R4 */ + + return (k_stack_t *)sp; +} + +#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u + +__KERNEL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth) +{ + uint8_t *slot; + uint8_t *sp, *bp; + int the_depth = 0; + + bp = (uint8_t *)&stk_base[0]; + + sp = &stk_base[stk_size]; + sp = (uint8_t *)((cpu_addr_t)sp & 0xFFFFFFF8); + + for (slot = sp - 1; slot >= bp; --slot) { + if (*slot != 0xCC) { + the_depth = sp - slot; + } + } + + *depth = the_depth; + if (the_depth == stk_size) { + return K_ERR_TASK_STK_OVERFLOW; + } + + return K_ERR_NONE; +} + +#endif + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) +__KERNEL__ void cpu_flush_fpu(void) +{ + (void)__get_FPSCR(); +} +#endif + +__KERNEL__ void cpu_fault_diagnosis(void) +{ + port_fault_diagnosis(); +} + +#endif /* TOS_CFG_FAULT_BACKTRACE_EN */ + diff --git a/arch/arm/arm-v8m/common/tos_fault.c b/arch/arm/arm-v8m/common/tos_fault.c new file mode 100644 index 00000000..d2f2e951 --- /dev/null +++ b/arch/arm/arm-v8m/common/tos_fault.c @@ -0,0 +1,268 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos.h" + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u + +__STATIC_INLINE__ void fault_spin(void) +{ + tos_knl_sched_lock(); + tos_cpu_int_disable(); + while (K_TRUE) { + ; + } +} + +/* EXC_RETURN: + 31 - 28 : EXC_RETURN flag + 27 - 5 : reserved + 4 : 1, basic stack frame; 0, extended stack frame + 3 : 1, return to Thread mode; 0, return to Handler mode + 2 : 1, return to PSP; 0, return to MSP + 1 : reserved, 0 + 0 : reserved, 1 + */ +__STATIC_INLINE__ int fault_is_on_task(cpu_data_t lr) +{ + return (lr & (1u << 2)) != 0; +} + +__STATIC_INLINE__ int fault_is_thumb(cpu_data_t psr) +{ + return (psr & (1u << 24)) != 0; +} + +__STATIC_INLINE__ int fault_is_code(fault_info_t *info, cpu_data_t value) +{ + return value >= info->code_start && value <= info->code_limit; +} + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) +__STATIC_INLINE__ int fault_is_extended_stack_frame(cpu_data_t lr) +{ + return (lr & (1u << 4)) == 0; +} + +__STATIC__ void fault_dump_fpu_frame(fault_fpu_frame_t *fpu_frame) +{ + /* + * As known, v7-m has a feature named "LAZY PUSH", for the reason we do not do any float + * operation in fault_backtrace, cpu will not do the real fpu register push to the stack. + * that means the value we dump in fault_dump_fpu_frame will not be the correct value of + * each FPU register. + * We define a function here which access to FPSCR, if this function involved, cpu will do + * the real FPU register push so we will get the correct dump. + * I know it's ugly, but it works. If you know a better way, please tell me. + */ + cpu_flush_fpu(); + + k_fault_log_writer("\n\n====================== FPU Registers =======================\n"); + k_fault_log_writer(" %s: %08x\n", "FPSCR", fpu_frame->fpscr); + k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n", + "S0 ", fpu_frame->s0, + "S1 ", fpu_frame->s1, + "S2 ", fpu_frame->s2, + "S3 ", fpu_frame->s3); + k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n", + "S4 ", fpu_frame->s4, + "S5 ", fpu_frame->s5, + "S6 ", fpu_frame->s6, + "S7 ", fpu_frame->s7); + k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n", + "S8 ", fpu_frame->s8, + "S9 ", fpu_frame->s9, + "S10", fpu_frame->s10, + "S11", fpu_frame->s11); + k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n", + "S12", fpu_frame->s12, + "S13", fpu_frame->s13, + "S14", fpu_frame->s14, + "S15", fpu_frame->s15); +} + +#endif + +__STATIC__ void fault_dump_cpu_frame(fault_cpu_frame_t *cpu_frame) +{ + k_fault_log_writer("\n\n====================== CPU Registers =======================\n"); + k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n", + "R0 ", cpu_frame->r0, + "R1 ", cpu_frame->r1, + "R2 ", cpu_frame->r2, + "R3 ", cpu_frame->r3); + k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n", + "R12", cpu_frame->r12, + "LR ", cpu_frame->lr, + "PC ", cpu_frame->pc, + "PSR", cpu_frame->spsr); +} + +__STATIC__ void fault_dump_stack(fault_info_t *info, size_t depth) +{ + cpu_addr_t sp = info->sp_before_fault;; + + k_fault_log_writer("\nTASK STACK DUMP:\n"); + while (sp <= info->stack_limit && depth--) { + k_fault_log_writer(" addr: %08x data: %08x\n", sp, (cpu_data_t)*(cpu_data_t *)sp); + sp += sizeof(cpu_addr_t); + } +} + +__STATIC__ void fault_call_stack_backtrace(fault_info_t *info, size_t depth) +{ + cpu_data_t value; + cpu_addr_t sp = info->sp_before_fault; + + if (info->is_stk_ovrf) { + return; + } + + k_fault_log_writer("\n\n====================== Dump Call Stack =====================\n"); + + k_fault_log_writer(" %x\n", info->pc); + + /* walk through the stack, check every content on stack whether is a instruction(code) */ + for (; sp < info->stack_limit && depth; sp += sizeof(cpu_addr_t)) { + value = *((cpu_addr_t *)sp) - sizeof(cpu_addr_t); + + /* if thumb, a instruction's first bit must be 1 */ + if (info->is_thumb && !(value & 1)) { + continue; + } + + if (fault_is_code(info, value)) { + k_fault_log_writer(" %x\n", value); + --depth; + } + } +} + +__STATIC__ void fault_dump_task(fault_info_t *info) +{ + k_task_t *task; + + if (!info->is_on_task) { + return; + } + + task = k_curr_task; + k_fault_log_writer("\n\n====================== Fault on task =======================\n"); + k_fault_log_writer(" TASK NAME: %s\n", task->name); + k_fault_log_writer(" STK BASE: %x\n", info->stack_start); + k_fault_log_writer(" STK SIZE: %x\n", task->stk_size * sizeof(k_stack_t)); + k_fault_log_writer(" STK LIMIT: %x\n", info->stack_limit); + + if (!info->is_stk_ovrf) { + fault_dump_stack(info, K_FAULT_STACK_DUMP_DEPTH); + } +} + +__STATIC__ void fault_dump_information(fault_info_t *info) +{ + k_fault_log_writer("\n\n================== Dump Fault Information ==================\n"); + k_fault_log_writer(" THUMB: %s\n", info->is_thumb ? "TRUE" : "FALSE"); + k_fault_log_writer(" ON TASK: %s\n", info->is_on_task? "TRUE" : "FALSE"); + k_fault_log_writer(" STK OVRF: %s\n", info->is_stk_ovrf? "TRUE" : "FALSE"); + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + k_fault_log_writer(" EXT STK: %s\n", info->is_ext_stk_frm? "TRUE" : "FALSE"); +#endif + + k_fault_log_writer(" PC: %08x\n", info->pc); + k_fault_log_writer(" SP: %08x\n", info->sp_before_fault); + k_fault_log_writer(" STK START: %08x\n", info->stack_start); + k_fault_log_writer(" STK LIMIT: %08x\n", info->stack_limit); + k_fault_log_writer(" COD START: %08x\n", info->code_start); + k_fault_log_writer(" COD LIMIT: %08x\n", info->code_limit); +} + +__STATIC__ void fault_gather_information(cpu_data_t lr, fault_exc_frame_t *frame, fault_info_t *info) +{ + info->is_thumb = fault_is_thumb(frame->cpu_frame.spsr); + info->is_on_task = fault_is_on_task(lr); + + info->pc = frame->cpu_frame.pc; + + info->sp_before_fault = (cpu_addr_t)frame + sizeof(fault_cpu_frame_t); + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + info->is_ext_stk_frm = fault_is_extended_stack_frame(lr); + + if (info->is_ext_stk_frm) { + info->sp_before_fault += sizeof(fault_fpu_frame_t); + } +#endif + + info->code_start = fault_code_start(); + info->code_limit = fault_code_limit(); + + if (info->is_on_task) { + info->stack_start = (cpu_addr_t)k_curr_task->stk_base; + info->stack_limit = info->stack_start + k_curr_task->stk_size * sizeof(k_task_t); + } else { + info->stack_start = fault_msp_start(); + info->stack_limit = fault_msp_limit(); + } + + info->is_stk_ovrf = (info->sp_before_fault < info->stack_start || info->sp_before_fault > info->stack_limit); +} + +__KERNEL__ int fault_default_log_writer(const char *format, ...) +{ + int len; + va_list ap; + + va_start(ap, format); + len = vprintf(format, ap); + va_end(ap); + + return len; +} + +__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer) +{ + k_fault_log_writer = log_writer; +} + +__KERNEL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame) +{ + fault_info_t info; + + fault_gather_information(lr, frame, &info); + + fault_dump_information(&info); + + fault_dump_task(&info); + + fault_dump_cpu_frame(&frame->cpu_frame); + +#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U) + if (info.is_ext_stk_frm) { + fault_dump_fpu_frame(&frame->fpu_frame); + } +#endif + + fault_call_stack_backtrace(&info, K_FAULT_CALL_STACK_BACKTRACE_DEPTH); + + cpu_fault_diagnosis(); + + fault_spin(); +} + +#endif + diff --git a/arch/arm/arm-v8m/cortex-m23/armcc/port.h b/arch/arm/arm-v8m/cortex-m23/armcc/port.h new file mode 100644 index 00000000..10a6c89b --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/armcc/port.h @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _PORT_H_ +#define _PORT_H_ + +__PORT__ void port_int_disable(void); + +__PORT__ void port_int_enable(void); + +__PORT__ cpu_cpsr_t port_cpsr_save(void); + +__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr); + +__PORT__ void port_cpu_reset(void); + +__PORT__ void port_sched_start(void) __NO_RETURN__; + +__PORT__ void port_context_switch(void); + +__PORT__ void port_irq_context_switch(void); + +__PORT__ void port_systick_config(uint32_t cycle_per_tick); + +__PORT__ void port_systick_priority_set(uint32_t prio); + +#if TOS_CFG_TICKLESS_EN > 0u + +__PORT__ void port_systick_resume(void); + +__PORT__ void port_systick_suspend(void); + +__PORT__ void port_systick_reload(uint32_t cycle_per_tick); + +__PORT__ void port_systick_pending_reset(void); + +__PORT__ k_time_t port_systick_max_delay_millisecond(void); + +#endif + +#if TOS_CFG_PWR_MGR_EN > 0u + +__PORT__ void port_sleep_mode_enter(void); + +__PORT__ void port_stop_mode_enter(void); + +__PORT__ void port_standby_mode_enter(void); + +#endif + + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u +__PORT__ void HardFault_Handler(void); + +__PORT__ void port_fault_diagnosis(void); +#endif + +#endif /* _PORT_H_ */ + diff --git a/arch/arm/arm-v8m/cortex-m23/armcc/port_c.c b/arch/arm/arm-v8m/cortex-m23/armcc/port_c.c new file mode 100644 index 00000000..b2e55608 --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/armcc/port_c.c @@ -0,0 +1,145 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos.h" +#include "core_cm0plus.h" + +__PORT__ void port_cpu_reset(void) +{ + NVIC_SystemReset(); +} + +__PORT__ void port_systick_config(uint32_t cycle_per_tick) +{ + (void)SysTick_Config(cycle_per_tick); +} + +__PORT__ void port_systick_priority_set(uint32_t prio) +{ + NVIC_SetPriority(SysTick_IRQn, prio); +} + +#if TOS_CFG_TICKLESS_EN > 0u + +__PORT__ k_time_t port_systick_max_delay_millisecond(void) +{ + k_time_t max_millisecond; + uint32_t max_cycle; + + max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit + max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second + return max_millisecond; +} + +__PORT__ void port_systick_resume(void) +{ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +__PORT__ void port_systick_suspend(void) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; +} + +__PORT__ void port_systick_reload(uint32_t cycle_per_tick) +{ + uint32_t max_cycle; + + max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit + + if (max_cycle - SysTick->VAL > cycle_per_tick - 1u) { + SysTick->LOAD = max_cycle; + } else { + SysTick->LOAD = (cycle_per_tick - 1u) + SysTick->VAL; + } + + SysTick->VAL = 0; +} + +__PORT__ void port_systick_pending_reset(void) +{ + SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; +} + +#endif + +#if TOS_CFG_PWR_MGR_EN > 0u + +__PORT__ void port_sleep_mode_enter(void) +{ +#if 1 + HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI); +#else + HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); +#endif +} + +__PORT__ void port_stop_mode_enter(void) +{ + HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); +} + +__PORT__ void port_standby_mode_enter(void) +{ + HAL_PWR_EnterSTANDBYMode(); +} + +#endif + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u +__PORT__ void port_fault_diagnosis(void) +{ + k_fault_log_writer("fault diagnosis does not supported in CORTEX M0\n"); +} + +/*------------------ RealView Compiler -----------------*/ +/* V5 */ +#if defined(__CC_ARM) + +__PORT__ __ASM__ void HardFault_Handler(void) +{ + IMPORT fault_backtrace + + MOV r0, lr + TST lr, #0x04 + ITE EQ + MRSEQ r1, MSP + MRSNE r1, PSP + BL fault_backtrace +} + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + +__PORT__ void __NAKED__ HardFault_Handler(void) +{ + __ASM__ __VOLATILE__ ( + "MOV r0, lr\n\t" + "TST lr, #0x04\n\t" + "ITE EQ\n\t" + "MRSEQ r1, MSP\n\t" + "MRSNE r1, PSP\n\t" + "BL fault_backtrace\n\t" + ); +} + +#endif /* ARMCC VERSION */ + +#endif /* TOS_CFG_FAULT_BACKTRACE_EN */ + diff --git a/arch/arm/arm-v8m/cortex-m23/armcc/port_config.h b/arch/arm/arm-v8m/cortex-m23/armcc/port_config.h new file mode 100644 index 00000000..b0300236 --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/armcc/port_config.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _PORT_CONFIG_H_ +#define _PORT_CONFIG_H_ + +#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING +// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_HRTIMER_EN 0u +#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u + +#endif /* _PORT_CONFIG_H_ */ + diff --git a/arch/arm/arm-v8m/cortex-m23/armcc/port_s.S b/arch/arm/arm-v8m/cortex-m23/armcc/port_s.S new file mode 100644 index 00000000..114a99cf --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/armcc/port_s.S @@ -0,0 +1,137 @@ + EXPORT port_int_disable + EXPORT port_int_enable + + EXPORT port_cpsr_save + EXPORT port_cpsr_restore + + EXPORT port_sched_start + EXPORT port_context_switch + EXPORT port_irq_context_switch + + EXPORT PendSV_Handler + + IMPORT k_curr_task + IMPORT k_next_task + + +NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register. +NVIC_SYSPRI14 EQU 0xE000ED20 ; System priority register (priority 14). +NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest). +NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. + + + AREA |.text|, CODE, READONLY, ALIGN=2 + THUMB + REQUIRE8 + PRESERVE8 + + GLOBAL port_int_disable +port_int_disable + CPSID I + BX LR + + + GLOBAL port_int_enable +port_int_enable + CPSIE I + BX LR + + + GLOBAL port_cpsr_save +port_cpsr_save + MRS R0, PRIMASK + CPSID I + BX LR + + + GLOBAL port_cpsr_restore +port_cpsr_restore + MSR PRIMASK, R0 + BX LR + + + GLOBAL port_sched_start +port_sched_start + LDR R0, =NVIC_SYSPRI14 + LDR R1, =NVIC_PENDSV_PRI + STR R1, [R0] + + MOVS R0, #0 + MSR PSP, R0 + + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + + CPSIE I + +__unreachable + B __unreachable + + + GLOBAL port_context_switch +port_context_switch + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + BX LR + + + GLOBAL port_irq_context_switch +port_irq_context_switch + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + BX LR + + + GLOBAL PendSV_Handler +PendSV_Handler + CPSID I + MRS R0, PSP + CMP R0, #0 + BEQ PendSVHandler_nosave + + SUBS R0, R0, #0x20 + STMIA R0!, {R4 - R7} + MOV R4, R8 + MOV R5, R9 + MOV R6, R10 + MOV R7, R11 + STMIA R0!, {R4-R7} + SUBS R0, R0, #0x20 + + LDR R1, =k_curr_task + LDR R1, [R1] + STR R0, [R1] + +PendSVHandler_nosave + LDR R0, =k_curr_task + LDR R1, =k_next_task + LDR R2, [R1] + STR R2, [R0] + + LDR R0, [R2] + + LDMIA R0!, {R4 - R7} + LDMIA R0!, {R2 - R3} + MOV R8, R2 + MOV R9, R3 + LDMIA R0!, {R2 - R3} + MOV R10, R2 + MOV R11, R3 + MSR PSP, R0 + + MOV R0, R14 + MOVS R1, #0x04 + ORRS R0, R1 + MOV R14, R0 + + CPSIE I + + BX LR + + ALIGN + + END + diff --git a/arch/arm/arm-v8m/cortex-m23/gcc/port.h b/arch/arm/arm-v8m/cortex-m23/gcc/port.h new file mode 100644 index 00000000..10a6c89b --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/gcc/port.h @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _PORT_H_ +#define _PORT_H_ + +__PORT__ void port_int_disable(void); + +__PORT__ void port_int_enable(void); + +__PORT__ cpu_cpsr_t port_cpsr_save(void); + +__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr); + +__PORT__ void port_cpu_reset(void); + +__PORT__ void port_sched_start(void) __NO_RETURN__; + +__PORT__ void port_context_switch(void); + +__PORT__ void port_irq_context_switch(void); + +__PORT__ void port_systick_config(uint32_t cycle_per_tick); + +__PORT__ void port_systick_priority_set(uint32_t prio); + +#if TOS_CFG_TICKLESS_EN > 0u + +__PORT__ void port_systick_resume(void); + +__PORT__ void port_systick_suspend(void); + +__PORT__ void port_systick_reload(uint32_t cycle_per_tick); + +__PORT__ void port_systick_pending_reset(void); + +__PORT__ k_time_t port_systick_max_delay_millisecond(void); + +#endif + +#if TOS_CFG_PWR_MGR_EN > 0u + +__PORT__ void port_sleep_mode_enter(void); + +__PORT__ void port_stop_mode_enter(void); + +__PORT__ void port_standby_mode_enter(void); + +#endif + + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u +__PORT__ void HardFault_Handler(void); + +__PORT__ void port_fault_diagnosis(void); +#endif + +#endif /* _PORT_H_ */ + diff --git a/arch/arm/arm-v8m/cortex-m23/gcc/port_c.c b/arch/arm/arm-v8m/cortex-m23/gcc/port_c.c new file mode 100644 index 00000000..b2e55608 --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/gcc/port_c.c @@ -0,0 +1,145 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos.h" +#include "core_cm0plus.h" + +__PORT__ void port_cpu_reset(void) +{ + NVIC_SystemReset(); +} + +__PORT__ void port_systick_config(uint32_t cycle_per_tick) +{ + (void)SysTick_Config(cycle_per_tick); +} + +__PORT__ void port_systick_priority_set(uint32_t prio) +{ + NVIC_SetPriority(SysTick_IRQn, prio); +} + +#if TOS_CFG_TICKLESS_EN > 0u + +__PORT__ k_time_t port_systick_max_delay_millisecond(void) +{ + k_time_t max_millisecond; + uint32_t max_cycle; + + max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit + max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second + return max_millisecond; +} + +__PORT__ void port_systick_resume(void) +{ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +__PORT__ void port_systick_suspend(void) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; +} + +__PORT__ void port_systick_reload(uint32_t cycle_per_tick) +{ + uint32_t max_cycle; + + max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit + + if (max_cycle - SysTick->VAL > cycle_per_tick - 1u) { + SysTick->LOAD = max_cycle; + } else { + SysTick->LOAD = (cycle_per_tick - 1u) + SysTick->VAL; + } + + SysTick->VAL = 0; +} + +__PORT__ void port_systick_pending_reset(void) +{ + SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; +} + +#endif + +#if TOS_CFG_PWR_MGR_EN > 0u + +__PORT__ void port_sleep_mode_enter(void) +{ +#if 1 + HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI); +#else + HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); +#endif +} + +__PORT__ void port_stop_mode_enter(void) +{ + HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); +} + +__PORT__ void port_standby_mode_enter(void) +{ + HAL_PWR_EnterSTANDBYMode(); +} + +#endif + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u +__PORT__ void port_fault_diagnosis(void) +{ + k_fault_log_writer("fault diagnosis does not supported in CORTEX M0\n"); +} + +/*------------------ RealView Compiler -----------------*/ +/* V5 */ +#if defined(__CC_ARM) + +__PORT__ __ASM__ void HardFault_Handler(void) +{ + IMPORT fault_backtrace + + MOV r0, lr + TST lr, #0x04 + ITE EQ + MRSEQ r1, MSP + MRSNE r1, PSP + BL fault_backtrace +} + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + +__PORT__ void __NAKED__ HardFault_Handler(void) +{ + __ASM__ __VOLATILE__ ( + "MOV r0, lr\n\t" + "TST lr, #0x04\n\t" + "ITE EQ\n\t" + "MRSEQ r1, MSP\n\t" + "MRSNE r1, PSP\n\t" + "BL fault_backtrace\n\t" + ); +} + +#endif /* ARMCC VERSION */ + +#endif /* TOS_CFG_FAULT_BACKTRACE_EN */ + diff --git a/arch/arm/arm-v8m/cortex-m23/gcc/port_config.h b/arch/arm/arm-v8m/cortex-m23/gcc/port_config.h new file mode 100644 index 00000000..b0300236 --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/gcc/port_config.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _PORT_CONFIG_H_ +#define _PORT_CONFIG_H_ + +#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING +// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_HRTIMER_EN 0u +#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u + +#endif /* _PORT_CONFIG_H_ */ + diff --git a/arch/arm/arm-v8m/cortex-m23/gcc/port_s.S b/arch/arm/arm-v8m/cortex-m23/gcc/port_s.S new file mode 100644 index 00000000..28e5520b --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/gcc/port_s.S @@ -0,0 +1,143 @@ + .global port_int_disable + .global port_int_enable + + .global port_cpsr_save + .global port_cpsr_restore + + .global port_sched_start + .global port_context_switch + .global port_irq_context_switch + + .global PendSV_Handler + + .global k_curr_task + .global k_next_task + + +.equ NVIC_INT_CTRL , 0xE000ED04 @Interrupt control state register. +.equ NVIC_SYSPRI14 , 0xE000ED20 @System priority register (priority 14). +.equ NVIC_PENDSV_PRI , 0x00FF0000 @ PendSV priority value (lowest). +.equ NVIC_PENDSVSET , 0x10000000 @ Value to trigger PendSV exception. + + + .text + .align 2 + .thumb + .syntax unified + +.type port_int_disable, %function +port_int_disable: + CPSID I + BX LR + + +.type port_int_enable, %function +port_int_enable: + CPSIE I + BX LR + + +.type port_cpsr_save, %function +port_cpsr_save: + MRS R0, PRIMASK + CPSID I + BX LR + + +.type port_cpsr_restore, %function +port_cpsr_restore: + MSR PRIMASK, R0 + BX LR + + +.thumb_func +.type port_sched_start, %function +port_sched_start: + LDR R0, =NVIC_SYSPRI14 + + + LDR R1, =NVIC_PENDSV_PRI + + + STR R1, [R0] + + MOVS R0, #0 + MSR PSP, R0 + + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + + CPSIE I + +__unreachable: + B __unreachable + + +.thumb_func +.type port_context_switch, %function +port_context_switch: + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + BX LR + + +.thumb_func +.type port_irq_context_switch, %function +port_irq_context_switch: + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + BX LR + + +.thumb_func +.type PendSV_Handler, %function +PendSV_Handler: + CPSID I + MRS R0, PSP + CMP R0, #0 + BEQ PendSVHandler_nosave + + SUBS R0, R0, #0x20 + STMIA R0!, {R4 - R7} + MOV R4, R8 + MOV R5, R9 + MOV R6, R10 + MOV R7, R11 + STMIA R0!, {R4-R7} + SUBS R0, R0, #0x20 + + LDR R1, =k_curr_task + LDR R1, [R1] + STR R0, [R1] + +PendSVHandler_nosave: + LDR R0, =k_curr_task + LDR R1, =k_next_task + LDR R2, [R1] + STR R2, [R0] + + LDR R0, [R2] + + LDMIA R0!, {R4 - R7} + LDMIA R0!, {R2 - R3} + MOV R8, R2 + MOV R9, R3 + LDMIA R0!, {R2 - R3} + MOV R10, R2 + MOV R11, R3 + MSR PSP, R0 + + MOV R0, R14 + MOVS R1, #0x04 + ORRS R0, R1 + MOV R14, R0 + + CPSIE I + + BX LR + +.end + diff --git a/arch/arm/arm-v8m/cortex-m23/iccarm/port.h b/arch/arm/arm-v8m/cortex-m23/iccarm/port.h new file mode 100644 index 00000000..10a6c89b --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/iccarm/port.h @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _PORT_H_ +#define _PORT_H_ + +__PORT__ void port_int_disable(void); + +__PORT__ void port_int_enable(void); + +__PORT__ cpu_cpsr_t port_cpsr_save(void); + +__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr); + +__PORT__ void port_cpu_reset(void); + +__PORT__ void port_sched_start(void) __NO_RETURN__; + +__PORT__ void port_context_switch(void); + +__PORT__ void port_irq_context_switch(void); + +__PORT__ void port_systick_config(uint32_t cycle_per_tick); + +__PORT__ void port_systick_priority_set(uint32_t prio); + +#if TOS_CFG_TICKLESS_EN > 0u + +__PORT__ void port_systick_resume(void); + +__PORT__ void port_systick_suspend(void); + +__PORT__ void port_systick_reload(uint32_t cycle_per_tick); + +__PORT__ void port_systick_pending_reset(void); + +__PORT__ k_time_t port_systick_max_delay_millisecond(void); + +#endif + +#if TOS_CFG_PWR_MGR_EN > 0u + +__PORT__ void port_sleep_mode_enter(void); + +__PORT__ void port_stop_mode_enter(void); + +__PORT__ void port_standby_mode_enter(void); + +#endif + + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u +__PORT__ void HardFault_Handler(void); + +__PORT__ void port_fault_diagnosis(void); +#endif + +#endif /* _PORT_H_ */ + diff --git a/arch/arm/arm-v8m/cortex-m23/iccarm/port_c.c b/arch/arm/arm-v8m/cortex-m23/iccarm/port_c.c new file mode 100644 index 00000000..b2e55608 --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/iccarm/port_c.c @@ -0,0 +1,145 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#include "tos.h" +#include "core_cm0plus.h" + +__PORT__ void port_cpu_reset(void) +{ + NVIC_SystemReset(); +} + +__PORT__ void port_systick_config(uint32_t cycle_per_tick) +{ + (void)SysTick_Config(cycle_per_tick); +} + +__PORT__ void port_systick_priority_set(uint32_t prio) +{ + NVIC_SetPriority(SysTick_IRQn, prio); +} + +#if TOS_CFG_TICKLESS_EN > 0u + +__PORT__ k_time_t port_systick_max_delay_millisecond(void) +{ + k_time_t max_millisecond; + uint32_t max_cycle; + + max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit + max_millisecond = (k_time_t)((uint64_t)max_cycle * K_TIME_MILLISEC_PER_SEC / TOS_CFG_CPU_CLOCK); // CLOCK: cycle per second + return max_millisecond; +} + +__PORT__ void port_systick_resume(void) +{ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +__PORT__ void port_systick_suspend(void) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; +} + +__PORT__ void port_systick_reload(uint32_t cycle_per_tick) +{ + uint32_t max_cycle; + + max_cycle = SysTick_LOAD_RELOAD_Msk; // 24 bit + + if (max_cycle - SysTick->VAL > cycle_per_tick - 1u) { + SysTick->LOAD = max_cycle; + } else { + SysTick->LOAD = (cycle_per_tick - 1u) + SysTick->VAL; + } + + SysTick->VAL = 0; +} + +__PORT__ void port_systick_pending_reset(void) +{ + SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; +} + +#endif + +#if TOS_CFG_PWR_MGR_EN > 0u + +__PORT__ void port_sleep_mode_enter(void) +{ +#if 1 + HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI); +#else + HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); +#endif +} + +__PORT__ void port_stop_mode_enter(void) +{ + HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); +} + +__PORT__ void port_standby_mode_enter(void) +{ + HAL_PWR_EnterSTANDBYMode(); +} + +#endif + +#if TOS_CFG_FAULT_BACKTRACE_EN > 0u +__PORT__ void port_fault_diagnosis(void) +{ + k_fault_log_writer("fault diagnosis does not supported in CORTEX M0\n"); +} + +/*------------------ RealView Compiler -----------------*/ +/* V5 */ +#if defined(__CC_ARM) + +__PORT__ __ASM__ void HardFault_Handler(void) +{ + IMPORT fault_backtrace + + MOV r0, lr + TST lr, #0x04 + ITE EQ + MRSEQ r1, MSP + MRSNE r1, PSP + BL fault_backtrace +} + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + +__PORT__ void __NAKED__ HardFault_Handler(void) +{ + __ASM__ __VOLATILE__ ( + "MOV r0, lr\n\t" + "TST lr, #0x04\n\t" + "ITE EQ\n\t" + "MRSEQ r1, MSP\n\t" + "MRSNE r1, PSP\n\t" + "BL fault_backtrace\n\t" + ); +} + +#endif /* ARMCC VERSION */ + +#endif /* TOS_CFG_FAULT_BACKTRACE_EN */ + diff --git a/arch/arm/arm-v8m/cortex-m23/iccarm/port_config.h b/arch/arm/arm-v8m/cortex-m23/iccarm/port_config.h new file mode 100644 index 00000000..b0300236 --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/iccarm/port_config.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------- + * Tencent is pleased to support the open source community by making TencentOS + * available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * If you have downloaded a copy of the TencentOS binary from Tencent, please + * note that the TencentOS binary is licensed under the BSD 3-Clause License. + * + * If you have downloaded a copy of the TencentOS source code from Tencent, + * please note that TencentOS source code is licensed under the BSD 3-Clause + * License, except for the third-party components listed below which are + * subject to different license terms. Your integration of TencentOS into your + * own projects may require compliance with the BSD 3-Clause License, as well + * as the other licenses applicable to the third-party components included + * within TencentOS. + *---------------------------------------------------------------------------*/ + +#ifndef _PORT_CONFIG_H_ +#define _PORT_CONFIG_H_ + +#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING +// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32 +#define TOS_CFG_CPU_HRTIMER_EN 0u +#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u + +#endif /* _PORT_CONFIG_H_ */ + diff --git a/arch/arm/arm-v8m/cortex-m23/iccarm/port_s.S b/arch/arm/arm-v8m/cortex-m23/iccarm/port_s.S new file mode 100644 index 00000000..ce6b02f7 --- /dev/null +++ b/arch/arm/arm-v8m/cortex-m23/iccarm/port_s.S @@ -0,0 +1,126 @@ + PUBLIC port_int_disable + PUBLIC port_int_enable + + PUBLIC port_cpsr_save + PUBLIC port_cpsr_restore + + PUBLIC port_sched_start + PUBLIC port_context_switch + PUBLIC port_irq_context_switch + + PUBLIC PendSV_Handler + + EXTERN k_curr_task + EXTERN k_next_task + + +NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register. +NVIC_SYSPRI14 EQU 0xE000ED20 ; System priority register (priority 14). +NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest). +NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. + + + RSEG CODE:CODE:NOROOT(2) + THUMB + +port_int_disable + CPSID I + BX LR + + +port_int_enable + CPSIE I + BX LR + + +port_cpsr_save + MRS R0, PRIMASK + CPSID I + BX LR + + +port_cpsr_restore + MSR PRIMASK, R0 + BX LR + + +port_sched_start + LDR R0, =NVIC_SYSPRI14 + LDR R1, =NVIC_PENDSV_PRI + STR R1, [R0] + + MOVS R0, #0 + MSR PSP, R0 + + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + + CPSIE I + +__unreachable + B __unreachable + + +port_context_switch + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + BX LR + + +port_irq_context_switch + LDR R0, =NVIC_INT_CTRL + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + BX LR + + +PendSV_Handler + CPSID I + MRS R0, PSP + CMP R0, #0 + BEQ PendSVHandler_nosave + + SUBS R0, R0, #0x20 + STMIA R0!, {R4 - R7} + MOV R4, R8 + MOV R5, R9 + MOV R6, R10 + MOV R7, R11 + STMIA R0!, {R4-R7} + SUBS R0, R0, #0x20 + + LDR R1, =k_curr_task + LDR R1, [R1] + STR R0, [R1] + +PendSVHandler_nosave + LDR R0, =k_curr_task + LDR R1, =k_next_task + LDR R2, [R1] + STR R2, [R0] + + LDR R0, [R2] + + LDMIA R0!, {R4 - R7} + LDMIA R0!, {R2 - R3} + MOV R8, R2 + MOV R9, R3 + LDMIA R0!, {R2 - R3} + MOV R10, R2 + MOV R11, R3 + MSR PSP, R0 + + MOV R0, R14 + MOVS R1, #0x04 + ORRS R0, R1 + MOV R14, R0 + + CPSIE I + + BX LR + + + END +