arch: arc: update the ARC port
* add basic synopsys arc em processor support * add basic arc nsim em virtual board support * add basic arc mwdt toolchain support Signed-off-by: Watson Zeng <zhiwei@synopsys.com>
This commit is contained in:
313
arch/arc/arcem/port.h
Normal file
313
arch/arc/arcem/port.h
Normal file
@@ -0,0 +1,313 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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__ uint32_t port_cpu_clz(uint32_t);
|
||||
|
||||
__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_ */
|
||||
|
151
arch/arc/arcem/port_c.c
Normal file
151
arch/arc/arcem/port_c.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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 "arc/arc_timer.h"
|
||||
#include "board.h"
|
||||
#include "arc/arc_exception.h"
|
||||
|
||||
__PORT__ void port_cpu_reset(void)
|
||||
{
|
||||
exc_entry_reset();
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_config(uint32_t cycle_per_tick) // Configure SysTick to generate an interrupt every cycle_per_tick
|
||||
{
|
||||
arc_timer_int_clear(0); // nsim #define BOARD_SYS_TIMER_ID TIMER_0
|
||||
board_timer_update(cycle_per_tick); // board.c
|
||||
}
|
||||
__PORT__ void port_systick_priority_set(uint32_t prio) // Sets the int priority
|
||||
{
|
||||
int_pri_set(INTNO_TIMER0, prio); // get system tick from timer 0 arc_timer.h
|
||||
}
|
||||
|
||||
|
||||
#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 = arc_aux_read(AUX_TIMER0_LIMIT); // AUX_TIMER0_CNT, reset value 0x00FFFFFF
|
||||
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)
|
||||
{
|
||||
arc_aux_write(AUX_TIMER0_CTRL, TIMER_CTRL_IE); // enables the generation of an interrupt after the timer has reached its limit
|
||||
arc_aux_write(AUX_TIMER0_CNT, 0); //Writing to this register sets 0 for the timer, and restarts the timer
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_suspend(void)
|
||||
{
|
||||
arc_aux_write(AUX_TIMER0_CTRL, TIMER_CTRL_NH); // counting is suspended during host debugger interactions with the processor.
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_reload(uint32_t cycle_per_tick)
|
||||
{
|
||||
uint32_t max_cycle;
|
||||
uint32_t systick_value;
|
||||
|
||||
max_cycle = arc_aux_read(AUX_TIMER0_LIMIT); // AUX_TIMER0_CNT, reset value 0x00FFFFFF
|
||||
systick_value = arc_aux_read(AUX_TIMER0_CNT);
|
||||
|
||||
if (max_cycle - systick_value > cycle_per_tick - 1u) {
|
||||
arc_aux_write(AUX_TIMER0_LIMIT, max_cycle);
|
||||
} else {
|
||||
arc_aux_write(AUX_TIMER0_LIMIT, (cycle_per_tick - 1u) + systick_value);
|
||||
}
|
||||
|
||||
arc_aux_write(AUX_TIMER0_CNT, 0);
|
||||
}
|
||||
|
||||
__PORT__ void port_systick_pending_reset(void)
|
||||
{
|
||||
// SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
|
||||
arc_aux_write(AUX_TIMER0_CTRL, TIMER_CTRL_IP); // interrupt pending
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
|
||||
__PORT__ void port_sleep_mode_enter(void)
|
||||
{
|
||||
Asm("sleep");
|
||||
}
|
||||
|
||||
__PORT__ void port_stop_mode_enter(void)
|
||||
{
|
||||
Asm("brk");
|
||||
}
|
||||
|
||||
__PORT__ void port_standby_mode_enter(void)
|
||||
{
|
||||
Asm("nop");
|
||||
}
|
||||
|
||||
#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");
|
||||
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void port_fault_diagnosis(void)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== Fault Diagnosis .. =====================\n");
|
||||
|
||||
}
|
||||
|
||||
__PORT__ void __NAKED__ HardFault_Handler(void)
|
||||
{
|
||||
k_fault_log_writer("\n\n====================== Fault Diagnosis Handler =====================\n");
|
||||
}
|
||||
|
||||
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */
|
||||
|
30
arch/arc/arcem/port_config.h
Normal file
30
arch/arc/arcem/port_config.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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_EN 0u
|
||||
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
|
||||
|
||||
#define TOS_CFG_CPU_ARM_FPU_EN 0u
|
||||
|
||||
#endif /* _PORT_CONFIG_H_ */
|
||||
|
360
arch/arc/arcem/port_s.s
Normal file
360
arch/arc/arcem/port_s.s
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Synopsys, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define __ASSEMBLY__
|
||||
#include "arc.h"
|
||||
#include "arc_asm_common.h"
|
||||
|
||||
.global k_curr_task
|
||||
.global k_next_task
|
||||
|
||||
.global g_exc_nest_count
|
||||
.global g_context_switch_reqflg
|
||||
|
||||
.global tos_knl_irq_enter
|
||||
.global tos_knl_irq_leave
|
||||
|
||||
.text
|
||||
.align 4
|
||||
dispatcher:
|
||||
st sp, [r0] // ld r0, [k_curr_task]
|
||||
ld sp, [r1] // ld r1, [k_next_task]
|
||||
# k_curr_task = k_next_task;
|
||||
st r1, [k_curr_task]
|
||||
pop r0
|
||||
j [r0]
|
||||
|
||||
/* return routine when task dispatch happened in task context */
|
||||
dispatch_r:
|
||||
RESTORE_NONSCRATCH_REGS
|
||||
j [blink]
|
||||
|
||||
/*
|
||||
* void port_int_disable(void);
|
||||
*/
|
||||
.global port_int_disable
|
||||
.align 4
|
||||
port_int_disable:
|
||||
clri
|
||||
j [blink]
|
||||
|
||||
/*
|
||||
* void port_int_enable(void);
|
||||
*/
|
||||
.global port_int_enable
|
||||
.align 4
|
||||
port_int_enable:
|
||||
seti
|
||||
j [blink]
|
||||
|
||||
/*
|
||||
* cpu_cpsr_t port_cpsr_save(void);
|
||||
*/
|
||||
.global port_cpsr_save
|
||||
.align 4
|
||||
port_cpsr_save:
|
||||
clri r0
|
||||
j [blink]
|
||||
|
||||
/*
|
||||
* void port_cpsr_restore(cpu_cpsr_t cpsr);
|
||||
*/
|
||||
.global port_cpsr_restore
|
||||
.align 4
|
||||
port_cpsr_restore:
|
||||
seti r0
|
||||
j [blink]
|
||||
|
||||
/*
|
||||
* uint32_t port_cpu_clz(uint32_t val)
|
||||
* r0 --> val
|
||||
*/
|
||||
.global port_cpu_clz
|
||||
.align 4
|
||||
port_cpu_clz:
|
||||
breq r0, 0, cpu_clz_return
|
||||
ffs r1, r0
|
||||
add r0, r1, 1
|
||||
cpu_clz_return:
|
||||
j [blink]
|
||||
|
||||
/*
|
||||
* void port_sched_start(void)
|
||||
*/
|
||||
.global port_sched_start
|
||||
.align 4
|
||||
port_sched_start:
|
||||
ld r0, [k_curr_task]
|
||||
ld sp, [r0]
|
||||
pop r0
|
||||
j [r0]
|
||||
|
||||
|
||||
/*
|
||||
* void port_context_switch(void)
|
||||
*/
|
||||
.global port_context_switch
|
||||
.align 4
|
||||
port_context_switch:
|
||||
SAVE_NONSCRATCH_REGS
|
||||
mov r2, dispatch_r
|
||||
push r2
|
||||
ld r0, [k_curr_task]
|
||||
ld r1, [k_next_task]
|
||||
b dispatcher
|
||||
|
||||
/*
|
||||
* void port_irq_context_switch(void)
|
||||
*/
|
||||
.global port_irq_context_switch
|
||||
.align 4
|
||||
port_irq_context_switch:
|
||||
mov r0, 1
|
||||
st r0, [g_context_switch_reqflg]
|
||||
j [blink]
|
||||
|
||||
|
||||
/*
|
||||
* void start_r(void)
|
||||
*/
|
||||
.global start_r
|
||||
.align 4
|
||||
start_r:
|
||||
pop blink;
|
||||
pop r1
|
||||
pop r2
|
||||
pop r0
|
||||
|
||||
j_s.d [r1]
|
||||
kflag r2
|
||||
|
||||
/****** exceptions and interrupts handing ******/
|
||||
/****** entry for exception handling ******/
|
||||
.global exc_entry_cpu
|
||||
.align 4
|
||||
exc_entry_cpu:
|
||||
|
||||
EXCEPTION_PROLOGUE
|
||||
|
||||
mov blink, sp
|
||||
mov r3, sp /* as exception handler's para(p_excinfo) */
|
||||
|
||||
ld r0, [g_exc_nest_count]
|
||||
add r1, r0, 1
|
||||
st r1, [g_exc_nest_count]
|
||||
brne r0, 0, exc_handler_1
|
||||
/* change to exception stack if interrupt happened in task context */
|
||||
mov sp, _e_stack
|
||||
exc_handler_1:
|
||||
PUSH blink
|
||||
|
||||
jl tos_knl_irq_enter
|
||||
|
||||
lr r0, [AUX_ECR]
|
||||
lsr r0, r0, 16
|
||||
mov r1, exc_int_handler_table
|
||||
ld.as r2, [r1, r0]
|
||||
|
||||
mov r0, r3
|
||||
jl [r2]
|
||||
|
||||
jl tos_knl_irq_leave
|
||||
|
||||
/* interrupts are not allowed */
|
||||
ret_exc:
|
||||
POP sp
|
||||
mov r1, g_exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
st r0, [r1]
|
||||
brne r0, 0, ret_exc_1 /* nest exception case */
|
||||
lr r1, [AUX_IRQ_ACT] /* nest interrupt case */
|
||||
brne r1, 0, ret_exc_1
|
||||
|
||||
ld r0, [g_context_switch_reqflg]
|
||||
brne r0, 0, ret_exc_2
|
||||
ret_exc_1: /* return from non-task context, interrupts or exceptions are nested */
|
||||
EXCEPTION_EPILOGUE
|
||||
rtie
|
||||
|
||||
/* there is a dispatch request */
|
||||
ret_exc_2:
|
||||
/* clear dispatch request */
|
||||
mov r0, 0
|
||||
st r0, [g_context_switch_reqflg]
|
||||
|
||||
SAVE_CALLEE_REGS /* save callee save registers */
|
||||
|
||||
/* clear exception bit to do exception exit by SW */
|
||||
lr r0, [AUX_STATUS32]
|
||||
bclr r0, r0, AUX_STATUS_BIT_AE
|
||||
kflag r0
|
||||
|
||||
mov r1, ret_exc_r /* save return address */
|
||||
PUSH r1
|
||||
|
||||
ld r0, [k_curr_task]
|
||||
ld r1, [k_next_task]
|
||||
b dispatcher
|
||||
|
||||
ret_exc_r:
|
||||
/* recover exception status */
|
||||
lr r0, [AUX_STATUS32]
|
||||
bset r0, r0, AUX_STATUS_BIT_AE
|
||||
kflag r0
|
||||
|
||||
RESTORE_CALLEE_REGS
|
||||
EXCEPTION_EPILOGUE
|
||||
rtie
|
||||
|
||||
/****** entry for normal interrupt exception handling ******/
|
||||
.global exc_entry_int /* entry for interrupt handling */
|
||||
.align 4
|
||||
exc_entry_int:
|
||||
#if ARC_FEATURE_FIRQ == 1
|
||||
/* check whether it is P0 interrupt */
|
||||
#if ARC_FEATURE_RGF_NUM_BANKS > 1
|
||||
lr r0, [AUX_IRQ_ACT]
|
||||
btst r0, 0
|
||||
jnz exc_entry_firq
|
||||
#else
|
||||
PUSH r10
|
||||
lr r10, [AUX_IRQ_ACT]
|
||||
btst r10, 0
|
||||
POP r10
|
||||
jnz exc_entry_firq
|
||||
#endif
|
||||
#endif
|
||||
INTERRUPT_PROLOGUE
|
||||
|
||||
mov blink, sp
|
||||
|
||||
clri /* disable interrupt */
|
||||
ld r3, [g_exc_nest_count]
|
||||
add r2, r3, 1
|
||||
st r2, [g_exc_nest_count]
|
||||
seti /* enable higher priority interrupt */
|
||||
|
||||
brne r3, 0, irq_handler_1
|
||||
/* change to exception stack if interrupt happened in task context */
|
||||
mov sp, _e_stack
|
||||
#if ARC_FEATURE_STACK_CHECK
|
||||
#if ARC_FEATURE_SEC_PRESENT
|
||||
lr r0, [AUX_SEC_STAT]
|
||||
bclr r0, r0, AUX_SEC_STAT_BIT_SSC
|
||||
sflag r0
|
||||
#else
|
||||
lr r0, [AUX_STATUS32]
|
||||
bclr r0, r0, AUX_STATUS_BIT_SC
|
||||
kflag r0
|
||||
#endif
|
||||
#endif
|
||||
irq_handler_1:
|
||||
PUSH blink
|
||||
|
||||
jl tos_knl_irq_enter
|
||||
|
||||
lr r0, [AUX_IRQ_CAUSE]
|
||||
sr r0, [AUX_IRQ_SELECT]
|
||||
mov r1, exc_int_handler_table
|
||||
ld.as r2, [r1, r0] /* r2 = exc_int_handler_table + irqno *4 */
|
||||
/* handle software triggered interrupt */
|
||||
lr r3, [AUX_IRQ_HINT]
|
||||
cmp r3, r0
|
||||
bne.d irq_hint_handled
|
||||
xor r3, r3, r3
|
||||
sr r3, [AUX_IRQ_HINT]
|
||||
irq_hint_handled:
|
||||
lr r3, [AUX_IRQ_PRIORITY]
|
||||
PUSH r3 /* save irq priority */
|
||||
|
||||
jl [r2] /* jump to interrupt handler */
|
||||
|
||||
jl tos_knl_irq_leave
|
||||
|
||||
ret_int:
|
||||
clri /* disable interrupt */
|
||||
POP r3 /* irq priority */
|
||||
POP sp
|
||||
mov r1, g_exc_nest_count
|
||||
ld r0, [r1]
|
||||
sub r0, r0, 1
|
||||
st r0, [r1]
|
||||
/* if there are multi-bits set in IRQ_ACT, it's still in nest interrupt */
|
||||
lr r0, [AUX_IRQ_CAUSE]
|
||||
sr r0, [AUX_IRQ_SELECT]
|
||||
lr r3, [AUX_IRQ_PRIORITY]
|
||||
lr r1, [AUX_IRQ_ACT]
|
||||
bclr r2, r1, r3
|
||||
brne r2, 0, ret_int_1
|
||||
|
||||
ld r0, [g_context_switch_reqflg]
|
||||
brne r0, 0, ret_int_2
|
||||
ret_int_1: /* return from non-task context */
|
||||
INTERRUPT_EPILOGUE
|
||||
rtie
|
||||
/* there is a dispatch request */
|
||||
ret_int_2:
|
||||
/* clear dispatch request */
|
||||
mov r0, 0
|
||||
st r0, [g_context_switch_reqflg]
|
||||
|
||||
/* interrupt return by SW */
|
||||
lr r10, [AUX_IRQ_ACT]
|
||||
PUSH r10
|
||||
bclr r10, r10, r3 /* clear related bits in IRQ_ACT */
|
||||
sr r10, [AUX_IRQ_ACT]
|
||||
|
||||
SAVE_CALLEE_REGS /* save callee save registers */
|
||||
mov r1, ret_int_r /* save return address */
|
||||
PUSH r1
|
||||
|
||||
ld r0, [k_curr_task]
|
||||
ld r1, [k_next_task]
|
||||
b dispatcher
|
||||
|
||||
ret_int_r:
|
||||
RESTORE_CALLEE_REGS
|
||||
/* recover AUX_IRQ_ACT to restore the interrup status */
|
||||
POPAX AUX_IRQ_ACT
|
||||
INTERRUPT_EPILOGUE
|
||||
rtie
|
||||
|
||||
/****** entry for fast irq exception handling ******/
|
||||
.global exc_entry_firq
|
||||
.align 4
|
||||
exc_entry_firq:
|
||||
SAVE_FIQ_EXC_REGS
|
||||
|
||||
jl tos_knl_irq_enter
|
||||
|
||||
lr r0, [AUX_IRQ_CAUSE]
|
||||
mov r1, exc_int_handler_table
|
||||
/* r2 = _kernel_exc_tbl + irqno *4 */
|
||||
ld.as r2, [r1, r0]
|
||||
|
||||
/* for the case of software triggered interrupt */
|
||||
lr r3, [AUX_IRQ_HINT]
|
||||
cmp r3, r0
|
||||
bne.d firq_hint_handled
|
||||
xor r3, r3, r3
|
||||
sr r3, [AUX_IRQ_HINT]
|
||||
firq_hint_handled:
|
||||
/* jump to interrupt handler */
|
||||
mov r0, sp
|
||||
jl [r2]
|
||||
|
||||
jl tos_knl_irq_leave
|
||||
|
||||
firq_return:
|
||||
RESTORE_FIQ_EXC_REGS
|
||||
rtie
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user