add cortex-m33 support, TrustZone-m not supported now

add cortex-m33 support, TrustZone-m not supported now
This commit is contained in:
supowang
2020-11-05 15:36:33 +08:00
parent 6de2e8b5e1
commit abd5fa994b
275 changed files with 302366 additions and 0 deletions

View File

@@ -0,0 +1,312 @@
/*----------------------------------------------------------------------------
* 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.
*---------------------------------------------------------------------------*/
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _PORT_H_
#define _PORT_H_
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
typedef struct port_fault_regs {
union {
/* System Handler Control and State Register (0xE000ED24) */
uint32_t value;
struct {
/* Read as 1 if memory management fault is active */
uint32_t MEMFAULTACT : 1;
/* Read as 1 if bus fault exception is active */
uint32_t BUSFAULTACT : 1;
uint32_t UnusedBits1 : 1;
/* Read as 1 if usage fault exception is active */
uint32_t USGFAULTACT : 1;
uint32_t UnusedBits2 : 3;
/* Read as 1 if SVC exception is active */
uint32_t SVCALLACT : 1;
/* Read as 1 if debug monitor exception is active */
uint32_t MONITORACT : 1;
uint32_t UnusedBits3 : 1;
/* Read as 1 if PendSV exception is active */
uint32_t PENDSVACT : 1;
/* Read as 1 if SYSTICK exception is active */
uint32_t SYSTICKACT : 1;
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
uint32_t USGFAULTPENDED : 1;
/* Memory management fault pended; memory management fault started but was replaced by a
higher-priority exception */
uint32_t MEMFAULTPENDED : 1;
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
exception */
uint32_t BUSFAULTPENDED : 1;
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
uint32_t SVCALLPENDED : 1;
/* Memory management fault handler enable */
uint32_t MEMFAULTENA : 1;
/* Bus fault handler enable */
uint32_t BUSFAULTENA : 1;
/* Usage fault handler enable */
uint32_t USGFAULTENA : 1;
} bits;
} syshndctrl;
union {
uint32_t value;
struct {
union {
/* Memory Management Fault Status Register (0xE000ED28) */
uint8_t value;
struct {
/* Instruction access violation */
uint8_t IACCVIOL : 1;
/* Data access violation */
uint8_t DACCVIOL : 1;
uint8_t UnusedBits : 1;
/* Unstacking error */
uint8_t MUNSTKERR : 1;
/* Stacking error */
uint8_t MSTKERR : 1;
/* Floating-point lazy state preservation (M4/M7) */
uint8_t MLSPERR : 1;
uint8_t UnusedBits2 : 1;
/* Indicates the MMAR is valid */
uint8_t MMARVALID : 1;
} bits;
} mfsr;
union {
/* Bus Fault Status Register (0xE000ED29) */
uint8_t value;
struct {
/* Instruction access violation */
uint8_t IBUSERR : 1;
/* Precise data access violation */
uint8_t PRECISERR : 1;
/* Imprecise data access violation */
uint8_t IMPREISERR : 1;
/* Unstacking error */
uint8_t UNSTKERR : 1;
/* Stacking error */
uint8_t STKERR : 1;
/* Floating-point lazy state preservation (M4/M7) */
uint8_t LSPERR : 1;
uint8_t UnusedBits : 1;
/* Indicates BFAR is valid */
uint8_t BFARVALID : 1;
} bits;
} bfsr;
union {
/* Usage Fault Status Register (0xE000ED2A) */
uint16_t value;
struct {
/* Attempts to execute an undefined instruction */
uint16_t UNDEFINSTR : 1;
/* Attempts to switch to an invalid state (e.g., ARM) */
uint16_t INVSTATE : 1;
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
uint16_t INVPC : 1;
/* Attempts to execute a coprocessor instruction */
uint16_t NOCP : 1;
uint16_t UnusedBits : 4;
/* Indicates that an unaligned access fault has taken place */
uint16_t UNALIGNED : 1;
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
uint16_t DIVBYZERO0 : 1;
} bits;
} ufsr;
} part;
} cfsr;
/* Memory Management Fault Address Register (0xE000ED34) */
uint32_t mmar;
/* Bus Fault Manage Address Register (0xE000ED38) */
uint32_t bfar;
union {
/* Hard Fault Status Register (0xE000ED2C) */
uint32_t value;
struct {
uint32_t UnusedBits : 1;
/* Indicates hard fault is caused by failed vector fetch */
uint32_t VECTBL : 1;
uint32_t UnusedBits2 : 28;
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
uint32_t FORCED : 1;
/* Indicates hard fault is triggered by debug event */
uint32_t DEBUGEVT : 1;
} bits;
} hfsr;
union {
/* Debug Fault Status Register (0xE000ED30) */
uint32_t value;
struct {
/* Halt requested in NVIC */
uint32_t HALTED : 1;
/* BKPT instruction executed */
uint32_t BKPT : 1;
/* DWT match occurred */
uint32_t DWTTRAP : 1;
/* Vector fetch occurred */
uint32_t VCATCH : 1;
/* EDBGRQ signal asserted */
uint32_t EXTERNAL : 1;
} bits;
} dfsr;
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
uint32_t afsr;
} port_fault_regs_t;
enum fault_info {
FAULT_INFO_ASSERT_ON_THREAD,
FAULT_INFO_HFSR_VECTBL,
FAULT_INFO_MFSR_IACCVIOL,
FAULT_INFO_MFSR_DACCVIOL,
FAULT_INFO_MFSR_MUNSTKERR,
FAULT_INFO_MFSR_MSTKERR,
FAULT_INFO_MFSR_MLSPERR,
FAULT_INFO_BFSR_IBUSERR,
FAULT_INFO_BFSR_PRECISERR,
FAULT_INFO_BFSR_IMPREISERR,
FAULT_INFO_BFSR_UNSTKERR,
FAULT_INFO_BFSR_STKERR,
FAULT_INFO_BFSR_LSPERR,
FAULT_INFO_UFSR_UNDEFINSTR,
FAULT_INFO_UFSR_INVSTATE,
FAULT_INFO_UFSR_INVPC,
FAULT_INFO_UFSR_NOCP,
FAULT_INFO_UFSR_UNALIGNED,
FAULT_INFO_UFSR_DIVBYZERO0,
FAULT_INFO_DFSR_HALTED,
FAULT_INFO_DFSR_BKPT,
FAULT_INFO_DFSR_DWTTRAP,
FAULT_INFO_DFSR_VCATCH,
FAULT_INFO_DFSR_EXTERNAL,
FAULT_INFO_MMAR,
FAULT_INFO_BFAR,
};
static const char *const fault_msg[] = {
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
};
__PORT__ void HardFault_Handler(void);
__PORT__ void port_fault_diagnosis(void);
#endif
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
__PORT__ uint32_t port_clz(uint32_t val);
#endif
__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
#endif /* _PORT_H_ */

