add cortex-v7a support

How To Run:
    see TencentOS-tiny\board\ALPHA_I.MX_emmc_256ddr\README.md

TODO Next:
1. VFP support
2. fault diagnosis support
3. qemu vexpress ca9 support
4. raspberry pi support
5. SMP support
This commit is contained in:
daishengdong
2020-01-19 19:06:24 +08:00
parent 08ab1d88e1
commit 3d9d6198c8
115 changed files with 98070 additions and 29 deletions

View File

@@ -0,0 +1,43 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_ARM_H_
#define _TOS_ARM_H_
#define DSB __ASM__ __VOLATILE__("dsb" ::: "memory")
#define DMB __ASM__ __VOLATILE__("dmb" ::: "memory")
#define ISB __ASM__ __VOLATILE__("isb" ::: "memory")
#define __STRINGIFY(x) #x
#define ARM_MCR(coproc, opcode_1, src, CRn, CRm, opcode_2) \
__ASM__ __VOLATILE__ ("MCR " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
__STRINGIFY(opcode_2) \
: : "r" (src) )
#define ARM_MRC(coproc, opcode_1, CRn, CRm, opcode_2) \
({ \
uint32_t __dst; \
__ASM__ __VOLATILE__ ("MRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
__STRINGIFY(opcode_2) \
: "=r" (__dst) ); \
__dst; \
})
#endif /* _TOS_ARM_H_ */

View File

@@ -0,0 +1,27 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_CHIP_H_
#define _TOS_CHIP_H_
#include "chip/gic.h"
#include "chip/chip.h"
void chip_init(void);
#endif /* _TOS_CHIP_H_ */

View File

@@ -0,0 +1,145 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_CPU_H_
#define _TOS_CPU_H_
#include "tos_arm.h"
#include "tos_chip.h"
#include "tos_gic.h"
#include "tos_interrupt.h"
typedef struct cpu_context_st {
cpu_data_t r0;
cpu_data_t r1;
cpu_data_t r2;
cpu_data_t r3;
cpu_data_t r4;
cpu_data_t r5;
cpu_data_t r6;
cpu_data_t r7;
cpu_data_t r8;
cpu_data_t r9;
cpu_data_t r10;
cpu_data_t r11;
cpu_data_t r12;
cpu_data_t lr;
cpu_data_t pc;
cpu_data_t cpsr;
} cpu_context_t;
__API__ uint32_t tos_cpu_clz(uint32_t val);
__API__ void tos_cpu_int_disable(void);
__API__ void tos_cpu_int_enable(void);
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void);
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr);
#if (TOS_CFG_CPU_HRTIMER_EN > 0u)
__API__ void tos_cpu_hrtimer_init(void);
__API__ cpu_hrtimer_t tos_cpu_hrtimer_read(void);
#endif
__KERNEL__ void cpu_init(void);
__KERNEL__ void cpu_reset(void);
__KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick);
__KERNEL__ void cpu_sched_start(void);
__KERNEL__ void cpu_context_switch(void);
__KERNEL__ void cpu_irq_context_switch(void);
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
__KERNEL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth);
#endif
__KERNEL__ k_stack_t *cpu_task_stk_init(void *entry,
void *arg,
void *exit,
k_stack_t *stk_base,
size_t stk_size);
#if TOS_CFG_TICKLESS_EN > 0u
__KERNEL__ void cpu_systick_resume(void);
__KERNEL__ void cpu_systick_suspend(void);
__KERNEL__ void cpu_systick_reload_reset(void);
__KERNEL__ void cpu_systick_pending_reset(void);
__KERNEL__ k_time_t cpu_systick_max_delay_millisecond(void);
__KERNEL__ void cpu_systick_expires_set(k_time_t millisecond);
__KERNEL__ void cpu_systick_reset(void);
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
__KERNEL__ void cpu_sleep_mode_enter(void);
__KERNEL__ void cpu_stop_mode_enter(void);
__KERNEL__ void cpu_standby_mode_enter(void);
#endif
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
__KERNEL__ void cpu_flush_fpu(void);
#endif /* TOS_CFG_CPU_ARM_FPU_EN */
__KERNEL__ void cpu_fault_diagnosis(void);
#endif
/* Allocates CPU status register word. */
#define TOS_CPU_CPSR_ALLOC() cpu_cpsr_t cpu_cpsr = (cpu_cpsr_t)0u
/* Save CPU status word & disable interrupts.*/
#define TOS_CPU_INT_DISABLE() \
do { \
cpu_cpsr = tos_cpu_cpsr_save(); \
} while (0)
/* Restore CPU status word. */
#define TOS_CPU_INT_ENABLE() \
do { \
tos_cpu_cpsr_restore(cpu_cpsr); \
} while (0)
#endif /* _TOS_CPU_H_ */

View File

@@ -0,0 +1,34 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_CPU_DEF_H_
#define _TOS_CPU_DEF_H_
enum CPU_WORD_SIZE {
CPU_WORD_SIZE_08,
CPU_WORD_SIZE_16,
CPU_WORD_SIZE_32,
CPU_WORD_SIZE_64,
};
enum CPU_STK_GROWTH {
CPU_STK_GROWTH_ASCENDING,
CPU_STK_GROWTH_DESCENDING,
};
#endif /* _TOS_CPU_DEF_H_ */

View File

@@ -0,0 +1,57 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_CPU_TYPES_H_
#define _TOS_CPU_TYPES_H_
/* CPU address type based on address bus size. */
#if (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_32)
typedef uint32_t cpu_addr_t;
#elif (TOS_CFG_CPU_ADDR_SIZE == CPU_WORD_SIZE_16)
typedef uint16_t cpu_addr_t;
#else
typedef uint8_t cpu_addr_t;
#endif
/* CPU data type based on data bus size. */
#if (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_32)
typedef uint32_t cpu_data_t;
#elif (TOS_CFG_CPU_DATA_SIZE == CPU_WORD_SIZE_16)
typedef uint16_t cpu_data_t;
#else
typedef uint8_t cpu_data_t;
#endif
#if (TOS_CFG_CPU_HRTIMER_EN > 0)
#if (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_08)
typedef uint8_t cpu_hrtimer_t;
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_16)
typedef uint16_t cpu_hrtimer_t;
#elif (TOS_CFG_CPU_HRTIMER_SIZE == CPU_WORD_SIZE_64)
typedef uint64_t cpu_hrtimer_t;
#else
typedef uint32_t cpu_hrtimer_t;
#endif
#else
typedef uint32_t cpu_hrtimer_t;
#endif
//typedef cpu_addr_t size_t;
typedef cpu_addr_t cpu_cpsr_t;
#endif

View File

@@ -0,0 +1,236 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_FAULT_H_
#define _TOS_FAULT_H_
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
typedef int (*k_fault_log_writer_t)(const char *format, ...);
#define K_FAULT_STACK_DUMP_DEPTH 10u
#define K_FAULT_CALL_STACK_BACKTRACE_DEPTH 5u
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
typedef struct fault_fpu_frame_st {
cpu_data_t s0;
cpu_data_t s1;
cpu_data_t s2;
cpu_data_t s3;
cpu_data_t s4;
cpu_data_t s5;
cpu_data_t s6;
cpu_data_t s7;
cpu_data_t s8;
cpu_data_t s9;
cpu_data_t s10;
cpu_data_t s11;
cpu_data_t s12;
cpu_data_t s13;
cpu_data_t s14;
cpu_data_t s15;
cpu_data_t fpscr;
} fault_fpu_frame_t;
#endif
typedef struct fault_cpu_frame_st {
cpu_data_t r0;
cpu_data_t r1;
cpu_data_t r2;
cpu_data_t r3;
cpu_data_t r12;
cpu_data_t lr;
cpu_data_t pc;
cpu_data_t spsr;
} fault_cpu_frame_t;
typedef struct fault_exc_frame_st {
fault_cpu_frame_t cpu_frame;
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
fault_fpu_frame_t fpu_frame;
#endif
} fault_exc_frame_t;
/**
* information we need to do fault backtrace
*/
typedef struct fault_information_st {
int is_thumb : 1; /**< whether it is thumb we use when we fall into fault? */
int is_on_task : 1; /**< whether we are on a task when fall into fault? */
int is_stk_ovrf : 1; /**< whether we get a stack overflow */
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
int is_ext_stk_frm : 1; /**< whether it is a extended stack frame?(whether the cpu has pushed fpu registers onto the stack) */
#endif
cpu_addr_t pc; /**< just where fault happens */
cpu_addr_t sp_before_fault; /**< original sp just before the cpu push the fault exception frame */
/**
* we need main_stack_start & main_stack_limit to do call stack backtrace
* when we fall into fault during a task, we should do the call stack backtrace on the task's stack
* but if not, which means we are in kernel, we should do the call stack backtrace on the main stack
* in arm v7-m, this should be the MSP's start and limit
* in arm v7-a, call stack backtrace is another story(much more elegant because we have FP).
*/
cpu_addr_t stack_start; /**< current sp start address we use. if on task, it'll be the task's stack, otherwise it'll be the msp */
cpu_addr_t stack_limit; /**< current sp limit address */
cpu_addr_t code_start; /**< current code start address */
cpu_addr_t code_limit; /**< current code limit address */
} fault_info_t;
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
#define DEFAULT_CODE_SECTION_NAME ER_IROM1
#define DEFAULT_CSTACK_SECTION_NAME STACK
#define SECTION_START(_name_) _name_##$$Base
#define SECTION_END(_name_) _name_##$$Limit
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit
#define CSTACK_BLOCK_START(_name_) SECTION_START(_name_)
#define CSTACK_BLOCK_END(_name_) SECTION_END(_name_)
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
extern const int CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
extern const int CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
extern const int CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
extern const int CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
{
return (cpu_addr_t)&CODE_SECTION_START(DEFAULT_CODE_SECTION_NAME);
}
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
{
return (cpu_addr_t)&CODE_SECTION_END(DEFAULT_CODE_SECTION_NAME);
}
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
{
return (cpu_addr_t)&CSTACK_BLOCK_START(DEFAULT_CSTACK_SECTION_NAME);
}
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
{
return (cpu_addr_t)&CSTACK_BLOCK_END(DEFAULT_CSTACK_SECTION_NAME);
}
#elif defined(__ICCARM__)
#define DEFAULT_CODE_SECTION_NAME ".text"
#define DEFAULT_CSTACK_SECTION_NAME "CSTACK"
#pragma section=DEFAULT_CSTACK_SECTION_NAME
#pragma section=DEFAULT_CODE_SECTION_NAME
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
{
return (cpu_addr_t)__section_begin(DEFAULT_CODE_SECTION_NAME);
}
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
{
return (cpu_addr_t)__section_end(DEFAULT_CODE_SECTION_NAME);
}
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
{
return (cpu_addr_t)__section_begin(DEFAULT_CSTACK_SECTION_NAME);
}
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
{
return (cpu_addr_t)__section_end(DEFAULT_CSTACK_SECTION_NAME);
}
#elif defined(__GNUC__)
/**
* if we are using keil(armcc) or mdk(iccarm), we probably use the defult link script supplied by the IDE.
* the way to locate the text/stack section start and limit is to find them in default link script.
* but if we build our project by makefile(or something like scons, cmake, etc), we probably need to write
* our own link scrpit, if so, we should do like this(just a demo):
*
_stext = .;
.text : {
*(.text.startup)
*(.text)
*(.text.*)
}
_etext = .;
__bss_start = .;
.bss : {
*(.bss)
*(.bss.*)
*(COMMON)
_sstack = .;
*(.cstack)
_estack = .;
}
__bss_end = .;
* by this, we can locate text/stack section start and limit by _stext/_etext and _sstack/_estack
*/
#define DEFAULT_CODE_SECTION_START _stext
#define DEFAULT_CODE_SECTION_END _etext
#define DEFAULT_CSTACK_SECTION_START _sstack
#define DEFAULT_CSTACK_SECTION_END _estack
extern const int DEFAULT_CODE_SECTION_START;
extern const int DEFAULT_CODE_SECTION_END;
extern const int DEFAULT_CSTACK_SECTION_START;
extern const int DEFAULT_CSTACK_SECTION_END;
__STATIC_INLINE__ cpu_addr_t fault_code_start(void)
{
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_START));
}
__STATIC_INLINE__ cpu_addr_t fault_code_limit(void)
{
return (cpu_addr_t)(&(DEFAULT_CODE_SECTION_END));
}
__STATIC_INLINE__ cpu_addr_t fault_msp_start(void)
{
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_START));
}
__STATIC_INLINE__ cpu_addr_t fault_msp_limit(void)
{
return (cpu_addr_t)(&(DEFAULT_CSTACK_SECTION_END));
}
#endif
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer);
__KERNEL__ int fault_default_log_writer(const char *format, ...);
__KERNEL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame);
#endif
#endif /* _TOS_FAULT_H_ */