View File

@@ -0,0 +1,281 @@
/*----------------------------------------------------------------------------
* 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.
*---------------------------------------------------------------------------*/
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "tos_k.h"
#include "core_cm33.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__ k_cycle_t port_systick_max_reload_cycle(void)
{
return SysTick_LOAD_RELOAD_Msk;
}
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
{
port_systick_config(cycle_per_tick);
}
__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
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
{
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
if (regs->hfsr.bits.VECTBL) {
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
}
if (regs->hfsr.bits.FORCED) {
/* Memory Management Fault */
if (regs->cfsr.part.mfsr.value) {
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
}
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
}
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
}
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
}
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
}
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
}
}
}
/* Bus Fault */
if (regs->cfsr.part.bfsr.value) {
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
}
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
}
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
}
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
}
if (regs->cfsr.part.bfsr.bits.STKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
}
if (regs->cfsr.part.bfsr.bits.LSPERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
}
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
}
}
}
/* Usage Fault */
if (regs->cfsr.part.ufsr.value) {
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
}
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
}
if (regs->cfsr.part.ufsr.bits.INVPC) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
}
if (regs->cfsr.part.ufsr.bits.NOCP) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
}
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
}
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
}
}
}
/* Debug Fault */
if (regs->hfsr.bits.DEBUGEVT) {
if (regs->dfsr.value) {
if (regs->dfsr.bits.HALTED) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
}
if (regs->dfsr.bits.BKPT) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
}
if (regs->dfsr.bits.DWTTRAP) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
}
if (regs->dfsr.bits.VCATCH) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
}
if (regs->dfsr.bits.EXTERNAL) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
}
}
}
}
__PORT__ void port_fault_diagnosis(void)
{
port_fault_regs_t regs;
regs.syshndctrl.value = SCB->SHCSR;
regs.cfsr.value = SCB->CFSR;
regs.mmar = SCB->MMFAR;
regs.bfar = SCB->BFAR;
regs.hfsr.value = SCB->HFSR;
regs.dfsr.value = SCB->DFSR;
regs.afsr = SCB->AFSR;
port_fault_do_diagnosis(&regs);
}
/*------------------ 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 */

View File

@@ -0,0 +1,37 @@
/*----------------------------------------------------------------------------
* 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 1u
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
#if (defined(ARMCC_V5) && !defined(__TARGET_FPU_SOFTVFP)) || \
(defined(ARMCC_V6) && defined(__ARM_PCS_VFP))
#define TOS_CFG_CPU_ARM_FPU_EN 1u
#else
#define TOS_CFG_CPU_ARM_FPU_EN 0u
#endif
#endif /* _PORT_CONFIG_H_ */

View File

@@ -0,0 +1,188 @@
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 port_clz
EXPORT PendSV_Handler
IMPORT k_curr_task
IMPORT k_next_task
SCB_VTOR EQU 0xE000ED08
NVIC_INT_CTRL EQU 0xE000ED04
NVIC_SYSPRI14 EQU 0xE000ED22
NVIC_PENDSV_PRI EQU 0xFF
NVIC_PENDSVSET EQU 0x10000000
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_clz
port_clz
CLZ R0, R0
BX LR
GLOBAL port_sched_start
port_sched_start
CPSID I
; set pendsv priority lowest
; otherwise trigger pendsv in port_irq_context_switch will cause a context switch in irq
; that would be a disaster
MOV32 R0, NVIC_SYSPRI14
MOV32 R1, NVIC_PENDSV_PRI
STRB R1, [R0]
LDR R0, =SCB_VTOR
LDR R0, [R0]
LDR R0, [R0]
MSR MSP, R0
; k_curr_task = k_next_task
MOV32 R0, k_curr_task
MOV32 R1, k_next_task
LDR R2, [R1]
STR R2, [R0]
; sp = k_next_task->sp
LDR R0, [R2]
; PSP = sp
MSR PSP, R0
; using PSP
MRS R0, CONTROL
ORR R0, R0, #2
MSR CONTROL, R0
ISB
; restore r4-11 from new process stack
LDMFD SP!, {R4 - R11}
IF {FPU} != "SoftVFP"
; ignore EXC_RETURN the first switch
LDMFD SP!, {R0}
ENDIF
; restore r0, r3
LDMFD SP!, {R0 - R3}
; load R12 and LR
LDMFD SP!, {R12, LR}
; load PC and discard xPSR
LDMFD SP!, {R1, R2}
CPSIE I
BX R1
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
_context_save
; R0-R3, R12, LR, PC, xPSR is saved automatically here
IF {FPU} != "SoftVFP"
; is it extended frame?
TST LR, #0x10
IT EQ
VSTMDBEQ R0!, {S16 - S31}
; S0 - S16, FPSCR saved automatically here
; save EXC_RETURN
STMFD R0!, {LR}
ENDIF
; save remaining regs r4-11 on process stack
STMFD R0!, {R4 - R11}
; k_curr_task->sp = PSP
MOV32 R5, k_curr_task
LDR R6, [R5]
; R0 is SP of process being switched out
STR R0, [R6]
_context_restore
; k_curr_task = k_next_task
MOV32 R1, k_next_task
LDR R2, [R1]
STR R2, [R5]
; R0 = k_next_task->sp
LDR R0, [R2]
; restore R4 - R11
LDMFD R0!, {R4 - R11}
IF {FPU} != "SoftVFP"
; restore EXC_RETURN
LDMFD R0!, {LR}
; is it extended frame?
TST LR, #0x10
IT EQ
VLDMIAEQ R0!, {S16 - S31}
ENDIF
; Load PSP with new process SP
MSR PSP, R0
CPSIE I
; R0-R3, R12, LR, PC, xPSR restored automatically here
; S0 - S16, FPSCR restored automatically here if FPCA = 1
BX LR
ALIGN
END

View File

@@ -0,0 +1,311 @@
/*----------------------------------------------------------------------------
* 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.
*---------------------------------------------------------------------------*/
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _PORT_H_
#define _PORT_H_
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
typedef struct port_fault_regs {
union {
/* System Handler Control and State Register (0xE000ED24) */
uint32_t value;
struct {
/* Read as 1 if memory management fault is active */
uint32_t MEMFAULTACT : 1;
/* Read as 1 if bus fault exception is active */
uint32_t BUSFAULTACT : 1;
uint32_t UnusedBits1 : 1;
/* Read as 1 if usage fault exception is active */
uint32_t USGFAULTACT : 1;
uint32_t UnusedBits2 : 3;
/* Read as 1 if SVC exception is active */
uint32_t SVCALLACT : 1;
/* Read as 1 if debug monitor exception is active */
uint32_t MONITORACT : 1;
uint32_t UnusedBits3 : 1;
/* Read as 1 if PendSV exception is active */
uint32_t PENDSVACT : 1;
/* Read as 1 if SYSTICK exception is active */
uint32_t SYSTICKACT : 1;
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
uint32_t USGFAULTPENDED : 1;
/* Memory management fault pended; memory management fault started but was replaced by a
higher-priority exception */
uint32_t MEMFAULTPENDED : 1;
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
exception */
uint32_t BUSFAULTPENDED : 1;
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
uint32_t SVCALLPENDED : 1;
/* Memory management fault handler enable */
uint32_t MEMFAULTENA : 1;
/* Bus fault handler enable */
uint32_t BUSFAULTENA : 1;
/* Usage fault handler enable */
uint32_t USGFAULTENA : 1;
} bits;
} syshndctrl;
union {
uint32_t value;
struct {
union {
/* Memory Management Fault Status Register (0xE000ED28) */
uint8_t value;
struct {
/* Instruction access violation */
uint8_t IACCVIOL : 1;
/* Data access violation */
uint8_t DACCVIOL : 1;
uint8_t UnusedBits : 1;
/* Unstacking error */
uint8_t MUNSTKERR : 1;
/* Stacking error */
uint8_t MSTKERR : 1;
/* Floating-point lazy state preservation (M4/M7) */
uint8_t MLSPERR : 1;
uint8_t UnusedBits2 : 1;
/* Indicates the MMAR is valid */
uint8_t MMARVALID : 1;
} bits;
} mfsr;
union {
/* Bus Fault Status Register (0xE000ED29) */
uint8_t value;
struct {
/* Instruction access violation */
uint8_t IBUSERR : 1;
/* Precise data access violation */
uint8_t PRECISERR : 1;
/* Imprecise data access violation */
uint8_t IMPREISERR : 1;
/* Unstacking error */
uint8_t UNSTKERR : 1;
/* Stacking error */
uint8_t STKERR : 1;
/* Floating-point lazy state preservation (M4/M7) */
uint8_t LSPERR : 1;
uint8_t UnusedBits : 1;
/* Indicates BFAR is valid */
uint8_t BFARVALID : 1;
} bits;
} bfsr;
union {
/* Usage Fault Status Register (0xE000ED2A) */
uint16_t value;
struct {
/* Attempts to execute an undefined instruction */
uint16_t UNDEFINSTR : 1;
/* Attempts to switch to an invalid state (e.g., ARM) */
uint16_t INVSTATE : 1;
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
uint16_t INVPC : 1;
/* Attempts to execute a coprocessor instruction */
uint16_t NOCP : 1;
uint16_t UnusedBits : 4;
/* Indicates that an unaligned access fault has taken place */
uint16_t UNALIGNED : 1;
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
uint16_t DIVBYZERO0 : 1;
} bits;
} ufsr;
} part;
} cfsr;
/* Memory Management Fault Address Register (0xE000ED34) */
uint32_t mmar;
/* Bus Fault Manage Address Register (0xE000ED38) */
uint32_t bfar;
union {
/* Hard Fault Status Register (0xE000ED2C) */
uint32_t value;
struct {
uint32_t UnusedBits : 1;
/* Indicates hard fault is caused by failed vector fetch */
uint32_t VECTBL : 1;
uint32_t UnusedBits2 : 28;
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
uint32_t FORCED : 1;
/* Indicates hard fault is triggered by debug event */
uint32_t DEBUGEVT : 1;
} bits;
} hfsr;
union {
/* Debug Fault Status Register (0xE000ED30) */
uint32_t value;
struct {
/* Halt requested in NVIC */
uint32_t HALTED : 1;
/* BKPT instruction executed */
uint32_t BKPT : 1;
/* DWT match occurred */
uint32_t DWTTRAP : 1;
/* Vector fetch occurred */
uint32_t VCATCH : 1;
/* EDBGRQ signal asserted */
uint32_t EXTERNAL : 1;
} bits;
} dfsr;
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
uint32_t afsr;
} port_fault_regs_t;
enum fault_info {
FAULT_INFO_ASSERT_ON_THREAD,
FAULT_INFO_HFSR_VECTBL,
FAULT_INFO_MFSR_IACCVIOL,
FAULT_INFO_MFSR_DACCVIOL,
FAULT_INFO_MFSR_MUNSTKERR,
FAULT_INFO_MFSR_MSTKERR,
FAULT_INFO_MFSR_MLSPERR,
FAULT_INFO_BFSR_IBUSERR,
FAULT_INFO_BFSR_PRECISERR,
FAULT_INFO_BFSR_IMPREISERR,
FAULT_INFO_BFSR_UNSTKERR,
FAULT_INFO_BFSR_STKERR,
FAULT_INFO_BFSR_LSPERR,
FAULT_INFO_UFSR_UNDEFINSTR,
FAULT_INFO_UFSR_INVSTATE,
FAULT_INFO_UFSR_INVPC,
FAULT_INFO_UFSR_NOCP,
FAULT_INFO_UFSR_UNALIGNED,
FAULT_INFO_UFSR_DIVBYZERO0,
FAULT_INFO_DFSR_HALTED,
FAULT_INFO_DFSR_BKPT,
FAULT_INFO_DFSR_DWTTRAP,
FAULT_INFO_DFSR_VCATCH,
FAULT_INFO_DFSR_EXTERNAL,
FAULT_INFO_MMAR,
FAULT_INFO_BFAR,
};
static const char *const fault_msg[] = {
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
};
__PORT__ void HardFault_Handler(void);
__PORT__ void port_fault_diagnosis(void);
#endif
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
__PORT__ uint32_t port_clz(uint32_t val);
#endif
__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
#endif /* _PORT_H_ */