View File

@@ -0,0 +1,106 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_GIC_H_
#define _TOS_GIC_H_
typedef struct gic_distributor_registers_st {
uint32_t D_CTLR; /*!< Offset: 0x1000 (R/W) Distributor Control Register */
uint32_t D_TYPER; /*!< Offset: 0x1004 (R/ ) Interrupt Controller Type Register */
uint32_t D_IIDR; /*!< Offset: 0x1008 (R/ ) Distributor Implementer Identification Register */
uint32_t RESERVED1[29];
uint32_t D_IGROUPR[16]; /*!< Offset: 0x1080 - 0x0BC (R/W) Interrupt Group Registers */
uint32_t RESERVED2[16];
uint32_t D_ISENABLER[16]; /*!< Offset: 0x1100 - 0x13C (R/W) Interrupt Set-Enable Registers */
uint32_t RESERVED3[16];
uint32_t D_ICENABLER[16]; /*!< Offset: 0x1180 - 0x1BC (R/W) Interrupt Clear-Enable Registers */
uint32_t RESERVED4[16];
uint32_t D_ISPENDR[16]; /*!< Offset: 0x1200 - 0x23C (R/W) Interrupt Set-Pending Registers */
uint32_t RESERVED5[16];
uint32_t D_ICPENDR[16]; /*!< Offset: 0x1280 - 0x2BC (R/W) Interrupt Clear-Pending Registers */
uint32_t RESERVED6[16];
uint32_t D_ISACTIVER[16]; /*!< Offset: 0x1300 - 0x33C (R/W) Interrupt Set-Active Registers */
uint32_t RESERVED7[16];
uint32_t D_ICACTIVER[16]; /*!< Offset: 0x1380 - 0x3BC (R/W) Interrupt Clear-Active Registers */
uint32_t RESERVED8[16];
uint8_t D_IPRIORITYR[512]; /*!< Offset: 0x1400 - 0x5FC (R/W) Interrupt Priority Registers */
uint32_t RESERVED9[128];
uint8_t D_ITARGETSR[512]; /*!< Offset: 0x1800 - 0x9FC (R/W) Interrupt Targets Registers */
uint32_t RESERVED10[128];
uint32_t D_ICFGR[32]; /*!< Offset: 0x1C00 - 0xC7C (R/W) Interrupt configuration registers */
uint32_t RESERVED11[32];
uint32_t D_PPISR; /*!< Offset: 0x1D00 (R/ ) Private Peripheral Interrupt Status Register */
uint32_t D_SPISR[15]; /*!< Offset: 0x1D04 - 0xD3C (R/ ) Shared Peripheral Interrupt Status Registers */
uint32_t RESERVED12[112];
uint32_t D_SGIR; /*!< Offset: 0x1F00 ( /W) Software Generated Interrupt Register */
uint32_t RESERVED13[3];
uint8_t D_CPENDSGIR[16]; /*!< Offset: 0x1F10 - 0xF1C (R/W) SGI Clear-Pending Registers */
uint8_t D_SPENDSGIR[16]; /*!< Offset: 0x1F20 - 0xF2C (R/W) SGI Set-Pending Registers */
uint32_t RESERVED14[40];
uint32_t D_PIDR4; /*!< Offset: 0x1FD0 (R/ ) Peripheral ID4 Register */
uint32_t D_PIDR5; /*!< Offset: 0x1FD4 (R/ ) Peripheral ID5 Register */
uint32_t D_PIDR6; /*!< Offset: 0x1FD8 (R/ ) Peripheral ID6 Register */
uint32_t D_PIDR7; /*!< Offset: 0x1FDC (R/ ) Peripheral ID7 Register */
uint32_t D_PIDR0; /*!< Offset: 0x1FE0 (R/ ) Peripheral ID0 Register */
uint32_t D_PIDR1; /*!< Offset: 0x1FE4 (R/ ) Peripheral ID1 Register */
uint32_t D_PIDR2; /*!< Offset: 0x1FE8 (R/ ) Peripheral ID2 Register */
uint32_t D_PIDR3; /*!< Offset: 0x1FEC (R/ ) Peripheral ID3 Register */
uint32_t D_CIDR0; /*!< Offset: 0x1FF0 (R/ ) Component ID0 Register */
uint32_t D_CIDR1; /*!< Offset: 0x1FF4 (R/ ) Component ID1 Register */
uint32_t D_CIDR2; /*!< Offset: 0x1FF8 (R/ ) Component ID2 Register */
uint32_t D_CIDR3; /*!< Offset: 0x1FFC (R/ ) Component ID3 Register */
} gic_dist_t;
typedef struct gic_cpu_interface_registers_st {
uint32_t C_CTLR; /*!< Offset: 0x2000 (R/W) CPU Interface Control Register */
uint32_t C_PMR; /*!< Offset: 0x2004 (R/W) Interrupt Priority Mask Register */
uint32_t C_BPR; /*!< Offset: 0x2008 (R/W) Binary Point Register */
uint32_t C_IAR; /*!< Offset: 0x200C (R/ ) Interrupt Acknowledge Register */
uint32_t C_EOIR; /*!< Offset: 0x2010 ( /W) End Of Interrupt Register */
uint32_t C_RPR; /*!< Offset: 0x2014 (R/ ) Running Priority Register */
uint32_t C_HPPIR; /*!< Offset: 0x2018 (R/ ) Highest Priority Pending Interrupt Register */
uint32_t C_ABPR; /*!< Offset: 0x201C (R/W) Aliased Binary Point Register */
uint32_t C_AIAR; /*!< Offset: 0x2020 (R/ ) Aliased Interrupt Acknowledge Register */
uint32_t C_AEOIR; /*!< Offset: 0x2024 ( /W) Aliased End Of Interrupt Register */
uint32_t C_AHPPIR; /*!< Offset: 0x2028 (R/ ) Aliased Highest Priority Pending Interrupt Register */
uint32_t RESERVED15[41];
uint32_t C_APR0; /*!< Offset: 0x20D0 (R/W) Active Priority Register */
uint32_t RESERVED16[3];
uint32_t C_NSAPR0; /*!< Offset: 0x20E0 (R/W) Non-secure Active Priority Register */
uint32_t RESERVED17[6];
uint32_t C_IIDR; /*!< Offset: 0x20FC (R/ ) CPU Interface Identification Register */
uint32_t RESERVED18[960];
uint32_t C_DIR; /*!< Offset: 0x3000 ( /W) Deactivate Interrupt Register */
} gic_cpu_t;
typedef struct gic_data_st {
gic_dist_t *dist;
gic_cpu_t *cpu;
} gic_data_t;
__KERNEL__ uint32_t gic_interrupt_id_get(uint32_t gic_nr);
__KERNEL__ void gic_interrupt_end(uint32_t gic_nr, uint32_t vector);
__KERNEL__ int gic_init(uint32_t gic_nr);
__KERNEL__ void gic_interrupt_enable(uint32_t gic_nr, uint32_t vector);
__KERNEL__ void gic_interrupt_disable(uint32_t gic_nr, uint32_t vector);
#endif /* _TOS_GIC_H_ */

View File

@@ -0,0 +1,65 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _TOS_INTERRUPT_H_
#define _TOS_INTERRUPT_H_
typedef void (*int_handler_t)(void *arg);
typedef struct int_handle_st {
int_handler_t handler;
void *arg;
} int_handle_t;
typedef struct int_frame_st {
#if 0
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
uint32_t fpexc;
#endif
#endif
cpu_data_t r0;
cpu_data_t r1;
cpu_data_t r2;
cpu_data_t r3;
cpu_data_t r4;
cpu_data_t r5;
cpu_data_t r6;
cpu_data_t r7;
cpu_data_t r8;
cpu_data_t r9;
cpu_data_t r10;
cpu_data_t r11;
cpu_data_t r12;
cpu_data_t lr;
cpu_data_t pc;
cpu_data_t spsr;
} int_frame_t;
__KERNEL__ void interrupt_irq(int_frame_t *int_frame);
__KERNEL__ int interrupt_init(void);
__API__ int tos_interrupt_handler_register(uint32_t vector, int_handler_t handler, void *arg);
__API__ void tos_interrupt_enable(uint32_t vector);
__API__ void tos_interrupt_disable(uint32_t vector);
#endif /* _TOS_INTERRUPT_H_ */

View File

@@ -0,0 +1,25 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#define __STUB__ __WEAK__
__STUB__ void chip_init(void)
{
}

View File