View File

@@ -0,0 +1,255 @@
/*----------------------------------------------------------------------------
* 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.
*---------------------------------------------------------------------------*/
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "tos_k.h"
#include "core_cm33.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)
{
port_systick_config(cycle_per_tick);
}
__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
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
{
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
if (regs->hfsr.bits.VECTBL) {
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
}
if (regs->hfsr.bits.FORCED) {
/* Memory Management Fault */
if (regs->cfsr.part.mfsr.value) {
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
}
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
}
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
}
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
}
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
}
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
}
}
}
/* Bus Fault */
if (regs->cfsr.part.bfsr.value) {
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
}
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
}
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
}
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
}
if (regs->cfsr.part.bfsr.bits.STKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
}
if (regs->cfsr.part.bfsr.bits.LSPERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
}
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
}
}
}
/* Usage Fault */
if (regs->cfsr.part.ufsr.value) {
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
}
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
}
if (regs->cfsr.part.ufsr.bits.INVPC) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
}
if (regs->cfsr.part.ufsr.bits.NOCP) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
}
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
}
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
}
}
}
/* Debug Fault */
if (regs->hfsr.bits.DEBUGEVT) {
if (regs->dfsr.value) {
if (regs->dfsr.bits.HALTED) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
}
if (regs->dfsr.bits.BKPT) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
}
if (regs->dfsr.bits.DWTTRAP) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
}
if (regs->dfsr.bits.VCATCH) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
}
if (regs->dfsr.bits.EXTERNAL) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
}
}
}
}
__PORT__ void port_fault_diagnosis(void)
{
port_fault_regs_t regs;
regs.syshndctrl.value = SCB->SHCSR;
regs.cfsr.value = SCB->CFSR;
regs.mmar = SCB->MMFAR;
regs.bfar = SCB->BFAR;
regs.hfsr.value = SCB->HFSR;
regs.dfsr.value = SCB->DFSR;
regs.afsr = SCB->AFSR;
port_fault_do_diagnosis(&regs);
}
__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 /* TOS_CFG_FAULT_BACKTRACE_EN */

View File

@@ -0,0 +1,36 @@
/*----------------------------------------------------------------------------
* 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 1u
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
#define TOS_CFG_CPU_ARM_FPU_EN 1u
#else
#define TOS_CFG_CPU_ARM_FPU_EN 0u
#endif
#endif /* _PORT_CONFIG_H_ */

View File

@@ -0,0 +1,202 @@
.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 port_clz
.global PendSV_Handler
.extern k_curr_task
.extern k_next_task
.equ SCB_VTOR, 0xE000ED08
.equ NVIC_INT_CTRL, 0xE000ED04
.equ NVIC_SYSPRI14, 0xE000ED22
.equ NVIC_PENDSV_PRI, 0xFF
.equ NVIC_PENDSVSET, 0x10000000
.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
.type port_clz, %function
port_clz:
CLZ R0, R0
BX LR
.thumb_func
.type port_sched_start, %function
port_sched_start:
CPSID I
@ set pendsv priority lowest
@ otherwise trigger pendsv in port_irq_context_switch will cause a context switch in irq
@ that would be a disaster
MOVW R0, #:lower16:NVIC_SYSPRI14
MOVT R0, #:upper16:NVIC_SYSPRI14
MOVW R1, #:lower16:NVIC_PENDSV_PRI
MOVT R1, #:upper16:NVIC_PENDSV_PRI
STRB R1, [R0]
MOVW R0, #:lower16:SCB_VTOR
MOVT R0, #:upper16:SCB_VTOR
LDR R0, [R0]
LDR R0, [R0]
MSR MSP, R0
MOVW R0, #:lower16:k_curr_task
MOVT R0, #:upper16:k_curr_task
@ k_curr_task = k_next_task;
MOVW R1, #:lower16:k_next_task
MOVT R1, #:upper16:k_next_task
LDR R2, [R1]
STR R2, [R0]
@ sp = k_next_task->sp
LDR R0, [R2]
@ PSP = sp
MSR PSP, R0
MRS R0, CONTROL
ORR R0, R0, #2
MSR CONTROL, R0
ISB
@ restore r4-11 from new process stack
LDMFD SP!, {R4 - R11}
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
@ ignore EXC_RETURN the first switch
LDMFD SP!, {R0}
#endif
@ restore r0, r3
LDMFD SP!, {R0 - R3}
@ load R12 and LR
LDMFD SP!, {R12, LR}
@ load PC and discard xPSR
LDMFD SP!, {R1, R2}
CPSIE I
BX R1
.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
_context_save:
@ R0-R3, R12, LR, PC, xPSR is saved automatically here
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
@ is it extended frame?
TST LR, #0x10
IT EQ
VSTMDBEQ R0!, {S16 - S31}
@ S0 - S16, FPSCR saved automatically here
@ save EXC_RETURN
STMFD R0!, {LR}
#endif
@ save remaining regs r4 - 11 on process stack
STMFD R0!, {R4 - R11}
@ k_curr_task->sp = PSP;
MOVW R5, #:lower16:k_curr_task
MOVT R5, #:upper16:k_curr_task
LDR R6, [R5]
@ R0 is SP of process being switched out
STR R0, [R6]
_context_restore:
@ k_curr_task = k_next_task;
MOVW R1, #:lower16:k_next_task
MOVT R1, #:upper16:k_next_task
LDR R2, [R1]
STR R2, [R5]
@ R0 = k_next_task->sp
LDR R0, [R2]
@ restore R4 - R11
LDMFD R0!, {R4 - R11}
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
@ restore EXC_RETURN
LDMFD R0!, {LR}
@ is it extended frame?
TST LR, #0x10
IT EQ
VLDMIAEQ R0!, {S16 - S31}
#endif
@ Load PSP with new process SP
MSR PSP, R0
CPSIE I
@ R0-R3, R12, LR, PC, xPSR restored automatically here
@ S0 - S16, FPSCR restored automatically here if FPCA = 1
BX LR
.end

View File