@@ -0,0 +1,286 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
__API__ uint32_t tos_cpu_clz(uint32_t val)
{
#if defined(TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT) && (TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT == 0u)
uint32_t nbr_lead_zeros = 0;
if (!(val & 0XFFFF0000)) {
val <<= 16;
nbr_lead_zeros += 16;
}
if (!(val & 0XFF000000)) {
val <<= 8;
nbr_lead_zeros += 8;
}
if (!(val & 0XF0000000)) {
val <<= 4;
nbr_lead_zeros += 4;
}
if (!(val & 0XC0000000)) {
val <<= 2;
nbr_lead_zeros += 2;
}
if (!(val & 0X80000000)) {
nbr_lead_zeros += 1;
}
if (!val) {
nbr_lead_zeros += 1;
}
return (nbr_lead_zeros);
#else
return port_clz(val);
#endif
}
__API__ void tos_cpu_int_disable(void)
{
port_int_disable();
}
__API__ void tos_cpu_int_enable(void)
{
port_int_enable();
}
__API__ cpu_cpsr_t tos_cpu_cpsr_save(void)
{
return port_cpsr_save();
}
__API__ void tos_cpu_cpsr_restore(cpu_cpsr_t cpsr)
{
port_cpsr_restore(cpsr);
}
__KERNEL__ void cpu_init(void)
{
k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second;
interrupt_init();
chip_init();
}
__KERNEL__ void cpu_reset(void)
{
port_cpu_reset();
}
__KERNEL__ void cpu_sched_start(void)
{
port_sched_start();
}
__KERNEL__ void cpu_context_switch(void)
{
port_context_switch();
}
__KERNEL__ void cpu_irq_context_switch(void)
{
port_irq_context_switch();
}
__KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick)
{
port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO);
port_systick_config(cycle_per_tick);
}
#if TOS_CFG_TICKLESS_EN > 0u
/**
* @brief Set value to systick reload value register
*
* @param cycles The value set to register
*
* @return None
*/
__STATIC_INLINE__ void cpu_systick_reload(k_cycle_t cycle_per_tick)
{
port_systick_reload(cycle_per_tick);
}
/**
* @brief Enable systick interrupt
*
* @return None
*/
__KERNEL__ void cpu_systick_resume(void)
{
port_systick_resume();
}
/**
* @brief Disable systick interrupt
*
* @return None
*/
__KERNEL__ void cpu_systick_suspend(void)
{
port_systick_suspend();
}
__KERNEL__ k_time_t cpu_systick_max_delay_millisecond(void)
{
return port_systick_max_delay_millisecond();
}
__KERNEL__ void cpu_systick_expires_set(k_time_t millisecond)
{
k_cycle_t cycles;
cycles = (k_cycle_t)((uint64_t)millisecond * TOS_CFG_CPU_CLOCK / K_TIME_MILLISEC_PER_SEC); /* CLOCK means cycle per second */
cpu_systick_reload(cycles - 12); /* interrupt delay */
}
__KERNEL__ void cpu_systick_pending_reset(void)
{
port_systick_pending_reset();
}
__KERNEL__ void cpu_systick_reset(void)
{
cpu_systick_reload(k_cpu_cycle_per_tick);
}
#endif /* TOS_CFG_TICKLESS_EN */
#if TOS_CFG_PWR_MGR_EN > 0u
__KERNEL__ void cpu_sleep_mode_enter(void)
{
port_sleep_mode_enter();
}
__KERNEL__ void cpu_stop_mode_enter(void)
{
port_stop_mode_enter();
}
__KERNEL__ void cpu_standby_mode_enter(void)
{
port_standby_mode_enter();
}
#endif /* TOS_CFG_PWR_MGR_EN */
__KERNEL__ k_stack_t *cpu_task_stk_init(void *entry,
void *arg,
void *exit,
k_stack_t *stk_base,
size_t stk_size)
{
cpu_data_t *sp;
cpu_context_t *context;
sp = (cpu_data_t *)&stk_base[stk_size];
sp = (cpu_data_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
uint8_t *slot = (uint8_t *)&stk_base[0];
for (; slot < (uint8_t *)sp; ++slot) {
*slot = 0xCC;
}
#endif
context = (cpu_context_t *)sp;
--context;
#define CPSR_SVC_MODE 0x13
#define CPSR_BIT_T 0x20
/* we donnot set the irq bit, so first time context switch should enable irq */
context->cpsr = CPSR_SVC_MODE;
if ((cpu_addr_t)entry & 1) {
context->cpsr |= CPSR_BIT_T;
}
context->pc = (cpu_data_t)entry;
context->lr = (cpu_data_t)exit;
context->r12 = (cpu_data_t)0x12121212u;
context->r11 = (cpu_data_t)0x11111111u;
context->r10 = (cpu_data_t)0x10101010u;
context->r9 = (cpu_data_t)0x09090909u;
context->r8 = (cpu_data_t)0x08080808u;
context->r7 = (cpu_data_t)0x07070707u;
context->r6 = (cpu_data_t)0x06060606u;
context->r5 = (cpu_data_t)0x05050505u;
context->r4 = (cpu_data_t)0x04040404u;
context->r3 = (cpu_data_t)0x03030303u;
context->r2 = (cpu_data_t)0x02020202u;
context->r1 = (cpu_data_t)0x01010101u;
context->r0 = (cpu_data_t)arg;
return (k_stack_t *)context;
}
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
__KERNEL__ k_err_t cpu_task_stack_draught_depth(k_stack_t *stk_base, size_t stk_size, int *depth)
{
uint8_t *slot;
uint8_t *sp, *bp;
int the_depth = 0;
bp = (uint8_t *)&stk_base[0];
sp = &stk_base[stk_size];
sp = (uint8_t *)((cpu_addr_t)sp & 0xFFFFFFF8);
for (slot = sp - 1; slot >= bp; --slot) {
if (*slot != 0xCC) {
the_depth = sp - slot;
}
}
*depth = the_depth;
if (the_depth == stk_size) {
return K_ERR_TASK_STK_OVERFLOW;
}
return K_ERR_NONE;
}
#endif
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
__KERNEL__ void cpu_flush_fpu(void)
{
(void)__get_FPSCR();
}
#endif
__KERNEL__ void cpu_fault_diagnosis(void)
{
port_fault_diagnosis();
}
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */

View File

@@ -0,0 +1,392 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
__STATIC_INLINE__ void fault_spin(void)
{
tos_knl_sched_lock();
tos_cpu_int_disable();
while (K_TRUE) {
;
}
}
/* EXC_RETURN:
31 - 28 : EXC_RETURN flag
27 - 5 : reserved
4 : 1, basic stack frame; 0, extended stack frame
3 : 1, return to Thread mode; 0, return to Handler mode
2 : 1, return to PSP; 0, return to MSP
1 : reserved, 0
0 : reserved, 1
*/
__STATIC_INLINE__ int fault_is_on_task(cpu_data_t lr)
{
return (lr & (1u << 2)) != 0;
}
__STATIC_INLINE__ int fault_is_thumb(cpu_data_t psr)
{
return (psr & (1u << 24)) != 0;
}
__STATIC_INLINE__ int fault_is_code(fault_info_t *info, cpu_data_t value)
{
return value >= info->code_start && value <= info->code_limit;
}
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
__STATIC_INLINE__ int fault_is_extended_stack_frame(cpu_data_t lr)
{
return (lr & (1u << 4)) == 0;
}
__STATIC__ void fault_dump_fpu_frame(fault_fpu_frame_t *fpu_frame)
{
/*
* As known, v7-m has a feature named "LAZY PUSH", for the reason we do not do any float
* operation in fault_backtrace, cpu will not do the real fpu register push to the stack.
* that means the value we dump in fault_dump_fpu_frame will not be the correct value of
* each FPU register.
* We define a function here which access to FPSCR, if this function involved, cpu will do
* the real FPU register push so we will get the correct dump.
* I know it's ugly, but it works. If you know a better way, please tell me.
*/
cpu_flush_fpu();
k_fault_log_writer("\n\n====================== FPU Registers =======================\n");
k_fault_log_writer(" %s: %08x\n", "FPSCR", fpu_frame->fpscr);
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
"S0 ", fpu_frame->s0,
"S1 ", fpu_frame->s1,
"S2 ", fpu_frame->s2,
"S3 ", fpu_frame->s3);
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
"S4 ", fpu_frame->s4,
"S5 ", fpu_frame->s5,
"S6 ", fpu_frame->s6,
"S7 ", fpu_frame->s7);
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
"S8 ", fpu_frame->s8,
"S9 ", fpu_frame->s9,
"S10", fpu_frame->s10,
"S11", fpu_frame->s11);
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
"S12", fpu_frame->s12,
"S13", fpu_frame->s13,
"S14", fpu_frame->s14,
"S15", fpu_frame->s15);
}
#endif
__STATIC__ void fault_dump_cpu_frame(fault_cpu_frame_t *cpu_frame)
{
k_fault_log_writer("\n\n====================== CPU Registers =======================\n");
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
"R0 ", cpu_frame->r0,
"R1 ", cpu_frame->r1,
"R2 ", cpu_frame->r2,
"R3 ", cpu_frame->r3);
k_fault_log_writer(" %s: %08x %s: %08x %s: %08x %s: %08x\n",
"R12", cpu_frame->r12,
"LR ", cpu_frame->lr,
"PC ", cpu_frame->pc,
"PSR", cpu_frame->spsr);
}
__STATIC__ void fault_dump_stack(fault_info_t *info, size_t depth)
{
cpu_addr_t sp = info->sp_before_fault;;
k_fault_log_writer("\nTASK STACK DUMP:\n");
while (sp <= info->stack_limit && depth--) {
k_fault_log_writer(" addr: %08x data: %08x\n", sp, (cpu_data_t)*(cpu_data_t *)sp);
sp += sizeof(cpu_addr_t);
}
}
__STATIC__ void fault_call_stack_backtrace(fault_info_t *info, size_t depth)
{
cpu_data_t value;
cpu_addr_t sp = info->sp_before_fault;
if (info->is_stk_ovrf) {
return;
}
k_fault_log_writer("\n\n====================== Dump Call Stack =====================\n");
k_fault_log_writer(" %x\n", info->pc);
/* walk through the stack, check every content on stack whether is a instruction(code) */
for (; sp < info->stack_limit && depth; sp += sizeof(cpu_addr_t)) {
value = *((cpu_addr_t *)sp) - sizeof(cpu_addr_t);
/* if thumb, a instruction's first bit must be 1 */
if (info->is_thumb && !(value & 1)) {
continue;
}
if (fault_is_code(info, value)) {
k_fault_log_writer(" %x\n", value);
--depth;
}
}
}
__STATIC__ void fault_dump_task(fault_info_t *info)
{
k_task_t *task;
if (!info->is_on_task) {
return;
}
task = k_curr_task;
k_fault_log_writer("\n\n====================== Fault on task =======================\n");
k_fault_log_writer(" TASK NAME: %s\n", task->name);
k_fault_log_writer(" STK BASE: %x\n", info->stack_start);
k_fault_log_writer(" STK SIZE: %x\n", task->stk_size * sizeof(k_stack_t));
k_fault_log_writer(" STK LIMIT: %x\n", info->stack_limit);
if (!info->is_stk_ovrf) {
fault_dump_stack(info, K_FAULT_STACK_DUMP_DEPTH);
}
}
__STATIC__ void fault_dump_information(fault_info_t *info)
{
k_fault_log_writer("\n\n================== Dump Fault Information ==================\n");
k_fault_log_writer(" THUMB: %s\n", info->is_thumb ? "TRUE" : "FALSE");
k_fault_log_writer(" ON TASK: %s\n", info->is_on_task? "TRUE" : "FALSE");
k_fault_log_writer(" STK OVRF: %s\n", info->is_stk_ovrf? "TRUE" : "FALSE");
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
k_fault_log_writer(" EXT STK: %s\n", info->is_ext_stk_frm? "TRUE" : "FALSE");
#endif
k_fault_log_writer(" PC: %08x\n", info->pc);
k_fault_log_writer(" SP: %08x\n", info->sp_before_fault);
k_fault_log_writer(" STK START: %08x\n", info->stack_start);
k_fault_log_writer(" STK LIMIT: %08x\n", info->stack_limit);
k_fault_log_writer(" COD START: %08x\n", info->code_start);
k_fault_log_writer(" COD LIMIT: %08x\n", info->code_limit);
}
__STATIC__ void fault_gather_information(cpu_data_t lr, fault_exc_frame_t *frame, fault_info_t *info)
{
info->is_thumb = fault_is_thumb(frame->cpu_frame.spsr);
info->is_on_task = fault_is_on_task(lr);
info->pc = frame->cpu_frame.pc;
info->sp_before_fault = (cpu_addr_t)frame + sizeof(fault_cpu_frame_t);
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
info->is_ext_stk_frm = fault_is_extended_stack_frame(lr);
if (info->is_ext_stk_frm) {
info->sp_before_fault += sizeof(fault_fpu_frame_t);
}
#endif
info->code_start = fault_code_start();
info->code_limit = fault_code_limit();
if (info->is_on_task) {
info->stack_start = (cpu_addr_t)k_curr_task->stk_base;
info->stack_limit = info->stack_start + k_curr_task->stk_size * sizeof(k_task_t);
} else {
info->stack_start = fault_msp_start();
info->stack_limit = fault_msp_limit();
}
info->is_stk_ovrf = (info->sp_before_fault < info->stack_start || info->sp_before_fault > info->stack_limit);
}
__KERNEL__ int fault_default_log_writer(const char *format, ...)
{
int len;
va_list ap;
va_start(ap, format);
len = vprintf(format, ap);
va_end(ap);
return len;
}
__API__ void tos_fault_log_writer_set(k_fault_log_writer_t log_writer)
{
k_fault_log_writer = log_writer;
}
__KERNEL__ void fault_backtrace(cpu_addr_t lr, fault_exc_frame_t *frame)
{
fault_info_t info;
fault_gather_information(lr, frame, &info);
fault_dump_information(&info);
fault_dump_task(&info);
fault_dump_cpu_frame(&frame->cpu_frame);
#if defined (TOS_CFG_CPU_ARM_FPU_EN) && (TOS_CFG_CPU_ARM_FPU_EN == 1U)
if (info.is_ext_stk_frm) {
fault_dump_fpu_frame(&frame->fpu_frame);
}
#endif
fault_call_stack_backtrace(&info, K_FAULT_CALL_STACK_BACKTRACE_DEPTH);
cpu_fault_diagnosis();
fault_spin();
}
#endif
struct arm_iframe {
#if 0 // VFP
uint32_t fpexc;
#endif
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t spsr;
};
struct arm_fault_frame {
#if 0 // VFP
uint32_t fpexc;
#endif
uint32_t r[13];
uint32_t lr;
uint32_t pc;
uint32_t spsr;
};
#define CPSR_MODE_MASK 0x1f
#define CPSR_MODE_USR 0x10
#define CPSR_MODE_FIQ 0x11
#define CPSR_MODE_IRQ 0x12
#define CPSR_MODE_SVC 0x13
#define CPSR_MODE_MON 0x16
#define CPSR_MODE_ABT 0x17
#define CPSR_MODE_UND 0x1b
#define CPSR_MODE_SYS 0x1f
static void dump_fault_frame(struct arm_fault_frame *frame)
{
printf("r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", frame->r[0], frame->r[1], frame->r[2], frame->r[3]);
printf("r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", frame->r[4], frame->r[5], frame->r[6], frame->r[7]);
printf("r8 0x%08x r9 0x%08x r10 0x%08x r11 0x%08x\n", frame->r[8], frame->r[9], frame->r[10], frame->r[11]);
printf("r12 0x%08x pc 0x%08x\n", frame->r[12], frame->pc);
printf("spsr 0x%08x\n", frame->spsr);
while (1);
}
static void dump_iframe(struct arm_iframe *frame)
{
printf("r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", frame->r0, frame->r1, frame->r2, frame->r3);
printf("r12 0x%08x pc 0x%08x\n", frame->r12, frame->pc);
printf("spsr 0x%08x\n", frame->spsr);
}
static void exception_die_iframe(struct arm_iframe *frame, const char *msg)
{
printf("%s", msg);
dump_iframe(frame);
while (1);
}
void arm_undefined_handler(struct arm_iframe *frame)
{
printf("undefined\r\n");
/* look at the undefined instruction, figure out if it's something we can handle */
int in_thumb = frame->spsr & (1<<5);
if (in_thumb) {
frame->pc -= 2;
} else {
frame->pc -= 4;
}
uint32_t opcode = *(uint32_t *)frame->pc;
printf("undefined opcode 0x%x\n", opcode);
#if 0 // VFP
if (in_thumb) {
/* look for a 32bit thumb instruction */
if (opcode & 0x0000e800) {
/* swap the 16bit words */
opcode = (opcode >> 16) | (opcode << 16);
}
if (((opcode & 0xec000e00) == 0xec000a00) || // vfp
((opcode & 0xef000000) == 0xef000000) || // advanced simd data processing
((opcode & 0xff100000) == 0xf9000000)) { // VLD
//printf("vfp/neon thumb instruction 0x%08x at 0x%x\n", opcode, frame->pc);
goto fpu;
}
} else {
/* look for arm vfp/neon coprocessor instructions */
if (((opcode & 0x0c000e00) == 0x0c000a00) || // vfp
((opcode & 0xfe000000) == 0xf2000000) || // advanced simd data processing
((opcode & 0xff100000) == 0xf4000000)) { // VLD
//printf("vfp/neon arm instruction 0x%08x at 0x%x\n", opcode, frame->pc);
goto fpu;
}
}
#endif
exception_die_iframe(frame, "undefined abort, halting\n");
return;
#if 0 // VFP
fpu:
arm_fpu_undefined_instruction(frame);
#endif
}
void arm_data_abort_handler(struct arm_fault_frame *frame)
{
printf("data abort!!\r\n");
dump_fault_frame(frame);
}
void arm_prefetch_abort_handler(struct arm_fault_frame *frame)
{
printf("prefetch abort!!\r\n");
dump_fault_frame(frame);
}