@@ -0,0 +1,312 @@
/*----------------------------------------------------------------------------
* 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.
*---------------------------------------------------------------------------*/
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _PORT_H_
#define _PORT_H_
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
typedef struct port_fault_regs {
union {
/* System Handler Control and State Register (0xE000ED24) */
uint32_t value;
struct {
/* Read as 1 if memory management fault is active */
uint32_t MEMFAULTACT : 1;
/* Read as 1 if bus fault exception is active */
uint32_t BUSFAULTACT : 1;
uint32_t UnusedBits1 : 1;
/* Read as 1 if usage fault exception is active */
uint32_t USGFAULTACT : 1;
uint32_t UnusedBits2 : 3;
/* Read as 1 if SVC exception is active */
uint32_t SVCALLACT : 1;
/* Read as 1 if debug monitor exception is active */
uint32_t MONITORACT : 1;
uint32_t UnusedBits3 : 1;
/* Read as 1 if PendSV exception is active */
uint32_t PENDSVACT : 1;
/* Read as 1 if SYSTICK exception is active */
uint32_t SYSTICKACT : 1;
/* Usage fault pended; usage fault started but was replaced by a higher-priority exception */
uint32_t USGFAULTPENDED : 1;
/* Memory management fault pended; memory management fault started but was replaced by a
higher-priority exception */
uint32_t MEMFAULTPENDED : 1;
/* Bus fault pended; bus fault handler was started but was replaced by a higher-priority
exception */
uint32_t BUSFAULTPENDED : 1;
/* SVC pended; SVC was started but was replaced by a higher-priority exception */
uint32_t SVCALLPENDED : 1;
/* Memory management fault handler enable */
uint32_t MEMFAULTENA : 1;
/* Bus fault handler enable */
uint32_t BUSFAULTENA : 1;
/* Usage fault handler enable */
uint32_t USGFAULTENA : 1;
} bits;
} syshndctrl;
union {
uint32_t value;
struct {
union {
/* Memory Management Fault Status Register (0xE000ED28) */
uint8_t value;
struct {
/* Instruction access violation */
uint8_t IACCVIOL : 1;
/* Data access violation */
uint8_t DACCVIOL : 1;
uint8_t UnusedBits : 1;
/* Unstacking error */
uint8_t MUNSTKERR : 1;
/* Stacking error */
uint8_t MSTKERR : 1;
/* Floating-point lazy state preservation (M4/M7) */
uint8_t MLSPERR : 1;
uint8_t UnusedBits2 : 1;
/* Indicates the MMAR is valid */
uint8_t MMARVALID : 1;
} bits;
} mfsr;
union {
/* Bus Fault Status Register (0xE000ED29) */
uint8_t value;
struct {
/* Instruction access violation */
uint8_t IBUSERR : 1;
/* Precise data access violation */
uint8_t PRECISERR : 1;
/* Imprecise data access violation */
uint8_t IMPREISERR : 1;
/* Unstacking error */
uint8_t UNSTKERR : 1;
/* Stacking error */
uint8_t STKERR : 1;
/* Floating-point lazy state preservation (M4/M7) */
uint8_t LSPERR : 1;
uint8_t UnusedBits : 1;
/* Indicates BFAR is valid */
uint8_t BFARVALID : 1;
} bits;
} bfsr;
union {
/* Usage Fault Status Register (0xE000ED2A) */
uint16_t value;
struct {
/* Attempts to execute an undefined instruction */
uint16_t UNDEFINSTR : 1;
/* Attempts to switch to an invalid state (e.g., ARM) */
uint16_t INVSTATE : 1;
/* Attempts to do an exception with a bad value in the EXC_RETURN number */
uint16_t INVPC : 1;
/* Attempts to execute a coprocessor instruction */
uint16_t NOCP : 1;
uint16_t UnusedBits : 4;
/* Indicates that an unaligned access fault has taken place */
uint16_t UNALIGNED : 1;
/* Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set) */
uint16_t DIVBYZERO0 : 1;
} bits;
} ufsr;
} part;
} cfsr;
/* Memory Management Fault Address Register (0xE000ED34) */
uint32_t mmar;
/* Bus Fault Manage Address Register (0xE000ED38) */
uint32_t bfar;
union {
/* Hard Fault Status Register (0xE000ED2C) */
uint32_t value;
struct {
uint32_t UnusedBits : 1;
/* Indicates hard fault is caused by failed vector fetch */
uint32_t VECTBL : 1;
uint32_t UnusedBits2 : 28;
/* Indicates hard fault is taken because of bus fault/memory management fault/usage fault */
uint32_t FORCED : 1;
/* Indicates hard fault is triggered by debug event */
uint32_t DEBUGEVT : 1;
} bits;
} hfsr;
union {
/* Debug Fault Status Register (0xE000ED30) */
uint32_t value;
struct {
/* Halt requested in NVIC */
uint32_t HALTED : 1;
/* BKPT instruction executed */
uint32_t BKPT : 1;
/* DWT match occurred */
uint32_t DWTTRAP : 1;
/* Vector fetch occurred */
uint32_t VCATCH : 1;
/* EDBGRQ signal asserted */
uint32_t EXTERNAL : 1;
} bits;
} dfsr;
/* Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional) */
uint32_t afsr;
} port_fault_regs_t;
enum fault_info {
FAULT_INFO_ASSERT_ON_THREAD,
FAULT_INFO_HFSR_VECTBL,
FAULT_INFO_MFSR_IACCVIOL,
FAULT_INFO_MFSR_DACCVIOL,
FAULT_INFO_MFSR_MUNSTKERR,
FAULT_INFO_MFSR_MSTKERR,
FAULT_INFO_MFSR_MLSPERR,
FAULT_INFO_BFSR_IBUSERR,
FAULT_INFO_BFSR_PRECISERR,
FAULT_INFO_BFSR_IMPREISERR,
FAULT_INFO_BFSR_UNSTKERR,
FAULT_INFO_BFSR_STKERR,
FAULT_INFO_BFSR_LSPERR,
FAULT_INFO_UFSR_UNDEFINSTR,
FAULT_INFO_UFSR_INVSTATE,
FAULT_INFO_UFSR_INVPC,
FAULT_INFO_UFSR_NOCP,
FAULT_INFO_UFSR_UNALIGNED,
FAULT_INFO_UFSR_DIVBYZERO0,
FAULT_INFO_DFSR_HALTED,
FAULT_INFO_DFSR_BKPT,
FAULT_INFO_DFSR_DWTTRAP,
FAULT_INFO_DFSR_VCATCH,
FAULT_INFO_DFSR_EXTERNAL,
FAULT_INFO_MMAR,
FAULT_INFO_BFAR,
};
static const char *const fault_msg[] = {
[FAULT_INFO_ASSERT_ON_THREAD] = "Assert on thread %s\n",
[FAULT_INFO_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
[FAULT_INFO_MFSR_IACCVIOL] = "Memory management fault: instruction access violation\n",
[FAULT_INFO_MFSR_DACCVIOL] = "Memory management fault: data access violation\n",
[FAULT_INFO_MFSR_MUNSTKERR] = "Memory management fault: unstacking error\n",
[FAULT_INFO_MFSR_MSTKERR] = "Memory management fault: stacking error\n",
[FAULT_INFO_MFSR_MLSPERR] = "Memory management fault: floating-point lazy state preservation\n",
[FAULT_INFO_BFSR_IBUSERR] = "Bus fault: instruction access violation\n",
[FAULT_INFO_BFSR_PRECISERR] = "Bus fault: precise data access violation\n",
[FAULT_INFO_BFSR_IMPREISERR] = "Bus fault: imprecise data access violation\n",
[FAULT_INFO_BFSR_UNSTKERR] = "Bus fault: unstacking error\n",
[FAULT_INFO_BFSR_STKERR] = "Bus fault: stacking error\n",
[FAULT_INFO_BFSR_LSPERR] = "Bus fault: floating-point lazy state preservation\n",
[FAULT_INFO_UFSR_UNDEFINSTR] = "Usage fault: undefined instruction\n",
[FAULT_INFO_UFSR_INVSTATE] = "Usage fault: invalid state (e.g., ARM)\n",
[FAULT_INFO_UFSR_INVPC] = "Usage fault: invalid EXC_RETURN\n",
[FAULT_INFO_UFSR_NOCP] = "Usage fault: coprocessor instruction\n",
[FAULT_INFO_UFSR_UNALIGNED] = "Usage fault: unaligned access\n",
[FAULT_INFO_UFSR_DIVBYZERO0] = "Usage fault: divide by zero(can be set only if DIV_0_TRP is set)\n",
[FAULT_INFO_DFSR_HALTED] = "Debug fault: halt requested in NVIC\n",
[FAULT_INFO_DFSR_BKPT] = "Debug fault: BKPT instruction executed\n",
[FAULT_INFO_DFSR_DWTTRAP] = "Debug fault: DWT match occurred\n",
[FAULT_INFO_DFSR_VCATCH] = "Debug fault: Vector fetch occurred\n",
[FAULT_INFO_DFSR_EXTERNAL] = "Debug fault: EDBGRQ signal asserted\n",
[FAULT_INFO_MMAR] = "The memory management fault occurred address is %08x\n",
[FAULT_INFO_BFAR] = "The bus fault occurred address is %08x\n",
};
__PORT__ void HardFault_Handler(void);
__PORT__ void port_fault_diagnosis(void);
#endif
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 1u)
__PORT__ uint32_t port_clz(uint32_t val);
#endif
__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
#endif /* _PORT_H_ */