View File

@@ -0,0 +1,150 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
__STATIC__ gic_data_t gic_data[GIC_NRS];
__STATIC_INLINE__ cpu_addr_t gic_base_get(void)
{
/* read CBAR */
return (ARM_MRC(15, 4, 15, 0, 0) & 0xFFFF0000UL);
}
__STATIC__ void gic_data_init(gic_data_t *gic)
{
cpu_addr_t gic_base;
gic_base = gic_base_get();
gic->dist = (gic_dist_t *)(gic_base + GICD_OFFSET); /* distributor */
gic->cpu = (gic_cpu_t *)(gic_base + GICC_OFFSET); /* cpu interface */
}
__STATIC__ void gic_dist_init(gic_dist_t *gic_dist)
{
uint32_t i = 0, int_id_max = 0;
// let's make it simple here, maybe SMP someday, but not now
#define IT_LINES_NUMBER(d_type) ((d_type) & 0x1FUL)
int_id_max = IT_LINES_NUMBER(gic_dist->D_TYPER) + 1;
/* Disable all PPI, SGI and SPI */
for (i = 0; i < int_id_max; ++i) {
gic_dist->D_ICENABLER[i] = 0xFFFFFFFFUL;
}
/* Enable group0 distribution */
gic_dist->D_CTLR = 1UL;
}
__STATIC__ void gic_cpu_init(gic_cpu_t *gic_cpu)
{
/* Make all interrupts have higher priority */
gic_cpu->C_PMR = (0xFFUL << (8 - GIC_PRIO_BITS)) & 0xFFUL;
/* No subpriority, all priority level allows preemption */
gic_cpu->C_BPR = 7 - GIC_PRIO_BITS;
/* Enable group0 signaling */
gic_cpu->C_CTLR = 1UL;
}
__STATIC_INLINE__ gic_data_t *gic_get(uint32_t gic_nr)
{
gic_data_t *gic;
if (gic_nr >= GIC_NRS) {
return K_NULL;
}
gic = &gic_data[gic_nr];
if (gic->cpu && gic->dist) {
return gic;
}
return K_NULL;
}
__KERNEL__ uint32_t gic_interrupt_id_get(uint32_t gic_nr)
{
gic_data_t *gic = gic_get(gic_nr);
if (gic) {
#define INTERRUPT_ID(iar) ((iar) & 0x3FFUL)
return INTERRUPT_ID(gic->cpu->C_IAR);
}
return (uint32_t)-1;
}
__KERNEL__ void gic_interrupt_end(uint32_t gic_nr, uint32_t vector)
{
gic_data_t *gic = gic_get(gic_nr);
if (gic) {
gic->cpu->C_EOIR = vector;
}
}
__KERNEL__ int gic_init(uint32_t gic_nr)
{
gic_data_t *gic;
if (gic_nr >= GIC_NRS) {
return -1;
}
gic = &gic_data[gic_nr];
gic_data_init(gic);
gic_dist_init(gic->dist);
gic_cpu_init(gic->cpu);
return 0;
}
__KERNEL__ void gic_interrupt_enable(uint32_t gic_nr, uint32_t vector)
{
int reg;
uint32_t mask;
gic_data_t *gic;
gic = gic_get(gic_nr);
if (gic) {
reg = vector / 32;
mask = 1ULL << (vector % 32);
gic->dist->D_ISENABLER[reg] = mask;
}
}
__KERNEL__ void gic_interrupt_disable(uint32_t gic_nr, uint32_t vector)
{
int reg;
uint32_t mask;
gic_data_t *gic;
gic = gic_get(gic_nr);
if (gic) {
reg = vector / 32;
mask = 1ULL << (vector % 32);
gic->dist->D_ICENABLER[reg] = mask;
}
}

View File

@@ -0,0 +1,67 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
__STATIC__ int_handle_t int_handle_table[INTERRUPT_MAX];
__KERNEL__ void interrupt_irq(int_frame_t *int_frame)
{
uint32_t vector;
int_handle_t *handle;
vector = gic_interrupt_id_get(0u);
if (vector > INTERRUPT_MAX || vector == (uint32_t)-1) {
return;
}
handle = &int_handle_table[vector];
if (handle->handler) {
handle->handler(handle->arg);
}
gic_interrupt_end(0u, vector);
}
__KERNEL__ int interrupt_init(void)
{
gic_init(0u);
return 0;
}
__API__ int tos_interrupt_handler_register(uint32_t vector, int_handler_t handler, void *arg)
{
if (vector < INTERRUPT_MAX) {
int_handle_table[vector].handler = handler;
int_handle_table[vector].arg = arg;
return 0;
}
return -1;
}
__API__ void tos_interrupt_enable(uint32_t vector)
{
gic_interrupt_enable(0u, vector);
}
__API__ void tos_interrupt_disable(uint32_t vector)
{
gic_interrupt_disable(0u, vector);
}

View File

@@ -0,0 +1,62 @@
#include "tos_k.h"
#include "imx6ul.h"
/* set the core clock to 528MHz */
void clock_init(void)
{
unsigned int reg = 0;
if ((((CCM->CCSR) >> 2) & 0x1) == 0) {
CCM->CCSR &= ~(1 << 8);
CCM->CCSR |= (1 << 2);
}
CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 << 0) & 0X7F);
CCM->CCSR &= ~(1 << 2);
CCM->CACRR = 1;
reg = CCM_ANALOG->PFD_528;
reg &= ~(0X3F3F3F3F);
reg |= 32 << 24;
reg |= 24 << 16;
reg |= 16 << 8;
reg |= 27 << 0;
CCM_ANALOG->PFD_528 = reg;
reg = 0;
reg = CCM_ANALOG->PFD_480;
reg &= ~(0X3F3F3F3F);
reg |= 19 << 24;
reg |= 17 << 16;
reg |= 16 << 8;
reg |= 12 << 0;
CCM_ANALOG->PFD_480 = reg;
CCM->CBCMR &= ~(3 << 18);
CCM->CBCMR |= (1 << 18);
CCM->CBCDR &= ~(1 << 25);
while(CCM->CDHIPR & (1 << 5)) {
;
}
CCM->CBCDR &= ~(3 << 8);
CCM->CBCDR |= 1 << 8;
CCM->CSCMR1 &= ~(1 << 6);
CCM->CSCMR1 &= ~(7 << 0);
CCM->CSCDR1 &= ~(1 << 6);
CCM->CSCDR1 &= ~0X3F;
}
void clock_enable(void)
{
CCM->CCGR0 = 0XFFFFFFFF;
CCM->CCGR1 = 0XFFFFFFFF;
CCM->CCGR2 = 0XFFFFFFFF;
CCM->CCGR3 = 0XFFFFFFFF;
CCM->CCGR4 = 0XFFFFFFFF;
CCM->CCGR5 = 0XFFFFFFFF;
CCM->CCGR6 = 0XFFFFFFFF;
}

View File