View File

@@ -0,0 +1,261 @@
/*----------------------------------------------------------------------------
* 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.
*---------------------------------------------------------------------------*/
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "tos_k.h"
#include "core_cm33.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__ k_cycle_t port_systick_max_reload_cycle(void)
{
return SysTick_LOAD_RELOAD_Msk;
}
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
{
port_systick_config(cycle_per_tick);
}
__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
__STATIC__ void port_fault_do_diagnosis(port_fault_regs_t *regs)
{
k_fault_log_writer("\n\n====================== Fault Diagnosis =====================\n");
if (regs->hfsr.bits.VECTBL) {
k_fault_log_writer(fault_msg[FAULT_INFO_HFSR_VECTBL]);
}
if (regs->hfsr.bits.FORCED) {
/* Memory Management Fault */
if (regs->cfsr.part.mfsr.value) {
if (regs->cfsr.part.mfsr.bits.IACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_IACCVIOL]);
}
if (regs->cfsr.part.mfsr.bits.DACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_DACCVIOL]);
}
if (regs->cfsr.part.mfsr.bits.MUNSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MUNSTKERR]);
}
if (regs->cfsr.part.mfsr.bits.MSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MSTKERR]);
}
if (regs->cfsr.part.mfsr.bits.MLSPERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_MFSR_MLSPERR]);
}
if (regs->cfsr.part.mfsr.bits.MMARVALID) {
if (regs->cfsr.part.mfsr.bits.IACCVIOL || regs->cfsr.part.mfsr.bits.DACCVIOL) {
k_fault_log_writer(fault_msg[FAULT_INFO_MMAR], regs->mmar);
}
}
}
/* Bus Fault */
if (regs->cfsr.part.bfsr.value) {
if (regs->cfsr.part.bfsr.bits.IBUSERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IBUSERR]);
}
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_PRECISERR]);
}
if (regs->cfsr.part.bfsr.bits.IMPREISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_IMPREISERR]);
}
if (regs->cfsr.part.bfsr.bits.UNSTKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_UNSTKERR]);
}
if (regs->cfsr.part.bfsr.bits.STKERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_STKERR]);
}
if (regs->cfsr.part.bfsr.bits.LSPERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFSR_LSPERR]);
}
if (regs->cfsr.part.bfsr.bits.BFARVALID) {
if (regs->cfsr.part.bfsr.bits.PRECISERR) {
k_fault_log_writer(fault_msg[FAULT_INFO_BFAR], regs->bfar);
}
}
}
/* Usage Fault */
if (regs->cfsr.part.ufsr.value) {
if (regs->cfsr.part.ufsr.bits.UNDEFINSTR) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNDEFINSTR]);
}
if (regs->cfsr.part.ufsr.bits.INVSTATE) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVSTATE]);
}
if (regs->cfsr.part.ufsr.bits.INVPC) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_INVPC]);
}
if (regs->cfsr.part.ufsr.bits.NOCP) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_NOCP]);
}
if (regs->cfsr.part.ufsr.bits.UNALIGNED) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_UNALIGNED]);
}
if (regs->cfsr.part.ufsr.bits.DIVBYZERO0) {
k_fault_log_writer(fault_msg[FAULT_INFO_UFSR_DIVBYZERO0]);
}
}
}
/* Debug Fault */
if (regs->hfsr.bits.DEBUGEVT) {
if (regs->dfsr.value) {
if (regs->dfsr.bits.HALTED) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_HALTED]);
}
if (regs->dfsr.bits.BKPT) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_BKPT]);
}
if (regs->dfsr.bits.DWTTRAP) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_DWTTRAP]);
}
if (regs->dfsr.bits.VCATCH) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_VCATCH]);
}
if (regs->dfsr.bits.EXTERNAL) {
k_fault_log_writer(fault_msg[FAULT_INFO_DFSR_EXTERNAL]);
}
}
}
}
__PORT__ void port_fault_diagnosis(void)
{
port_fault_regs_t regs;
regs.syshndctrl.value = SCB->SHCSR;
regs.cfsr.value = SCB->CFSR;
regs.mmar = SCB->MMFAR;
regs.bfar = SCB->BFAR;
regs.hfsr.value = SCB->HFSR;
regs.dfsr.value = SCB->DFSR;
regs.afsr = SCB->AFSR;
port_fault_do_diagnosis(&regs);
}
__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"
"LDR r2, =fault_backtrace\n\t"
"BX r2\n\t"
);
}
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */

View File

@@ -0,0 +1,36 @@
/*----------------------------------------------------------------------------
* 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 1u
#define TOS_CFG_CPU_BYTE_ORDER CPU_BYTE_ORDER_LITTLE_ENDIAN
#ifndef __ARMVFP__
#define TOS_CFG_CPU_ARM_FPU_EN 0u
#else
#define TOS_CFG_CPU_ARM_FPU_EN 1u
#endif
#endif /* _PORT_CONFIG_H_ */

View File

@@ -0,0 +1,176 @@
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 port_clz
PUBLIC PendSV_Handler
EXTERN k_curr_task
EXTERN k_next_task
SCB_VTOR EQU 0xE000ED08
NVIC_INT_CTRL EQU 0xE000ED04
NVIC_SYSPRI14 EQU 0xE000ED22
NVIC_PENDSV_PRI EQU 0xFF
NVIC_PENDSVSET EQU 0x10000000
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_clz
CLZ R0, R0
BX LR
port_sched_start
CPSID I
; set pendsv priority lowest
; otherwise trigger pendsv in port_irq_context_switch will cause a context switch in irq
; that would be a disaster
MOV32 R0, NVIC_SYSPRI14
MOV32 R1, NVIC_PENDSV_PRI
STRB R1, [R0]
LDR R0, =SCB_VTOR
LDR R0, [R0]
LDR R0, [R0]
MSR MSP, R0
; k_curr_task = k_next_task
MOV32 R0, k_curr_task
MOV32 R1, k_next_task
LDR R2, [R1]
STR R2, [R0]
; sp = k_next_task->sp
LDR R0, [R2]
; PSP = sp
MSR PSP, R0
; using PSP
MRS R0, CONTROL
ORR R0, R0, #2
MSR CONTROL, R0
ISB
; restore r4-11 from new process stack
LDMFD SP!, {R4 - R11}
#if defined(__ARMVFP__)
; ignore EXC_RETURN the first switch
LDMFD SP!, {R0}
#endif
; restore r0, r3
LDMFD SP!, {R0 - R3}
; load R12 and LR
LDMFD SP!, {R12, LR}
; load PC and discard xPSR
LDMFD SP!, {R1, R2}
CPSIE I
BX R1
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
_context_save
; R0-R3, R12, LR, PC, xPSR is saved automatically here
#if defined(__ARMVFP__)
; is it extended frame?
TST LR, #0x10
IT EQ
VSTMDBEQ R0!, {S16 - S31}
; S0 - S16, FPSCR saved automatically here
; save EXC_RETURN
STMFD R0!, {LR}
#endif
; save remaining regs r4-11 on process stack
STMFD R0!, {R4 - R11}
; k_curr_task->sp = PSP
MOV32 R5, k_curr_task
LDR R6, [R5]
; R0 is SP of process being switched out
STR R0, [R6]
_context_restore
; k_curr_task = k_next_task
MOV32 R1, k_next_task
LDR R2, [R1]
STR R2, [R5]
; R0 = k_next_task->sp
LDR R0, [R2]
; restore R4 - R11
LDMFD R0!, {R4 - R11}
#if defined(__ARMVFP__)
; restore EXC_RETURN
LDMFD R0!, {LR}
; is it extended frame?
TST LR, #0x10
IT EQ
VLDMIAEQ R0!, {S16 - S31}
#endif
; Load PSP with new process SP
MSR PSP, R0
CPSIE I
; R0-R3, R12, LR, PC, xPSR restored automatically here
; S0 - S16, FPSCR restored automatically here if FPCA = 1
BX LR
END