@@ -0,0 +1,27 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#include "imx6ul.h"
__KERNEL__ void chip_init(void)
{
clock_init();
clock_enable();
systick_init(k_cpu_tick_per_second);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/*----------------------------------------------------------------------------
* 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 _PLATFORM_H_
#define _PLATFORM_H_
#define INTERRUPT_MAX 128
#define KERNEL_BASE 0X87800000
#endif /* _CHIP_H_ */

View File

@@ -0,0 +1,27 @@
/*----------------------------------------------------------------------------
* 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 _GIC_H_
#define _GIC_H_
#define GICD_OFFSET 0x1000
#define GICC_OFFSET 0x2000
#define GIC_PRIO_BITS 5 /**< Number of Bits used for Priority Levels */
#define GIC_NRS 1 /**< how many gic on this chip? */
#endif /* _GIC_H_ */

View File

@@ -0,0 +1,25 @@
/*----------------------------------------------------------------------------
* 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 _CLOCK_H_
#define _CLOCK_H_
void clock_init(void);
void clock_enable(void);
#endif

View File

@@ -0,0 +1,723 @@
#ifndef __CORTEX_CA7_H
#define __CORTEX_CA7_H
#include <stdint.h>
#include <string.h>
#define FORCEDINLINE __attribute__((always_inline))
#define __ASM __asm /* GNU C语言内嵌汇编关键字 */
#define __INLINE inline /* GNU内联关键字 */
#define __STATIC_INLINE static inline
#define __IM volatile const /* 只读 */
#define __OM volatile /* 只写 */
#define __IOM volatile /* 读写 */
#define __STRINGIFY(x) #x
/* C语言实现MCR指令 */
#define __MCR(coproc, opcode_1, src, CRn, CRm, opcode_2) \
__ASM volatile ("MCR " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
__STRINGIFY(opcode_2) \
: : "r" (src) )
/* C语言实现MRC指令 */
#define __MRC(coproc, opcode_1, CRn, CRm, opcode_2) \
({ \
uint32_t __dst; \
__ASM volatile ("MRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
"%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \
__STRINGIFY(opcode_2) \
: "=r" (__dst) ); \
__dst; \
})
/* 其他一些C语言内嵌汇编 */
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_APSR(uint32_t apsr)
{
__ASM volatile ("MSR apsr, %0" : : "r" (apsr) : "cc");
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, cpsr" : "=r" (result) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CPSR(uint32_t cpsr)
{
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "cc");
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPEXC(void)
{
uint32_t result;
__ASM volatile ("VMRS %0, fpexc" : "=r" (result) );
return result;
}
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
{
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc));
}
/*******************************************************************************
* 一些内核寄存器定义和抽象
定义如下几个内核寄存器:
- CPSR
- CP15
******************************************************************************/
/* CPSR寄存器
* 参考资料ARM Cortex-A(armV7)编程手册V4.0.pdf P46
*/
typedef union
{
struct
{
uint32_t M:5; /*!< bit: 0.. 4 Mode field */
uint32_t T:1; /*!< bit: 5 Thumb execution state bit */
uint32_t F:1; /*!< bit: 6 FIQ mask bit */
uint32_t I:1; /*!< bit: 7 IRQ mask bit */
uint32_t A:1; /*!< bit: 8 Asynchronous abort mask bit */
uint32_t E:1; /*!< bit: 9 Endianness execution state bit */
uint32_t IT1:6; /*!< bit: 10..15 If-Then execution state bits 2-7 */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved0:4; /*!< bit: 20..23 Reserved */
uint32_t J:1; /*!< bit: 24 Jazelle bit */
uint32_t IT0:2; /*!< bit: 25..26 If-Then execution state bits 0-1 */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CPSR_Type;
/* CP15的SCTLR寄存器
* 参考资料Cortex-A7 Technical ReferenceManua.pdf P105
*/
typedef union
{
struct
{
uint32_t M:1; /*!< bit: 0 MMU enable */
uint32_t A:1; /*!< bit: 1 Alignment check enable */
uint32_t C:1; /*!< bit: 2 Cache enable */
uint32_t _reserved0:2; /*!< bit: 3.. 4 Reserved */
uint32_t CP15BEN:1; /*!< bit: 5 CP15 barrier enable */
uint32_t _reserved1:1; /*!< bit: 6 Reserved */
uint32_t B:1; /*!< bit: 7 Endianness model */
uint32_t _reserved2:2; /*!< bit: 8.. 9 Reserved */
uint32_t SW:1; /*!< bit: 10 SWP and SWPB enable */
uint32_t Z:1; /*!< bit: 11 Branch prediction enable */
uint32_t I:1; /*!< bit: 12 Instruction cache enable */
uint32_t V:1; /*!< bit: 13 Vectors bit */
uint32_t RR:1; /*!< bit: 14 Round Robin select */
uint32_t _reserved3:2; /*!< bit:15..16 Reserved */
uint32_t HA:1; /*!< bit: 17 Hardware Access flag enable */
uint32_t _reserved4:1; /*!< bit: 18 Reserved */
uint32_t WXN:1; /*!< bit: 19 Write permission implies XN */
uint32_t UWXN:1; /*!< bit: 20 Unprivileged write permission implies PL1 XN */
uint32_t FI:1; /*!< bit: 21 Fast interrupts configuration enable */
uint32_t U:1; /*!< bit: 22 Alignment model */
uint32_t _reserved5:1; /*!< bit: 23 Reserved */
uint32_t VE:1; /*!< bit: 24 Interrupt Vectors Enable */
uint32_t EE:1; /*!< bit: 25 Exception Endianness */
uint32_t _reserved6:1; /*!< bit: 26 Reserved */
uint32_t NMFI:1; /*!< bit: 27 Non-maskable FIQ (NMFI) support */
uint32_t TRE:1; /*!< bit: 28 TEX remap enable. */
uint32_t AFE:1; /*!< bit: 29 Access flag enable */
uint32_t TE:1; /*!< bit: 30 Thumb Exception enable */
uint32_t _reserved7:1; /*!< bit: 31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} SCTLR_Type;
/* CP15 寄存器SCTLR各个位定义 */
#define SCTLR_TE_Pos 30U /*!< SCTLR: TE Position */
#define SCTLR_TE_Msk (1UL << SCTLR_TE_Pos) /*!< SCTLR: TE Mask */
#define SCTLR_AFE_Pos 29U /*!< SCTLR: AFE Position */
#define SCTLR_AFE_Msk (1UL << SCTLR_AFE_Pos) /*!< SCTLR: AFE Mask */
#define SCTLR_TRE_Pos 28U /*!< SCTLR: TRE Position */
#define SCTLR_TRE_Msk (1UL << SCTLR_TRE_Pos) /*!< SCTLR: TRE Mask */
#define SCTLR_NMFI_Pos 27U /*!< SCTLR: NMFI Position */
#define SCTLR_NMFI_Msk (1UL << SCTLR_NMFI_Pos) /*!< SCTLR: NMFI Mask */
#define SCTLR_EE_Pos 25U /*!< SCTLR: EE Position */
#define SCTLR_EE_Msk (1UL << SCTLR_EE_Pos) /*!< SCTLR: EE Mask */
#define SCTLR_VE_Pos 24U /*!< SCTLR: VE Position */
#define SCTLR_VE_Msk (1UL << SCTLR_VE_Pos) /*!< SCTLR: VE Mask */
#define SCTLR_U_Pos 22U /*!< SCTLR: U Position */
#define SCTLR_U_Msk (1UL << SCTLR_U_Pos) /*!< SCTLR: U Mask */
#define SCTLR_FI_Pos 21U /*!< SCTLR: FI Position */
#define SCTLR_FI_Msk (1UL << SCTLR_FI_Pos) /*!< SCTLR: FI Mask */
#define SCTLR_UWXN_Pos 20U /*!< SCTLR: UWXN Position */
#define SCTLR_UWXN_Msk (1UL << SCTLR_UWXN_Pos) /*!< SCTLR: UWXN Mask */
#define SCTLR_WXN_Pos 19U /*!< SCTLR: WXN Position */
#define SCTLR_WXN_Msk (1UL << SCTLR_WXN_Pos) /*!< SCTLR: WXN Mask */
#define SCTLR_HA_Pos 17U /*!< SCTLR: HA Position */
#define SCTLR_HA_Msk (1UL << SCTLR_HA_Pos) /*!< SCTLR: HA Mask */
#define SCTLR_RR_Pos 14U /*!< SCTLR: RR Position */
#define SCTLR_RR_Msk (1UL << SCTLR_RR_Pos) /*!< SCTLR: RR Mask */
#define SCTLR_V_Pos 13U /*!< SCTLR: V Position */
#define SCTLR_V_Msk (1UL << SCTLR_V_Pos) /*!< SCTLR: V Mask */
#define SCTLR_I_Pos 12U /*!< SCTLR: I Position */
#define SCTLR_I_Msk (1UL << SCTLR_I_Pos) /*!< SCTLR: I Mask */
#define SCTLR_Z_Pos 11U /*!< SCTLR: Z Position */
#define SCTLR_Z_Msk (1UL << SCTLR_Z_Pos) /*!< SCTLR: Z Mask */
#define SCTLR_SW_Pos 10U /*!< SCTLR: SW Position */
#define SCTLR_SW_Msk (1UL << SCTLR_SW_Pos) /*!< SCTLR: SW Mask */
#define SCTLR_B_Pos 7U /*!< SCTLR: B Position */
#define SCTLR_B_Msk (1UL << SCTLR_B_Pos) /*!< SCTLR: B Mask */
#define SCTLR_CP15BEN_Pos 5U /*!< SCTLR: CP15BEN Position */
#define SCTLR_CP15BEN_Msk (1UL << SCTLR_CP15BEN_Pos) /*!< SCTLR: CP15BEN Mask */
#define SCTLR_C_Pos 2U /*!< SCTLR: C Position */
#define SCTLR_C_Msk (1UL << SCTLR_C_Pos) /*!< SCTLR: C Mask */
#define SCTLR_A_Pos 1U /*!< SCTLR: A Position */
#define SCTLR_A_Msk (1UL << SCTLR_A_Pos) /*!< SCTLR: A Mask */
#define SCTLR_M_Pos 0U /*!< SCTLR: M Position */
#define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< SCTLR: M Mask */
/* CP15的ACTLR寄存器
* 参考资料:Cortex-A7 Technical ReferenceManua.pdf P113
*/
typedef union
{
struct
{
uint32_t _reserved0:6; /*!< bit: 0.. 5 Reserved */
uint32_t SMP:1; /*!< bit: 6 Enables coherent requests to the processor */
uint32_t _reserved1:3; /*!< bit: 7.. 9 Reserved */
uint32_t DODMBS:1; /*!< bit: 10 Disable optimized data memory barrier behavior */
uint32_t L2RADIS:1; /*!< bit: 11 L2 Data Cache read-allocate mode disable */
uint32_t L1RADIS:1; /*!< bit: 12 L1 Data Cache read-allocate mode disable */
uint32_t L1PCTL:2; /*!< bit:13..14 L1 Data prefetch control */
uint32_t DDVM:1; /*!< bit: 15 Disable Distributed Virtual Memory (DVM) transactions */
uint32_t _reserved3:12; /*!< bit:16..27 Reserved */
uint32_t DDI:1; /*!< bit: 28 Disable dual issue */
uint32_t _reserved7:3; /*!< bit:29..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} ACTLR_Type;
#define ACTLR_DDI_Pos 28U /*!< ACTLR: DDI Position */
#define ACTLR_DDI_Msk (1UL << ACTLR_DDI_Pos) /*!< ACTLR: DDI Mask */
#define ACTLR_DDVM_Pos 15U /*!< ACTLR: DDVM Position */
#define ACTLR_DDVM_Msk (1UL << ACTLR_DDVM_Pos) /*!< ACTLR: DDVM Mask */
#define ACTLR_L1PCTL_Pos 13U /*!< ACTLR: L1PCTL Position */
#define ACTLR_L1PCTL_Msk (3UL << ACTLR_L1PCTL_Pos) /*!< ACTLR: L1PCTL Mask */
#define ACTLR_L1RADIS_Pos 12U /*!< ACTLR: L1RADIS Position */
#define ACTLR_L1RADIS_Msk (1UL << ACTLR_L1RADIS_Pos) /*!< ACTLR: L1RADIS Mask */
#define ACTLR_L2RADIS_Pos 11U /*!< ACTLR: L2RADIS Position */
#define ACTLR_L2RADIS_Msk (1UL << ACTLR_L2RADIS_Pos) /*!< ACTLR: L2RADIS Mask */
#define ACTLR_DODMBS_Pos 10U /*!< ACTLR: DODMBS Position */
#define ACTLR_DODMBS_Msk (1UL << ACTLR_DODMBS_Pos) /*!< ACTLR: DODMBS Mask */
#define ACTLR_SMP_Pos 6U /*!< ACTLR: SMP Position */
#define ACTLR_SMP_Msk (1UL << ACTLR_SMP_Pos) /*!< ACTLR: SMP Mask */
/* CP15的CPACR寄存器
* 参考资料Cortex-A7 Technical ReferenceManua.pdf P115
*/
typedef union
{
struct
{
uint32_t _reserved0:20; /*!< bit: 0..19 Reserved */
uint32_t cp10:2; /*!< bit:20..21 Access rights for coprocessor 10 */
uint32_t cp11:2; /*!< bit:22..23 Access rights for coprocessor 11 */
uint32_t _reserved1:6; /*!< bit:24..29 Reserved */
uint32_t D32DIS:1; /*!< bit: 30 Disable use of registers D16-D31 of the VFP register file */
uint32_t ASEDIS:1; /*!< bit: 31 Disable Advanced SIMD Functionality */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CPACR_Type;
#define CPACR_ASEDIS_Pos 31U /*!< CPACR: ASEDIS Position */
#define CPACR_ASEDIS_Msk (1UL << CPACR_ASEDIS_Pos) /*!< CPACR: ASEDIS Mask */
#define CPACR_D32DIS_Pos 30U /*!< CPACR: D32DIS Position */
#define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< CPACR: D32DIS Mask */
#define CPACR_cp11_Pos 22U /*!< CPACR: cp11 Position */
#define CPACR_cp11_Msk (3UL << CPACR_cp11_Pos) /*!< CPACR: cp11 Mask */
#define CPACR_cp10_Pos 20U /*!< CPACR: cp10 Position */
#define CPACR_cp10_Msk (3UL << CPACR_cp10_Pos) /*!< CPACR: cp10 Mask */
/* CP15的DFSR寄存器
* 参考资料Cortex-A7 Technical ReferenceManua.pdf P128
*/
typedef union
{
struct
{
uint32_t FS0:4; /*!< bit: 0.. 3 Fault Status bits bit 0-3 */
uint32_t Domain:4; /*!< bit: 4.. 7 Fault on which domain */
uint32_t _reserved0:2; /*!< bit: 8.. 9 Reserved */
uint32_t FS1:1; /*!< bit: 10 Fault Status bits bit 4 */
uint32_t WnR:1; /*!< bit: 11 Write not Read bit */
uint32_t ExT:1; /*!< bit: 12 External abort type */
uint32_t CM:1; /*!< bit: 13 Cache maintenance fault */
uint32_t _reserved1:18; /*!< bit:14..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} DFSR_Type;
#define DFSR_CM_Pos 13U /*!< DFSR: CM Position */
#define DFSR_CM_Msk (1UL << DFSR_CM_Pos) /*!< DFSR: CM Mask */
#define DFSR_Ext_Pos 12U /*!< DFSR: Ext Position */
#define DFSR_Ext_Msk (1UL << DFSR_Ext_Pos) /*!< DFSR: Ext Mask */
#define DFSR_WnR_Pos 11U /*!< DFSR: WnR Position */
#define DFSR_WnR_Msk (1UL << DFSR_WnR_Pos) /*!< DFSR: WnR Mask */
#define DFSR_FS1_Pos 10U /*!< DFSR: FS1 Position */
#define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< DFSR: FS1 Mask */
#define DFSR_Domain_Pos 4U /*!< DFSR: Domain Position */
#define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< DFSR: Domain Mask */
#define DFSR_FS0_Pos 0U /*!< DFSR: FS0 Position */
#define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< DFSR: FS0 Mask */
/* CP15的IFSR寄存器
* 参考资料Cortex-A7 Technical ReferenceManua.pdf P131
*/
typedef union
{
struct
{
uint32_t FS0:4; /*!< bit: 0.. 3 Fault Status bits bit 0-3 */
uint32_t _reserved0:6; /*!< bit: 4.. 9 Reserved */
uint32_t FS1:1; /*!< bit: 10 Fault Status bits bit 4 */
uint32_t _reserved1:1; /*!< bit: 11 Reserved */
uint32_t ExT:1; /*!< bit: 12 External abort type */
uint32_t _reserved2:19; /*!< bit:13..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IFSR_Type;
#define IFSR_ExT_Pos 12U /*!< IFSR: ExT Position */
#define IFSR_ExT_Msk (1UL << IFSR_ExT_Pos) /*!< IFSR: ExT Mask */
#define IFSR_FS1_Pos 10U /*!< IFSR: FS1 Position */
#define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< IFSR: FS1 Mask */
#define IFSR_FS0_Pos 0U /*!< IFSR: FS0 Position */
#define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< IFSR: FS0 Mask */
/* CP15的ISR寄存器
* 参考资料ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf P1640
*/
typedef union
{
struct
{
uint32_t _reserved0:6; /*!< bit: 0.. 5 Reserved */
uint32_t F:1; /*!< bit: 6 FIQ pending bit */
uint32_t I:1; /*!< bit: 7 IRQ pending bit */
uint32_t A:1; /*!< bit: 8 External abort pending bit */
uint32_t _reserved1:23; /*!< bit:14..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} ISR_Type;
#define ISR_A_Pos 13U /*!< ISR: A Position */
#define ISR_A_Msk (1UL << ISR_A_Pos) /*!< ISR: A Mask */
#define ISR_I_Pos 12U /*!< ISR: I Position */
#define ISR_I_Msk (1UL << ISR_I_Pos) /*!< ISR: I Mask */
#define ISR_F_Pos 11U /*!< ISR: F Position */
#define ISR_F_Msk (1UL << ISR_F_Pos) /*!< ISR: F Mask */
/* Mask and shift a bit field value for use in a register bit range. */
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/* Mask and shift a register value to extract a bit filed value. */
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*******************************************************************************
* CP15 访问函数
******************************************************************************/
FORCEDINLINE __STATIC_INLINE uint32_t __get_SCTLR(void)
{
return __MRC(15, 0, 1, 0, 0);
}
FORCEDINLINE __STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
{
__MCR(15, 0, sctlr, 1, 0, 0);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_ACTLR(void)
{
return __MRC(15, 0, 1, 0, 1);
}
FORCEDINLINE __STATIC_INLINE void __set_ACTLR(uint32_t actlr)
{
__MCR(15, 0, actlr, 1, 0, 1);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_CPACR(void)
{
return __MRC(15, 0, 1, 0, 2);
}
FORCEDINLINE __STATIC_INLINE void __set_CPACR(uint32_t cpacr)
{
__MCR(15, 0, cpacr, 1, 0, 2);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_TTBR0(void)
{
return __MRC(15, 0, 2, 0, 0);
}
FORCEDINLINE __STATIC_INLINE void __set_TTBR0(uint32_t ttbr0)
{
__MCR(15, 0, ttbr0, 2, 0, 0);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_TTBR1(void)
{
return __MRC(15, 0, 2, 0, 1);
}
FORCEDINLINE __STATIC_INLINE void __set_TTBR1(uint32_t ttbr1)
{
__MCR(15, 0, ttbr1, 2, 0, 1);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_TTBCR(void)
{
return __MRC(15, 0, 2, 0, 2);
}
FORCEDINLINE __STATIC_INLINE void __set_TTBCR(uint32_t ttbcr)
{
__MCR(15, 0, ttbcr, 2, 0, 2);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_DACR(void)
{
return __MRC(15, 0, 3, 0, 0);
}
FORCEDINLINE __STATIC_INLINE void __set_DACR(uint32_t dacr)
{
__MCR(15, 0, dacr, 3, 0, 0);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_DFSR(void)
{
return __MRC(15, 0, 5, 0, 0);
}
FORCEDINLINE __STATIC_INLINE void __set_DFSR(uint32_t dfsr)
{
__MCR(15, 0, dfsr, 5, 0, 0);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_IFSR(void)
{
return __MRC(15, 0, 5, 0, 1);
}
FORCEDINLINE __STATIC_INLINE void __set_IFSR(uint32_t ifsr)
{
__MCR(15, 0, ifsr, 5, 0, 1);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_DFAR(void)
{
return __MRC(15, 0, 6, 0, 0);
}
FORCEDINLINE __STATIC_INLINE void __set_DFAR(uint32_t dfar)
{
__MCR(15, 0, dfar, 6, 0, 0);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_IFAR(void)
{
return __MRC(15, 0, 6, 0, 2);
}
FORCEDINLINE __STATIC_INLINE void __set_IFAR(uint32_t ifar)
{
__MCR(15, 0, ifar, 6, 0, 2);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_VBAR(void)
{
return __MRC(15, 0, 12, 0, 0);
}
FORCEDINLINE __STATIC_INLINE void __set_VBAR(uint32_t vbar)
{
__MCR(15, 0, vbar, 12, 0, 0);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_ISR(void)
{
return __MRC(15, 0, 12, 1, 0);
}
FORCEDINLINE __STATIC_INLINE void __set_ISR(uint32_t isr)
{
__MCR(15, 0, isr, 12, 1, 0);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_CONTEXTIDR(void)
{
return __MRC(15, 0, 13, 0, 1);
}
FORCEDINLINE __STATIC_INLINE void __set_CONTEXTIDR(uint32_t contextidr)
{
__MCR(15, 0, contextidr, 13, 0, 1);
}
FORCEDINLINE __STATIC_INLINE uint32_t __get_CBAR(void)
{
return __MRC(15, 4, 15, 0, 0);
}
/*******************************************************************************
* GIC相关内容
*有关GIC的内容参考ARM Generic Interrupt Controller(ARM GIC控制器)V2.0.pdf
******************************************************************************/
/*
* GIC寄存器描述结构体
* GIC分为分发器端和CPU接口端
*/
typedef struct
{
uint32_t RESERVED0[1024];
__IOM uint32_t D_CTLR; /*!< Offset: 0x1000 (R/W) Distributor Control Register */
__IM uint32_t D_TYPER; /*!< Offset: 0x1004 (R/ ) Interrupt Controller Type Register */
__IM uint32_t D_IIDR; /*!< Offset: 0x1008 (R/ ) Distributor Implementer Identification Register */
uint32_t RESERVED1[29];
__IOM uint32_t D_IGROUPR[16]; /*!< Offset: 0x1080 - 0x0BC (R/W) Interrupt Group Registers */
uint32_t RESERVED2[16];
__IOM uint32_t D_ISENABLER[16]; /*!< Offset: 0x1100 - 0x13C (R/W) Interrupt Set-Enable Registers */
uint32_t RESERVED3[16];
__IOM uint32_t D_ICENABLER[16]; /*!< Offset: 0x1180 - 0x1BC (R/W) Interrupt Clear-Enable Registers */
uint32_t RESERVED4[16];
__IOM uint32_t D_ISPENDR[16]; /*!< Offset: 0x1200 - 0x23C (R/W) Interrupt Set-Pending Registers */
uint32_t RESERVED5[16];
__IOM uint32_t D_ICPENDR[16]; /*!< Offset: 0x1280 - 0x2BC (R/W) Interrupt Clear-Pending Registers */
uint32_t RESERVED6[16];
__IOM uint32_t D_ISACTIVER[16]; /*!< Offset: 0x1300 - 0x33C (R/W) Interrupt Set-Active Registers */
uint32_t RESERVED7[16];
__IOM uint32_t D_ICACTIVER[16]; /*!< Offset: 0x1380 - 0x3BC (R/W) Interrupt Clear-Active Registers */
uint32_t RESERVED8[16];
__IOM uint8_t D_IPRIORITYR[512]; /*!< Offset: 0x1400 - 0x5FC (R/W) Interrupt Priority Registers */
uint32_t RESERVED9[128];
__IOM uint8_t D_ITARGETSR[512]; /*!< Offset: 0x1800 - 0x9FC (R/W) Interrupt Targets Registers */
uint32_t RESERVED10[128];
__IOM uint32_t D_ICFGR[32]; /*!< Offset: 0x1C00 - 0xC7C (R/W) Interrupt configuration registers */
uint32_t RESERVED11[32];
__IM uint32_t D_PPISR; /*!< Offset: 0x1D00 (R/ ) Private Peripheral Interrupt Status Register */
__IM uint32_t D_SPISR[15]; /*!< Offset: 0x1D04 - 0xD3C (R/ ) Shared Peripheral Interrupt Status Registers */
uint32_t RESERVED12[112];
__OM uint32_t D_SGIR; /*!< Offset: 0x1F00 ( /W) Software Generated Interrupt Register */
uint32_t RESERVED13[3];
__IOM uint8_t D_CPENDSGIR[16]; /*!< Offset: 0x1F10 - 0xF1C (R/W) SGI Clear-Pending Registers */
__IOM uint8_t D_SPENDSGIR[16]; /*!< Offset: 0x1F20 - 0xF2C (R/W) SGI Set-Pending Registers */
uint32_t RESERVED14[40];
__IM uint32_t D_PIDR4; /*!< Offset: 0x1FD0 (R/ ) Peripheral ID4 Register */
__IM uint32_t D_PIDR5; /*!< Offset: 0x1FD4 (R/ ) Peripheral ID5 Register */
__IM uint32_t D_PIDR6; /*!< Offset: 0x1FD8 (R/ ) Peripheral ID6 Register */
__IM uint32_t D_PIDR7; /*!< Offset: 0x1FDC (R/ ) Peripheral ID7 Register */
__IM uint32_t D_PIDR0; /*!< Offset: 0x1FE0 (R/ ) Peripheral ID0 Register */
__IM uint32_t D_PIDR1; /*!< Offset: 0x1FE4 (R/ ) Peripheral ID1 Register */
__IM uint32_t D_PIDR2; /*!< Offset: 0x1FE8 (R/ ) Peripheral ID2 Register */
__IM uint32_t D_PIDR3; /*!< Offset: 0x1FEC (R/ ) Peripheral ID3 Register */
__IM uint32_t D_CIDR0; /*!< Offset: 0x1FF0 (R/ ) Component ID0 Register */
__IM uint32_t D_CIDR1; /*!< Offset: 0x1FF4 (R/ ) Component ID1 Register */
__IM uint32_t D_CIDR2; /*!< Offset: 0x1FF8 (R/ ) Component ID2 Register */
__IM uint32_t D_CIDR3; /*!< Offset: 0x1FFC (R/ ) Component ID3 Register */
__IOM uint32_t C_CTLR; /*!< Offset: 0x2000 (R/W) CPU Interface Control Register */
__IOM uint32_t C_PMR; /*!< Offset: 0x2004 (R/W) Interrupt Priority Mask Register */
__IOM uint32_t C_BPR; /*!< Offset: 0x2008 (R/W) Binary Point Register */
__IM uint32_t C_IAR; /*!< Offset: 0x200C (R/ ) Interrupt Acknowledge Register */
__OM uint32_t C_EOIR; /*!< Offset: 0x2010 ( /W) End Of Interrupt Register */
__IM uint32_t C_RPR; /*!< Offset: 0x2014 (R/ ) Running Priority Register */
__IM uint32_t C_HPPIR; /*!< Offset: 0x2018 (R/ ) Highest Priority Pending Interrupt Register */
__IOM uint32_t C_ABPR; /*!< Offset: 0x201C (R/W) Aliased Binary Point Register */
__IM uint32_t C_AIAR; /*!< Offset: 0x2020 (R/ ) Aliased Interrupt Acknowledge Register */
__OM uint32_t C_AEOIR; /*!< Offset: 0x2024 ( /W) Aliased End Of Interrupt Register */
__IM uint32_t C_AHPPIR; /*!< Offset: 0x2028 (R/ ) Aliased Highest Priority Pending Interrupt Register */
uint32_t RESERVED15[41];
__IOM uint32_t C_APR0; /*!< Offset: 0x20D0 (R/W) Active Priority Register */
uint32_t RESERVED16[3];
__IOM uint32_t C_NSAPR0; /*!< Offset: 0x20E0 (R/W) Non-secure Active Priority Register */
uint32_t RESERVED17[6];
__IM uint32_t C_IIDR; /*!< Offset: 0x20FC (R/ ) CPU Interface Identification Register */
uint32_t RESERVED18[960];
__OM uint32_t C_DIR; /*!< Offset: 0x3000 ( /W) Deactivate Interrupt Register */
} GIC_Type;
/*
* GIC初始化
* 为了简单使用GIC的group0
*/
FORCEDINLINE __STATIC_INLINE void GIC_Init(void)
{
uint32_t i;
uint32_t irqRegs;
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
irqRegs = (gic->D_TYPER & 0x1FUL) + 1;
/* On POR, all SPI is in group 0, level-sensitive and using 1-N model */
/* Disable all PPI, SGI and SPI */
for (i = 0; i < irqRegs; i++)
gic->D_ICENABLER[i] = 0xFFFFFFFFUL;
/* Make all interrupts have higher priority */
gic->C_PMR = (0xFFUL << (8 - __GIC_PRIO_BITS)) & 0xFFUL;
/* No subpriority, all priority level allows preemption */
gic->C_BPR = 7 - __GIC_PRIO_BITS;
/* Enable group0 distribution */
gic->D_CTLR = 1UL;
/* Enable group0 signaling */
gic->C_CTLR = 1UL;
}
/*
* 使能指定的中断
*/
FORCEDINLINE __STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
gic->D_ISENABLER[((uint32_t)(int32_t)IRQn) >> 5] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/*
* 关闭指定的中断
*/
FORCEDINLINE __STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
gic->D_ICENABLER[((uint32_t)(int32_t)IRQn) >> 5] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/*
* 返回中断号
*/
FORCEDINLINE __STATIC_INLINE uint32_t GIC_AcknowledgeIRQ(void)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
return gic->C_IAR & 0x1FFFUL;
}
/*
* 向EOIR写入发送中断的中断号来释放中断
*/
FORCEDINLINE __STATIC_INLINE void GIC_DeactivateIRQ(uint32_t value)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
gic->C_EOIR = value;
}
/*
* 获取运行优先级
*/
FORCEDINLINE __STATIC_INLINE uint32_t GIC_GetRunningPriority(void)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
return gic->C_RPR & 0xFFUL;
}
/*
* 设置组优先级
*/
FORCEDINLINE __STATIC_INLINE void GIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
gic->C_BPR = PriorityGroup & 0x7UL;
}
/*
* 获取组优先级
*/
FORCEDINLINE __STATIC_INLINE uint32_t GIC_GetPriorityGrouping(void)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
return gic->C_BPR & 0x7UL;
}
/*
* 设置优先级
*/
FORCEDINLINE __STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
gic->D_IPRIORITYR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8UL - __GIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
/*
* 获取优先级
*/
FORCEDINLINE __STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn)
{
GIC_Type *gic = (GIC_Type *)(__get_CBAR() & 0xFFFF0000UL);
return(((uint32_t)gic->D_IPRIORITYR[((uint32_t)(int32_t)IRQn)] >> (8UL - __GIC_PRIO_BITS)));
}
#endif

View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------------
* 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 _IMX6UL_H_
#define _IMX6UL_H_
#include "MCIMX6Y2.h"
#include "core_ca7.h"
#include "clock.h"
#include "systick.h"
#endif /* _IMX6UL_H_ */

View File

@@ -0,0 +1,7 @@
#ifndef _SYSTICK_H_
#define _SYSTICK_H_
void systick_init(k_tick_t tick_per_second);
#endif /* _SYSTICK_H_ */

View File

@@ -0,0 +1,37 @@
#include "tos_k.h"
#include "imx6ul.h"
static void epit1_init(unsigned int frac, unsigned int value)
{
if (frac > 0XFFF) {
frac = 0XFFF;
}
EPIT1->CR = 0;
EPIT1->CR = (1 << 24 | frac << 4 | 1 << 3 | 1 << 2 | 1 << 1);
EPIT1->LR = value;
EPIT1->CMPR = 0;
GIC_EnableIRQ(EPIT1_IRQn);
EPIT1->CR |= 1 << 0;
}
void systick_handler(void *arg)
{
if (EPIT1->SR & (1 << 0)) {
tos_tick_handler();
}
EPIT1->SR |= 1 << 0;
}
void systick_init(k_tick_t tick_per_second)
{
epit1_init(0, 66000000 / tick_per_second);
tos_interrupt_handler_register(EPIT1_IRQn, (int_handler_t)systick_handler, NULL);
}

View File

@@ -0,0 +1,202 @@
/* Fuchsia's code is nice here, so I learn from it(fine, almost copy). thanks */
.syntax unified
.text
/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */
.macro stack_align, tempreg
/* make sure the stack is aligned */
mov \tempreg, sp
tst sp, #4
subeq sp, #4
push { \tempreg }
/* tempreg holds the original stack */
.endm
.macro stack_restore, tempreg
/* restore the potentially unaligned stack */
pop { \tempreg }
mov sp, \tempreg
.endm
/* save and disable the vfp unit */
.macro vfp_save, temp1
/* save old fpexc */
vmrs \temp1, fpexc
push { \temp1 }
/* hard disable the vfp unit */
bic \temp1, #(1<<30)
vmsr fpexc, \temp1
.endm
/* restore the vfp enable/disable state */
.macro vfp_restore, temp1
/* restore fpexc */
pop { \temp1 }
vmsr fpexc, \temp1
.endm
/* Save callee trashed registers.
* At exit r0 contains a pointer to the register frame.
*/
.macro save
/* save spsr and r14 onto the svc stack */
srsdb #0x13!
/* switch to svc mode, interrupts disabled */
cpsid i, #0x13
/* save callee trashed regs and lr */
push { r0-r3, r12, lr }
#if 0
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
/* save and disable the vfp unit */
vfp_save r0
#endif
#endif
/* make sure the stack is 8 byte aligned */
stack_align r0
/* r0 now holds the pointer to the original iframe (before alignment) */
.endm
.macro save_offset, offset
sub lr, \offset
save
.endm
.macro restore
/* undo the stack alignment we did before */
stack_restore r0
#if 0
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
/* restore the old state of the vfp unit */
vfp_restore r0
#endif
#endif
pop { r0-r3, r12, lr }
/* return to whence we came from */
rfeia sp!
.endm
/* Save all registers.
* At exit r0 contains a pointer to the register frame.
*/
.macro saveall
/* save spsr and r14 onto the svc stack */
srsdb #0x13!
/* switch to svc mode, interrupts disabled */
cpsid i,#0x13
/* save all regs */
push { r0-r12, lr }
#if 0
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
/* save and disable the vfp unit */
vfp_save r0
#endif
#endif
/* make sure the stack is 8 byte aligned */
stack_align r0
/* r0 now holds the pointer to the original iframe (before alignment) */
.endm
.macro saveall_offset, offset
sub lr, \offset
saveall
.endm
.macro restoreall
/* undo the stack alignment we did before */
stack_restore r0
#if 0
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
/* restore the old state of the vfp unit */
vfp_restore r0
#endif
#endif
pop { r0-r12, r14 }
/* return to whence we came from */
rfeia sp!
.endm
.extern tos_knl_irq_enter
.extern tos_knl_irq_leave
.global arm_undefined
arm_undefined:
save
/* r0 now holds pointer to iframe */
bl arm_undefined_handler
restore
.global arm_syscall
arm_syscall:
b .
.global arm_prefetch_abort
arm_prefetch_abort:
saveall_offset #4
/* r0 now holds pointer to iframe */
bl arm_prefetch_abort_handler
restoreall
.global arm_data_abort
arm_data_abort:
saveall_offset #8
/* r0 now holds pointer to iframe */
bl arm_data_abort_handler
restoreall
.global arm_reserved
arm_reserved:
b .
.global arm_irq
arm_irq:
saveall_offset #4
/* r0 now holds pointer to iframe */
bl tos_knl_irq_enter
/* call into higher level code */
bl interrupt_irq
bl tos_knl_irq_leave
restoreall
.global arm_fiq
arm_fiq:
b .
.end

View File

@@ -0,0 +1,73 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _PORT_H_
#define _PORT_H_
__PORT__ void port_int_disable(void);
__PORT__ void port_int_enable(void);
__PORT__ cpu_cpsr_t port_cpsr_save(void);
__PORT__ void port_cpsr_restore(cpu_cpsr_t cpsr);
__PORT__ void port_cpu_reset(void);
__PORT__ void port_sched_start(void) __NO_RETURN__;
__PORT__ void port_context_switch(void);
__PORT__ void port_irq_context_switch(void);
__PORT__ void port_systick_config(uint32_t cycle_per_tick);
__PORT__ void port_systick_priority_set(uint32_t prio);
#if TOS_CFG_TICKLESS_EN > 0u
__PORT__ void port_systick_resume(void);
__PORT__ void port_systick_suspend(void);
__PORT__ void port_systick_reload(uint32_t cycle_per_tick);
__PORT__ void port_systick_pending_reset(void);
__PORT__ k_time_t port_systick_max_delay_millisecond(void);
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
__PORT__ void port_sleep_mode_enter(void);
__PORT__ void port_stop_mode_enter(void);
__PORT__ void port_standby_mode_enter(void);
#endif
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
__PORT__ void HardFault_Handler(void);
__PORT__ void port_fault_diagnosis(void);
#endif
#endif /* _PORT_H_ */

View File

@@ -0,0 +1,134 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
__PORT__ void port_cpu_reset(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__ k_time_t port_systick_max_delay_millisecond(void)
{
}
__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)
{
}
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
__PORT__ void port_sleep_mode_enter(void)
{
#if 0
#if 1
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
#else
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
#endif
#endif
}
__PORT__ void port_stop_mode_enter(void)
{
#if 0
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
#endif
}
__PORT__ void port_standby_mode_enter(void)
{
#if 0
HAL_PWR_EnterSTANDBYMode();
#endif
}
#endif
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
__PORT__ void port_fault_diagnosis(void)
{
// k_fault_log_writer("fault diagnosis does not supported in CORTEX M0\n");
}
#if 0
/*------------------ 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
#endif /* TOS_CFG_FAULT_BACKTRACE_EN */

View File

@@ -0,0 +1,35 @@
/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#ifndef _PORT_CONFIG_H_
#define _PORT_CONFIG_H_
#define TOS_CFG_CPU_ADDR_SIZE CPU_WORD_SIZE_32
#define TOS_CFG_CPU_DATA_SIZE CPU_WORD_SIZE_32
#define TOS_CFG_CPU_STK_GROWTH CPU_STK_GROWTH_DESCENDING
// #define TOS_CFG_CPU_HRTIMER_SIZE CPU_WORD_SIZE_32
#define TOS_CFG_CPU_HRTIMER_EN 0u
#define TOS_CFG_CPU_LEAD_ZEROS_ASM_PRESENT 0u
#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,80 @@
.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
.extern k_curr_task
.extern k_next_task
.syntax unified
.align 2
.text
.type port_int_disable, %function
port_int_disable:
CPSID I
.type port_int_enable, %function
port_int_enable:
CPSIE I
.type port_cpsr_save, %function
port_cpsr_save:
MRS R0, CPSR
CPSID I
BX LR
.type port_cpsr_restore, %function
port_cpsr_restore:
MSR CPSR, R0
BX LR
.type port_sched_start, %function
port_sched_start:
B .L__context_restore
.type port_context_switch, %function
port_context_switch:
.L__context_save:
STR R0, [SP, #-0xC] /* backup R0 */
MRS R0, CPSR
TST LR, #0x01
ORRNE R0, R0, 0x20 /* set thumb bit*/
STMFD SP!, { R0 } /* save CPSR */
STMFD SP!, { LR } /* save PC */
LDR R0, [SP, #-0x4] /* restore R0 */
STMFD SP!, { R0 - R12, LR }
/* k_curr_task->sp = SP */
LDR R0, =k_curr_task
LDR R0, [R0]
STR SP, [R0]
.L__context_restore:
/* k_curr_task = k_next_task */
LDR R0, =k_next_task
LDR R0, [R0]
LDR R1, =k_curr_task
STR R0, [R1]
/* SP = k_next_task->sp */
LDR SP, [R0]
LDMFD SP!, { R0 - R12, LR }
RFEIA SP!
.type port_irq_context_switch, %function
port_irq_context_switch:
/* we already store the k_curr_task's context onto its stack by arm_irq(see saveall_offset) */
/* ATTENTION: our kernel always runs in SVC mode even in user task,
if one day we make the user task run in USR mode(although I cannot see any meaning to do this in RTOS),
we must deal with more logic */
B .L__context_restore /* magnificent */

View File

@@ -0,0 +1,150 @@
.equ MODE_USR, 0x10
.equ MODE_FIQ, 0x11
.equ MODE_IRQ, 0x12
.equ MODE_SVC, 0x13
.equ MODE_ABT, 0x17
.equ MODE_UND, 0x1B
.equ MODE_SYS, 0x1F
.equ BIT_I, 0x80 @ when I bit is set, IRQ is disabled
.equ BIT_F, 0x40 @ when F bit is set, FIQ is disabled
.equ STACK_SIZE_USR, 0x00000100
.equ STACK_SIZE_FIQ, 0x00000100
.equ STACK_SIZE_IRQ, 0x00001000
.equ STACK_SIZE_ABT, 0x00000100
.equ STACK_SIZE_UND, 0x00000100
.equ STACK_SIZE_SYS, 0x00000800
.equ STACK_SIZE_SVC, 0x00001000
.syntax unified
.section ".text.vector", "ax"
.code 32
.align 0
.global _start
_start:
_vector:
ldr pc, vector_reset
ldr pc, vector_undefined
ldr pc, vector_swi
ldr pc, vector_prefetch_abort
ldr pc, vector_data_abort
ldr pc, vector_reserved
ldr pc, vector_irq
ldr pc, vector_fiq
.align 3
vector_reset:
.word arm_reset
vector_undefined:
.word arm_undefined
vector_swi:
.word arm_syscall
vector_prefetch_abort:
.word arm_prefetch_abort
vector_data_abort:
.word arm_data_abort
vector_reserved:
.word arm_reserved
vector_irq:
.word arm_irq
vector_fiq:
.word arm_fiq
.section ".text", "ax"
.global arm_reset
arm_reset:
.L__cache_disable:
mrc p15, 0, r12, c1, c0, 0 /* read SCTLR */
bic r12, #(1 << 12) /* i-cache disable */
bic r12, #(1 << 2 | 1 << 0) /* d-cache, mmu disable */
mcr p15, 0, r12, c1, c0, 0 /* write SCTLR */
/* set up the stack */
.L__stack_setup:
cpsid i, #MODE_IRQ /* irq */
ldr sp, =__irq_stack_limit
cpsid i, #MODE_FIQ /* fiq */
ldr sp, =__fiq_stack_limit
cpsid i, #MODE_ABT /* abort */
ldr sp, =__abt_stack_limit
cpsid i, #MODE_UND /* undefined */
ldr sp, =__und_stack_limit
cpsid i, #MODE_SYS /* system */
ldr sp, =__sys_stack_limit
cpsid i, #MODE_SVC /* supervisor */
ldr sp, =__svc_stack_limit
/* init vector table */
.L__vector_setup:
dsb
isb
ldr r0, =_vector
mcr p15, 0, r0, c12, c0, #0 /* write VBAR */
dsb
isb
/* clear bss */
.L__bss_clear:
ldr r0, =__bss_start__
ldr r1, =__bss_end__
mov r2, #0
.L__bss_loop:
cmp r0, r1
strlt r2, [r0], #4
blt .L__bss_loop
bl main
b .
.section ".bss.prebss.exc_stk", "wa"
.bss
.align 2
__usr_stack_base:
.space STACK_SIZE_USR
__usr_stack_limit:
__fiq_stack_base:
.space STACK_SIZE_FIQ
__fiq_stack_limit:
__irq_stack_base:
.space STACK_SIZE_IRQ
__irq_stack_limit:
__abt_stack_base:
.space STACK_SIZE_ABT
__abt_stack_limit:
__und_stack_base:
.space STACK_SIZE_UND
__und_stack_limit:
__sys_stack_base:
.space STACK_SIZE_SYS
__sys_stack_limit:
__svc_stack_base:
.space STACK_SIZE_SVC
__svc_stack_limit:
.size __usr_stack_base, . - __usr_stack_base
.end

View File

@@ -0,0 +1,90 @@
#include "chip/chip.h"
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = KERNEL_BASE;
_start = .;
.text : AT(KERNEL_BASE) {
__text_start = .;
KEEP(*(.text.vector))
*(.text)
*(.text.*)
KEEP(*(.init))
KEEP(*(.fini))
}
.ARM.extab : ALIGN(4) {
*(.ARM.extab* .gnu.linkonce.armextab.*)
}
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx : ALIGN(4) {
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
}
__exidx_end = .;
.dummy_post_text : {
__text_end = .;
}
.rodata : ALIGN(4) {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
}
.dummy_post_rodata : {
__rodata_end = .;
}
.data : ALIGN(4) {
__data_start = .;
*(.data)
*(.data.*)
}
.ctors : ALIGN(4) {
__ctor_list = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.ctors .init_array*))
__ctor_end = .;
}
.dtors : ALIGN(4) {
__dtor_list = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.dtors .fini_array*))
__dtor_end = .;
}
.dummy_post_rodata : {
__data_end = .;
}
.bss : ALIGN(4) {
KEEP(*(.bss.prebss.*))
. = ALIGN(4);
__bss_start__ = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
}
_end = .;
/* Strip unnecessary stuff */
/DISCARD/ : { *(.comment .note) }
}