mirror of
https://github.com/Ai-Thinker-Open/Ai-Thinker-Open_RTL8710BX_ALIOS_SDK.git
synced 2025-07-31 19:31:05 +00:00
rel_1.6.0 init
This commit is contained in:
commit
27b3e2883d
19359 changed files with 8093121 additions and 0 deletions
20
Living_SDK/platform/arch/arm/armv5/README.md
Normal file
20
Living_SDK/platform/arch/arm/armv5/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
## Contents
|
||||
|
||||
## Introduction
|
||||
**armv5** arch files of armv5
|
||||
|
||||
### Features
|
||||
- armv5 system api
|
||||
|
||||
### Directories
|
||||
|
||||
```sh
|
||||
armv5
|
||||
├─ gcc # System adapter file of armv5 architecture for gcc
|
||||
├─ armcc # System adapter file of armv5 architecture for armcc
|
||||
├─ panic # panic adapter file of armv5 architecture
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
## Reference
|
||||
25
Living_SDK/platform/arch/arm/armv5/armcc/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv5/armcc/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv5/armcc/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv5/armcc/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
165
Living_SDK/platform/arch/arm/armv5/armcc/port_c.c
Normal file
165
Living_SDK/platform/arch/arm/armv5/armcc/port_c.c
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#pragma arm
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(base + size);
|
||||
|
||||
/*stack need 8 bytes align*/
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
*(--stk) = (uint32_t)entry; /* Entry Point */
|
||||
*(--stk) = (uint32_t)krhino_task_deathbed; /* LR */
|
||||
*(--stk) = (uint32_t)0; /* R12 */
|
||||
*(--stk) = (uint32_t)0; /* R11 */
|
||||
*(--stk) = (uint32_t)0; /* R10 */
|
||||
*(--stk) = (uint32_t)0; /* R9 */
|
||||
*(--stk) = (uint32_t)0; /* R8 */
|
||||
*(--stk) = (uint32_t)0; /* R7 : */
|
||||
*(--stk) = (uint32_t)0; /* R6 */
|
||||
*(--stk) = (uint32_t)0; /* R5 */
|
||||
*(--stk) = (uint32_t)0; /* R4 */
|
||||
*(--stk) = (uint32_t)0; /* R3 */
|
||||
*(--stk) = (uint32_t)0; /* R2 */
|
||||
*(--stk) = (uint32_t)0; /* R1 */
|
||||
*(--stk) = (uint32_t)arg; /* R0 argument */
|
||||
*(--stk) = (uint32_t)0x13; /* CPSR SVC mode */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
void fiq_pre_proc(void)
|
||||
{
|
||||
g_intrpt_nested_level[cpu_cur_get()]++;
|
||||
}
|
||||
|
||||
void fiq_end_proc(void)
|
||||
{
|
||||
g_intrpt_nested_level[cpu_cur_get()]--;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_irq_enable( void )
|
||||
{
|
||||
#define ARM968_IF_MASK 0xC0
|
||||
#define ARM968_IRQ_ENABLE 0x80
|
||||
|
||||
uint32_t interrupt;
|
||||
|
||||
__asm volatile(
|
||||
"MRS interrupt,CPSR\n"
|
||||
"AND interrupt,interrupt,#0xC0\n"
|
||||
);
|
||||
|
||||
return (!(interrupt & ARM968_IRQ_ENABLE));
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_fiq_enable( void )
|
||||
{
|
||||
#define ARM968_IF_MASK 0xC0
|
||||
#define ARM968_FIQ_ENABLE 0x40
|
||||
|
||||
uint32_t interrupt;
|
||||
|
||||
__asm volatile(
|
||||
"MRS interrupt,CPSR\n"
|
||||
"AND interrupt,interrupt,#0xC0\n"
|
||||
);
|
||||
|
||||
return (!(interrupt & ARM968_FIQ_ENABLE));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_irq_context( void )
|
||||
{
|
||||
#define ARM968_IRQ_MODE 0x12
|
||||
|
||||
uint32_t mode;
|
||||
|
||||
__asm volatile(
|
||||
"MRS mode,CPSR\n"
|
||||
"AND mode,mode,#0x1f\n"
|
||||
);
|
||||
|
||||
return (ARM968_IRQ_MODE == mode);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_fiq_context( void )
|
||||
{
|
||||
#define ARM968_FIQ_MODE 0x11
|
||||
|
||||
uint32_t mode;
|
||||
|
||||
__asm volatile(
|
||||
"MRS mode,CPSR\n"
|
||||
"AND mode,mode,#0x1f\n"
|
||||
);
|
||||
|
||||
return (ARM968_FIQ_MODE == mode);
|
||||
}
|
||||
|
||||
|
||||
uint32_t platform_is_in_interrupt_context( void )
|
||||
{
|
||||
return ((platform_is_in_fiq_context())
|
||||
|| (platform_is_in_irq_context()));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
int portDISABLE_FIQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
unsigned long mask;
|
||||
|
||||
__asm volatile(
|
||||
"mrs mask, cpsr \n"
|
||||
"orr temp, mask, #0x40\n"
|
||||
"msr cpsr_c, temp"
|
||||
);
|
||||
|
||||
return (!!(mask & 0x40));
|
||||
}
|
||||
|
||||
int portDISABLE_IRQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
unsigned long mask;
|
||||
|
||||
__asm volatile(
|
||||
"mrs mask, cpsr \n"
|
||||
"orr temp, mask, #0x80\n"
|
||||
"msr cpsr_c, temp"
|
||||
);
|
||||
|
||||
return (!!(mask & 0x80));
|
||||
}
|
||||
|
||||
void portENABLE_IRQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm volatile(
|
||||
"mrs temp, cpsr \n"
|
||||
"bic temp, temp, #0x80\n"
|
||||
"msr cpsr_c, temp"
|
||||
);
|
||||
}
|
||||
|
||||
void portENABLE_FIQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm volatile(
|
||||
"mrs temp, cpsr \n"
|
||||
"bic temp, temp, #0x40\n"
|
||||
"msr cpsr_c, temp"
|
||||
);
|
||||
}
|
||||
94
Living_SDK/platform/arch/arm/armv5/armcc/port_s.S
Normal file
94
Living_SDK/platform/arch/arm/armv5/armcc/port_s.S
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include <k_config.h>
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN g_active_task
|
||||
EXTERN g_preferred_ready_task
|
||||
EXTERN krhino_stack_ovf_check
|
||||
EXTERN krhino_task_sched_stats_get
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
EXPORT cpu_intrpt_save
|
||||
EXPORT cpu_intrpt_restore
|
||||
EXPORT cpu_task_switch
|
||||
EXPORT cpu_intrpt_switch
|
||||
EXPORT cpu_first_task_start
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
PRESERVE8
|
||||
CODE32
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
GLOBAL cpu_intrpt_save
|
||||
cpu_intrpt_save
|
||||
MRS R0, CPSR ; Set IRQ and FIQ bits in CPSR to disable all interrupts
|
||||
ORR R1, R0, #0xC0
|
||||
MSR CPSR_c, R1
|
||||
MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags
|
||||
AND R1, R1, #0xC0
|
||||
CMP R1, #0xC0
|
||||
BNE cpu_intrpt_save ; Not properly disabled (try again)
|
||||
BX LR ; Disabled, return the original CPSR contents in R0
|
||||
|
||||
GLOBAL cpu_intrpt_restore
|
||||
cpu_intrpt_restore
|
||||
MSR CPSR_c, R0
|
||||
BX LR
|
||||
|
||||
cpu_first_task_start
|
||||
LDR R0, =g_active_task
|
||||
LDR R0, [R0]
|
||||
LDR SP, [R0]
|
||||
|
||||
LDMFD SP!, {R0}
|
||||
LDR R1, [SP, #56]
|
||||
TST R1, #1
|
||||
ORRNE R0, #32 ; if PC is thumb mode, set SPSR to thumb
|
||||
MSR SPSR_cxsf, R0
|
||||
LDMFD SP!, {R0-R12, LR, PC}^
|
||||
|
||||
GLOBAL cpu_task_switch
|
||||
cpu_task_switch
|
||||
STMFD SP!, {LR}
|
||||
STMFD SP!, {R0-R12,LR}
|
||||
MRS R0, CPSR
|
||||
STMFD SP!, {R0} ; push current cpsr
|
||||
|
||||
; g_active_task->task_stack = SP
|
||||
LDR R0, =g_active_task
|
||||
LDR R0, [R0]
|
||||
STR SP, [R0]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
GLOBAL cpu_intrpt_switch
|
||||
cpu_intrpt_switch
|
||||
LDR R0, =g_preferred_ready_task
|
||||
LDR R1, =g_active_task
|
||||
LDR R0, [R0]
|
||||
STR R0, [R1]
|
||||
|
||||
LDR R0, =g_active_task
|
||||
LDR R0, [R0]
|
||||
LDR SP, [R0]
|
||||
|
||||
; Restore New Task context
|
||||
LDMFD SP!, {R0}
|
||||
LDR R1, [SP, #56]
|
||||
TST R1, #1
|
||||
ORRNE R0, #32 ; if PC is thumb mode, set SPSR to thumb
|
||||
MSR SPSR_cxsf, R0
|
||||
LDMFD SP!, {R0-R12, LR, PC}^
|
||||
|
||||
END
|
||||
|
||||
15
Living_SDK/platform/arch/arm/armv5/armv5.mk
Normal file
15
Living_SDK/platform/arch/arm/armv5/armv5.mk
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
NAME := arch_armv5
|
||||
|
||||
$(NAME)_MBINS_TYPE := kernel
|
||||
$(NAME)_VERSION := 1.0.0
|
||||
$(NAME)_SUMMARY := arch for armv5
|
||||
|
||||
GLOBAL_INCLUDES += common
|
||||
|
||||
$(NAME)_CFLAGS := -marm -mthumb-interwork
|
||||
|
||||
$(NAME)_SOURCES += gcc/port_c.c \
|
||||
gcc/port_s.S \
|
||||
common/panic_c.c \
|
||||
common/panic_gcc.S
|
||||
|
||||
56
Living_SDK/platform/arch/arm/armv5/common/k_compiler.h
Normal file
56
Living_SDK/platform/arch/arm/armv5/common/k_compiler.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_COMPILER_H
|
||||
#define K_COMPILER_H
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#define RHINO_INLINE static __inline
|
||||
/* get the return address of the current function
|
||||
unsigned int __return_address(void) */
|
||||
#define RHINO_GET_RA() (void *)__return_address()
|
||||
/* get the the value of the stack pointer
|
||||
unsigned int __current_sp(void) */
|
||||
#define RHINO_GET_SP() (void *)__current_sp()
|
||||
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
#define RHINO_INLINE static inline
|
||||
/* get the return address of the current function
|
||||
unsigned int __get_LR(void) */
|
||||
#define RHINO_GET_RA() (void *)__get_LR()
|
||||
/* get the the value of the stack pointer
|
||||
unsigned int __get_SP(void) */
|
||||
#define RHINO_GET_SP() (void *)__get_SP()
|
||||
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define RHINO_INLINE static inline
|
||||
/* get the return address of the current function
|
||||
void * __builtin_return_address (unsigned int level) */
|
||||
#define RHINO_GET_RA() __builtin_return_address(0)
|
||||
/* get the return address of the current function */
|
||||
__attribute__((always_inline)) RHINO_INLINE void *RHINO_GET_SP(void)
|
||||
{
|
||||
void *sp;
|
||||
asm volatile("mov %0, SP\n" : "=r" (sp));
|
||||
return sp;
|
||||
}
|
||||
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "Unsupported compiler"
|
||||
#endif
|
||||
|
||||
#endif /* K_COMPILER_H */
|
||||
|
||||
21
Living_SDK/platform/arch/arm/armv5/common/k_types.h
Normal file
21
Living_SDK/platform/arch/arm/armv5/common/k_types.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_TYPES_H
|
||||
#define K_TYPES_H
|
||||
|
||||
#include "k_compiler.h"
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* K_TYPES_H */
|
||||
|
||||
94
Living_SDK/platform/arch/arm/armv5/common/panic_armcc.S
Normal file
94
Living_SDK/platform/arch/arm/armv5/common/panic_armcc.S
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include "k_config.h"
|
||||
#include "k_dftdbg_config.h"
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN panicHandler
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
EXPORT _exc_udf_handler
|
||||
EXPORT _exc_pabt_handler
|
||||
EXPORT _exc_dabt_handler
|
||||
|
||||
;******************************************************************************
|
||||
; FAULT FUNCTIONS
|
||||
;******************************************************************************
|
||||
_exc_udf_handler
|
||||
PUSH {R0-R3}
|
||||
MOV R2, #1 ; Exception type
|
||||
MRS R1, SPSR ; CPSR before exception
|
||||
SUB R0, LR, #2
|
||||
TST R1, #0x20 ; CPSR[5], 1 Thumb, 0 ARM
|
||||
SUBEQ R0, R0, #2 ; PC before exception
|
||||
PUSH {R4}
|
||||
MOV R3, SP ; SP_udf
|
||||
ADD SP, SP, #20
|
||||
B _exc_handler
|
||||
|
||||
_exc_pabt_handler
|
||||
PUSH {R0-R3}
|
||||
MOV R2, #2 ; Exception type
|
||||
MRS R1, SPSR ; CPSR before exception
|
||||
SUB R0, LR, #4 ; PC before exception
|
||||
PUSH {R4}
|
||||
MOV R3, SP ; SP_abt
|
||||
ADD SP, SP, #20
|
||||
B _exc_handler
|
||||
|
||||
_exc_dabt_handler
|
||||
PUSH {R0-R3}
|
||||
MOV R2, #3 ; Exception type
|
||||
MRS R1, SPSR ; CPSR before exception
|
||||
SUB R0, LR, #8 ; PC before exception
|
||||
PUSH {R4}
|
||||
MOV R3, SP ; SP_abt
|
||||
ADD SP, SP, #20
|
||||
B _exc_handler
|
||||
|
||||
;input R0 PC; R1 CPSR; R2, exctype; R3 where saved context R0~R3; R4 temp
|
||||
_exc_handler
|
||||
AND R4, R1, #0x1F
|
||||
ORR R4, R4, #0xC0
|
||||
MSR CPSR_c, R4
|
||||
LDMFD R3!, {R4}
|
||||
STMFD R3!, {R0-R2} ; save "PANIC_CONTEXT" on exception stack
|
||||
MOV R0, SP
|
||||
STMFD R3!, {R0, LR}
|
||||
STMFD R3!, {R4-R12}
|
||||
ADD R0, R3, #56
|
||||
LDMFD R0, {R5-R8}
|
||||
STMFD R3!, {R5-R8}
|
||||
|
||||
LDR R0, =g_crash_steps
|
||||
LDR R1, [R0]
|
||||
ADD R1, #1
|
||||
STR R1, [R0]
|
||||
|
||||
MOV R4, SP
|
||||
MOV SP, R3
|
||||
MOV R0, R3
|
||||
CMP R1, #1
|
||||
MOVNE R0, #0
|
||||
BL panicHandler
|
||||
|
||||
ALIGN
|
||||
#endif
|
||||
|
||||
END
|
||||
|
||||
542
Living_SDK/platform/arch/arm/armv5/common/panic_c.c
Normal file
542
Living_SDK/platform/arch/arm/armv5/common/panic_c.c
Normal file
|
|
@ -0,0 +1,542 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "k_dbg_api.h"
|
||||
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#ifdef __BIG_ENDIAN
|
||||
#error "Not support big-endian!"
|
||||
#endif
|
||||
#elif defined(__ICCARM__)
|
||||
#if (__LITTLE_ENDIAN__ == 0)
|
||||
#error "Not support big-endian!"
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
#error "Not support big-endian!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FUNC_SIZE_LIMIT 0x2000
|
||||
#define BACK_TRACE_LIMIT 64
|
||||
#define LR_2_ADDR(lr) ((char *)(((int)(lr)) & 0xfffffffe))
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
static unsigned int __builtin_popcount(unsigned int u)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
while (u) {
|
||||
u = (u & (u - 1));
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void getPLSfromCtx(void *context, char **PC, char **LR, int **SP)
|
||||
{
|
||||
int *ptr = context;
|
||||
/* reference to cpu_task_stack_init */
|
||||
*PC = LR_2_ADDR((char *)ptr[15]);
|
||||
*LR = LR_2_ADDR((char *)ptr[14]);
|
||||
*SP = ptr + 16;
|
||||
}
|
||||
|
||||
/* get "blx" or "bl" before LR, return offset */
|
||||
static int backtraceFindLROffset(char *LR,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
char *PC;
|
||||
unsigned short ins16;
|
||||
char s_panic_call[] = "backtrace : 0x \r\n";
|
||||
|
||||
/* compiler specific */
|
||||
#if defined(__CC_ARM)
|
||||
PC = (char *)__current_pc();
|
||||
#elif defined(__ICCARM__)
|
||||
asm volatile("mov %0, pc\n" : "=r"(PC));
|
||||
#elif defined(__GNUC__)
|
||||
__asm__ volatile("mov %0, pc\n" : "=r"(PC));
|
||||
#endif
|
||||
|
||||
/* backtrace bottom check for interrupt */
|
||||
if (LR != NULL && ((int)LR & 1) == 0 &&
|
||||
((int)LR & 0x400000) == ((int)PC & 0x400000)) {
|
||||
if (print_func != NULL) {
|
||||
print_func("backtrace : ^interrupt^\r\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LR = LR_2_ADDR(LR);
|
||||
|
||||
if (LR == LR_2_ADDR(&krhino_task_deathbed)) {
|
||||
/* task delete, so here is callstack bottom of task */
|
||||
if (print_func != NULL) {
|
||||
print_func("backtrace : ^task entry^\r\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ins16 = *(unsigned short *)(LR - 4);
|
||||
if ((ins16 & 0xf000) == 0xf000) {
|
||||
if (print_func != NULL) {
|
||||
k_int2str((int)LR - 4, &s_panic_call[14]);
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
return 5;
|
||||
} else {
|
||||
if (print_func != NULL) {
|
||||
k_int2str((int)LR - 2, &s_panic_call[14]);
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* find current function caller, update PC and SP
|
||||
returns: 0 success
|
||||
1 success and find buttom
|
||||
-1 fail */
|
||||
int backtraceFromStack(int **pSP, char **pPC,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
char *CodeAddr = NULL;
|
||||
int *SP = *pSP;
|
||||
char *PC = *pPC;
|
||||
char *LR;
|
||||
int i;
|
||||
unsigned short ins16;
|
||||
unsigned int ins32;
|
||||
unsigned int framesize = 0;
|
||||
unsigned int shift = 0;
|
||||
unsigned int sub = 0;
|
||||
unsigned int offset = 1;
|
||||
|
||||
if (SP == krhino_task_stack_bottom(NULL)) {
|
||||
if (print_func != NULL) {
|
||||
print_func("backtrace : ^task entry^\r\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* func call ways:
|
||||
1. "stmdb sp!, ..." or "push ..." to open stack frame and save LR
|
||||
2. "sub sp, ..." or "sub.w sp, ..." to open stack more
|
||||
3. call
|
||||
*/
|
||||
|
||||
/* 1. scan code, find frame size from "push" or "stmdb sp!" */
|
||||
for (i = 2; i < FUNC_SIZE_LIMIT; i += 2) {
|
||||
/* find nearest "push {..., lr}" */
|
||||
ins16 = *(unsigned short *)(PC - i);
|
||||
if ((ins16 & 0xff00) == 0xb500) {
|
||||
framesize = __builtin_popcount((unsigned char)ins16);
|
||||
framesize++;
|
||||
/* find double push */
|
||||
ins16 = *(unsigned short *)(PC - i - 2);
|
||||
if ((ins16 & 0xff00) == 0xb400) {
|
||||
offset += __builtin_popcount((unsigned char)ins16);
|
||||
framesize += __builtin_popcount((unsigned char)ins16);
|
||||
}
|
||||
CodeAddr = PC - i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* find "stmdb sp!, ..." */
|
||||
/* The Thumb instruction stream is a sequence of halfword-aligned
|
||||
* halfwords */
|
||||
ins32 = *(unsigned short *)(PC - i);
|
||||
ins32 <<= 16;
|
||||
ins32 |= *(unsigned short *)(PC - i + 2);
|
||||
if ((ins32 & 0xFFFFF000) == 0xe92d4000) {
|
||||
framesize = __builtin_popcount(ins32 & 0xfff);
|
||||
framesize++;
|
||||
CodeAddr = PC - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CodeAddr == NULL) {
|
||||
/* error branch */
|
||||
if (print_func != NULL) {
|
||||
print_func("Backtrace fail!\r\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 2. scan code, find frame size from "sub" or "sub.w" */
|
||||
for (i = 0; i < FUNC_SIZE_LIMIT;) {
|
||||
if (CodeAddr + i > PC) {
|
||||
break;
|
||||
}
|
||||
/* find "sub sp, ..." */
|
||||
ins16 = *(unsigned short *)(CodeAddr + i);
|
||||
if ((ins16 & 0xff80) == 0xb080) {
|
||||
framesize += (ins16 & 0x7f);
|
||||
break;
|
||||
}
|
||||
|
||||
/* find "sub.w sp, sp, ..." */
|
||||
ins32 = *(unsigned short *)(CodeAddr + i);
|
||||
ins32 <<= 16;
|
||||
ins32 |= *(unsigned short *)(CodeAddr + i + 2);
|
||||
if ((ins32 & 0xFBFF8F00) == 0xF1AD0D00) {
|
||||
sub = 128 + (ins32 & 0x7f);
|
||||
shift = (ins32 >> 7) & 0x1;
|
||||
shift += ((ins32 >> 12) & 0x7) << 1;
|
||||
shift += ((ins32 >> 26) & 0x1) << 4;
|
||||
framesize += sub<<(30 - shift);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ins16 & 0xf800) >= 0xe800) {
|
||||
i += 4;
|
||||
} else {
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3. output */
|
||||
*pSP = SP + framesize;
|
||||
LR = (char *)*(SP + framesize - offset);
|
||||
offset = backtraceFindLROffset(LR, print_func);
|
||||
*pPC = LR - offset;
|
||||
|
||||
return offset == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/* find current function caller, update PC and SP
|
||||
returns: 0 success
|
||||
1 success and find buttom
|
||||
-1 fail */
|
||||
int backtraceFromLR(int **pSP, char **pPC, char *LR,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int *SP = *pSP;
|
||||
char *PC = *pPC;
|
||||
char *CodeAddr = NULL;
|
||||
int i;
|
||||
unsigned short ins16;
|
||||
unsigned int framesize = 0;
|
||||
unsigned int offset;
|
||||
|
||||
if (PC == NULL) {
|
||||
offset = backtraceFindLROffset(LR, print_func);
|
||||
PC = LR - offset;
|
||||
*pPC = PC;
|
||||
return offset == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/*find stack framesize:
|
||||
1. "push ..." to open stack
|
||||
2. "sub sp, ..." to open stack
|
||||
3. 1 + 2
|
||||
4. do not open stack
|
||||
*/
|
||||
|
||||
/* 1. scan code, find frame size from "push" or "sub" */
|
||||
for (i = 2; i < FUNC_SIZE_LIMIT; i += 2) {
|
||||
ins16 = *(unsigned short *)(PC - i);
|
||||
/* find "push {..., lr}" */
|
||||
if ((ins16 & 0xff00) == 0xb500) {
|
||||
/* another function */
|
||||
break;
|
||||
}
|
||||
/* find "push {...}" */
|
||||
if ((ins16 & 0xff00) == 0xb400) {
|
||||
framesize = __builtin_popcount((unsigned char)ins16);
|
||||
CodeAddr = PC - i;
|
||||
break;
|
||||
}
|
||||
/* find "sub sp, ..." */
|
||||
if ((ins16 & 0xff80) == 0xb080) {
|
||||
framesize = (ins16 & 0x7f);
|
||||
CodeAddr = PC - i;
|
||||
/* find push before sub */
|
||||
ins16 = *(unsigned short *)(PC - i - 2);
|
||||
if ((ins16 & 0xff00) == 0xb400) {
|
||||
framesize += __builtin_popcount((unsigned char)ins16);
|
||||
CodeAddr = PC - i - 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. check the "push" or "sub sp" belongs to another function */
|
||||
if (CodeAddr != NULL) {
|
||||
for (i = 2; i < PC - CodeAddr; i += 2) {
|
||||
ins16 = *(unsigned short *)(PC - i);
|
||||
/* find "pop {..., pc}" or "bx lr" */
|
||||
if ((ins16 & 0xff00) == 0xbd00 || ins16 == 0x4770) {
|
||||
/* SP no changed */
|
||||
framesize = 0;
|
||||
}
|
||||
}
|
||||
} /* else: SP no changed */
|
||||
|
||||
/* 3. output */
|
||||
*pSP = SP + framesize;
|
||||
offset = backtraceFindLROffset(LR, print_func);
|
||||
*pPC = LR - offset;
|
||||
|
||||
return offset == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/* printf call stack */
|
||||
int backtrace_now(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
char *PC;
|
||||
int *SP;
|
||||
int lvl;
|
||||
int ret;
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
/* compiler specific */
|
||||
#if defined(__CC_ARM)
|
||||
SP = (int *)__current_sp();
|
||||
PC = (char *)__current_pc();
|
||||
#elif defined(__ICCARM__)
|
||||
asm volatile("mov %0, sp\n" : "=r"(SP));
|
||||
asm volatile("mov %0, pc\n" : "=r"(PC));
|
||||
#elif defined(__GNUC__)
|
||||
__asm__ volatile("mov %0, sp\n" : "=r"(SP));
|
||||
__asm__ volatile("mov %0, pc\n" : "=r"(PC));
|
||||
#endif
|
||||
|
||||
print_func("========== Call stack ==========\r\n");
|
||||
for (lvl = 0; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&SP, &PC, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_func("========== End ==========\r\n");
|
||||
return lvl;
|
||||
}
|
||||
|
||||
int backtrace_task(char *taskname, int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
char *PC;
|
||||
char *LR;
|
||||
int *SP;
|
||||
int lvl;
|
||||
int ret;
|
||||
ktask_t *task;
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
task = krhino_task_find(taskname);
|
||||
if (task == NULL) {
|
||||
print_func("Task not found : %s\n", taskname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (krhino_task_is_running(task)) {
|
||||
print_func("Status of task \"%s\" is 'Running', Can not backtrace!\n",
|
||||
taskname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
getPLSfromCtx(task->task_stack, &PC, &LR, &SP);
|
||||
|
||||
print_func("TaskName : %s\n", taskname);
|
||||
print_func("========== Call stack ==========\r\n");
|
||||
for (lvl = 0; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&SP, &PC, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_func("========== End ==========\r\n");
|
||||
return lvl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
#define REG_NAME_WIDTH 7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* saved in assembler */
|
||||
int R0;
|
||||
int R1;
|
||||
int R2;
|
||||
int R3;
|
||||
int R4;
|
||||
int R5;
|
||||
int R6;
|
||||
int R7;
|
||||
int R8;
|
||||
int R9;
|
||||
int R10;
|
||||
int R11;
|
||||
int R12;
|
||||
int SP; // Stack Pointer
|
||||
int LR; // Link Register
|
||||
int PC; // Program Counter
|
||||
int CPSR; // Current Program Status Registers
|
||||
int EXCTYPE; // 1-undefined; 2-prefetch; 3-data
|
||||
} PANIC_CONTEXT;
|
||||
|
||||
void panicGetCtx(void *context, char **pPC, char **pLR, int **pSP)
|
||||
{
|
||||
PANIC_CONTEXT *arm_context = (PANIC_CONTEXT *)context;
|
||||
|
||||
*pSP = (int *)arm_context->SP;
|
||||
*pPC = (char *)arm_context->PC;
|
||||
*pLR = (char *)arm_context->LR;
|
||||
}
|
||||
|
||||
void panicShowRegs(void *context, int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int x;
|
||||
int *regs = (int *)context;
|
||||
char s_panic_regs[REG_NAME_WIDTH + 14];
|
||||
/* PANIC_CONTEXT */
|
||||
char s_panic_ctx[] = "R0 "
|
||||
"R1 "
|
||||
"R2 "
|
||||
"R3 "
|
||||
"R4 "
|
||||
"R5 "
|
||||
"R6 "
|
||||
"R7 "
|
||||
"R8 "
|
||||
"R9 "
|
||||
"R10 "
|
||||
"R11 "
|
||||
"R12 "
|
||||
"SP "
|
||||
"LR "
|
||||
"PC "
|
||||
"CPSR "
|
||||
"EXCTYPE";
|
||||
|
||||
if (regs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
print_func("========== Regs info ==========\r\n");
|
||||
|
||||
/* show PANIC_CONTEXT */
|
||||
for (x = 0; x < sizeof(s_panic_ctx) / REG_NAME_WIDTH - 1; x++) {
|
||||
memcpy(&s_panic_regs[0], &s_panic_ctx[x * REG_NAME_WIDTH],
|
||||
REG_NAME_WIDTH);
|
||||
memcpy(&s_panic_regs[REG_NAME_WIDTH], " 0x", 3);
|
||||
k_int2str(regs[x], &s_panic_regs[REG_NAME_WIDTH + 3]);
|
||||
s_panic_regs[REG_NAME_WIDTH + 11] = '\r';
|
||||
s_panic_regs[REG_NAME_WIDTH + 12] = '\n';
|
||||
s_panic_regs[REG_NAME_WIDTH + 13] = 0;
|
||||
print_func(s_panic_regs);
|
||||
}
|
||||
switch (regs[x]) {
|
||||
case 1:
|
||||
print_func("ExcCasue: Undefined instruction\r\n");
|
||||
break;
|
||||
case 2:
|
||||
print_func("ExcCasue: Prefetch Abort\r\n");
|
||||
break;
|
||||
case 3:
|
||||
print_func("ExcCasue: Data Abort\r\n");
|
||||
break;
|
||||
default:
|
||||
print_func("ExcCasue: Unknown\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
/* backtrace start with PC and SP, find LR from stack memory
|
||||
return levels os callstack */
|
||||
int panicBacktraceCaller(char *PC, int *SP,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int *bt_sp;
|
||||
char *bt_pc;
|
||||
int lvl, ret;
|
||||
char s_panic_call[] = "backtrace : 0x \r\n";
|
||||
|
||||
/* caller must save LR in stack, so find LR from stack */
|
||||
|
||||
if (SP == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bt_sp = SP;
|
||||
bt_pc = LR_2_ADDR(PC);
|
||||
ret = -1;
|
||||
for (lvl = 0; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&bt_sp, &bt_pc, NULL);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret == 1) {
|
||||
/* assume right! print */
|
||||
k_int2str((int)PC, &s_panic_call[14]);
|
||||
if (print_func != NULL) {
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
bt_sp = SP;
|
||||
bt_pc = PC;
|
||||
ret = -1;
|
||||
for (lvl = 1; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&bt_sp, &bt_pc, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return lvl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* backtrace start with PC SP and LR */
|
||||
int panicBacktraceCallee(char *PC, int *SP, char *LR,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int *bt_sp;
|
||||
char *bt_pc;
|
||||
char *bt_lr;
|
||||
int lvl, ret;
|
||||
char s_panic_call[] = "backtrace : 0x \r\n";
|
||||
|
||||
if (SP == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backtrace: assume ReturnAddr is saved in LR when exception */
|
||||
k_int2str((int)PC, &s_panic_call[14]);
|
||||
if (print_func != NULL) {
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
lvl = 1;
|
||||
bt_sp = SP;
|
||||
bt_pc = PC;
|
||||
bt_lr = LR;
|
||||
ret = backtraceFromLR(&bt_sp, &bt_pc, bt_lr, print_func);
|
||||
if (ret == 0) {
|
||||
for (; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&bt_sp, &bt_pc, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lvl;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
99
Living_SDK/platform/arch/arm/armv5/common/panic_gcc.S
Normal file
99
Living_SDK/platform/arch/arm/armv5/common/panic_gcc.S
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#include "k_config.h"
|
||||
#include "k_dftdbg_config.h"
|
||||
|
||||
@******************************************************************************
|
||||
@ EQUATES
|
||||
@******************************************************************************
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
.text
|
||||
.align 2
|
||||
.syntax unified
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
|
||||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
.extern panicHandler
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
.global __wrap_boot_undefined
|
||||
.global __wrap_boot_pabort
|
||||
.global __wrap_boot_dabort
|
||||
|
||||
@******************************************************************************
|
||||
@ FAULT FUNCTIONS
|
||||
@******************************************************************************
|
||||
__wrap_boot_undefined:
|
||||
PUSH {R0-R3}
|
||||
MOV R2, #1 @ Exception type
|
||||
MRS R1, SPSR @ CPSR before exception
|
||||
SUB R0, LR, #2
|
||||
TST R1, #0x20 @ CPSR[5], 1 Thumb, 0 ARM
|
||||
SUBEQ R0, R0, #2 @ PC before exception
|
||||
PUSH {R4}
|
||||
MOV R3, SP @ SP_udf
|
||||
ADD SP, SP, #20
|
||||
B _exc_handler
|
||||
|
||||
__wrap_boot_pabort:
|
||||
PUSH {R0-R3}
|
||||
MOV R2, #2 @ Exception type
|
||||
MRS R1, SPSR @ CPSR before exception
|
||||
SUB R0, LR, #4 @ PC before exception
|
||||
PUSH {R4}
|
||||
MOV R3, SP @ SP_abt
|
||||
ADD SP, SP, #20
|
||||
B _exc_handler
|
||||
|
||||
__wrap_boot_dabort:
|
||||
PUSH {R0-R3}
|
||||
MOV R2, #3 @ Exception type
|
||||
MRS R1, SPSR @ CPSR before exception
|
||||
SUB R0, LR, #8 @ PC before exception
|
||||
PUSH {R4}
|
||||
MOV R3, SP @ SP_abt
|
||||
ADD SP, SP, #20
|
||||
B _exc_handler
|
||||
|
||||
@input: R0 PC; R1 CPSR; R2, exctype; R3 where saved context R0~R3; R4 temp
|
||||
_exc_handler:
|
||||
AND R4, R1, #0x1F
|
||||
ORR R4, R4, #0xC0
|
||||
MSR CPSR_c, R4
|
||||
LDMFD R3!, {R4}
|
||||
STMFD R3!, {R0-R2} @ save "PANIC_CONTEXT" on exception stack
|
||||
MOV R0, SP
|
||||
STMFD R3!, {R0, LR}
|
||||
STMFD R3!, {R4-R12}
|
||||
ADD R0, R3, #56
|
||||
LDMFD R0, {R5-R8}
|
||||
STMFD R3!, {R5-R8}
|
||||
|
||||
LDR R0, =g_crash_steps
|
||||
LDR R1, [R0]
|
||||
ADD R1, #1
|
||||
STR R1, [R0]
|
||||
|
||||
MOV R4, SP
|
||||
MOV SP, R3
|
||||
MOV R0, R3
|
||||
CMP R1, #1
|
||||
MOVNE R0, #0
|
||||
#if (RHINO_CONFIG_PANIC_PRT_INT > 0)
|
||||
@printf use interrupt, so here enable it
|
||||
MRS R1, CPSR @ Set IRQ and FIQ bits in CPSR to disable all interrupts
|
||||
ORR R1, R1, #0xC0
|
||||
MSR CPSR_c, R1
|
||||
#endif
|
||||
BL panicHandler
|
||||
|
||||
#endif
|
||||
|
||||
.end
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv5/common/port.h
Normal file
25
Living_SDK/platform/arch/arm/armv5/common/port.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
cpu_cpsr_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(cpu_cpsr_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() cpu_cpsr_t cpsr
|
||||
#define RHINO_CPU_INTRPT_DISABLE() do{cpsr = cpu_intrpt_save();}while(0)
|
||||
#define RHINO_CPU_INTRPT_ENABLE() do{cpu_intrpt_restore(cpsr);}while(0)
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv5/gcc/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv5/gcc/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv5/gcc/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv5/gcc/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
185
Living_SDK/platform/arch/arm/armv5/gcc/port_c.c
Normal file
185
Living_SDK/platform/arch/arm/armv5/gcc/port_c.c
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(base + size);
|
||||
|
||||
/*stack need 8 bytes align*/
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
*(--stk) = (uint32_t)entry; /* Entry Point */
|
||||
*(--stk) = (uint32_t)krhino_task_deathbed; /* LR */
|
||||
*(--stk) = (uint32_t)0; /* R12 */
|
||||
*(--stk) = (uint32_t)0; /* R11 */
|
||||
*(--stk) = (uint32_t)0; /* R10 */
|
||||
*(--stk) = (uint32_t)0; /* R9 */
|
||||
*(--stk) = (uint32_t)0; /* R8 */
|
||||
*(--stk) = (uint32_t)0; /* R7 : */
|
||||
*(--stk) = (uint32_t)0; /* R6 */
|
||||
*(--stk) = (uint32_t)0; /* R5 */
|
||||
*(--stk) = (uint32_t)0; /* R4 */
|
||||
*(--stk) = (uint32_t)0; /* R3 */
|
||||
*(--stk) = (uint32_t)0; /* R2 */
|
||||
*(--stk) = (uint32_t)0; /* R1 */
|
||||
*(--stk) = (uint32_t)arg; /* R0 argument */
|
||||
*(--stk) = (uint32_t)0x13; /* CPSR SVC mode */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
void fiq_pre_proc(void)
|
||||
{
|
||||
g_intrpt_nested_level[cpu_cur_get()]++;
|
||||
}
|
||||
|
||||
void fiq_end_proc(void)
|
||||
{
|
||||
g_intrpt_nested_level[cpu_cur_get()]--;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_irq_enable( void )
|
||||
{
|
||||
#define ARM968_IF_MASK 0xC0
|
||||
#define ARM968_IRQ_ENABLE 0x80
|
||||
|
||||
uint32_t interrupt;
|
||||
|
||||
__asm volatile(
|
||||
"MRS %0,CPSR\n"
|
||||
"AND %0,%0,#0xC0\n"
|
||||
: "=r" (interrupt)
|
||||
:
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return (!(interrupt & ARM968_IRQ_ENABLE));
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_fiq_enable( void )
|
||||
{
|
||||
#define ARM968_IF_MASK 0xC0
|
||||
#define ARM968_FIQ_ENABLE 0x40
|
||||
|
||||
uint32_t interrupt;
|
||||
|
||||
__asm volatile(
|
||||
"MRS %0,CPSR\n"
|
||||
"AND %0,%0,#0xC0\n"
|
||||
: "=r" (interrupt)
|
||||
:
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return (!(interrupt & ARM968_FIQ_ENABLE));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_irq_context( void )
|
||||
{
|
||||
#define ARM968_IRQ_MODE 0x12
|
||||
|
||||
uint32_t mode;
|
||||
|
||||
__asm volatile(
|
||||
"MRS %0,CPSR\n"
|
||||
"AND %0,%0,#0x1f\n"
|
||||
: "=r" (mode)
|
||||
:
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return (ARM968_IRQ_MODE == mode);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t platform_is_in_fiq_context( void )
|
||||
{
|
||||
#define ARM968_FIQ_MODE 0x11
|
||||
|
||||
uint32_t mode;
|
||||
|
||||
__asm volatile(
|
||||
"MRS %0,CPSR\n"
|
||||
"AND %0,%0,#0x1f\n"
|
||||
: "=r" (mode)
|
||||
:
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return (ARM968_FIQ_MODE == mode);
|
||||
}
|
||||
|
||||
|
||||
uint32_t platform_is_in_interrupt_context( void )
|
||||
{
|
||||
return ((platform_is_in_fiq_context())
|
||||
|| (platform_is_in_irq_context()));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
int portDISABLE_FIQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
unsigned long mask;
|
||||
|
||||
__asm volatile(
|
||||
"mrs %1, cpsr @ local_irq_disable\n"
|
||||
"orr %0, %1, #0x40\n"
|
||||
"msr cpsr_c, %0"
|
||||
: "=r" (temp), "=r" (mask)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return (!!(mask & 0x40));
|
||||
}
|
||||
|
||||
int portDISABLE_IRQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
unsigned long mask;
|
||||
|
||||
__asm volatile(
|
||||
"mrs %1, cpsr @ local_irq_disable\n"
|
||||
"orr %0, %1, #0x80\n"
|
||||
"msr cpsr_c, %0"
|
||||
: "=r" (temp), "=r" (mask)
|
||||
:
|
||||
: "memory");
|
||||
|
||||
return (!!(mask & 0x80));
|
||||
}
|
||||
|
||||
void portENABLE_IRQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm volatile(
|
||||
"mrs %0, cpsr @ local_irq_enable\n"
|
||||
"bic %0, %0, #0x80\n"
|
||||
"msr cpsr_c, %0"
|
||||
: "=r" (temp)
|
||||
:
|
||||
: "memory");
|
||||
}
|
||||
|
||||
void portENABLE_FIQ(void)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm volatile(
|
||||
"mrs %0, cpsr @ local_irq_enable\n"
|
||||
"bic %0, %0, #0x40\n"
|
||||
"msr cpsr_c, %0"
|
||||
: "=r" (temp)
|
||||
:
|
||||
: "memory");
|
||||
}
|
||||
|
||||
94
Living_SDK/platform/arch/arm/armv5/gcc/port_s.S
Normal file
94
Living_SDK/platform/arch/arm/armv5/gcc/port_s.S
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include <k_config.h>
|
||||
|
||||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.extern krhino_stack_ovf_check
|
||||
.extern krhino_task_sched_stats_get
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
.text
|
||||
.align 2
|
||||
|
||||
.type cpu_intrpt_save, %function
|
||||
cpu_intrpt_save:
|
||||
MRS R0, CPSR @ Set IRQ and FIQ bits in CPSR to disable all interrupts
|
||||
ORR R1, R0, #0xC0
|
||||
MSR CPSR_c, R1
|
||||
MRS R1, CPSR @ Confirm that CPSR contains the proper interrupt disable flags
|
||||
AND R1, R1, #0xC0
|
||||
CMP R1, #0xC0
|
||||
BNE cpu_intrpt_save @ Not properly disabled (try again)
|
||||
BX LR @ Disabled, return the original CPSR contents in R0
|
||||
|
||||
.type cpu_intrpt_restore, %function
|
||||
cpu_intrpt_restore:
|
||||
MSR CPSR_c, R0
|
||||
BX LR
|
||||
|
||||
.type cpu_first_task_start, %function
|
||||
cpu_first_task_start:
|
||||
LDR R0, =g_active_task
|
||||
LDR R0, [R0]
|
||||
LDR SP, [R0]
|
||||
|
||||
LDMFD SP!, {R0}
|
||||
LDR R1, [SP, #56]
|
||||
TST R1, #1
|
||||
ORRNE R0, #32 @ if PC is thumb mode, set SPSR to thumb
|
||||
MSR SPSR_cxsf, R0
|
||||
LDMFD SP!, {R0-R12, LR, PC}^
|
||||
|
||||
.type cpu_task_switch, %function
|
||||
cpu_task_switch:
|
||||
STMFD SP!, {LR}
|
||||
STMFD SP!, {R0-R12,LR}
|
||||
MRS R0, CPSR
|
||||
STMFD SP!, {R0} @ push current cpsr
|
||||
|
||||
@ g_active_task->task_stack = SP
|
||||
LDR R0, =g_active_task
|
||||
LDR R0, [R0]
|
||||
STR SP, [R0]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
.type cpu_intrpt_switch, %function
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =g_preferred_ready_task
|
||||
LDR R1, =g_active_task
|
||||
LDR R0, [R0]
|
||||
STR R0, [R1]
|
||||
|
||||
LDR R0, =g_active_task
|
||||
LDR R0, [R0]
|
||||
LDR SP, [R0]
|
||||
|
||||
@ Restore New Task context
|
||||
LDMFD SP!, {R0}
|
||||
LDR R1, [SP, #56]
|
||||
TST R1, #1
|
||||
ORRNE R0, #32 @ if PC is thumb mode, set SPSR to thumb
|
||||
MSR SPSR_cxsf, R0
|
||||
LDMFD SP!, {R0-R12, LR, PC}^
|
||||
|
||||
.end
|
||||
|
||||
16
Living_SDK/platform/arch/arm/armv5/ucube.py
Normal file
16
Living_SDK/platform/arch/arm/armv5/ucube.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
src = Split('''
|
||||
gcc/port_c.c
|
||||
gcc/port_s.S
|
||||
common/panic_c.c
|
||||
common/panic_gcc.S
|
||||
''')
|
||||
|
||||
component = aos_component('armv5', src)
|
||||
component.add_global_includes('common')
|
||||
|
||||
local_cflags = Split('''
|
||||
-marm
|
||||
-mthumb-interwork
|
||||
''')
|
||||
for cflags in local_cflags:
|
||||
component.add_cflags(cflags)
|
||||
25
Living_SDK/platform/arch/arm/armv6m/armcc/m0/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv6m/armcc/m0/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv6m/armcc/m0/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv6m/armcc/m0/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
39
Living_SDK/platform/arch/arm/armv6m/armcc/m0/port_c.c
Normal file
39
Living_SDK/platform/arch/arm/armv6m/armcc/m0/port_c.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* task context saved & restore by hardware: */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* task context saved & restore by software: */
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
165
Living_SDK/platform/arch/arm/armv6m/armcc/m0/port_s.S
Normal file
165
Living_SDK/platform/arch/arm/armv6m/armcc/m0/port_s.S
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
|
||||
IMPORT g_active_task
|
||||
IMPORT g_preferred_ready_task
|
||||
IMPORT krhino_stack_ovf_check
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
|
||||
EXPORT cpu_intrpt_save
|
||||
EXPORT cpu_intrpt_restore
|
||||
EXPORT cpu_task_switch
|
||||
EXPORT cpu_intrpt_switch
|
||||
EXPORT cpu_first_task_start
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14_15 EQU 0xE000ED20 ; System Handler Priority Register 3 (PendSV + SysTick).
|
||||
SHPR3_PRI_LVL EQU 0xC0C00000 ; PendSV + SysTick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14_15
|
||||
LDR R2, [R0]
|
||||
LDR R1, =SHPR3_PRI_LVL
|
||||
ORRS R2, R1
|
||||
STR R2, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;align MSP to 8 byte
|
||||
MRS R0, MSP
|
||||
LSRS R0, R0, #3
|
||||
LSLS R0, R0, #3
|
||||
MSR MSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
CMP R0, #0
|
||||
;branch if cpu_first_task_start
|
||||
BEQ _pendsv_handler_nosave
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
SUBS R0, R0, #0x20
|
||||
STMIA R0!, {R4 - R7}
|
||||
MOV R4, R8
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4 - R7}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
SUBS R0, R0, #0x20
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
;save and restore LR
|
||||
MOV R4, LR
|
||||
bl krhino_stack_ovf_check
|
||||
MOV LR, R4
|
||||
|
||||
_pendsv_handler_nosave
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDMIA R0!, {R4 - R7}
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R8, R2
|
||||
MOV R9, R3
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R10, R2
|
||||
MOV R11, R3
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
;after exception return: stack = PSP
|
||||
MOV R0, LR
|
||||
MOVS R1, #0x04
|
||||
ORRS R0, R1
|
||||
MOV LR, R0
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
END
|
||||
|
||||
15
Living_SDK/platform/arch/arm/armv6m/armv6m.mk
Normal file
15
Living_SDK/platform/arch/arm/armv6m/armv6m.mk
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
NAME := armv6m
|
||||
|
||||
ifeq ($(COMPILER),armcc)
|
||||
$(NAME)_SOURCES := armcc/m0/port_c.c
|
||||
$(NAME)_SOURCES += armcc/m0/port_s.S
|
||||
GLOBAL_INCLUDES += armcc/m0/
|
||||
else ifeq ($(COMPILER),iar)
|
||||
$(NAME)_SOURCES := iccarm/m0/port_c.c
|
||||
$(NAME)_SOURCES += iccarm/m0/port_s.S
|
||||
GLOBAL_INCLUDES += iccarm/m0/
|
||||
else
|
||||
$(NAME)_SOURCES := gcc/m0/port_c.c
|
||||
$(NAME)_SOURCES += gcc/m0/port_s.S
|
||||
GLOBAL_INCLUDES += gcc/m0/
|
||||
endif
|
||||
25
Living_SDK/platform/arch/arm/armv6m/gcc/m0/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv6m/gcc/m0/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv6m/gcc/m0/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv6m/gcc/m0/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
39
Living_SDK/platform/arch/arm/armv6m/gcc/m0/port_c.c
Normal file
39
Living_SDK/platform/arch/arm/armv6m/gcc/m0/port_c.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* task context saved & restore by hardware: */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* task context saved & restore by software: */
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
171
Living_SDK/platform/arch/arm/armv6m/gcc/m0/port_s.S
Normal file
171
Living_SDK/platform/arch/arm/armv6m/gcc/m0/port_s.S
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.extern krhino_stack_ovf_check
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
|
||||
.global PendSV_Handler
|
||||
|
||||
@******************************************************************************
|
||||
@ EQUATES
|
||||
@******************************************************************************
|
||||
|
||||
.equ SCB_ICSR, 0xE000ED04 @ Interrupt Control and State Register.
|
||||
.equ ICSR_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
.equ SHPR3_PRI_14_15, 0xE000ED20 @ System Handler Priority Register 3 (PendSV + SysTick).
|
||||
.equ SHPR3_PRI_LVL, 0xC0C00000 @ PendSV + SysTick priority level (lowest).
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ size_t cpu_intrpt_save(void);
|
||||
@ void cpu_intrpt_restore(size_t cpsr);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_intrpt_switch(void);
|
||||
@ void cpu_task_switch(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_first_task_start(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_first_task_start:
|
||||
@set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14_15
|
||||
LDR R2, [R0]
|
||||
LDR R1, =SHPR3_PRI_LVL
|
||||
ORRS R2, R1
|
||||
STR R2, [R0]
|
||||
|
||||
@indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
@align MSP to 8 byte
|
||||
MRS R0, MSP
|
||||
LSRS R0, R0, #3
|
||||
LSLS R0, R0, #3
|
||||
MSR MSP, R0
|
||||
|
||||
@make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
@goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void krhino_pendsv_handler(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
CMP R0, #0
|
||||
@branch if cpu_first_task_start
|
||||
BEQ _pendsv_handler_nosave
|
||||
|
||||
@hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
@save context
|
||||
SUBS R0, R0, #0x20
|
||||
STMIA R0!, {R4 - R7}
|
||||
MOV R4, R8
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4 - R7}
|
||||
|
||||
@g_active_task->task_stack = context region
|
||||
SUBS R0, R0, #0x20
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
@save and restore LR
|
||||
MOV R4, LR
|
||||
bl krhino_stack_ovf_check
|
||||
MOV LR, R4
|
||||
|
||||
.thumb_func
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
@R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
@restore context
|
||||
LDMIA R0!, {R4 - R7}
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R8, R2
|
||||
MOV R9, R3
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R10, R2
|
||||
MOV R11, R3
|
||||
|
||||
@return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
@after exception return: stack = PSP
|
||||
MOV R0, LR
|
||||
MOVS R1, #0x04
|
||||
ORRS R0, R1
|
||||
MOV LR, R0
|
||||
CPSIE I
|
||||
@hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
.end
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
39
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/port_c.c
Normal file
39
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/port_c.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* task context saved & restore by hardware: */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* task context saved & restore by software: */
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
165
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/port_s.S
Normal file
165
Living_SDK/platform/arch/arm/armv6m/iccarm/m0/port_s.S
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
|
||||
IMPORT g_active_task
|
||||
IMPORT g_preferred_ready_task
|
||||
IMPORT krhino_stack_ovf_check
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
|
||||
PUBLIC cpu_intrpt_save
|
||||
PUBLIC cpu_intrpt_restore
|
||||
PUBLIC cpu_task_switch
|
||||
PUBLIC cpu_intrpt_switch
|
||||
PUBLIC cpu_first_task_start
|
||||
|
||||
PUBLIC PendSV_Handler
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14_15 EQU 0xE000ED20 ; System Handler Priority Register 3 (PendSV + SysTick).
|
||||
SHPR3_PRI_LVL EQU 0xC0C00000 ; PendSV + SysTick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
SECTION .text:CODE(2)
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start:
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14_15
|
||||
LDR R2, [R0]
|
||||
LDR R1, =SHPR3_PRI_LVL
|
||||
ORRS R2, R1
|
||||
STR R2, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;align MSP to 8 byte
|
||||
MRS R0, MSP
|
||||
LSRS R0, R0, #3
|
||||
LSLS R0, R0, #3
|
||||
MSR MSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
CMP R0, #0
|
||||
;branch if cpu_first_task_start
|
||||
BEQ _pendsv_handler_nosave
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
SUBS R0, R0, #0x20
|
||||
STMIA R0!, {R4 - R7}
|
||||
MOV R4, R8
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4 - R7}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
SUBS R0, R0, #0x20
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
;save and restore LR
|
||||
MOV R4, LR
|
||||
bl krhino_stack_ovf_check
|
||||
MOV LR, R4
|
||||
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDMIA R0!, {R4 - R7}
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R8, R2
|
||||
MOV R9, R3
|
||||
LDMIA R0!, {R2 - R3}
|
||||
MOV R10, R2
|
||||
MOV R11, R3
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
;after exception return: stack = PSP
|
||||
MOV R0, LR
|
||||
MOVS R1, #0x04
|
||||
ORRS R0, R1
|
||||
MOV LR, R0
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
|
||||
END
|
||||
|
||||
10
Living_SDK/platform/arch/arm/armv7a/armv7a.mk
Normal file
10
Living_SDK/platform/arch/arm/armv7a/armv7a.mk
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
NAME := armv7a
|
||||
|
||||
ifeq ($(COMPILER),armcc)
|
||||
else ifeq ($(COMPILER),iar)
|
||||
else
|
||||
$(NAME)_SOURCES := gcc/a5/port_s.S
|
||||
$(NAME)_SOURCES += gcc/a5/port_c.c
|
||||
GLOBAL_INCLUDES += gcc/a5/
|
||||
|
||||
endif
|
||||
25
Living_SDK/platform/arch/arm/armv7a/gcc/a5/k_types.h
Executable file
25
Living_SDK/platform/arch/arm/armv7a/gcc/a5/k_types.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7a/gcc/a5/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7a/gcc/a5/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
74
Living_SDK/platform/arch/arm/armv7a/gcc/a5/port_c.c
Normal file
74
Living_SDK/platform/arch/arm/armv7a/gcc/a5/port_c.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
extern int fpu_reg_count(void);
|
||||
|
||||
|
||||
/* ARMCC || IAR || GNU */
|
||||
#define FPU_AVL ((defined(__CC_ARM) && defined(__TARGET_FPU_VFP)) \
|
||||
|| (defined(__ICCARM__) && defined(__ARMVFP__)) \
|
||||
|| (defined(__GNUC__) && defined(__VFP_FP__) && !defined(__SOFTFP__)))
|
||||
|
||||
#define ARM_MODE_ARM 0x00000000u
|
||||
#define ARM_MODE_THUMB 0x00000020u
|
||||
|
||||
#define ARM_SVC_MODE_THUMB (0x00000013u + ARM_MODE_THUMB)
|
||||
#define ARM_SVC_MODE_ARM (0x00000013u + ARM_MODE_ARM)
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
cpu_stack_t task_addr;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
task_addr = (cpu_stack_t)entry & ~1u; /* Mask off lower bit in case task is thumb mode */
|
||||
|
||||
*(--stk) = (cpu_stack_t)task_addr; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* Reg R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212u; /* Reg R12 */
|
||||
*(--stk) = (cpu_stack_t)0x11111111u; /* Reg R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010u; /* Reg R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909u; /* Reg R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808u; /* Reg R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707u; /* Reg R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606u; /* Reg R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505u; /* Reg R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404u; /* Reg R4 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303u; /* Reg R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202u; /* Reg R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101u; /* Reg R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* Reg R0 : argument */
|
||||
|
||||
if (((cpu_stack_t)entry & 0x01u) == 0x01u) { /* See if task runs in Thumb or ARM mode */
|
||||
*(--stk) = (cpu_stack_t)ARM_SVC_MODE_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMB-mode) */
|
||||
} else {
|
||||
*(--stk) = (cpu_stack_t)ARM_SVC_MODE_ARM; /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */
|
||||
}
|
||||
|
||||
#if (FPU_AVL > 0)
|
||||
uint32_t fpu_reg_cnt = fpu_reg_count();
|
||||
uint32_t i;
|
||||
|
||||
|
||||
if (fpu_reg_cnt != 0u) {
|
||||
*(--stk) = (cpu_stack_t)0; /* Initialize Floating point status & control register */
|
||||
/* Initialize general-purpose Floating point registers */
|
||||
for (i = 0u; i < fpu_reg_cnt * 2u; i++) {
|
||||
*(--stk) = (cpu_stack_t)0;
|
||||
}
|
||||
|
||||
*(--stk) = (cpu_stack_t)(0x40000000); /* Initialize Floating-Point Exception Register (Enable)*/
|
||||
}
|
||||
#endif
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
387
Living_SDK/platform/arch/arm/armv7a/gcc/a5/port_s.S
Normal file
387
Living_SDK/platform/arch/arm/armv7a/gcc/a5/port_s.S
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
*
|
||||
* @file port_s.S
|
||||
*
|
||||
*/
|
||||
|
||||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.extern krhino_stack_ovf_check
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
|
||||
.global fpu_reg_count
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
|
||||
.global vector_undef
|
||||
.global vector_swi
|
||||
.global vector_pabt
|
||||
.global vector_dabt
|
||||
.global vector_resv
|
||||
.global vector_irq
|
||||
.global vector_fiq
|
||||
|
||||
@******************************************************************************
|
||||
@ EQUATES
|
||||
@******************************************************************************
|
||||
|
||||
.equ AMR_Mode_USR, 0x10
|
||||
.equ AMR_Mode_FIQ, 0x11
|
||||
.equ AMR_Mode_IRQ, 0x12
|
||||
.equ AMR_Mode_SVC, 0x13
|
||||
.equ AMR_Mode_ABT, 0x17
|
||||
.equ AMR_Mode_UND, 0x1B
|
||||
.equ AMR_Mode_SYS, 0x1F
|
||||
|
||||
.equ ARM_CONTROL_INT_DIS, 0xC0 @ Disable both FIQ and IRQ.
|
||||
.equ ARM_CONTROL_FIQ_DIS, 0x40 @ Disable FIQ.
|
||||
.equ ARM_CONTROL_IRQ_DIS, 0x80 @ Disable IRQ.
|
||||
.equ ARM_CONTROL_THUMB, 0x20 @ Set THUMB mode.
|
||||
.equ ARM_CONTROL_ARM, 0x00 @ Set ARM mode.
|
||||
|
||||
.equ ARM_EXCEPT_RESET, 0x00
|
||||
.equ ARM_EXCEPT_UNDEF_INSTR, 0x01
|
||||
.equ ARM_EXCEPT_SWI, 0x02
|
||||
.equ ARM_EXCEPT_PREFETCH_ABORT, 0x03
|
||||
.equ ARM_EXCEPT_DATA_ABORT, 0x04
|
||||
.equ ARM_EXCEPT_ADDR_ABORT, 0x05
|
||||
.equ ARM_EXCEPT_IRQ, 0x06
|
||||
.equ ARM_EXCEPT_FIQ, 0x07
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
|
||||
.text
|
||||
.align 2
|
||||
|
||||
@******************************************************************************
|
||||
@ MACRO DEFINED
|
||||
@******************************************************************************
|
||||
|
||||
.macro POP_FP_REG reg
|
||||
POP {\reg}
|
||||
VMSR FPEXC, \reg /* Pop FPEXC */
|
||||
FLDMIAS SP!, {S0-S31} /* Pop floating point registers. */
|
||||
POP {\reg}
|
||||
VMSR FPSCR, \reg /* Pop FPSCR. */
|
||||
.endm
|
||||
|
||||
.macro PUSH_FP_REG reg
|
||||
VMRS \reg, FPSCR /* Save FPSCR */
|
||||
PUSH {\reg} /* Save floating-point registers. */
|
||||
FSTMDBS SP!, {S0-S31}
|
||||
VMRS \reg, FPEXC /* Save FPEXC. */
|
||||
PUSH {\reg}
|
||||
.endm
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ size_t fpu_reg_count(void);
|
||||
@******************************************************************************
|
||||
fpu_reg_count:
|
||||
MOV R0, #16
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ size_t cpu_intrpt_save(void);
|
||||
@ void cpu_intrpt_restore(size_t cpsr);
|
||||
@******************************************************************************
|
||||
cpu_intrpt_save:
|
||||
mrs r0, cpsr
|
||||
CPSID IF
|
||||
dsb
|
||||
bx lr
|
||||
|
||||
cpu_intrpt_restore:
|
||||
dsb
|
||||
msr cpsr, r0
|
||||
bx lr
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_first_task_start(void);
|
||||
@******************************************************************************
|
||||
cpu_first_task_start:
|
||||
MSR CPSR_c, #(ARM_CONTROL_INT_DIS | AMR_Mode_SVC) @ change to SVC mode.
|
||||
|
||||
@ switch to highest priority task:
|
||||
LDR R0, =g_active_task @ g_active_task = g_preferred_ready_task;
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0] @ R0 = g_active_task->task_stack = context region
|
||||
|
||||
LDR SP, [R2]
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
POP_FP_REG R0 @ Pop fpu register.
|
||||
#endif
|
||||
|
||||
LDR R0, [SP], #4 @ R0 = SPSR; SP = SP + 4
|
||||
|
||||
MSR SPSR_cxsf, R0 @ restore new task CPSR
|
||||
|
||||
LDMFD SP!, {R0-R12, LR, PC}^ @ restore new task context.
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_task_switch(void);
|
||||
@******************************************************************************
|
||||
cpu_task_switch:
|
||||
@ save current task context:
|
||||
STMFD SP!, {LR} @ Push return address.
|
||||
STMFD SP!, {LR}
|
||||
STMFD SP!, {R0-R12} @ Push R0-R12 registers
|
||||
MRS R0, CPSR @ Push old task CPSR
|
||||
TST LR, #1 @ test if called from Thumb mode,
|
||||
ORRNE R0, R0, #ARM_CONTROL_THUMB @ if yes, set the T-bit.
|
||||
STMFD SP!, {R0}
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
PUSH_FP_REG R0 @ Push fpu register.
|
||||
#endif
|
||||
|
||||
@g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task @ g_active_task->task_stack = SP;
|
||||
LDR R1, [R1]
|
||||
STR SP, [R1]
|
||||
|
||||
bl krhino_stack_ovf_check
|
||||
|
||||
LDR R0, =g_active_task @ g_active_task = g_preferred_ready_task;
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0] @ R0 = g_active_task->task_stack = context region
|
||||
|
||||
LDR SP, [R2]
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
POP_FP_REG R0 @ Pop fpu register.
|
||||
#endif
|
||||
|
||||
LDMFD SP!, {R0} @ restore CPSR
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
LDMFD SP!, {R0-R12, LR, PC}^ @ restore new task context.
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_intrpt_switch(void);
|
||||
@******************************************************************************
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =g_active_task @ g_active_task = g_preferred_ready_task;
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0] @ R0 = g_active_task->task_stack = context region
|
||||
|
||||
LDR SP, [R2]
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
POP_FP_REG R0 @ Pop fpu register.
|
||||
#endif
|
||||
|
||||
LDMFD SP!, {R0} @ Pop new task CPSR
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
LDMFD SP!, {R0-R12, LR, PC}^ @ restore new task context.
|
||||
|
||||
|
||||
.section .text.isr, "ax"
|
||||
/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */
|
||||
.align 5
|
||||
vector_undef:
|
||||
STMFD SP!, {R0-R3} @ Push R0-R3 registers.
|
||||
MOV R0, #ARM_EXCEPT_UNDEF_INSTR @ Set exception type to ARM_EXCEPT_UNDEF_INSTR.
|
||||
MRS R1, SPSR @ Save CPSR
|
||||
MOV R2, LR @ Save LR(PC) register.
|
||||
MOV R3, SP @ Save SP register.
|
||||
ADD SP, SP, #(4 * 4) @ set SP to undef stack top.
|
||||
B common_except_handler @ bl to common_except_handler.
|
||||
|
||||
.align 5
|
||||
vector_swi:
|
||||
STMFD SP!, {R0-R3} @ Push R0-R3 registers.
|
||||
MOV R0, #ARM_EXCEPT_SWI @ Set exception type to ARM_EXCEPT_SWI.
|
||||
MRS R1, SPSR @ Save CPSR
|
||||
MOV R2, LR @ Save LR(PC) register.
|
||||
MOV R3, SP @ Save SP register.
|
||||
ADD SP, SP, #(4 * 4) @ set SP to swi stack top.
|
||||
B common_except_handler @ bl to common_except_handler.
|
||||
|
||||
.align 5
|
||||
vector_pabt:
|
||||
STMFD SP!, {R0-R3} @ Push R0-R3 registers.
|
||||
MOV R0, #ARM_EXCEPT_PREFETCH_ABORT @ Set exception type to ARM_EXCEPT_PREFETCH_ABORT.
|
||||
MRS R1, SPSR @ Save CPSR.
|
||||
SUB R2, LR, #4 @ Save LR(PC) register: -4.
|
||||
MOV R3, SP @ Save SP register.
|
||||
ADD SP, SP, #(4 * 4) @ set SP to padt stack top.
|
||||
B common_except_handler @ bl to common_except_handler.
|
||||
|
||||
.align 5
|
||||
vector_dabt:
|
||||
STMFD SP!, {R0-R3} @ Push R0-R3 registers.
|
||||
MOV R0, #ARM_EXCEPT_DATA_ABORT @ Set exception type to ARM_EXCEPT_DATA_ABORT.
|
||||
MRS R1, SPSR @ Save CPSR.
|
||||
SUB R2, LR, #8 @ Save LR(PC) register: -8.
|
||||
MOV R3, SP @ Save SP register.
|
||||
ADD SP, SP, #(4 * 4) @ set SP to dabt stack top.
|
||||
B common_except_handler @ bl to common_except_handler.
|
||||
|
||||
.align 5
|
||||
vector_resv:
|
||||
STMFD SP!, {R0-R3} @ Push R0-R3 registers.
|
||||
MOV R0, #ARM_EXCEPT_ADDR_ABORT @ Set exception type to ARM_EXCEPT_ADDR_ABORT.
|
||||
MRS R1, SPSR @ Save CPSR.
|
||||
SUB R2, LR, #8 @ Save LR(PC) register: -8.
|
||||
MOV R3, SP @ Save SP register.
|
||||
ADD SP, SP, #(4 * 4) @ set SP to resv stack top.
|
||||
B common_except_handler @ bl to common_except_handler.
|
||||
|
||||
.align 5
|
||||
vector_irq:
|
||||
STMFD SP!, {R0-R3} @ Push R0-R3 registers.
|
||||
MOV R0, #ARM_EXCEPT_IRQ @ Set exception type to ARM_EXCEPT_IRQ.
|
||||
MRS R1, SPSR @ Save CPSR.
|
||||
SUB R2, LR, #4 @ Save LR(PC) register: -4.
|
||||
MOV R3, SP @ Save SP register.
|
||||
ADD SP, SP, #(4 * 4) @ set SP to irq stack top.
|
||||
B common_except_handler @ bl to common_except_handler.
|
||||
|
||||
.align 5
|
||||
vector_fiq:
|
||||
STMFD SP!, {R0-R3} @ Push R0-R3 registers.
|
||||
MOV R0, #ARM_EXCEPT_FIQ @ Set exception type to ARM_EXCEPT_FIQ.
|
||||
MRS R1, SPSR @ Save CPSR.
|
||||
SUB R2, LR, #4 @ Save LR(PC) register: -4.
|
||||
MOV R3, SP @ Save SP register.
|
||||
ADD SP, SP, #(4 * 4) @ set SP to fiq stack top.
|
||||
B common_except_handler @ bl to common_except_handler.
|
||||
|
||||
common_except_handler:
|
||||
@ change to SVC mode & disable interruptions.
|
||||
MSR CPSR_c, #(ARM_CONTROL_INT_DIS | AMR_Mode_SVC)
|
||||
|
||||
STMFD SP!, {R2} @ Push old task PC,
|
||||
STMFD SP!, {LR} @ Push old task LR,
|
||||
STMFD SP!, {R4-R12} @ Push old task R12-R4,
|
||||
LDMFD R3!, {R5-R8} @ Pop old task R3-R0 from irq stack.
|
||||
STMFD SP!, {R5-R8} @ Push old task R3-R0,
|
||||
STMFD SP!, {R1} @ Push task CPSR.
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
PUSH_FP_REG R1 @ Push task fpu register.
|
||||
#endif
|
||||
@ if (g_sys_stat == RHINO_RUNNING)
|
||||
LDR R3, =g_sys_stat
|
||||
LDR R4, [R3]
|
||||
CMP R4, #3 @ RHINO_RUNNING = 3
|
||||
BNE except_before_task_running
|
||||
|
||||
PUSH {R0}
|
||||
BL krhino_intrpt_enter @ g_intrpt_nested_level++;
|
||||
POP {R0}
|
||||
|
||||
LDR R3,=g_intrpt_nested_level
|
||||
LDRB R4, [R3]
|
||||
CMP R4, #1 @ if (g_intrpt_nested_level == 1)
|
||||
BNE except_from_intrpt
|
||||
|
||||
except_from_task:
|
||||
@ g_active_task->task_stack = context region
|
||||
LDR R3, =g_active_task @ g_active_task->task_stack = SP;
|
||||
LDR R4, [R3]
|
||||
STR SP, [R4]
|
||||
|
||||
LDR R3, =except_stack_top @ Switch to except stack.
|
||||
MOV SP, R3
|
||||
|
||||
BL aos_cpu_except_handler @ aos_cpu_except_handler(except_type = R0)
|
||||
|
||||
@ change to SVC mode & disable interruptions.
|
||||
MSR CPSR_c, #(ARM_CONTROL_INT_DIS | AMR_Mode_SVC)
|
||||
|
||||
@ call krhino_intrpt_exit() to return if a ready task with higher priority.
|
||||
BL krhino_intrpt_exit
|
||||
|
||||
LDR R3, =g_active_task @ SP = g_active_task->task_stack;
|
||||
LDR R4, [R3]
|
||||
LDR SP, [R4]
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
POP_FP_REG R0 @ Pop task fpu register.
|
||||
#endif
|
||||
|
||||
LDMFD SP!, {R0} @ Pop new task CPSR,
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
LDMFD SP!, {R0-R12, LR, PC}^ @ restore new task context.
|
||||
|
||||
except_from_intrpt:
|
||||
@ align SP to 4 byte
|
||||
MOV R1, SP
|
||||
AND R1, R1, #4
|
||||
SUB SP, SP, R1
|
||||
STMFD SP!, {R1, LR}
|
||||
|
||||
BL aos_cpu_except_handler @ aos_cpu_except_handler(except_type = R0)
|
||||
|
||||
LDMIA SP!, {R1, LR}
|
||||
ADD SP, SP, R1
|
||||
|
||||
@ change to SVC mode & disable interruptions.
|
||||
MSR CPSR_c, #(ARM_CONTROL_INT_DIS | AMR_Mode_SVC)
|
||||
|
||||
LDR R3,=g_intrpt_nested_level @ g_intrpt_nested_level--;
|
||||
LDRB R4, [R3]
|
||||
SUB R4, R4, #1
|
||||
STRB R4, [R3]
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
POP_FP_REG R0 @ Pop task fpu register.
|
||||
#endif
|
||||
|
||||
LDMFD SP!, {R0} @ Pop old task CPSR,
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
LDMFD SP!, {R0-R12, LR, PC}^ @ restore working registers and return from exception.
|
||||
|
||||
|
||||
except_before_task_running:
|
||||
@ align SP to 4 byte.
|
||||
MOV R1, SP
|
||||
AND R1, R1, #4
|
||||
SUB SP, SP, R1
|
||||
STMFD SP!, {R1, LR}
|
||||
|
||||
LDR R3,=aos_cpu_except_handler @ aos_cpu_except_handler(except_type = R0)
|
||||
MOV LR, PC
|
||||
BX R3
|
||||
|
||||
LDMIA SP!, {R1, LR}
|
||||
ADD SP, SP, R1
|
||||
|
||||
@ change to SVC mode & disable interruptions.
|
||||
MSR CPSR_c, #(ARM_CONTROL_INT_DIS | AMR_Mode_SVC)
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
POP_FP_REG R0 @ Pop task fpu register.
|
||||
#endif
|
||||
|
||||
LDMFD SP!, {R0} @ Pop old CPSR,
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
LDMFD SP!, {R0-R12, LR, PC}^ @ restore working registers and return from exception.
|
||||
|
||||
|
||||
20
Living_SDK/platform/arch/arm/armv7m/README.md
Normal file
20
Living_SDK/platform/arch/arm/armv7m/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
## Contents
|
||||
|
||||
## Introduction
|
||||
**armv7m** arch files of armv7m
|
||||
|
||||
### Features
|
||||
- armv7m system api
|
||||
|
||||
### Directories
|
||||
|
||||
```sh
|
||||
armv7m
|
||||
├─ gcc # System adapter file of armv7m architecture for gcc
|
||||
├─ armcc # System adapter file of armv7m architecture for armcc
|
||||
├─ iccarm # System adapter file of armv7m architecture for iccarm
|
||||
├─ panic # panic adapter file of armv7m architecture
|
||||
```
|
||||
### Dependencies
|
||||
|
||||
## Reference
|
||||
25
Living_SDK/platform/arch/arm/armv7m/armcc/m3/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/armcc/m3/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/armcc/m3/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/armcc/m3/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
42
Living_SDK/platform/arch/arm/armv7m/armcc/m3/port_c.c
Normal file
42
Living_SDK/platform/arch/arm/armv7m/armcc/m3/port_c.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* task context saved & restore by hardware: */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
161
Living_SDK/platform/arch/arm/armv7m/armcc/m3/port_s.S
Normal file
161
Living_SDK/platform/arch/arm/armv7m/armcc/m3/port_s.S
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
#include <k_config.h>
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN g_active_task
|
||||
EXTERN g_preferred_ready_task
|
||||
EXTERN krhino_stack_ovf_check
|
||||
EXTERN krhino_task_sched_stats_get
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
EXPORT cpu_intrpt_save
|
||||
EXPORT cpu_intrpt_restore
|
||||
EXPORT cpu_task_switch
|
||||
EXPORT cpu_intrpt_switch
|
||||
EXPORT cpu_first_task_start
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
EXPORT _first_task_restore
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14 EQU 0xE000ED22 ; System Handler Priority Register 3 (PendSV).
|
||||
PRI_LVL_PENDSV EQU 0xFF ; PendSV priority level (lowest).
|
||||
SHPR3_PRI_15 EQU 0xE000ED23 ; System Handler Priority Register 3 (SysTick).
|
||||
PRI_LVL_SYSTICK EQU 0xFF ; SYstick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
;set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
;branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
_pendsv_handler_nosave
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
_first_task_restore
|
||||
;set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
ALIGN
|
||||
END
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/armcc/m4/k_types.h
Executable file
25
Living_SDK/platform/arch/arm/armv7m/armcc/m4/k_types.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/armcc/m4/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/armcc/m4/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
67
Living_SDK/platform/arch/arm/armv7m/armcc/m4/port_c.c
Normal file
67
Living_SDK/platform/arch/arm/armv7m/armcc/m4/port_c.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
/* ARMCC || IAR || GNU */
|
||||
#define FPU_AVL ((defined(__CC_ARM) && defined(__TARGET_FPU_VFP)) \
|
||||
|| (defined(__ICCARM__) && defined(__ARMVFP__)) \
|
||||
|| (defined(__GNUC__) && defined(__VFP_FP__) && !defined(__SOFTFP__)))
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* Exception stack frame with non-floating-point state */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* in PendSV_Handler, D8~D15 is always saved & restroe */
|
||||
#if (FPU_AVL > 0)
|
||||
*(--stk) = (cpu_stack_t)0x31uL; /* S31 */
|
||||
*(--stk) = (cpu_stack_t)0x30uL; /* S30 */
|
||||
*(--stk) = (cpu_stack_t)0x29uL; /* S29 */
|
||||
*(--stk) = (cpu_stack_t)0x28uL; /* S28 */
|
||||
*(--stk) = (cpu_stack_t)0x27uL; /* S27 */
|
||||
*(--stk) = (cpu_stack_t)0x26uL; /* S26 */
|
||||
*(--stk) = (cpu_stack_t)0x25uL; /* S25 */
|
||||
*(--stk) = (cpu_stack_t)0x24uL; /* S24 */
|
||||
*(--stk) = (cpu_stack_t)0x23uL; /* S23 */
|
||||
*(--stk) = (cpu_stack_t)0x22uL; /* S22 */
|
||||
*(--stk) = (cpu_stack_t)0x21uL; /* S21 */
|
||||
*(--stk) = (cpu_stack_t)0x20uL; /* S20 */
|
||||
*(--stk) = (cpu_stack_t)0x19uL; /* S19 */
|
||||
*(--stk) = (cpu_stack_t)0x18uL; /* S18 */
|
||||
*(--stk) = (cpu_stack_t)0x17uL; /* S17 */
|
||||
*(--stk) = (cpu_stack_t)0x16uL; /* S16 */
|
||||
#endif
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + non-floating-point state + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
177
Living_SDK/platform/arch/arm/armv7m/armcc/m4/port_s.S
Normal file
177
Living_SDK/platform/arch/arm/armv7m/armcc/m4/port_s.S
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
#include <k_config.h>
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN g_active_task
|
||||
EXTERN g_preferred_ready_task
|
||||
EXTERN krhino_stack_ovf_check
|
||||
EXTERN krhino_task_sched_stats_get
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
EXPORT cpu_intrpt_save
|
||||
EXPORT cpu_intrpt_restore
|
||||
EXPORT cpu_task_switch
|
||||
EXPORT cpu_intrpt_switch
|
||||
EXPORT cpu_first_task_start
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
EXPORT _first_task_restore
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14 EQU 0xE000ED22 ; System Handler Priority Register 3 (PendSV).
|
||||
PRI_LVL_PENDSV EQU 0xFF ; PendSV priority level (lowest).
|
||||
SHPR3_PRI_15 EQU 0xE000ED23 ; System Handler Priority Register 3 (SysTick).
|
||||
PRI_LVL_SYSTICK EQU 0xFF ; SYstick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
;set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
;branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
IF {FPU} != "SoftVFP"
|
||||
;if the switchout task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VSTMFDEQ R0!, {D8 - D15}
|
||||
;hardware saved D0~D7, FPSCR
|
||||
ENDIF
|
||||
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
_pendsv_handler_nosave
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
IF {FPU} != "SoftVFP"
|
||||
;if the switchin task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VLDMFDEQ R0!, {D8 - D15}
|
||||
;hardware will restore D0~D7, FPSCR
|
||||
ENDIF
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
_first_task_restore
|
||||
;set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
ALIGN
|
||||
END
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/armcc/m7/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/armcc/m7/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/armcc/m7/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/armcc/m7/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
67
Living_SDK/platform/arch/arm/armv7m/armcc/m7/port_c.c
Normal file
67
Living_SDK/platform/arch/arm/armv7m/armcc/m7/port_c.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
/* ARMCC || IAR || GNU */
|
||||
#define FPU_AVL ((defined(__CC_ARM) && defined(__TARGET_FPU_VFP)) \
|
||||
|| (defined(__ICCARM__) && defined(__ARMVFP__)) \
|
||||
|| (defined(__GNUC__) && defined(__VFP_FP__) && !defined(__SOFTFP__)))
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* Exception stack frame with non-floating-point state */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* in PendSV_Handler, D8~D15 is always saved & restroe */
|
||||
#if (FPU_AVL > 0)
|
||||
*(--stk) = (cpu_stack_t)0x31uL; /* S31 */
|
||||
*(--stk) = (cpu_stack_t)0x30uL; /* S30 */
|
||||
*(--stk) = (cpu_stack_t)0x29uL; /* S29 */
|
||||
*(--stk) = (cpu_stack_t)0x28uL; /* S28 */
|
||||
*(--stk) = (cpu_stack_t)0x27uL; /* S27 */
|
||||
*(--stk) = (cpu_stack_t)0x26uL; /* S26 */
|
||||
*(--stk) = (cpu_stack_t)0x25uL; /* S25 */
|
||||
*(--stk) = (cpu_stack_t)0x24uL; /* S24 */
|
||||
*(--stk) = (cpu_stack_t)0x23uL; /* S23 */
|
||||
*(--stk) = (cpu_stack_t)0x22uL; /* S22 */
|
||||
*(--stk) = (cpu_stack_t)0x21uL; /* S21 */
|
||||
*(--stk) = (cpu_stack_t)0x20uL; /* S20 */
|
||||
*(--stk) = (cpu_stack_t)0x19uL; /* S19 */
|
||||
*(--stk) = (cpu_stack_t)0x18uL; /* S18 */
|
||||
*(--stk) = (cpu_stack_t)0x17uL; /* S17 */
|
||||
*(--stk) = (cpu_stack_t)0x16uL; /* S16 */
|
||||
#endif
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + non-floating-point state + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
177
Living_SDK/platform/arch/arm/armv7m/armcc/m7/port_s.S
Normal file
177
Living_SDK/platform/arch/arm/armv7m/armcc/m7/port_s.S
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
#include <k_config.h>
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN g_active_task
|
||||
EXTERN g_preferred_ready_task
|
||||
EXTERN krhino_stack_ovf_check
|
||||
EXTERN krhino_task_sched_stats_get
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
EXPORT cpu_intrpt_save
|
||||
EXPORT cpu_intrpt_restore
|
||||
EXPORT cpu_task_switch
|
||||
EXPORT cpu_intrpt_switch
|
||||
EXPORT cpu_first_task_start
|
||||
|
||||
EXPORT PendSV_Handler
|
||||
EXPORT _first_task_restore
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14 EQU 0xE000ED22 ; System Handler Priority Register 3 (PendSV).
|
||||
PRI_LVL_PENDSV EQU 0xFF ; PendSV priority level (lowest).
|
||||
SHPR3_PRI_15 EQU 0xE000ED23 ; System Handler Priority Register 3 (SysTick).
|
||||
PRI_LVL_SYSTICK EQU 0xFF ; SYstick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
;set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
;branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
IF {FPU} != "SoftVFP"
|
||||
;if the switchout task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VSTMFDEQ R0!, {D8 - D15}
|
||||
;hardware saved D0~D7, FPSCR
|
||||
ENDIF
|
||||
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
_pendsv_handler_nosave
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
IF {FPU} != "SoftVFP"
|
||||
;if the switchin task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VLDMFDEQ R0!, {D8 - D15}
|
||||
;hardware will restore D0~D7, FPSCR
|
||||
ENDIF
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
_first_task_restore
|
||||
;set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
ALIGN
|
||||
END
|
||||
|
||||
47
Living_SDK/platform/arch/arm/armv7m/armv7m.mk
Normal file
47
Living_SDK/platform/arch/arm/armv7m/armv7m.mk
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
NAME := arch_armv7m
|
||||
|
||||
$(NAME)_MBINS_TYPE := kernel
|
||||
$(NAME)_VERSION := 1.0.0
|
||||
$(NAME)_SUMMARY := arch for armv7m
|
||||
|
||||
$(NAME)_SOURCES := common/panic_c.c
|
||||
$(NAME)_SOURCES += common/port_c.c
|
||||
$(NAME)_SOURCES += common/panic_mpu.c
|
||||
|
||||
GLOBAL_INCLUDES += common/
|
||||
|
||||
ifeq ($(COMPILER),armcc)
|
||||
$(NAME)_SOURCES += common/panic_armcc.S
|
||||
GLOBAL_ASMFLAGS += --cpreproc
|
||||
|
||||
ifeq ($(HOST_ARCH),Cortex-M3)
|
||||
$(NAME)_SOURCES += armcc/m3/port_s.S
|
||||
else ifeq ($(HOST_ARCH),Cortex-M4)
|
||||
$(NAME)_SOURCES += armcc/m4/port_s.S
|
||||
else ifeq ($(HOST_ARCH),Cortex-M7)
|
||||
$(NAME)_SOURCES += armcc/m7/port_s.S
|
||||
endif
|
||||
|
||||
else ifeq ($(COMPILER),iar)
|
||||
$(NAME)_SOURCES += common/panic_iccarm.S
|
||||
|
||||
ifeq ($(HOST_ARCH),Cortex-M3)
|
||||
$(NAME)_SOURCES += iccarm/m3/port_s.S
|
||||
else ifeq ($(HOST_ARCH),Cortex-M4)
|
||||
$(NAME)_SOURCES += iccarm/m4/port_s.S
|
||||
else ifeq ($(HOST_ARCH),Cortex-M7)
|
||||
$(NAME)_SOURCES += iccarm/m7/port_s.S
|
||||
endif
|
||||
|
||||
else
|
||||
$(NAME)_SOURCES += common/panic_gcc.S
|
||||
|
||||
ifeq ($(HOST_ARCH),Cortex-M3)
|
||||
$(NAME)_SOURCES += gcc/m3/port_s.S
|
||||
else ifeq ($(HOST_ARCH),Cortex-M4)
|
||||
$(NAME)_SOURCES += gcc/m4/port_s.S
|
||||
else ifeq ($(HOST_ARCH),Cortex-M7)
|
||||
$(NAME)_SOURCES += gcc/m7/port_s.S
|
||||
endif
|
||||
|
||||
endif
|
||||
101
Living_SDK/platform/arch/arm/armv7m/common/k_compiler.h
Normal file
101
Living_SDK/platform/arch/arm/armv7m/common/k_compiler.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_COMPILER_H
|
||||
#define K_COMPILER_H
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#define RHINO_INLINE static __inline
|
||||
/* get the return address of the current function
|
||||
unsigned int __return_address(void) */
|
||||
#define RHINO_GET_RA() (void *)__return_address()
|
||||
/* get the the value of the stack pointer
|
||||
unsigned int __current_sp(void) */
|
||||
#define RHINO_GET_SP() (void *)__current_sp()
|
||||
/* get the number of leading 0-bits in x
|
||||
unsigned char __clz(unsigned int val) */
|
||||
#define RHINO_BIT_CLZ(x) __clz(x)
|
||||
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
|
||||
/* Instruction Synchronization Barrier */
|
||||
#define OS_ISB() __isb(15) /* Full system Any-Any */
|
||||
|
||||
/* Data Memory Barrier */
|
||||
#define OS_DMB() __dmb(15) /* Full system Any-Any */
|
||||
|
||||
/* Data Synchronization Barrier */
|
||||
#define OS_DSB() __dsb(15) /* Full system Any-Any */
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
#define RHINO_INLINE static inline
|
||||
/* get the return address of the current function
|
||||
unsigned int __get_LR(void) */
|
||||
#define RHINO_GET_RA() (void *)__get_LR()
|
||||
/* get the the value of the stack pointer
|
||||
unsigned int __get_SP(void) */
|
||||
#define RHINO_GET_SP() (void *)__get_SP()
|
||||
/* get the value of the stack pointer register
|
||||
unsigned int __CLZ(unsigned int) */
|
||||
//#define RHINO_BIT_CLZ(x) __CLZ(x)
|
||||
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
|
||||
/* Instruction Synchronization Barrier */
|
||||
#define OS_ISB() __isb(15) /* Full system Any-Any */
|
||||
|
||||
/* Data Memory Barrier */
|
||||
#define OS_DMB() __dmb(15) /* Full system Any-Any */
|
||||
|
||||
/* Data Synchronization Barrier */
|
||||
#define OS_DSB() __dsb(15) /* Full system Any-Any */
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define RHINO_INLINE static inline
|
||||
/* get the return address of the current function
|
||||
void * __builtin_return_address (unsigned int level) */
|
||||
#define RHINO_GET_RA() __builtin_return_address(0)
|
||||
/* get the return address of the current function */
|
||||
__attribute__((always_inline)) RHINO_INLINE void *RHINO_GET_SP(void)
|
||||
{
|
||||
void *sp;
|
||||
asm volatile("mov %0, SP\n":"=r"(sp));
|
||||
return sp;
|
||||
}
|
||||
__attribute__((always_inline)) RHINO_INLINE unsigned char RHINO_BIT_CLZ_(unsigned int bitmap)
|
||||
{
|
||||
unsigned char cnt;
|
||||
asm volatile("clz %0, %1":"=r"(cnt):"r"(bitmap));
|
||||
return cnt;
|
||||
}
|
||||
/* get the number of leading 0-bits in x
|
||||
int __builtin_clz (unsigned int x) */
|
||||
#define RHINO_BIT_CLZ(x) RHINO_BIT_CLZ_(x)
|
||||
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
|
||||
/* Instruction Synchronization Barrier */
|
||||
#define OS_ISB() \
|
||||
__asm volatile ("isb sy":::"memory")
|
||||
|
||||
/* Data Memory Barrier */
|
||||
#define OS_DMB() \
|
||||
__asm volatile ("dmb sy":::"memory")
|
||||
|
||||
/* Data Synchronization Barrier */
|
||||
#define OS_DSB() \
|
||||
__asm volatile ("dsb sy":::"memory")
|
||||
|
||||
#else
|
||||
#error "Unsupported compiler"
|
||||
#endif
|
||||
|
||||
#endif /* K_COMPILER_H */
|
||||
|
||||
21
Living_SDK/platform/arch/arm/armv7m/common/k_types.h
Normal file
21
Living_SDK/platform/arch/arm/armv7m/common/k_types.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef K_TYPES_H
|
||||
#define K_TYPES_H
|
||||
|
||||
#include "k_compiler.h"
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* K_TYPES_H */
|
||||
|
||||
152
Living_SDK/platform/arch/arm/armv7m/common/panic_armcc.S
Normal file
152
Living_SDK/platform/arch/arm/armv7m/common/panic_armcc.S
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
#include "k_config.h"
|
||||
#include "k_dftdbg_config.h"
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
CONTEXT_REGION EQU 88 ;bigger than sizeof(PANIC_CONTEXT)
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
AREA |.text|, CODE, READONLY, ALIGN=2
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN panicHandler
|
||||
EXTERN g_crash_steps
|
||||
EXTERN _first_task_restore
|
||||
EXTERN panicRestoreCheck
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
EXPORT HardFault_Handler
|
||||
EXPORT MemManage_Handler
|
||||
EXPORT BusFault_Handler
|
||||
EXPORT UsageFault_Handler
|
||||
|
||||
;******************************************************************************
|
||||
; FAULT FUNCTIONS
|
||||
;******************************************************************************
|
||||
HardFault_Handler
|
||||
MemManage_Handler
|
||||
BusFault_Handler
|
||||
UsageFault_Handler
|
||||
PUSH {R1, LR}
|
||||
BL panicRestoreCheck
|
||||
POP {R1, LR}
|
||||
CBZ R0, unrecoverable_crash
|
||||
BL _first_task_restore
|
||||
|
||||
unrecoverable_crash
|
||||
;check double crash
|
||||
LDR R1, =g_crash_steps
|
||||
LDR R2, [R1]
|
||||
ADD R3, R2, #1
|
||||
STR R3, [R1]
|
||||
CBZ R2, first_panic
|
||||
;return from exc to handle panic
|
||||
MRS R1, PSP
|
||||
AND R2, LR, #4 ;EXC_RETURN:bit2, 0 MSP, 1 PSP
|
||||
CBNZ R2, double_panic
|
||||
MRS R1, MSP
|
||||
double_panic
|
||||
LDR R0, =double_panic_entry
|
||||
STR R0, [R1, #24]
|
||||
LDR R0, [R1, #28]
|
||||
ORR R0, R0, #0x1000000
|
||||
STR R0, [R1, #28] ;set thumb mode
|
||||
BX LR
|
||||
|
||||
double_panic_entry
|
||||
MOV R0, #0 ;double crash, do not save context
|
||||
BL panicHandler
|
||||
B .
|
||||
|
||||
first_panic
|
||||
;R0 as PANIC_CONTEXT
|
||||
SUB R0, SP, #CONTEXT_REGION
|
||||
|
||||
;R1 as CONTEXT saved by hardware
|
||||
MRS R1, PSP
|
||||
AND R2, LR, #4 ;EXC_RETURN:bit2, 0 MSP, 1 PSP
|
||||
CBNZ R2, context_save
|
||||
MRS R1, MSP
|
||||
context_save
|
||||
|
||||
ADD R2, R0, #16
|
||||
STM R2!,{R4-R11} ;ctx save, R4~R11
|
||||
|
||||
LDM R1, {R4-R11}
|
||||
STM R0, {R4-R7} ;ctx save, R0~R3
|
||||
|
||||
STM R2!,{R8-R11} ;ctx save, R12 LR PC xPSR
|
||||
|
||||
;xPSR[9] and EXC_RETURN[4] to determine whether
|
||||
;the previous top-of-stack was at offset 0x20, 0x24, 0x68, or0x6C
|
||||
ADD R4, R1, #0x20
|
||||
IF {FPU} != "SoftVFP"
|
||||
AND R3, LR, #0x10 ;EXC_RETURN:bit4, 0 floating, 1 non-floating
|
||||
CBNZ R3, check_aligner
|
||||
ADD R4, R4, #0x48
|
||||
check_aligner
|
||||
ENDIF
|
||||
LDR R3, [R1, #28]
|
||||
AND R3, R3, #0x200 ;xPSR:bit9, 0 no-aligner, 1 aligner
|
||||
CBZ R3, sp_save
|
||||
ADD R4, R4, #0x4
|
||||
sp_save
|
||||
STM R2!,{R4} ;ctx save, SP
|
||||
|
||||
MOV R4, LR
|
||||
STM R2!,{R4} ;ctx save, EXC_RETURN
|
||||
|
||||
MRS R4, IPSR
|
||||
STM R2!,{R4} ;ctx save, EXC_NUMBER
|
||||
|
||||
MRS R4, PRIMASK
|
||||
STM R2!,{R4} ;ctx save, PRIMASK
|
||||
|
||||
MRS R4, FAULTMASK
|
||||
STM R2!,{R4} ;ctx save, FAULTMASK
|
||||
|
||||
MRS R4, BASEPRI
|
||||
STM R2!,{R4} ;ctx save, BASEPRI
|
||||
|
||||
;return from exc to handle panic
|
||||
STR R0, [R1, #0]
|
||||
LDR R0, =panic_entry
|
||||
STR R0, [R1, #24]
|
||||
LDR R0, [R1, #28]
|
||||
ORR R0, R0, #0x1000000
|
||||
STR R0, [R1, #28] ;set thumb mode
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
panic_entry
|
||||
#if (RHINO_CONFIG_PANIC_PRT_INT > 0)
|
||||
MRS R1, CONTROL
|
||||
MOVS R2, #2
|
||||
BICS R1, R2
|
||||
MSR CONTROL, R1
|
||||
ISB
|
||||
;printf use interrupt, so here enable it
|
||||
CPSIE I
|
||||
#endif
|
||||
|
||||
MOV SP, R0
|
||||
BL panicHandler
|
||||
B .
|
||||
|
||||
ALIGN
|
||||
|
||||
#endif
|
||||
|
||||
END
|
||||
569
Living_SDK/platform/arch/arm/armv7m/common/panic_c.c
Normal file
569
Living_SDK/platform/arch/arm/armv7m/common/panic_c.c
Normal file
|
|
@ -0,0 +1,569 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "k_dbg_api.h"
|
||||
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#ifdef __BIG_ENDIAN
|
||||
#error "Not support big-endian!"
|
||||
#endif
|
||||
#elif defined(__ICCARM__)
|
||||
#if (__LITTLE_ENDIAN__ == 0)
|
||||
#error "Not support big-endian!"
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
#error "Not support big-endian!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FUNC_SIZE_LIMIT 0x2000
|
||||
#define BACK_TRACE_LIMIT 64
|
||||
#define LR_2_ADDR(lr) ((char *)(((int)(lr)) & 0xfffffffe))
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
static unsigned int __builtin_popcount(unsigned int u)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
while (u) {
|
||||
u = (u & (u - 1));
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void getPLSfromCtx(void *context, char **PC, char **LR, int **SP)
|
||||
{
|
||||
int *ptr = context;
|
||||
int exc_return;
|
||||
|
||||
/* reference to cpu_task_stack_init */
|
||||
exc_return = ptr[8];
|
||||
|
||||
if ((exc_return & 0x10) == 0x10) {
|
||||
*PC = (char *)ptr[15];
|
||||
*LR = (char *)ptr[14];
|
||||
*SP = ptr + 17;
|
||||
} else {
|
||||
*PC = (char *)ptr[31];
|
||||
*LR = (char *)ptr[30];
|
||||
*SP = ptr + 51;
|
||||
}
|
||||
}
|
||||
|
||||
/* get "blx" or "bl" before LR, return offset */
|
||||
static int backtraceFindLROffset(char *LR,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
unsigned short ins16;
|
||||
char s_panic_call[] = "backtrace : 0x \r\n";
|
||||
|
||||
LR = LR_2_ADDR(LR);
|
||||
|
||||
/* callstack bottom */
|
||||
if (((int)LR & 0xffffffe0) == 0xffffffe0) {
|
||||
/* EXC_RETURN, so here is callstack bottom of interrupt handler */
|
||||
if (print_func != NULL) {
|
||||
print_func("backtrace : ^interrupt^\r\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (LR == LR_2_ADDR(&krhino_task_deathbed)) {
|
||||
/* task delete, so here is callstack bottom of task */
|
||||
if (print_func != NULL) {
|
||||
print_func("backtrace : ^task entry^\r\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ins16 = *(unsigned short *)(LR - 4);
|
||||
if ((ins16 & 0xf000) == 0xf000) {
|
||||
if (print_func != NULL) {
|
||||
k_int2str((int)LR - 4, &s_panic_call[14]);
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
return 5;
|
||||
} else {
|
||||
if (print_func != NULL) {
|
||||
k_int2str((int)LR - 2, &s_panic_call[14]);
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* find current function caller, update PC and SP
|
||||
returns: 0 success
|
||||
1 success and find buttom
|
||||
-1 fail */
|
||||
int backtraceFromStack(int **pSP, char **pPC,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
char *CodeAddr = NULL;
|
||||
int *SP = *pSP;
|
||||
char *PC = *pPC;
|
||||
char *LR;
|
||||
int i;
|
||||
unsigned short ins16;
|
||||
unsigned int ins32;
|
||||
unsigned int framesize = 0;
|
||||
unsigned int shift = 0;
|
||||
unsigned int sub = 0;
|
||||
unsigned int offset = 1;
|
||||
|
||||
if (SP == krhino_task_stack_bottom(NULL)) {
|
||||
if (print_func != NULL) {
|
||||
print_func("backtrace : ^task entry^\r\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* func call ways:
|
||||
1. "stmdb sp!, ..." or "push ..." to open stack frame and save LR
|
||||
2. "sub sp, ..." or "sub.w sp, ..." to open stack more
|
||||
3. call
|
||||
*/
|
||||
|
||||
/* 1. scan code, find frame size from "push" or "stmdb sp!" */
|
||||
for (i = 2; i < FUNC_SIZE_LIMIT; i += 2) {
|
||||
/* find nearest "push {..., lr}" */
|
||||
ins16 = *(unsigned short *)(PC - i);
|
||||
if ((ins16 & 0xff00) == 0xb500) {
|
||||
framesize = __builtin_popcount((unsigned char)ins16);
|
||||
framesize++;
|
||||
/* find double push */
|
||||
ins16 = *(unsigned short *)(PC - i - 2);
|
||||
if ((ins16 & 0xff00) == 0xb400) {
|
||||
offset += __builtin_popcount((unsigned char)ins16);
|
||||
framesize += __builtin_popcount((unsigned char)ins16);
|
||||
}
|
||||
CodeAddr = PC - i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* find "stmdb sp!, ..." */
|
||||
/* The Thumb instruction stream is a sequence of halfword-aligned
|
||||
* halfwords */
|
||||
ins32 = *(unsigned short *)(PC - i);
|
||||
ins32 <<= 16;
|
||||
ins32 |= *(unsigned short *)(PC - i + 2);
|
||||
if ((ins32 & 0xFFFFF000) == 0xe92d4000) {
|
||||
framesize = __builtin_popcount(ins32 & 0xfff);
|
||||
framesize++;
|
||||
CodeAddr = PC - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CodeAddr == NULL) {
|
||||
/* error branch */
|
||||
if (print_func != NULL) {
|
||||
print_func("Backtrace fail!\r\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 2. scan code, find frame size from "sub" or "sub.w" */
|
||||
for (i = 0; i < FUNC_SIZE_LIMIT;) {
|
||||
if (CodeAddr + i > PC) {
|
||||
break;
|
||||
}
|
||||
/* find "sub sp, ..." */
|
||||
ins16 = *(unsigned short *)(CodeAddr + i);
|
||||
if ((ins16 & 0xff80) == 0xb080) {
|
||||
framesize += (ins16 & 0x7f);
|
||||
break;
|
||||
}
|
||||
|
||||
/* find "sub.w sp, sp, ..." */
|
||||
ins32 = *(unsigned short *)(CodeAddr + i);
|
||||
ins32 <<= 16;
|
||||
ins32 |= *(unsigned short *)(CodeAddr + i + 2);
|
||||
if ((ins32 & 0xFBFF8F00) == 0xF1AD0D00) {
|
||||
sub = 128 + (ins32 & 0x7f);
|
||||
shift = (ins32 >> 7) & 0x1;
|
||||
shift += ((ins32 >> 12) & 0x7) << 1;
|
||||
shift += ((ins32 >> 26) & 0x1) << 4;
|
||||
framesize += sub<<(30 - shift);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ins16 & 0xf800) >= 0xe800) {
|
||||
i += 4;
|
||||
} else {
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3. output */
|
||||
*pSP = SP + framesize;
|
||||
LR = (char *)*(SP + framesize - offset);
|
||||
offset = backtraceFindLROffset(LR, print_func);
|
||||
*pPC = LR - offset;
|
||||
|
||||
return offset == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/* find current function caller, update PC and SP
|
||||
returns: 0 success
|
||||
1 success and find buttom
|
||||
-1 fail */
|
||||
int backtraceFromLR(int **pSP, char **pPC, char *LR,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int *SP = *pSP;
|
||||
char *PC = *pPC;
|
||||
char *CodeAddr = NULL;
|
||||
int i;
|
||||
unsigned short ins16;
|
||||
unsigned int framesize = 0;
|
||||
unsigned int offset;
|
||||
|
||||
if (PC == NULL) {
|
||||
offset = backtraceFindLROffset(LR, print_func);
|
||||
PC = LR - offset;
|
||||
*pPC = PC;
|
||||
return offset == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/*find stack framesize:
|
||||
1. "push ..." to open stack
|
||||
2. "sub sp, ..." to open stack
|
||||
3. 1 + 2
|
||||
4. do not open stack
|
||||
*/
|
||||
|
||||
/* 1. scan code, find frame size from "push" or "sub" */
|
||||
for (i = 2; i < FUNC_SIZE_LIMIT; i += 2) {
|
||||
ins16 = *(unsigned short *)(PC - i);
|
||||
/* find "push {..., lr}" */
|
||||
if ((ins16 & 0xff00) == 0xb500) {
|
||||
/* another function */
|
||||
break;
|
||||
}
|
||||
/* find "push {...}" */
|
||||
if ((ins16 & 0xff00) == 0xb400) {
|
||||
framesize = __builtin_popcount((unsigned char)ins16);
|
||||
CodeAddr = PC - i;
|
||||
break;
|
||||
}
|
||||
/* find "sub sp, ..." */
|
||||
if ((ins16 & 0xff80) == 0xb080) {
|
||||
framesize = (ins16 & 0x7f);
|
||||
CodeAddr = PC - i;
|
||||
/* find push before sub */
|
||||
ins16 = *(unsigned short *)(PC - i - 2);
|
||||
if ((ins16 & 0xff00) == 0xb400) {
|
||||
framesize += __builtin_popcount((unsigned char)ins16);
|
||||
CodeAddr = PC - i - 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. check the "push" or "sub sp" belongs to another function */
|
||||
if (CodeAddr != NULL) {
|
||||
for (i = 2; i < PC - CodeAddr; i += 2) {
|
||||
ins16 = *(unsigned short *)(PC - i);
|
||||
/* find "pop {..., pc}" or "bx lr" */
|
||||
if ((ins16 & 0xff00) == 0xbd00 || ins16 == 0x4770) {
|
||||
/* SP no changed */
|
||||
framesize = 0;
|
||||
}
|
||||
}
|
||||
} /* else: SP no changed */
|
||||
|
||||
/* 3. output */
|
||||
*pSP = SP + framesize;
|
||||
offset = backtraceFindLROffset(LR, print_func);
|
||||
*pPC = LR - offset;
|
||||
|
||||
return offset == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/* printf call stack */
|
||||
int backtrace_now(int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
char *PC;
|
||||
int *SP;
|
||||
int lvl;
|
||||
int ret;
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
/* compiler specific */
|
||||
#if defined(__CC_ARM)
|
||||
SP = (int *)__current_sp();
|
||||
PC = (char *)__current_pc();
|
||||
#elif defined(__ICCARM__)
|
||||
asm volatile("mov %0, sp\n" : "=r"(SP));
|
||||
asm volatile("mov %0, pc\n" : "=r"(PC));
|
||||
#elif defined(__GNUC__)
|
||||
__asm__ volatile("mov %0, sp\n" : "=r"(SP));
|
||||
__asm__ volatile("mov %0, pc\n" : "=r"(PC));
|
||||
#endif
|
||||
|
||||
print_func("========== Call stack ==========\r\n");
|
||||
for (lvl = 0; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&SP, &PC, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_func("========== End ==========\r\n");
|
||||
return lvl;
|
||||
}
|
||||
|
||||
int backtrace_task(char *taskname, int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
char *PC;
|
||||
char *LR;
|
||||
int *SP;
|
||||
int lvl;
|
||||
int ret;
|
||||
ktask_t *task;
|
||||
|
||||
if (print_func == NULL) {
|
||||
print_func = printf;
|
||||
}
|
||||
|
||||
task = krhino_task_find(taskname);
|
||||
if (task == NULL) {
|
||||
print_func("Task not found : %s\n", taskname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (krhino_task_is_running(task)) {
|
||||
print_func("Status of task \"%s\" is 'Running', Can not backtrace!\n",
|
||||
taskname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
getPLSfromCtx(task->task_stack, &PC, &LR, &SP);
|
||||
|
||||
print_func("TaskName : %s\n", taskname);
|
||||
print_func("========== Call stack ==========\r\n");
|
||||
for (lvl = 0; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&SP, &PC, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_func("========== End ==========\r\n");
|
||||
return lvl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
#define REG_NAME_WIDTH 7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* saved in assembler */
|
||||
int R0;
|
||||
int R1;
|
||||
int R2;
|
||||
int R3;
|
||||
int R4;
|
||||
int R5;
|
||||
int R6;
|
||||
int R7;
|
||||
int R8;
|
||||
int R9;
|
||||
int R10;
|
||||
int R11;
|
||||
int R12;
|
||||
int LR; // Link Register (LR)
|
||||
int PC; // Program Counter (PC)
|
||||
int xPSR; // Program Status Registers
|
||||
int SP; // Stack Pointer
|
||||
int EXC_RETURN; // Exception Return
|
||||
int EXC_NUMBER; // Exception Num
|
||||
int PRIMASK; // Interrupt Mask
|
||||
int FAULTMASK; // Interrupt Mask
|
||||
int BASEPRI; // Interrupt Mask
|
||||
} PANIC_CONTEXT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int CFSR;
|
||||
int HFSR;
|
||||
int MMFAR;
|
||||
int BFAR;
|
||||
int AFSR;
|
||||
} FAULT_REGS;
|
||||
|
||||
void panicGetCtx(void *context, char **pPC, char **pLR, int **pSP)
|
||||
{
|
||||
PANIC_CONTEXT *arm_context = (PANIC_CONTEXT *)context;
|
||||
|
||||
*pSP = (int *)arm_context->SP;
|
||||
*pPC = (char *)arm_context->PC;
|
||||
*pLR = (char *)arm_context->LR;
|
||||
}
|
||||
|
||||
void panicShowRegs(void *context, int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int x;
|
||||
int *regs = (int *)context;
|
||||
char s_panic_regs[REG_NAME_WIDTH + 14];
|
||||
FAULT_REGS stFregs;
|
||||
/* PANIC_CONTEXT */
|
||||
char s_panic_ctx[] = "R0 "
|
||||
"R1 "
|
||||
"R2 "
|
||||
"R3 "
|
||||
"R4 "
|
||||
"R5 "
|
||||
"R6 "
|
||||
"R7 "
|
||||
"R8 "
|
||||
"R9 "
|
||||
"R10 "
|
||||
"R11 "
|
||||
"R12 "
|
||||
"LR "
|
||||
"PC "
|
||||
"xPSR "
|
||||
"SP "
|
||||
"EXC_RET"
|
||||
"EXC_NUM"
|
||||
"PRIMASK"
|
||||
"FLTMASK"
|
||||
"BASEPRI";
|
||||
/* FAULT_REGS */
|
||||
char s_panic_reg[] = "CFSR "
|
||||
"HFSR "
|
||||
"MMFAR "
|
||||
"BFAR "
|
||||
"AFSR ";
|
||||
|
||||
if (regs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
print_func("========== Regs info ==========\r\n");
|
||||
|
||||
/* show PANIC_CONTEXT */
|
||||
for (x = 0; x < sizeof(s_panic_ctx) / REG_NAME_WIDTH; x++) {
|
||||
memcpy(&s_panic_regs[0], &s_panic_ctx[x * REG_NAME_WIDTH],
|
||||
REG_NAME_WIDTH);
|
||||
memcpy(&s_panic_regs[REG_NAME_WIDTH], " 0x", 3);
|
||||
k_int2str(regs[x], &s_panic_regs[REG_NAME_WIDTH + 3]);
|
||||
s_panic_regs[REG_NAME_WIDTH + 11] = '\r';
|
||||
s_panic_regs[REG_NAME_WIDTH + 12] = '\n';
|
||||
s_panic_regs[REG_NAME_WIDTH + 13] = 0;
|
||||
print_func(s_panic_regs);
|
||||
}
|
||||
|
||||
/* show FAULT_REGS */
|
||||
stFregs.CFSR = (*((volatile int *)(0xE000ED28)));
|
||||
stFregs.HFSR = (*((volatile int *)(0xE000ED2C)));
|
||||
stFregs.MMFAR = (*((volatile int *)(0xE000ED34)));
|
||||
stFregs.BFAR = (*((volatile int *)(0xE000ED38)));
|
||||
stFregs.AFSR = (*((volatile int *)(0xE000ED3C)));
|
||||
for (x = 0; x < sizeof(stFregs) / sizeof(int); x++) {
|
||||
memcpy(&s_panic_regs[0], &s_panic_reg[x * REG_NAME_WIDTH],
|
||||
REG_NAME_WIDTH);
|
||||
memcpy(&s_panic_regs[REG_NAME_WIDTH], " 0x", 3);
|
||||
k_int2str(((int *)(&stFregs))[x], &s_panic_regs[REG_NAME_WIDTH + 3]);
|
||||
s_panic_regs[REG_NAME_WIDTH + 11] = '\r';
|
||||
s_panic_regs[REG_NAME_WIDTH + 12] = '\n';
|
||||
s_panic_regs[REG_NAME_WIDTH + 13] = 0;
|
||||
print_func(s_panic_regs);
|
||||
}
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_BACKTRACE > 0)
|
||||
/* backtrace start with PC and SP, find LR from stack memory
|
||||
return levels os callstack */
|
||||
int panicBacktraceCaller(char *PC, int *SP,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int *bt_sp;
|
||||
char *bt_pc;
|
||||
int lvl, ret;
|
||||
char s_panic_call[] = "backtrace : 0x \r\n";
|
||||
|
||||
/* caller must save LR in stack, so find LR from stack */
|
||||
|
||||
if (SP == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bt_sp = SP;
|
||||
bt_pc = LR_2_ADDR(PC);
|
||||
ret = -1;
|
||||
for (lvl = 0; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&bt_sp, &bt_pc, NULL);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret == 1) {
|
||||
/* assume right! print */
|
||||
k_int2str((int)PC, &s_panic_call[14]);
|
||||
if (print_func != NULL) {
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
bt_sp = SP;
|
||||
bt_pc = PC;
|
||||
ret = -1;
|
||||
for (lvl = 1; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&bt_sp, &bt_pc, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return lvl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* backtrace start with PC SP and LR */
|
||||
int panicBacktraceCallee(char *PC, int *SP, char *LR,
|
||||
int (*print_func)(const char *fmt, ...))
|
||||
{
|
||||
int *bt_sp;
|
||||
char *bt_pc;
|
||||
char *bt_lr;
|
||||
int lvl, ret;
|
||||
char s_panic_call[] = "backtrace : 0x \r\n";
|
||||
|
||||
if (SP == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Backtrace: assume ReturnAddr is saved in LR when exception */
|
||||
k_int2str((int)PC, &s_panic_call[14]);
|
||||
if (print_func != NULL) {
|
||||
print_func(s_panic_call);
|
||||
}
|
||||
lvl = 1;
|
||||
bt_sp = SP;
|
||||
bt_pc = PC;
|
||||
bt_lr = LR;
|
||||
ret = backtraceFromLR(&bt_sp, &bt_pc, bt_lr, print_func);
|
||||
if (ret == 0) {
|
||||
for (; lvl < BACK_TRACE_LIMIT; lvl++) {
|
||||
ret = backtraceFromStack(&bt_sp, &bt_pc, print_func);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lvl;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
154
Living_SDK/platform/arch/arm/armv7m/common/panic_gcc.S
Normal file
154
Living_SDK/platform/arch/arm/armv7m/common/panic_gcc.S
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
#include "k_config.h"
|
||||
#include "k_dftdbg_config.h"
|
||||
|
||||
@******************************************************************************
|
||||
@ EQUATES
|
||||
@******************************************************************************
|
||||
.equ CONTEXT_REGION, 88 @bigger than sizeof(PANIC_CONTEXT)
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
|
||||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
.extern panicHandler
|
||||
.extern g_crash_steps
|
||||
.extern _first_task_restore
|
||||
.extern panicRestoreCheck
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
.global HardFault_Handler
|
||||
.global MemManage_Handler
|
||||
.global BusFault_Handler
|
||||
.global UsageFault_Handler
|
||||
|
||||
@******************************************************************************
|
||||
@ FAULT FUNCTIONS
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
HardFault_Handler:
|
||||
.thumb_func
|
||||
MemManage_Handler:
|
||||
.thumb_func
|
||||
BusFault_Handler:
|
||||
.thumb_func
|
||||
UsageFault_Handler:
|
||||
PUSH {R1, LR}
|
||||
BL panicRestoreCheck
|
||||
POP {R1, LR}
|
||||
CBZ R0, unrecoverable_crash
|
||||
BL _first_task_restore
|
||||
|
||||
unrecoverable_crash:
|
||||
@check double crash
|
||||
LDR R1, =g_crash_steps
|
||||
LDR R2, [R1]
|
||||
ADD R3, R2, #1
|
||||
STR R3, [R1]
|
||||
CBZ R2, first_panic
|
||||
@return from exc to handle panic
|
||||
MRS R1, PSP
|
||||
AND R2, LR, #4 @EXC_RETURN:bit2, 0 MSP, 1 PSP
|
||||
CBNZ R2, double_panic
|
||||
MRS R1, MSP
|
||||
double_panic:
|
||||
LDR R0, =double_panic_entry
|
||||
STR R0, [R1, #24]
|
||||
LDR R0, [R1, #28]
|
||||
ORR R0, R0, #0x1000000
|
||||
STR R0, [R1, #28] @set thumb mode
|
||||
BX LR
|
||||
|
||||
double_panic_entry:
|
||||
MOV R0, #0 @double crash, do not save context
|
||||
BL panicHandler
|
||||
B .
|
||||
|
||||
first_panic:
|
||||
@R0 as PANIC_CONTEXT
|
||||
SUB R0, SP, #CONTEXT_REGION
|
||||
|
||||
@R1 as CONTEXT saved by hardware
|
||||
MRS R1, PSP
|
||||
AND R2, LR, #4 @EXC_RETURN:bit2, 0 MSP, 1 PSP
|
||||
CBNZ R2, context_save
|
||||
MRS R1, MSP
|
||||
context_save:
|
||||
|
||||
ADD R2, R0, #16
|
||||
STM R2!,{R4-R11} @ctx save, R4~R11
|
||||
|
||||
LDM R1, {R4-R11}
|
||||
STM R0, {R4-R7} @ctx save, R0~R3
|
||||
|
||||
STM R2!,{R8-R11} @ctx save, R12 LR PC xPSR
|
||||
|
||||
@xPSR[9] and EXC_RETURN[4] to determine whether
|
||||
@the previous top-of-stack was at offset 0x20, 0x24, 0x68, or0x6C
|
||||
ADD R4, R1, #0x20
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
AND R3, LR, #0x10 @EXC_RETURN:bit4, 0 floating, 1 non-floating
|
||||
CBNZ R3, check_aligner
|
||||
ADD R4, R4, #0x48
|
||||
check_aligner:
|
||||
#endif
|
||||
LDR R3, [R1, #28]
|
||||
AND R3, R3, #0x200 @xPSR:bit9, 0 no-aligner, 1 aligner
|
||||
CBZ R3, sp_save
|
||||
ADD R4, R4, #0x4
|
||||
sp_save:
|
||||
STM R2!,{R4} @ctx save, SP
|
||||
|
||||
MOV R4, LR
|
||||
STM R2!,{R4} @ctx save, EXC_RETURN
|
||||
|
||||
MRS R4, IPSR
|
||||
STM R2!,{R4} @ctx save, EXC_NUMBER
|
||||
|
||||
MRS R4, PRIMASK
|
||||
STM R2!,{R4} @ctx save, PRIMASK
|
||||
|
||||
MRS R4, FAULTMASK
|
||||
STM R2!,{R4} @ctx save, FAULTMASK
|
||||
|
||||
MRS R4, BASEPRI
|
||||
STM R2!,{R4} @ctx save, BASEPRI
|
||||
|
||||
@return from exc to handle panic
|
||||
STR R0, [R1, #0]
|
||||
LDR R0, =panic_entry
|
||||
STR R0, [R1, #24]
|
||||
LDR R0, [R1, #28]
|
||||
ORR R0, R0, #0x1000000
|
||||
STR R0, [R1, #28] @set thumb mode
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
panic_entry:
|
||||
#if (RHINO_CONFIG_PANIC_PRT_INT > 0)
|
||||
MRS R1, CONTROL
|
||||
MOVS R2, #2
|
||||
BICS R1, R2
|
||||
MSR CONTROL, R1
|
||||
ISB
|
||||
@printf use interrupt, so here enable it
|
||||
CPSIE I
|
||||
#endif
|
||||
MOV SP, R0
|
||||
BL panicHandler
|
||||
B .
|
||||
|
||||
#endif
|
||||
|
||||
.end
|
||||
|
||||
151
Living_SDK/platform/arch/arm/armv7m/common/panic_iccarm.S
Normal file
151
Living_SDK/platform/arch/arm/armv7m/common/panic_iccarm.S
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#include "k_config.h"
|
||||
#include "k_dftdbg_config.h"
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
CONTEXT_REGION EQU 88 ;bigger than sizeof(PANIC_CONTEXT)
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
SECTION .text:CODE(2)
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN panicHandler
|
||||
EXTERN g_crash_steps
|
||||
EXTERN _first_task_restore
|
||||
EXTERN panicRestoreCheck
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
PUBLIC HardFault_Handler
|
||||
PUBLIC MemManage_Handler
|
||||
PUBLIC BusFault_Handler
|
||||
PUBLIC UsageFault_Handler
|
||||
|
||||
;******************************************************************************
|
||||
; FAULT FUNCTIONS
|
||||
;******************************************************************************
|
||||
HardFault_Handler:
|
||||
MemManage_Handler:
|
||||
BusFault_Handler:
|
||||
UsageFault_Handler:
|
||||
PUSH {R1, LR}
|
||||
BL panicRestoreCheck
|
||||
POP {R1, LR}
|
||||
CBZ R0, unrecoverable_crash
|
||||
BL _first_task_restore
|
||||
|
||||
unrecoverable_crash:
|
||||
;check double crash
|
||||
LDR R1, =g_crash_steps
|
||||
LDR R2, [R1]
|
||||
ADD R3, R2, #1
|
||||
STR R3, [R1]
|
||||
CBZ R2, first_panic
|
||||
;return from exc to handle panic
|
||||
MRS R1, PSP
|
||||
AND R2, LR, #4 ;EXC_RETURN:bit2, 0 MSP, 1 PSP
|
||||
CBNZ R2, double_panic
|
||||
MRS R1, MSP
|
||||
double_panic:
|
||||
LDR R0, =double_panic_entry
|
||||
STR R0, [R1, #24]
|
||||
LDR R0, [R1, #28]
|
||||
ORR R0, R0, #0x1000000
|
||||
STR R0, [R1, #28] ;set thumb mode
|
||||
BX LR
|
||||
|
||||
double_panic_entry:
|
||||
MOV R0, #0 ;double crash, do not save context
|
||||
BL panicHandler
|
||||
B .
|
||||
|
||||
first_panic:
|
||||
;R0 as PANIC_CONTEXT
|
||||
SUB R0, SP, #CONTEXT_REGION
|
||||
|
||||
;R1 as CONTEXT saved by hardware
|
||||
MRS R1, PSP
|
||||
AND R2, LR, #4 ;EXC_RETURN:bit2, 0 MSP, 1 PSP
|
||||
CBNZ R2, context_save
|
||||
MRS R1, MSP
|
||||
context_save:
|
||||
|
||||
ADD R2, R0, #16
|
||||
STM R2!,{R4-R11} ;ctx save, R4~R11
|
||||
|
||||
LDM R1, {R4-R11}
|
||||
STM R0, {R4-R7} ;ctx save, R0~R3
|
||||
|
||||
STM R2!,{R8-R11} ;ctx save, R12 LR PC xPSR
|
||||
|
||||
;xPSR[9] and EXC_RETURN[4] to determine whether
|
||||
;the previous top-of-stack was at offset 0x20, 0x24, 0x68, or0x6C
|
||||
ADD R4, R1, #0x20
|
||||
#if defined(__ARMVFP__)
|
||||
AND R3, LR, #0x10 ;EXC_RETURN:bit4, 0 floating, 1 non-floating
|
||||
CBNZ R3, check_aligner
|
||||
ADD R4, R4, #0x48
|
||||
check_aligner:
|
||||
#endif
|
||||
LDR R3, [R1, #28]
|
||||
AND R3, R3, #0x200 ;xPSR:bit9, 0 no-aligner, 1 aligner
|
||||
CBZ R3, sp_save
|
||||
ADD R4, R4, #0x4
|
||||
sp_save:
|
||||
STM R2!,{R4} ;ctx save, SP
|
||||
|
||||
MOV R4, LR
|
||||
STM R2!,{R4} ;ctx save, EXC_RETURN
|
||||
|
||||
MRS R4, IPSR
|
||||
STM R2!,{R4} ;ctx save, EXC_NUMBER
|
||||
|
||||
MRS R4, PRIMASK
|
||||
STM R2!,{R4} ;ctx save, PRIMASK
|
||||
|
||||
MRS R4, FAULTMASK
|
||||
STM R2!,{R4} ;ctx save, FAULTMASK
|
||||
|
||||
MRS R4, BASEPRI
|
||||
STM R2!,{R4} ;ctx save, BASEPRI
|
||||
|
||||
;return from exc to handle panic
|
||||
STR R0, [R1, #0]
|
||||
LDR R0, =panic_entry
|
||||
STR R0, [R1, #24]
|
||||
LDR R0, [R1, #28]
|
||||
ORR R0, R0, #0x1000000
|
||||
STR R0, [R1, #28] ;set thumb mode
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
panic_entry:
|
||||
#if (RHINO_CONFIG_PANIC_PRT_INT > 0)
|
||||
MRS R1, CONTROL
|
||||
MOVS R2, #2
|
||||
BICS R1, R2
|
||||
MSR CONTROL, R1
|
||||
ISB
|
||||
;printf use interrupt, so here enable it
|
||||
CPSIE I
|
||||
#endif
|
||||
|
||||
MOV SP, R0
|
||||
BL panicHandler
|
||||
B .
|
||||
|
||||
#endif
|
||||
END
|
||||
|
||||
224
Living_SDK/platform/arch/arm/armv7m/common/panic_mpu.c
Normal file
224
Living_SDK/platform/arch/arm/armv7m/common/panic_mpu.c
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "panic_mpu.h"
|
||||
#include "k_compiler.h"
|
||||
#include "k_dbg_api.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned long start;
|
||||
unsigned long size;
|
||||
unsigned long mpusize;
|
||||
} mem_region_t;
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
|
||||
static void mpu_enable(void);
|
||||
static void mpu_disable(void);
|
||||
static void mpu_config_region(MPU_Region_Init_t *init);
|
||||
static unsigned int size_to_mpusize(unsigned int size);
|
||||
|
||||
/*
|
||||
* Func: mpu is valid in mcu
|
||||
* IN : none
|
||||
* Out : 0 -- valid; 1 -- invalid
|
||||
* */
|
||||
static unsigned int mpu_is_valid(void)
|
||||
{
|
||||
return ((MPU->type) & MPU_TYPE_DREGION_MASK == 0) ? 1: 0;
|
||||
}
|
||||
|
||||
static void mpu_enable(void)
|
||||
{
|
||||
MPU->ctrl = MPU_CTRL_ENABLE_MASK | MPU_CTRL_PRIVDEFENA_MASK;
|
||||
|
||||
/* Enable memory manage fault */
|
||||
*(SHCSR_M) |= (1<<16);
|
||||
|
||||
OS_DSB();
|
||||
OS_ISB();
|
||||
OS_DMB();
|
||||
}
|
||||
|
||||
static void mpu_disable(void)
|
||||
{
|
||||
MPU->ctrl = 0U;
|
||||
|
||||
OS_DSB();
|
||||
OS_ISB();
|
||||
OS_DMB();
|
||||
}
|
||||
|
||||
static void enable_region(mem_region_t *region, int rng_no,
|
||||
int subregion_disable, int ext_type,
|
||||
int access_permission, int disable_exec,
|
||||
int shareable, int cacheable, int bufferable)
|
||||
{
|
||||
MPU_Region_Init_t init;
|
||||
|
||||
init.range_no = rng_no;
|
||||
init.base_addr = region->start;
|
||||
init.size = region->mpusize;
|
||||
init.subregion_disable = subregion_disable;
|
||||
init.ext_type = ext_type;
|
||||
init.access_permission = access_permission;
|
||||
init.disable_exec = disable_exec;
|
||||
init.shareable = shareable;
|
||||
init.cacheable = cacheable;
|
||||
init.bufferable = bufferable;
|
||||
init.enable = 1;
|
||||
|
||||
mpu_config_region(&init);
|
||||
}
|
||||
|
||||
|
||||
static void mpu_config_region(MPU_Region_Init_t *init)
|
||||
{
|
||||
MPU->rnr = init->range_no;
|
||||
|
||||
if (init->enable) {
|
||||
MPU->rbar = init->base_addr;
|
||||
MPU->rasr = (init->disable_exec << MPU_RASR_XN_OFFSET
|
||||
| init->access_permission << MPU_RASR_AP_OFFSET
|
||||
| init->ext_type << MPU_RASR_TEX_OFFSET
|
||||
| init->shareable << MPU_RASR_S_OFFSET
|
||||
| init->cacheable << MPU_RASR_C_OFFSET
|
||||
| init->bufferable << MPU_RASR_B_OFFSET
|
||||
| init->subregion_disable << MPU_RASR_SRD_OFFSET
|
||||
| init->size << MPU_RASR_SIZE_OFFSET
|
||||
| init->enable << MPU_RASR_ENABLE_OFFSET);
|
||||
} else {
|
||||
MPU->rbar = 0;
|
||||
MPU->rasr = 0;
|
||||
}
|
||||
|
||||
OS_DSB();
|
||||
OS_ISB();
|
||||
OS_DMB();
|
||||
}
|
||||
|
||||
static unsigned int size_to_mpusize(unsigned int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 0x20: return MPU_REGION_SIZE_32B;
|
||||
case 0x40: return MPU_REGION_SIZE_64B;
|
||||
case 0x80: return MPU_REGION_SIZE_128B;
|
||||
case 0x100: return MPU_REGION_SIZE_256B;
|
||||
case 0x200: return MPU_REGION_SIZE_512B;
|
||||
case 0x400: return MPU_REGION_SIZE_1KB;
|
||||
case 0x800: return MPU_REGION_SIZE_2KB;
|
||||
case 0x1000: return MPU_REGION_SIZE_4KB;
|
||||
case 0x2000: return MPU_REGION_SIZE_8KB;
|
||||
case 0x4000: return MPU_REGION_SIZE_16KB;
|
||||
case 0x8000: return MPU_REGION_SIZE_32KB;
|
||||
case 0x10000: return MPU_REGION_SIZE_64KB;
|
||||
case 0x20000: return MPU_REGION_SIZE_128KB;
|
||||
case 0x40000: return MPU_REGION_SIZE_256KB;
|
||||
case 0x80000: return MPU_REGION_SIZE_512KB;
|
||||
case 0x100000: return MPU_REGION_SIZE_1MB;
|
||||
case 0x200000: return MPU_REGION_SIZE_2MB;
|
||||
case 0x400000: return MPU_REGION_SIZE_4MB;
|
||||
case 0x800000: return MPU_REGION_SIZE_8MB;
|
||||
case 0x1000000: return MPU_REGION_SIZE_16MB;
|
||||
case 0x2000000: return MPU_REGION_SIZE_32MB;
|
||||
case 0x4000000: return MPU_REGION_SIZE_64MB;
|
||||
case 0x8000000: return MPU_REGION_SIZE_128MB;
|
||||
case 0x10000000: return MPU_REGION_SIZE_256MB;
|
||||
case 0x20000000: return MPU_REGION_SIZE_512MB;
|
||||
case 0x40000000: return MPU_REGION_SIZE_1GB;
|
||||
case 0x80000000: return MPU_REGION_SIZE_2GB;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void mpu_set(unsigned long addr, unsigned long size, unsigned int mode)
|
||||
{
|
||||
mem_region_t region;
|
||||
|
||||
region.start = addr;
|
||||
region.size = size;
|
||||
region.mpusize = size_to_mpusize(region.size);
|
||||
|
||||
mpu_disable();
|
||||
|
||||
enable_region(®ion, 0, 0, 0, mode, 0, 0, 1, 1);
|
||||
|
||||
mpu_enable();
|
||||
}
|
||||
|
||||
static unsigned int mpu_check(unsigned long addr, unsigned long size)
|
||||
{
|
||||
if ((size < 0x20) || (size > 0x80000000)) {
|
||||
printf("mpu region size error\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mpu_is_valid() != 0) {
|
||||
printf("error:no mpu in mcu\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* set mpu region for memory unauthorized access check
|
||||
*
|
||||
* @param[in] addr_start monitor start addr
|
||||
* @param[in] addr_size monitor size
|
||||
* @param[in] mode prohibit access (0) or read only(>0)
|
||||
*/
|
||||
void debug_memory_access_err_check(unsigned long addr_start, unsigned long addr_size, unsigned int mode)
|
||||
{
|
||||
unsigned int mpu_region_type;
|
||||
|
||||
if (mpu_check(addr_start, addr_size) != 0)
|
||||
return;
|
||||
|
||||
if ((addr_start % addr_size) != 0)
|
||||
addr_start = (addr_start + (addr_size - 1)) & ~(addr_size - 1);
|
||||
|
||||
if (mode > 0) {
|
||||
mpu_region_type = MPU_AP_RO_NA;
|
||||
} else
|
||||
mpu_region_type = MPU_AP_NA_NA;
|
||||
|
||||
mpu_set(addr_start, addr_size, mpu_region_type);
|
||||
printf("mpu addr: 0x%x\n", addr_start);
|
||||
}
|
||||
|
||||
void debug_task_stack_ovf_check(char *task_name)
|
||||
{
|
||||
int ret;
|
||||
ktask_t *task;
|
||||
cpu_stack_t *task_stack_base;
|
||||
|
||||
if (task_name == NULL) {
|
||||
printf("error: task name invalid\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
task = krhino_task_find(task_name);
|
||||
if (task == NULL) {
|
||||
printf("error: task do not exist\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
task_stack_base = task->task_stack_base;
|
||||
if (task_stack_base == NULL) {
|
||||
printf("error: task_stack_base err\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
debug_memory_access_err_check((unsigned long)task_stack_base, 0x20, 1);
|
||||
}
|
||||
|
||||
void debug_check_mem_access_disable(void)
|
||||
{
|
||||
mpu_disable();
|
||||
}
|
||||
|
||||
#endif
|
||||
187
Living_SDK/platform/arch/arm/armv7m/common/panic_mpu.h
Normal file
187
Living_SDK/platform/arch/arm/armv7m/common/panic_mpu.h
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef MPU_H
|
||||
#define MPU_H
|
||||
|
||||
|
||||
typedef struct {
|
||||
// MPU type register
|
||||
unsigned int type;
|
||||
// MPU control register
|
||||
unsigned int ctrl;
|
||||
// MPU range number register
|
||||
unsigned int rnr;
|
||||
// MPU region base address register
|
||||
unsigned int rbar;
|
||||
// MPU region attribute and size register
|
||||
unsigned int rasr;
|
||||
// MPU alias registers
|
||||
unsigned int rbar_a1;
|
||||
unsigned int rasr_a1;
|
||||
unsigned int rbar_a2;
|
||||
unsigned int rasr_a2;
|
||||
unsigned int rbar_a3;
|
||||
unsigned int rasr_a3;
|
||||
} MPU_t;
|
||||
|
||||
|
||||
/* System Handler Control and State register */
|
||||
#define SHCSR_M ((unsigned int*)0xE000ED24UL)
|
||||
|
||||
/* MPU registers */
|
||||
|
||||
#define MPU_BASE (0xE000ED90UL)
|
||||
#define MPU ((MPU_t*)(MPU_BASE))
|
||||
|
||||
#define MPU_TYPE_IREGION_OFFSET (16U)
|
||||
|
||||
#define MPU_TYPE_IREGION_MASK (0xFFUL << MPU_TYPE_IREGION_OFFSET)
|
||||
|
||||
#define MPU_TYPE_DREGION_OFFSET (8U)
|
||||
|
||||
#define MPU_TYPE_DREGION_MASK (0xFFUL << MPU_TYPE_DREGION_OFFSET)
|
||||
|
||||
#define MPU_TYPE_SEPARATE_OFFSET (0U)
|
||||
|
||||
#define MPU_TYPE_SEPARATE_MASK (1UL)
|
||||
|
||||
#define MPU_CTRL_PRIVDEFENA_OFFSET (2U)
|
||||
|
||||
#define MPU_CTRL_PRIVDEFENA_MASK (1UL << MPU_CTRL_PRIVDEFENA_OFFSET)
|
||||
|
||||
#define MPU_CTRL_HFNMIENA_OFFSET (1U)
|
||||
|
||||
#define MPU_CTRL_HFNMIENA_MASK (1UL << MPU_CTRL_HFNMIENA_OFFSET)
|
||||
|
||||
#define MPU_CTRL_ENABLE_OFFSET (0U)
|
||||
|
||||
#define MPU_CTRL_ENABLE_MASK (1UL)
|
||||
|
||||
#define MPU_RNR_REGION_OFFSET (0U)
|
||||
|
||||
#define MPU_RNR_REGION_MASK (0xFFUL)
|
||||
|
||||
#define MPU_RBAR_ADDR_OFFSET (5U)
|
||||
|
||||
#define MPU_RBAR_ADDR_MASK (0x7FFFFFFUL << MPU_RBAR_ADDR_OFFSET)
|
||||
|
||||
#define MPU_RBAR_VALID_OFFSET (4U)
|
||||
|
||||
#define MPU_RBAR_VALID_MASK (1UL << MPU_RBAR_VALID_OFFSET)
|
||||
|
||||
#define MPU_RBAR_REGION_OFFSET (0U)
|
||||
|
||||
#define MPU_RBAR_REGION_MASK (0xFUL)
|
||||
|
||||
#define MPU_RASR_ATTRS_OFFSET (16U)
|
||||
|
||||
#define MPU_RASR_ATTRS_MASK (0xFFFFUL << MPU_RASR_ATTRS_OFFSET)
|
||||
|
||||
#define MPU_RASR_XN_OFFSET (28U)
|
||||
|
||||
#define MPU_RASR_XN_MASK (1UL << MPU_RASR_XN_OFFSET)
|
||||
|
||||
#define MPU_RASR_AP_OFFSET (24U)
|
||||
|
||||
#define MPU_RASR_AP_MASK (0x7UL << MPU_RASR_AP_OFFSET)
|
||||
|
||||
#define MPU_RASR_TEX_OFFSET (19U)
|
||||
|
||||
#define MPU_RASR_TEX_MASK (0x7UL << MPU_RASR_TEX_OFFSET)
|
||||
|
||||
#define MPU_RASR_S_OFFSET (18U)
|
||||
|
||||
#define MPU_RASR_S_MASK (1UL << MPU_RASR_S_OFFSET)
|
||||
|
||||
#define MPU_RASR_C_OFFSET (17U)
|
||||
|
||||
#define MPU_RASR_C_MASK (1UL << MPU_RASR_C_OFFSET)
|
||||
|
||||
#define MPU_RASR_B_OFFSET (16U)
|
||||
|
||||
#define MPU_RASR_B_MASK (1UL << MPU_RASR_B_OFFSET)
|
||||
|
||||
#define MPU_RASR_SRD_OFFSET (8U)
|
||||
|
||||
#define MPU_RASR_SRD_MASK (0xFFUL << MPU_RASR_SRD_OFFSET)
|
||||
|
||||
#define MPU_RASR_SIZE_OFFSET (1U)
|
||||
|
||||
#define MPU_RASR_SIZE_MASK (0x1FUL << MPU_RASR_SIZE_OFFSET)
|
||||
|
||||
#define MPU_RASR_ENABLE_OFFSET (0U)
|
||||
|
||||
#define MPU_RASR_ENABLE_MASK (1UL)
|
||||
|
||||
|
||||
/* MPU regions size */
|
||||
|
||||
#define MPU_REGION_SIZE_32B (0x04U)
|
||||
#define MPU_REGION_SIZE_64B (0x05U)
|
||||
#define MPU_REGION_SIZE_128B (0x06U)
|
||||
#define MPU_REGION_SIZE_256B (0x07U)
|
||||
#define MPU_REGION_SIZE_512B (0x08U)
|
||||
#define MPU_REGION_SIZE_1KB (0x09U)
|
||||
#define MPU_REGION_SIZE_2KB (0x0AU)
|
||||
#define MPU_REGION_SIZE_4KB (0x0BU)
|
||||
#define MPU_REGION_SIZE_8KB (0x0CU)
|
||||
#define MPU_REGION_SIZE_16KB (0x0DU)
|
||||
#define MPU_REGION_SIZE_32KB (0x0EU)
|
||||
#define MPU_REGION_SIZE_64KB (0x0FU)
|
||||
#define MPU_REGION_SIZE_128KB (0x10U)
|
||||
#define MPU_REGION_SIZE_256KB (0x11U)
|
||||
#define MPU_REGION_SIZE_512KB (0x12U)
|
||||
#define MPU_REGION_SIZE_1MB (0x13U)
|
||||
#define MPU_REGION_SIZE_2MB (0x14U)
|
||||
#define MPU_REGION_SIZE_4MB (0x15U)
|
||||
#define MPU_REGION_SIZE_8MB (0x16U)
|
||||
#define MPU_REGION_SIZE_16MB (0x17U)
|
||||
#define MPU_REGION_SIZE_32MB (0x18U)
|
||||
#define MPU_REGION_SIZE_64MB (0x19U)
|
||||
#define MPU_REGION_SIZE_128MB (0x1AU)
|
||||
#define MPU_REGION_SIZE_256MB (0x1BU)
|
||||
#define MPU_REGION_SIZE_512MB (0x1CU)
|
||||
#define MPU_REGION_SIZE_1GB (0x1DU)
|
||||
#define MPU_REGION_SIZE_2GB (0x1EU)
|
||||
#define MPU_REGION_SIZE_4GB (0x1FU)
|
||||
|
||||
#define MPU_AP_NA_NA (0x00U)
|
||||
#define MPU_AP_RW_NA (0x01U)
|
||||
#define MPU_AP_RW_RO (0x02U)
|
||||
#define MPU_AP_RW_RW (0x03U)
|
||||
#define MPU_AP_RESV (0x04U)
|
||||
#define MPU_AP_RO_NA (0x05U)
|
||||
#define MPU_AP_RO_RO (0x06U)
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned long base_addr;
|
||||
unsigned char range_no;
|
||||
unsigned char size;
|
||||
unsigned char ext_type;
|
||||
unsigned char access_permission;
|
||||
unsigned char disable_exec;
|
||||
unsigned char subregion_disable;
|
||||
unsigned char shareable;
|
||||
unsigned char cacheable;
|
||||
unsigned char bufferable;
|
||||
unsigned char enable;
|
||||
} MPU_Region_Init_t;
|
||||
|
||||
#if (RHINO_CONFIG_PANIC > 0)
|
||||
/**
|
||||
* set mpu region for memory unauthorized access check
|
||||
*
|
||||
* @param[in] addr_start monitor start addr
|
||||
* @param[in] addr_size monitor size
|
||||
* @param[in] mode prohibit access(0) or read only(>0)
|
||||
*/
|
||||
void debug_memory_access_err_check(unsigned long addr_start, unsigned long addr_size, unsigned int mode);
|
||||
void debug_task_stack_ovf_check(char *task_name);
|
||||
void debug_check_mem_access_disable(void);
|
||||
#endif
|
||||
|
||||
#endif // MPU_H
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/common/port.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/common/port.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
cpu_cpsr_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(cpu_cpsr_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() cpu_cpsr_t cpsr
|
||||
#define RHINO_CPU_INTRPT_DISABLE() do{cpsr = cpu_intrpt_save();}while(0)
|
||||
#define RHINO_CPU_INTRPT_ENABLE() do{cpu_intrpt_restore(cpsr);}while(0)
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
43
Living_SDK/platform/arch/arm/armv7m/common/port_c.c
Normal file
43
Living_SDK/platform/arch/arm/armv7m/common/port_c.c
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* task context saved & restore by hardware: */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* task context saved & restore by software: */
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + non-floating-point state + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/gcc/m3/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/gcc/m3/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/gcc/m3/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/gcc/m3/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
42
Living_SDK/platform/arch/arm/armv7m/gcc/m3/port_c.c
Normal file
42
Living_SDK/platform/arch/arm/armv7m/gcc/m3/port_c.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* task context saved & restore by hardware: */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
168
Living_SDK/platform/arch/arm/armv7m/gcc/m3/port_s.S
Normal file
168
Living_SDK/platform/arch/arm/armv7m/gcc/m3/port_s.S
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#include <k_config.h>
|
||||
|
||||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.extern krhino_stack_ovf_check
|
||||
.extern krhino_task_sched_stats_get
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
|
||||
.global PendSV_Handler
|
||||
.global _first_task_restore
|
||||
|
||||
@******************************************************************************
|
||||
@ EQUATES
|
||||
@******************************************************************************
|
||||
.equ SCB_ICSR, 0xE000ED04 @ Interrupt Control and State Register.
|
||||
.equ SCB_VTOR, 0xE000ED08 @ Vector Table Offset Register.
|
||||
.equ ICSR_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
.equ SHPR3_PRI_14, 0xE000ED22 @ System Handler Priority Register 3 (PendSV).
|
||||
.equ PRI_LVL_PENDSV, 0xFF @ PendSV priority level (lowest).
|
||||
.equ SHPR3_PRI_15, 0xE000ED23 @ System Handler Priority Register 3 (Systick).
|
||||
.equ PRI_LVL_SYSTICK, 0xFF @ SYstick priority level (lowest).
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ size_t cpu_intrpt_save(void);
|
||||
@ void cpu_intrpt_restore(size_t cpsr);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_intrpt_switch(void);
|
||||
@ void cpu_task_switch(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_first_task_start(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_first_task_start:
|
||||
@set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
@set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
@indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
@make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
@goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void krhino_pendsv_handler(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
@branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
@hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
@save context
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
@g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
.thumb_func
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
@R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
@restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
@return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
@hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
_first_task_restore:
|
||||
@set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
.end
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/gcc/m4/k_types.h
Executable file
25
Living_SDK/platform/arch/arm/armv7m/gcc/m4/k_types.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/gcc/m4/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/gcc/m4/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
67
Living_SDK/platform/arch/arm/armv7m/gcc/m4/port_c.c
Normal file
67
Living_SDK/platform/arch/arm/armv7m/gcc/m4/port_c.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
/* ARMCC || IAR || GNU */
|
||||
#define FPU_AVL ((defined(__CC_ARM) && defined(__TARGET_FPU_VFP)) \
|
||||
|| (defined(__ICCARM__) && defined(__ARMVFP__)) \
|
||||
|| (defined(__GNUC__) && defined(__VFP_FP__) && !defined(__SOFTFP__)))
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* Exception stack frame with non-floating-point state */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* in PendSV_Handler, D8~D15 is always saved & restroe */
|
||||
#if (FPU_AVL > 0)
|
||||
*(--stk) = (cpu_stack_t)0x31uL; /* S31 */
|
||||
*(--stk) = (cpu_stack_t)0x30uL; /* S30 */
|
||||
*(--stk) = (cpu_stack_t)0x29uL; /* S29 */
|
||||
*(--stk) = (cpu_stack_t)0x28uL; /* S28 */
|
||||
*(--stk) = (cpu_stack_t)0x27uL; /* S27 */
|
||||
*(--stk) = (cpu_stack_t)0x26uL; /* S26 */
|
||||
*(--stk) = (cpu_stack_t)0x25uL; /* S25 */
|
||||
*(--stk) = (cpu_stack_t)0x24uL; /* S24 */
|
||||
*(--stk) = (cpu_stack_t)0x23uL; /* S23 */
|
||||
*(--stk) = (cpu_stack_t)0x22uL; /* S22 */
|
||||
*(--stk) = (cpu_stack_t)0x21uL; /* S21 */
|
||||
*(--stk) = (cpu_stack_t)0x20uL; /* S20 */
|
||||
*(--stk) = (cpu_stack_t)0x19uL; /* S19 */
|
||||
*(--stk) = (cpu_stack_t)0x18uL; /* S18 */
|
||||
*(--stk) = (cpu_stack_t)0x17uL; /* S17 */
|
||||
*(--stk) = (cpu_stack_t)0x16uL; /* S16 */
|
||||
#endif
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + non-floating-point state + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
184
Living_SDK/platform/arch/arm/armv7m/gcc/m4/port_s.S
Normal file
184
Living_SDK/platform/arch/arm/armv7m/gcc/m4/port_s.S
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
#include <k_config.h>
|
||||
|
||||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.extern krhino_stack_ovf_check
|
||||
.extern krhino_task_sched_stats_get
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
|
||||
.global PendSV_Handler
|
||||
.global _first_task_restore
|
||||
|
||||
@******************************************************************************
|
||||
@ EQUATES
|
||||
@******************************************************************************
|
||||
.equ SCB_ICSR, 0xE000ED04 @ Interrupt Control and State Register.
|
||||
.equ SCB_VTOR, 0xE000ED08 @ Vector Table Offset Register.
|
||||
.equ ICSR_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
.equ SHPR3_PRI_14, 0xE000ED22 @ System Handler Priority Register 3 (PendSV).
|
||||
.equ PRI_LVL_PENDSV, 0xFF @ PendSV priority level (lowest).
|
||||
.equ SHPR3_PRI_15, 0xE000ED23 @ System Handler Priority Register 3 (Systick).
|
||||
.equ PRI_LVL_SYSTICK, 0xFF @ SYstick priority level (lowest).
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ size_t cpu_intrpt_save(void);
|
||||
@ void cpu_intrpt_restore(size_t cpsr);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_intrpt_switch(void);
|
||||
@ void cpu_task_switch(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_first_task_start(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_first_task_start:
|
||||
@set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
@set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
@indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
@make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
@goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void krhino_pendsv_handler(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
@branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
@hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
@save context
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@if the switchout task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VSTMDBEQ R0!, {D8 - D15}
|
||||
@hardware saved D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
@g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
.thumb_func
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
@R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
@restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@if the switchin task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VLDMIAEQ R0!, {D8 - D15}
|
||||
@hardware will restore D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
@return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
@hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
_first_task_restore:
|
||||
@set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
.end
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/gcc/m7/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/gcc/m7/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/gcc/m7/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/gcc/m7/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
67
Living_SDK/platform/arch/arm/armv7m/gcc/m7/port_c.c
Normal file
67
Living_SDK/platform/arch/arm/armv7m/gcc/m7/port_c.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
/* ARMCC || IAR || GNU */
|
||||
#define FPU_AVL ((defined(__CC_ARM) && defined(__TARGET_FPU_VFP)) \
|
||||
|| (defined(__ICCARM__) && defined(__ARMVFP__)) \
|
||||
|| (defined(__GNUC__) && defined(__VFP_FP__) && !defined(__SOFTFP__)))
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* Exception stack frame with non-floating-point state */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* in PendSV_Handler, D8~D15 is always saved & restroe */
|
||||
#if (FPU_AVL > 0)
|
||||
*(--stk) = (cpu_stack_t)0x31uL; /* S31 */
|
||||
*(--stk) = (cpu_stack_t)0x30uL; /* S30 */
|
||||
*(--stk) = (cpu_stack_t)0x29uL; /* S29 */
|
||||
*(--stk) = (cpu_stack_t)0x28uL; /* S28 */
|
||||
*(--stk) = (cpu_stack_t)0x27uL; /* S27 */
|
||||
*(--stk) = (cpu_stack_t)0x26uL; /* S26 */
|
||||
*(--stk) = (cpu_stack_t)0x25uL; /* S25 */
|
||||
*(--stk) = (cpu_stack_t)0x24uL; /* S24 */
|
||||
*(--stk) = (cpu_stack_t)0x23uL; /* S23 */
|
||||
*(--stk) = (cpu_stack_t)0x22uL; /* S22 */
|
||||
*(--stk) = (cpu_stack_t)0x21uL; /* S21 */
|
||||
*(--stk) = (cpu_stack_t)0x20uL; /* S20 */
|
||||
*(--stk) = (cpu_stack_t)0x19uL; /* S19 */
|
||||
*(--stk) = (cpu_stack_t)0x18uL; /* S18 */
|
||||
*(--stk) = (cpu_stack_t)0x17uL; /* S17 */
|
||||
*(--stk) = (cpu_stack_t)0x16uL; /* S16 */
|
||||
#endif
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + non-floating-point state + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
184
Living_SDK/platform/arch/arm/armv7m/gcc/m7/port_s.S
Normal file
184
Living_SDK/platform/arch/arm/armv7m/gcc/m7/port_s.S
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
#include <k_config.h>
|
||||
|
||||
@******************************************************************************
|
||||
@ EXTERN PARAMETERS
|
||||
@******************************************************************************
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.extern krhino_stack_ovf_check
|
||||
.extern krhino_task_sched_stats_get
|
||||
|
||||
@******************************************************************************
|
||||
@ EXPORT FUNCTIONS
|
||||
@******************************************************************************
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
|
||||
.global PendSV_Handler
|
||||
.global _first_task_restore
|
||||
|
||||
@******************************************************************************
|
||||
@ EQUATES
|
||||
@******************************************************************************
|
||||
.equ SCB_ICSR, 0xE000ED04 @ Interrupt Control and State Register.
|
||||
.equ SCB_VTOR, 0xE000ED08 @ Vector Table Offset Register.
|
||||
.equ ICSR_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
.equ SHPR3_PRI_14, 0xE000ED22 @ System Handler Priority Register 3 (PendSV).
|
||||
.equ PRI_LVL_PENDSV, 0xFF @ PendSV priority level (lowest).
|
||||
.equ SHPR3_PRI_15, 0xE000ED23 @ System Handler Priority Register 3 (Systick).
|
||||
.equ PRI_LVL_SYSTICK, 0xFF @ SYstick priority level (lowest).
|
||||
|
||||
@******************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@******************************************************************************
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ size_t cpu_intrpt_save(void);
|
||||
@ void cpu_intrpt_restore(size_t cpsr);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_intrpt_switch(void);
|
||||
@ void cpu_task_switch(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void cpu_first_task_start(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
cpu_first_task_start:
|
||||
@set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
@set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
@indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
@make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
@goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
@******************************************************************************
|
||||
@ Functions:
|
||||
@ void krhino_pendsv_handler(void);
|
||||
@******************************************************************************
|
||||
.thumb_func
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
@branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
@hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
@save context
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@if the switchout task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VSTMDBEQ R0!, {D8 - D15}
|
||||
@hardware saved D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
@g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
.thumb_func
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
@R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
@restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
@if the switchin task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VLDMIAEQ R0!, {D8 - D15}
|
||||
@hardware will restore D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
@return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
@hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
.thumb_func
|
||||
_first_task_restore:
|
||||
@set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
.end
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
42
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/port_c.c
Normal file
42
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/port_c.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* task context saved & restore by hardware: */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
160
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/port_s.S
Normal file
160
Living_SDK/platform/arch/arm/armv7m/iccarm/m3/port_s.S
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#include <k_config.h>
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN g_active_task
|
||||
EXTERN g_preferred_ready_task
|
||||
EXTERN krhino_stack_ovf_check
|
||||
EXTERN krhino_task_sched_stats_get
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
PUBLIC cpu_intrpt_save
|
||||
PUBLIC cpu_intrpt_restore
|
||||
PUBLIC cpu_task_switch
|
||||
PUBLIC cpu_intrpt_switch
|
||||
PUBLIC cpu_first_task_start
|
||||
PUBLIC _first_task_restore
|
||||
|
||||
PUBLIC PendSV_Handler
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14 EQU 0xE000ED22 ; System Handler Priority Register 3 (PendSV).
|
||||
PRI_LVL_PENDSV EQU 0xFF ; PendSV priority level (lowest).
|
||||
SHPR3_PRI_15 EQU 0xE000ED23 ; System Handler Priority Register 3 (SysTick).
|
||||
PRI_LVL_SYSTICK EQU 0xFF ; SYstick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
SECTION .text:CODE(2)
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start:
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
;set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
;branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
_first_task_restore:
|
||||
;set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
END
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
67
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/port_c.c
Normal file
67
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/port_c.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
/* ARMCC || IAR || GNU */
|
||||
#define FPU_AVL ((defined(__CC_ARM) && defined(__TARGET_FPU_VFP)) \
|
||||
|| (defined(__ICCARM__) && defined(__ARMVFP__)) \
|
||||
|| (defined(__GNUC__) && defined(__VFP_FP__) && !defined(__SOFTFP__)))
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* Exception stack frame with non-floating-point state */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* in PendSV_Handler, D8~D15 is always saved & restroe */
|
||||
#if (FPU_AVL > 0)
|
||||
*(--stk) = (cpu_stack_t)0x31uL; /* S31 */
|
||||
*(--stk) = (cpu_stack_t)0x30uL; /* S30 */
|
||||
*(--stk) = (cpu_stack_t)0x29uL; /* S29 */
|
||||
*(--stk) = (cpu_stack_t)0x28uL; /* S28 */
|
||||
*(--stk) = (cpu_stack_t)0x27uL; /* S27 */
|
||||
*(--stk) = (cpu_stack_t)0x26uL; /* S26 */
|
||||
*(--stk) = (cpu_stack_t)0x25uL; /* S25 */
|
||||
*(--stk) = (cpu_stack_t)0x24uL; /* S24 */
|
||||
*(--stk) = (cpu_stack_t)0x23uL; /* S23 */
|
||||
*(--stk) = (cpu_stack_t)0x22uL; /* S22 */
|
||||
*(--stk) = (cpu_stack_t)0x21uL; /* S21 */
|
||||
*(--stk) = (cpu_stack_t)0x20uL; /* S20 */
|
||||
*(--stk) = (cpu_stack_t)0x19uL; /* S19 */
|
||||
*(--stk) = (cpu_stack_t)0x18uL; /* S18 */
|
||||
*(--stk) = (cpu_stack_t)0x17uL; /* S17 */
|
||||
*(--stk) = (cpu_stack_t)0x16uL; /* S16 */
|
||||
#endif
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + non-floating-point state + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
176
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/port_s.S
Normal file
176
Living_SDK/platform/arch/arm/armv7m/iccarm/m4/port_s.S
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#include <k_config.h>
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN g_active_task
|
||||
EXTERN g_preferred_ready_task
|
||||
EXTERN krhino_stack_ovf_check
|
||||
EXTERN krhino_task_sched_stats_get
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
PUBLIC cpu_intrpt_save
|
||||
PUBLIC cpu_intrpt_restore
|
||||
PUBLIC cpu_task_switch
|
||||
PUBLIC cpu_intrpt_switch
|
||||
PUBLIC cpu_first_task_start
|
||||
PUBLIC _first_task_restore
|
||||
|
||||
PUBLIC PendSV_Handler
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14 EQU 0xE000ED22 ; System Handler Priority Register 3 (PendSV).
|
||||
PRI_LVL_PENDSV EQU 0xFF ; PendSV priority level (lowest).
|
||||
SHPR3_PRI_15 EQU 0xE000ED23 ; System Handler Priority Register 3 (SysTick).
|
||||
PRI_LVL_SYSTICK EQU 0xFF ; SYstick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
SECTION .text:CODE(2)
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start:
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
;set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
;branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
#if defined(__ARMVFP__)
|
||||
;if the switchout task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VSTMDBEQ R0!, {D8 - D15}
|
||||
;hardware saved D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
#if defined(__ARMVFP__)
|
||||
;if the switchin task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VLDMIAEQ R0!, {D8 - D15}
|
||||
;hardware will restore D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
_first_task_restore:
|
||||
;set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
END
|
||||
|
||||
25
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/k_types.h
Normal file
25
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/k_types.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
typedef uint32_t hr_timer_t;
|
||||
typedef uint32_t lr_timer_t;
|
||||
typedef uint32_t mutex_nested_t;
|
||||
typedef uint8_t suspend_nested_t;
|
||||
typedef uint64_t ctx_switch_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
26
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/port.h
Normal file
26
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/port.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t cpsr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size, void *arg, task_entry_t entry);
|
||||
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CPSR_ALLOC() size_t cpsr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { cpsr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(cpsr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
67
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/port_c.c
Normal file
67
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/port_c.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
/* ARMCC || IAR || GNU */
|
||||
#define FPU_AVL ((defined(__CC_ARM) && defined(__TARGET_FPU_VFP)) \
|
||||
|| (defined(__ICCARM__) && defined(__ARMVFP__)) \
|
||||
|| (defined(__GNUC__) && defined(__VFP_FP__) && !defined(__SOFTFP__)))
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
/* stack aligned by 8 byte */
|
||||
temp &= 0xfffffff8;
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
/* Exception stack frame with non-floating-point state */
|
||||
*(--stk) = (cpu_stack_t)0x01000000L; /* xPSR: EPSR.T = 1, thumb mode */
|
||||
*(--stk) = (cpu_stack_t)entry; /* Entry Point */
|
||||
*(--stk) = (cpu_stack_t)krhino_task_deathbed; /* R14 (LR) */
|
||||
*(--stk) = (cpu_stack_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (cpu_stack_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (cpu_stack_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (cpu_stack_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (cpu_stack_t)arg; /* R0 : argument */
|
||||
|
||||
/* in PendSV_Handler, D8~D15 is always saved & restroe */
|
||||
#if (FPU_AVL > 0)
|
||||
*(--stk) = (cpu_stack_t)0x31uL; /* S31 */
|
||||
*(--stk) = (cpu_stack_t)0x30uL; /* S30 */
|
||||
*(--stk) = (cpu_stack_t)0x29uL; /* S29 */
|
||||
*(--stk) = (cpu_stack_t)0x28uL; /* S28 */
|
||||
*(--stk) = (cpu_stack_t)0x27uL; /* S27 */
|
||||
*(--stk) = (cpu_stack_t)0x26uL; /* S26 */
|
||||
*(--stk) = (cpu_stack_t)0x25uL; /* S25 */
|
||||
*(--stk) = (cpu_stack_t)0x24uL; /* S24 */
|
||||
*(--stk) = (cpu_stack_t)0x23uL; /* S23 */
|
||||
*(--stk) = (cpu_stack_t)0x22uL; /* S22 */
|
||||
*(--stk) = (cpu_stack_t)0x21uL; /* S21 */
|
||||
*(--stk) = (cpu_stack_t)0x20uL; /* S20 */
|
||||
*(--stk) = (cpu_stack_t)0x19uL; /* S19 */
|
||||
*(--stk) = (cpu_stack_t)0x18uL; /* S18 */
|
||||
*(--stk) = (cpu_stack_t)0x17uL; /* S17 */
|
||||
*(--stk) = (cpu_stack_t)0x16uL; /* S16 */
|
||||
#endif
|
||||
|
||||
/* EXC_RETURN = 0xFFFFFFFDL
|
||||
Task begin state: Thread mode + non-floating-point state + PSP */
|
||||
*(--stk) = (cpu_stack_t)0xFFFFFFFDL;
|
||||
|
||||
*(--stk) = (cpu_stack_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (cpu_stack_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (cpu_stack_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (cpu_stack_t)0x08080808L; /* R8 */
|
||||
*(--stk) = (cpu_stack_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (cpu_stack_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (cpu_stack_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (cpu_stack_t)0x04040404L; /* R4 */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
176
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/port_s.S
Normal file
176
Living_SDK/platform/arch/arm/armv7m/iccarm/m7/port_s.S
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#include <k_config.h>
|
||||
|
||||
;******************************************************************************
|
||||
; EXTERN PARAMETERS
|
||||
;******************************************************************************
|
||||
EXTERN g_active_task
|
||||
EXTERN g_preferred_ready_task
|
||||
EXTERN krhino_stack_ovf_check
|
||||
EXTERN krhino_task_sched_stats_get
|
||||
|
||||
;******************************************************************************
|
||||
; EXPORT FUNCTIONS
|
||||
;******************************************************************************
|
||||
PUBLIC cpu_intrpt_save
|
||||
PUBLIC cpu_intrpt_restore
|
||||
PUBLIC cpu_task_switch
|
||||
PUBLIC cpu_intrpt_switch
|
||||
PUBLIC cpu_first_task_start
|
||||
PUBLIC _first_task_restore
|
||||
|
||||
PUBLIC PendSV_Handler
|
||||
|
||||
;******************************************************************************
|
||||
; EQUATES
|
||||
;******************************************************************************
|
||||
SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register.
|
||||
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register.
|
||||
ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
|
||||
|
||||
SHPR3_PRI_14 EQU 0xE000ED22 ; System Handler Priority Register 3 (PendSV).
|
||||
PRI_LVL_PENDSV EQU 0xFF ; PendSV priority level (lowest).
|
||||
SHPR3_PRI_15 EQU 0xE000ED23 ; System Handler Priority Register 3 (SysTick).
|
||||
PRI_LVL_SYSTICK EQU 0xFF ; SYstick priority level (lowest).
|
||||
|
||||
;******************************************************************************
|
||||
; CODE GENERATION DIRECTIVES
|
||||
;******************************************************************************
|
||||
SECTION .text:CODE(2)
|
||||
THUMB
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; size_t cpu_intrpt_save(void);
|
||||
; void cpu_intrpt_restore(size_t cpsr);
|
||||
;******************************************************************************
|
||||
cpu_intrpt_save:
|
||||
MRS R0, PRIMASK
|
||||
CPSID I
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_intrpt_switch(void);
|
||||
; void cpu_task_switch(void);
|
||||
;******************************************************************************
|
||||
cpu_task_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
cpu_intrpt_switch:
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void cpu_first_task_start(void);
|
||||
;******************************************************************************
|
||||
cpu_first_task_start:
|
||||
;set PendSV prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_14
|
||||
LDR R1, =PRI_LVL_PENDSV
|
||||
STRB R1, [R0]
|
||||
|
||||
;set Systick prority to the lowest
|
||||
LDR R0, =SHPR3_PRI_15
|
||||
LDR R1, =PRI_LVL_SYSTICK
|
||||
STRB R1, [R0]
|
||||
|
||||
;indicate PendSV_Handler branch to _pendsv_handler_nosave
|
||||
MOVS R0, #0
|
||||
MSR PSP, R0
|
||||
|
||||
;make PendSV exception pending
|
||||
LDR R0, =SCB_ICSR
|
||||
LDR R1, =ICSR_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
;goto PendSV_Handler
|
||||
CPSIE I
|
||||
B .
|
||||
|
||||
;******************************************************************************
|
||||
; Functions:
|
||||
; void krhino_pendsv_handler(void);
|
||||
;******************************************************************************
|
||||
PendSV_Handler:
|
||||
CPSID I
|
||||
MRS R0, PSP
|
||||
;branch if cpu_first_task_start
|
||||
CMP R0, #0
|
||||
BEQ _first_task_restore
|
||||
|
||||
;hardware saved R0~R3,R12,LR,PC,xPSR
|
||||
|
||||
;save context
|
||||
#if defined(__ARMVFP__)
|
||||
;if the switchout task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VSTMDBEQ R0!, {D8 - D15}
|
||||
;hardware saved D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
SUBS R0, R0, #0x24
|
||||
STM R0, {R4-R11, LR}
|
||||
|
||||
;g_active_task->task_stack = context region
|
||||
LDR R1, =g_active_task
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1]
|
||||
|
||||
#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
BL krhino_stack_ovf_check
|
||||
#endif
|
||||
#if (RHINO_CONFIG_SYS_STATS > 0)
|
||||
BL krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
_pendsv_handler_nosave:
|
||||
LDR R0, =g_active_task
|
||||
LDR R1, =g_preferred_ready_task
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
;R0 = g_active_task->task_stack = context region
|
||||
LDR R0, [R2]
|
||||
|
||||
;restore context
|
||||
LDM R0, {R4-R11, LR}
|
||||
ADDS R0, R0, #0x24
|
||||
|
||||
#if defined(__ARMVFP__)
|
||||
;if the switchin task use FPU, save the FPU regs
|
||||
TST LR, #0x10
|
||||
IT EQ
|
||||
VLDMIAEQ R0!, {D8 - D15}
|
||||
;hardware will restore D0~D7, FPSCR
|
||||
#endif
|
||||
|
||||
;return stack = PSP
|
||||
MSR PSP, R0
|
||||
|
||||
CPSIE I
|
||||
;hardware restore R0~R3,R12,LR,PC,xPSR
|
||||
BX LR
|
||||
|
||||
_first_task_restore:
|
||||
;set MSP to the base of system stack
|
||||
LDR R0, =SCB_VTOR
|
||||
LDR R0, [R0]
|
||||
LDR R0, [R0]
|
||||
MSR MSP, R0
|
||||
|
||||
B _pendsv_handler_nosave
|
||||
|
||||
END
|
||||
|
||||
32
Living_SDK/platform/arch/arm/armv7m/ucube.py
Normal file
32
Living_SDK/platform/arch/arm/armv7m/ucube.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
src = []
|
||||
|
||||
component = aos_arch_component('armv7m', src)
|
||||
component.add_sources('common/panic_c.c', 'common/port_c.c')
|
||||
component.add_global_includes('common/')
|
||||
|
||||
if aos_global_config.compiler == 'armcc':
|
||||
component.add_global_asflags('--cpreproc')
|
||||
component.add_sources('common/panic_armcc.S')
|
||||
if aos_global_config.arch == 'Cortex-M3':
|
||||
component.add_sources('armcc/m3/port_s.S')
|
||||
elif aos_global_config.arch == 'Cortex-M4':
|
||||
component.add_sources('armcc/m4/port_s.S')
|
||||
elif aos_global_config.arch == 'Cortex-M7':
|
||||
component.add_sources('armcc/m7/port_s.S')
|
||||
elif aos_global_config.compiler == 'iar':
|
||||
component.add_sources('common/panic_iccarm.S')
|
||||
if aos_global_config.arch == 'Cortex-M3':
|
||||
component.add_sources('iccarm/m3/port_s.S')
|
||||
elif aos_global_config.arch == 'Cortex-M4':
|
||||
component.add_sources('iccarm/m4/port_s.S')
|
||||
elif aos_global_config.arch == 'Cortex-M7':
|
||||
component.add_sources('iccarm/m7/port_s.S')
|
||||
else:
|
||||
component.add_sources('common/panic_gcc.S')
|
||||
if aos_global_config.arch == 'Cortex-M3':
|
||||
component.add_sources('gcc/m3/port_s.S')
|
||||
elif aos_global_config.arch == 'Cortex-M4':
|
||||
component.add_sources('gcc/m4/port_s.S')
|
||||
elif aos_global_config.arch == 'Cortex-M7':
|
||||
component.add_sources('gcc/m7/port_s.S')
|
||||
|
||||
103
Living_SDK/platform/arch/csky/cskyv2-l/ckcpu.h
Normal file
103
Living_SDK/platform/arch/csky/cskyv2-l/ckcpu.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef CKCPU_H
|
||||
#define CKCPU_H
|
||||
|
||||
.macro csky_cpu_initpsr
|
||||
mfcr a3, psr
|
||||
bseti a3, 8
|
||||
bseti a3, 5
|
||||
bseti a3, 31
|
||||
bseti a3, 30
|
||||
mtcr a3, psr
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_initnspsr
|
||||
mfcr a3, cr<0,3>
|
||||
bseti a3, 5
|
||||
bseti a3, 6
|
||||
bseti a3, 8
|
||||
bseti a3, 31
|
||||
mtcr a3, cr<0,3>
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_initvec vsrtable
|
||||
lrw a2, \vsrtable
|
||||
mtcr a2, vbr
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_initnsvec nsvsrtable
|
||||
/* setup initial security vector base table for interrupts and exceptions */
|
||||
lrw a2, \nsvsrtable
|
||||
mtcr a2, cr<1,0>
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_initstack stack
|
||||
/* initialize the normal stack pointer from the linker definition */
|
||||
lrw a3, \stack
|
||||
mov sp, a3
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_init_nor_stack _nor_stack
|
||||
/* initialize the normal stack pointer from the linker definition */
|
||||
lrw a3, \_nor_stack
|
||||
mtcr a3, cr<14,3>
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_init_ns_stack ns_stack
|
||||
/* initialize the normal stack pointer from the linker definition */
|
||||
lrw a3, \ns_stack
|
||||
mov sp, a3
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_init_nor_ns_stack _nor_ns_stack
|
||||
/* initialize the normal stack pointer from the linker definition */
|
||||
lrw a3, \_nor_ns_stack
|
||||
mtcr a3, cr<14,1>
|
||||
.endm
|
||||
|
||||
.macro csky_cpu_initfstack fstack
|
||||
/* initialize the fast interrupt stack pointer */
|
||||
psrset af
|
||||
lrw a3, \fstack
|
||||
mov sp, a3
|
||||
psrclr af
|
||||
.endm
|
||||
|
||||
.macro csky_bss_init sadr eadr
|
||||
lrw r7, \sadr /* get start of bss from linking script file */
|
||||
lrw r6, \eadr /* get end of bss from linking script file */
|
||||
subu r6, r7 /* calculate size of bss */
|
||||
lsri r6, r6, 2 /* size of whole words */
|
||||
cmpnei r6, 0
|
||||
bf .L_bss_init_end
|
||||
movi r5, 0 /* set zero value to write */
|
||||
|
||||
.L_bss_init_loop:
|
||||
stw r5, (r7) /* zero next word */
|
||||
addi r7, 4 /* increase bss pointer */
|
||||
subi r6, 1 /* decrease counter */
|
||||
cmpnei r6, 0
|
||||
bt .L_bss_init_loop /* repeat for all bss */
|
||||
|
||||
.L_bss_init_end:
|
||||
.endm
|
||||
|
||||
.macro csky_load_data saddr eaddr eeaddr
|
||||
lrw a3, \saddr /* get start of data from linking script file */
|
||||
lrw a1, \eaddr /* get end of data from linking script file */
|
||||
cmphs a3, a1 /* galculate size of data */
|
||||
lrw a2, \eeaddr /* get end of rodata from linking script file */
|
||||
.L_load_data:
|
||||
ld.w a0, (a2, 0) /* load data from flash */
|
||||
st.w a0, (a3, 0) /* store data to SSRAM */
|
||||
addi a3, 4 /* increase data pointer of flash */
|
||||
addi a2, 4 /* increase data pointer of SSRAM */
|
||||
cmphs a3, a1
|
||||
bf .L_load_data /* repeat for all data */
|
||||
.endm
|
||||
|
||||
#endif
|
||||
|
||||
93
Living_SDK/platform/arch/csky/cskyv2-l/cpu_impl.c
Executable file
93
Living_SDK/platform/arch/csky/cskyv2-l/cpu_impl.c
Executable file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <k_config.h>
|
||||
|
||||
#if (YUNOS_CONFIG_STACK_OVF_CHECK_HW != 0)
|
||||
void cpu_intrpt_stack_protect(void)
|
||||
{
|
||||
}
|
||||
|
||||
void task_stack_crash_warning(void)
|
||||
{
|
||||
printf("****The task stack base has been broken !!!****\n");
|
||||
}
|
||||
|
||||
void cpu_task_stack_protect(cpu_stack_t *base, size_t size)
|
||||
{
|
||||
uint32_t base_addr = (uint32_t)base;
|
||||
|
||||
int num_return = wp_register(base_addr, AWATCH, task_stack_crash_warning);
|
||||
if (num_return == 1) {
|
||||
wp_enable(1);
|
||||
} else if (num_return == 2 || num_return == -1) {
|
||||
wp_unregister(1);
|
||||
int number_tmp = wp_register(base_addr, AWATCH, task_stack_crash_warning);
|
||||
if (number_tmp == 1){
|
||||
wp_enable(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
|
||||
void csky_set_stackbound(void)
|
||||
{
|
||||
uint32_t size;
|
||||
cpu_stack_t *base;
|
||||
|
||||
ktask_t *get_task = (ktask_t *)g_active_task;
|
||||
|
||||
base = get_task->task_stack_base;
|
||||
size = get_task->stack_size;
|
||||
|
||||
asm volatile(
|
||||
"mfcr r9, cr<0, 4>\n\r"
|
||||
"bclri r9, 0\n\r"
|
||||
"mtcr r9, cr<0, 4>\n\r"
|
||||
"mtcr %0, cr<2, 4>\n\r"
|
||||
"lsli %1, %1, 2\n\r"
|
||||
"add %0, %0, %1\n\r"
|
||||
"mtcr %0, cr<1, 4>\n\r"
|
||||
::"r"(base), "r"(size):"r9");
|
||||
}
|
||||
|
||||
int stack_guard_save(void)
|
||||
{
|
||||
int value;
|
||||
|
||||
asm volatile(
|
||||
"mfcr %0, cr<0, 4>\n\t"
|
||||
"mov r0, %0\n\t"
|
||||
"bclri r0, 0\n\t"
|
||||
"mtcr r0, cr<0, 4>\n\t"
|
||||
:"=r"(value)
|
||||
::"r0");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void stack_guard_restore(int value)
|
||||
{
|
||||
asm volatile(
|
||||
"mtcr %0, cr<0, 4>\n\t"
|
||||
::"r"(value):
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
92
Living_SDK/platform/arch/csky/cskyv2-l/csky_sched.c
Executable file
92
Living_SDK/platform/arch/csky/cskyv2-l/csky_sched.c
Executable file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
#undef PSR_SP
|
||||
#define PSR_SP (1UL << 29)
|
||||
static ktask_t *tee_caller_task = NULL;
|
||||
|
||||
static inline uint32_t getcurrentpsr(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mfcr %0, psr \n"
|
||||
:"=r"(flags)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void clear_psr_sp(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"mfcr r0, psr \n"
|
||||
"bclri r0, 29 \n"
|
||||
"mtcr r0, psr \n"
|
||||
:
|
||||
:
|
||||
:"r0"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void set_psr_sp(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"mfcr r0, psr \n"
|
||||
"bseti r0, 29 \n"
|
||||
"mtcr r0, psr \n"
|
||||
:
|
||||
:
|
||||
:"r0"
|
||||
);
|
||||
}
|
||||
|
||||
void csky_get_tee_caller_task(void)
|
||||
{
|
||||
uint32_t temp_psr;
|
||||
|
||||
temp_psr = getcurrentpsr();
|
||||
if (temp_psr & PSR_SP) {
|
||||
tee_caller_task = (tee_caller_task == NULL) ? g_active_task[cpu_cur_get()] : tee_caller_task;
|
||||
}
|
||||
}
|
||||
|
||||
void csky_deal_tee_caller_task(void)
|
||||
{
|
||||
uint32_t temp_psr;
|
||||
|
||||
temp_psr = getcurrentpsr();
|
||||
if (temp_psr & PSR_SP) {
|
||||
if (tee_caller_task != NULL) {
|
||||
if (tee_caller_task == g_active_task[cpu_cur_get()]) {
|
||||
tee_caller_task = NULL;
|
||||
} else {
|
||||
clear_psr_sp();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tee_caller_task != NULL) {
|
||||
if (tee_caller_task == g_active_task[cpu_cur_get()]) {
|
||||
tee_caller_task = NULL;
|
||||
set_psr_sp();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Living_SDK/platform/arch/csky/cskyv2-l/cskyv2-l.mk
Normal file
2
Living_SDK/platform/arch/csky/cskyv2-l/cskyv2-l.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
NAME := cskyv2-l
|
||||
|
||||
111
Living_SDK/platform/arch/csky/cskyv2-l/dump_backtrace.c
Executable file
111
Living_SDK/platform/arch/csky/cskyv2-l/dump_backtrace.c
Executable file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <csi_config.h>
|
||||
|
||||
#ifdef CONFIG_BACKTRACE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <backtrace.h>
|
||||
|
||||
#define BT_SIZE 40
|
||||
void *g_bt_buffer[BT_SIZE];
|
||||
#define BT_STACK_SIZE 600
|
||||
int g_bt_stack[BT_STACK_SIZE / 4];
|
||||
char *g_dumpbuf = NULL;
|
||||
int g_dump_len = 0;
|
||||
int g_dump_max = 0;
|
||||
|
||||
void dump_backtrace(void)
|
||||
{
|
||||
int i;
|
||||
int nptr;
|
||||
|
||||
g_dump_len = 0;
|
||||
|
||||
nptr = backtrace(g_bt_buffer, BT_SIZE);
|
||||
|
||||
if (nptr <= 0) {
|
||||
printf("error: backtrace_symbols\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < nptr; i++) {
|
||||
if (g_dumpbuf == NULL) {
|
||||
printf("[<%p>]\n", g_bt_buffer[i]);
|
||||
} else {
|
||||
g_dump_len += snprintf(&g_dumpbuf[g_dump_len], g_dump_max - g_dump_len, "[<%p>]\n", g_bt_buffer[i]);
|
||||
|
||||
if (g_dump_len >= g_dump_max) {
|
||||
printf("error, user buffer no space \n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((naked))csky_show_backtrace(void *stack)
|
||||
{
|
||||
asm volatile(
|
||||
"subi sp, 68\n\t"
|
||||
"stm r0-r13, (sp)\n\t"
|
||||
"mtcr sp, cr<14, 1>\n\t"
|
||||
"stw r15, (sp, 56)\n\t"
|
||||
"mov sp, %0\n\t"
|
||||
|
||||
"lrw r0, g_bt_stack\n\t"
|
||||
"mov r1, sp\n\t"
|
||||
"sub r1, %1\n\t"
|
||||
"mov r2, %1\n\t"
|
||||
"mov r4, %1\n\t"
|
||||
"jbsr memcpy\n\t"
|
||||
|
||||
"ldw r8, (sp, 32)\n\t"
|
||||
"ldw r15, (sp, 64)\n\t"
|
||||
"subi sp, 16\n\t"
|
||||
"stw r8, (sp, 0)\n\t"
|
||||
"stw r15, (sp, 4)\n\t"
|
||||
"mov r8, sp\n\t"
|
||||
"jbsr dump_backtrace\n\t"
|
||||
|
||||
"addi sp, 16\n\t"
|
||||
"lrw r1, g_bt_stack\n\t"
|
||||
"mov r0, sp\n\t"
|
||||
"sub r0, r4\n\t"
|
||||
"mov r2, r4\n\t"
|
||||
"jbsr memcpy\n\t"
|
||||
|
||||
"mfcr sp, cr<14, 1>\n\t"
|
||||
"ldw r15, (sp, 56)\n\t"
|
||||
"ldm r0-r13, (sp)\n\t"
|
||||
"addi sp, 68\n\t"
|
||||
"jmp r15\n\t"
|
||||
::"r"(stack), "r"(BT_STACK_SIZE):);
|
||||
|
||||
}
|
||||
|
||||
int csky_task_backtrace(void *stack, void *buf, int len)
|
||||
{
|
||||
g_dumpbuf = buf;
|
||||
g_dump_max = len;
|
||||
|
||||
csky_show_backtrace(stack);
|
||||
|
||||
return g_dump_len;
|
||||
}
|
||||
#endif
|
||||
162
Living_SDK/platform/arch/csky/cskyv2-l/entry.S
Executable file
162
Living_SDK/platform/arch/csky/cskyv2-l/entry.S
Executable file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <k_config.h>
|
||||
#include <csi_config.h>
|
||||
|
||||
.global watchpoint_handler
|
||||
|
||||
.import g_top_irqstack
|
||||
.import csky_get_tee_caller_task
|
||||
.import csky_deal_tee_caller_task
|
||||
.import g_irqvector
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void watchpoint_handler(void);
|
||||
* watchpoint exception handler
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(CONFIG_WATCHPOINT)
|
||||
.align 2
|
||||
.globl watchpoint_handler
|
||||
.type watchpoint_handler, %function
|
||||
watchpoint_handler:
|
||||
psrset ee
|
||||
subi sp, 72
|
||||
stm r0-r15, (sp)
|
||||
addi r0, sp, 72
|
||||
stw r0, (sp, 56)
|
||||
mfcr r0, epsr
|
||||
stw r0, (sp, 64)
|
||||
mfcr r0, epc
|
||||
stw r0, (sp, 68)
|
||||
|
||||
ldh r0, (r0)
|
||||
cmpnei r0, 0
|
||||
lrw r0, wp_get_callback
|
||||
lrw r1, trap_c
|
||||
movf r0, r1
|
||||
jsr r0
|
||||
|
||||
mov r0, sp
|
||||
|
||||
ldw r0, (sp, 64)
|
||||
mtcr r0, epsr
|
||||
ldw r0, (sp, 68)
|
||||
mtcr r0, epc
|
||||
|
||||
ldm r0-r13, (sp)
|
||||
ldw r15, (sp, 60)
|
||||
ldw sp, (sp, 56)
|
||||
|
||||
rte
|
||||
|
||||
.size watchpoint_handler, . - watchpoint_handler
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void NOVIC_IRQ_Default_Handler(void);
|
||||
* novic default irq entry
|
||||
******************************************************************************/
|
||||
|
||||
.global NOVIC_IRQ_Default_Handler
|
||||
.type NOVIC_IRQ_Default_Handler, %function
|
||||
NOVIC_IRQ_Default_Handler:
|
||||
psrset ee
|
||||
#ifndef CONFIG_HAVE_VIC
|
||||
subi sp, 68
|
||||
stm r0-r13, (sp)
|
||||
stw r15, (sp, 56)
|
||||
mfcr r0, epsr
|
||||
stw r0, (sp, 60)
|
||||
mfcr r0, epc
|
||||
stw r0, (sp, 64)
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
lrw r0, g_top_irqstack
|
||||
mtcr r0, cr<1, 4>
|
||||
subi r0, CONFIG_ARCH_INTERRUPTSTACK
|
||||
mtcr r0, cr<2, 4>
|
||||
|
||||
mfcr r0, cr<0, 4>
|
||||
bseti r0, 0
|
||||
bseti r0, 1
|
||||
mtcr r0, cr<0, 4>
|
||||
#endif
|
||||
|
||||
lrw r0, g_active_task
|
||||
ldw r0, (r0)
|
||||
stw sp, (r0)
|
||||
|
||||
lrw sp, g_top_irqstack
|
||||
|
||||
#if (YUNOS_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
jbsr krhino_stack_ovf_check
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SUPPORT_REE_SCHEDULE_IN_TEE
|
||||
jbsr csky_get_tee_caller_task
|
||||
#endif
|
||||
|
||||
lrw r1, g_irqvector
|
||||
mfcr r0, psr
|
||||
lsri r0, 16
|
||||
sextb r0
|
||||
subi r0, 32
|
||||
lsli r0, 2
|
||||
add r1, r0
|
||||
ldw r5, (r1)
|
||||
lsri r0, 2
|
||||
mov r4, r0
|
||||
jbsr krhino_intrpt_enter_hook
|
||||
mov r0, r4
|
||||
jsr r5
|
||||
mov r0, r4
|
||||
jbsr krhino_intrpt_exit_hook
|
||||
|
||||
#ifdef CONFIG_SUPPORT_REE_SCHEDULE_IN_TEE
|
||||
jbsr csky_deal_tee_caller_task
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
jbsr csky_set_stackbound
|
||||
#endif
|
||||
|
||||
lrw r0, g_active_task
|
||||
ldw r0, (r0)
|
||||
ldw sp, (r0)
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
mfcr r3, cr<0, 4>
|
||||
bseti r3, 0
|
||||
bseti r3, 1
|
||||
mtcr r3, cr<0, 4>
|
||||
#endif
|
||||
|
||||
ldw r0, (sp, 64)
|
||||
mtcr r0, epc
|
||||
ldw r0, (sp, 60)
|
||||
mtcr r0, epsr
|
||||
ldm r0-r13, (sp)
|
||||
ldw r15, (sp, 56)
|
||||
addi sp, 68
|
||||
|
||||
rte
|
||||
#else /* CONFIG_HAVE_VIC */
|
||||
bkpt
|
||||
#endif /* CONFIG_HAVE_VIC */
|
||||
194
Living_SDK/platform/arch/csky/cskyv2-l/k_config.h
Executable file
194
Living_SDK/platform/arch/csky/cskyv2-l/k_config.h
Executable file
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/* chip level conf */
|
||||
#ifndef RHINO_CONFIG_LITTLE_ENDIAN
|
||||
#define RHINO_CONFIG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_CPU_STACK_DOWN
|
||||
#define RHINO_CONFIG_CPU_STACK_DOWN 1
|
||||
#endif
|
||||
|
||||
/* kernel feature conf */
|
||||
#ifndef RHINO_CONFIG_SEM
|
||||
#define RHINO_CONFIG_SEM 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_QUEUE
|
||||
#define RHINO_CONFIG_QUEUE 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TASK_SEM
|
||||
#define RHINO_CONFIG_TASK_SEM 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_EVENT_FLAG
|
||||
#define RHINO_CONFIG_EVENT_FLAG 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TIMER
|
||||
#define RHINO_CONFIG_TIMER 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_BUF_QUEUE
|
||||
#define RHINO_CONFIG_BUF_QUEUE 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_MM_BLK
|
||||
#define RHINO_CONFIG_MM_BLK 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_KOBJ_SET
|
||||
#define RHINO_CONFIG_KOBJ_SET 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
|
||||
#define RHINO_CONFIG_TICKS_PER_SECOND 100
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY
|
||||
#define RHINO_CONFIG_TICK_HEAD_ARRAY 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_SCHED_RR
|
||||
#define RHINO_CONFIG_SCHED_RR 0
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TIMER_RATE
|
||||
#define RHINO_CONFIG_TIMER_RATE 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TIMER
|
||||
#define RHINO_CONFIG_TIMER 1
|
||||
#endif
|
||||
*/
|
||||
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
|
||||
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1
|
||||
#endif
|
||||
|
||||
/* kernel task conf */
|
||||
#ifndef RHINO_CONFIG_TASK_SUSPEND
|
||||
#define RHINO_CONFIG_TASK_SUSPEND 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TASK_INFO
|
||||
#define RHINO_CONFIG_TASK_INFO 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TASK_DEL
|
||||
#define RHINO_CONFIG_TASK_DEL 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
|
||||
#define RHINO_CONFIG_TASK_WAIT_ABORT 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
|
||||
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_SCHED_RR
|
||||
#define RHINO_CONFIG_SCHED_RR 0
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
|
||||
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_PRI_MAX
|
||||
#define RHINO_CONFIG_PRI_MAX 62
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_USER_PRI_MAX
|
||||
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
|
||||
#endif
|
||||
|
||||
/* kernel workqueue conf */
|
||||
#ifndef RHINO_CONFIG_WORKQUEUE
|
||||
#define RHINO_CONFIG_WORKQUEUE 0
|
||||
#endif
|
||||
|
||||
/* kernel timer&tick conf */
|
||||
#ifndef RHINO_CONFIG_HW_COUNT
|
||||
#define RHINO_CONFIG_HW_COUNT 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TICK_TASK
|
||||
#define RHINO_CONFIG_TICK_TASK 1
|
||||
#endif
|
||||
#if (RHINO_CONFIG_TICK_TASK > 0)
|
||||
#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE
|
||||
#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TICK_TASK_PRI
|
||||
#define RHINO_CONFIG_TICK_TASK_PRI 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
|
||||
#define RHINO_CONFIG_TICKS_PER_SECOND 100
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
|
||||
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 200
|
||||
#endif
|
||||
|
||||
#ifndef RHINO_CONFIG_TIMER_RATE
|
||||
#define RHINO_CONFIG_TIMER_RATE 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
|
||||
#define RHINO_CONFIG_TIMER_TASK_PRI 5
|
||||
#endif
|
||||
|
||||
/* kernel intrpt conf */
|
||||
#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET
|
||||
#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
|
||||
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL
|
||||
#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_INTRPT_GUARD
|
||||
#define RHINO_CONFIG_INTRPT_GUARD 0
|
||||
#endif
|
||||
|
||||
/* kernel dyn alloc conf */
|
||||
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
|
||||
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1
|
||||
#endif
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG
|
||||
#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
|
||||
#define RHINO_CONFIG_K_DYN_TASK_STACK 256
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
|
||||
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI RHINO_CONFIG_USER_PRI_MAX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* kernel idle conf */
|
||||
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
|
||||
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 100
|
||||
#endif
|
||||
|
||||
/* kernel hook conf */
|
||||
#ifndef RHINO_CONFIG_USER_HOOK
|
||||
#define RHINO_CONFIG_USER_HOOK 0
|
||||
#endif
|
||||
|
||||
/* kernel stats conf */
|
||||
#ifndef RHINO_CONFIG_SYSTEM_STATS
|
||||
#define RHINO_CONFIG_SYSTEM_STATS 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS
|
||||
#define RHINO_CONFIG_DISABLE_SCHED_STATS 0
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS
|
||||
#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_CPU_USAGE_STATS
|
||||
#define RHINO_CONFIG_CPU_USAGE_STATS 1
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI
|
||||
#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2)
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_TASK_SCHED_STATS
|
||||
#define RHINO_CONFIG_TASK_SCHED_STATS 0
|
||||
#endif
|
||||
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK
|
||||
#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
||||
27
Living_SDK/platform/arch/csky/cskyv2-l/k_types.h
Executable file
27
Living_SDK/platform/arch/csky/cskyv2-l/k_types.h
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */
|
||||
#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE
|
||||
#define RHINO_MM_FREE_DYE 0xABABABAB
|
||||
#define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */
|
||||
|
||||
typedef char name_t;
|
||||
typedef uint32_t sem_count_t;
|
||||
typedef uint32_t cpu_stack_t;
|
||||
/* you may change here depend on your hardware timer */
|
||||
typedef uint32_t hr_timer_t; /* 32 bit or 64 bit unsigned value */
|
||||
typedef uint32_t lr_timer_t; /* 32 bit or 64 bit unsigned value */
|
||||
typedef uint32_t mutex_nested_t; /* 8 bit or 16bit or 32bit unsigned value */
|
||||
typedef uint8_t suspend_nested_t; /* 8 bit normally */
|
||||
typedef uint64_t ctx_switch_t; /* 32 bit or 64 bit unsigned value */
|
||||
typedef int32_t ssize_t;
|
||||
typedef uint32_t cpu_cpsr_t;
|
||||
|
||||
#endif /* TYPES_H */
|
||||
|
||||
29
Living_SDK/platform/arch/csky/cskyv2-l/port.h
Normal file
29
Living_SDK/platform/arch/csky/cskyv2-l/port.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
#include <k_types.h>
|
||||
#include <k_task.h>
|
||||
|
||||
size_t cpu_intrpt_save(void);
|
||||
void cpu_intrpt_restore(size_t psr);
|
||||
void cpu_intrpt_switch(void);
|
||||
void cpu_task_switch(void);
|
||||
void cpu_first_task_start(void);
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *base, size_t size,
|
||||
void *arg, task_entry_t entry);
|
||||
RHINO_INLINE uint8_t cpu_cur_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#define CPSR_ALLOC() size_t psr
|
||||
|
||||
#define RHINO_CPU_INTRPT_DISABLE() { psr = cpu_intrpt_save(); }
|
||||
#define RHINO_CPU_INTRPT_ENABLE() { cpu_intrpt_restore(psr); }
|
||||
|
||||
#endif /* PORT_H */
|
||||
|
||||
53
Living_SDK/platform/arch/csky/cskyv2-l/port_c.c
Executable file
53
Living_SDK/platform/arch/csky/cskyv2-l/port_c.c
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
|
||||
void *cpu_task_stack_init(cpu_stack_t *stack_base, size_t stack_size,
|
||||
void *arg, task_entry_t entry)
|
||||
{
|
||||
cpu_stack_t *stk;
|
||||
uint32_t temp = (uint32_t)(stack_base + stack_size);
|
||||
|
||||
temp &= 0xfffffffc;
|
||||
|
||||
stk = (cpu_stack_t *)temp;
|
||||
|
||||
*(--stk) = (uint32_t)entry; /* entry point */
|
||||
#ifndef CONFIG_SYSTEM_SECURE
|
||||
*(--stk) = (uint32_t)0x80000140L; /* PSR */
|
||||
#else
|
||||
*(--stk) = (uint32_t)0xe0000140L; /* PSR */
|
||||
#endif
|
||||
*(--stk) = (uint32_t)krhino_task_deathbed; /* R15 (LR) */
|
||||
*(--stk) = (uint32_t)0x13131313L; /* R13 */
|
||||
*(--stk) = (uint32_t)0x12121212L; /* R12 */
|
||||
*(--stk) = (uint32_t)0x11111111L; /* R11 */
|
||||
*(--stk) = (uint32_t)0x10101010L; /* R10 */
|
||||
*(--stk) = (uint32_t)0x09090909L; /* R9 */
|
||||
*(--stk) = (uint32_t)0x00000000L; /* R8 */
|
||||
*(--stk) = (uint32_t)0x07070707L; /* R7 */
|
||||
*(--stk) = (uint32_t)0x06060606L; /* R6 */
|
||||
*(--stk) = (uint32_t)0x05050505L; /* R5 */
|
||||
*(--stk) = (uint32_t)0x04040404L; /* R4 */
|
||||
*(--stk) = (uint32_t)0x03030303L; /* R3 */
|
||||
*(--stk) = (uint32_t)0x02020202L; /* R2 */
|
||||
*(--stk) = (uint32_t)0x01010101L; /* R1 */
|
||||
*(--stk) = (uint32_t)arg; /* R0 : argument */
|
||||
|
||||
return stk;
|
||||
}
|
||||
|
||||
148
Living_SDK/platform/arch/csky/cskyv2-l/port_s.S
Executable file
148
Living_SDK/platform/arch/csky/cskyv2-l/port_s.S
Executable file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <k_config.h>
|
||||
|
||||
#define VIC_TSPDR 0XE000EC08
|
||||
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.extern krhino_task_sched_stats_get
|
||||
.extern krhino_stack_ovf_check
|
||||
/******************************************************************************
|
||||
* EXPORT FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
.global tspend_handler
|
||||
|
||||
/******************************************************************************
|
||||
* EQUATES
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* CODE GENERATION DIRECTIVES
|
||||
******************************************************************************/
|
||||
|
||||
.text
|
||||
.align 2
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* size_t cpu_intrpt_save(void);
|
||||
* void cpu_intrpt_restore(size_t psr);
|
||||
******************************************************************************/
|
||||
|
||||
.type cpu_intrpt_save, %function
|
||||
cpu_intrpt_save:
|
||||
mfcr r0, psr
|
||||
psrclr ie
|
||||
rts
|
||||
|
||||
.type cpu_intrpt_restore, %function
|
||||
cpu_intrpt_restore:
|
||||
mtcr r0, psr
|
||||
rts
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void cpu_intrpt_switch(void);
|
||||
* void cpu_task_switch(void);
|
||||
******************************************************************************/
|
||||
|
||||
.type cpu_task_switch, %function
|
||||
cpu_task_switch:
|
||||
lrw r0, VIC_TSPDR
|
||||
bgeni r1, 0
|
||||
stw r1, (r0)
|
||||
rts
|
||||
|
||||
.type cpu_intrpt_switch, %function
|
||||
cpu_intrpt_switch:
|
||||
lrw r0, VIC_TSPDR
|
||||
bgeni r1, 0
|
||||
stw r1, (r0)
|
||||
rts
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void cpu_first_task_start(void);
|
||||
******************************************************************************/
|
||||
|
||||
.type cpu_first_task_start, %function
|
||||
cpu_first_task_start:
|
||||
psrclr ie
|
||||
jbr __tspend_handler_nosave
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void __task_switch(void);
|
||||
******************************************************************************/
|
||||
|
||||
.type tspend_handler, %function
|
||||
tspend_handler:
|
||||
subi sp, 68
|
||||
stm r0-r13, (sp)
|
||||
stw r15, (sp, 56)
|
||||
mfcr r0, epsr
|
||||
stw r0, (sp, 60)
|
||||
mfcr r0, epc
|
||||
stw r0, (sp, 64)
|
||||
|
||||
lrw r1, g_active_task
|
||||
ldw r1, (r1)
|
||||
stw sp, (r1)
|
||||
|
||||
#if (YUNOS_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
jbsr krhino_stack_ovf_check
|
||||
#endif
|
||||
|
||||
#if (YUNOS_CONFIG_TASK_SCHED_STATS > 0)
|
||||
jbsr krhino_task_sched_stats_get
|
||||
#endif
|
||||
|
||||
__tspend_handler_nosave:
|
||||
lrw r4, g_active_task
|
||||
lrw r5, g_preferred_ready_task
|
||||
ldw r6, (r5)
|
||||
stw r6, (r4)
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
jbsr csky_set_stackbound
|
||||
#endif
|
||||
|
||||
ldw sp, (r6)
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
mfcr r3, cr<0, 4>
|
||||
bseti r3, 0
|
||||
bseti r3, 1
|
||||
mtcr r3, cr<0, 4>
|
||||
#endif
|
||||
|
||||
ldw r0, (sp, 64)
|
||||
mtcr r0, epc
|
||||
ldw r0, (sp, 60)
|
||||
mtcr r0, epsr
|
||||
ldw r15, (sp, 56)
|
||||
ldm r0-r13, (sp)
|
||||
addi sp, 68
|
||||
rte
|
||||
|
||||
166
Living_SDK/platform/arch/csky/cskyv2-l/port_s_novic.S
Executable file
166
Living_SDK/platform/arch/csky/cskyv2-l/port_s_novic.S
Executable file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <k_config.h>
|
||||
#include <csi_config.h>
|
||||
|
||||
.extern g_active_task
|
||||
.extern g_preferred_ready_task
|
||||
.import csky_deal_tee_caller_task
|
||||
.import csky_get_tee_caller_task
|
||||
|
||||
/******************************************************************************
|
||||
* EXPORT FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
.global cpu_intrpt_save
|
||||
.global cpu_intrpt_restore
|
||||
.global cpu_task_switch
|
||||
.global cpu_intrpt_switch
|
||||
.global cpu_first_task_start
|
||||
.global tspend_handler
|
||||
|
||||
/******************************************************************************
|
||||
* EQUATES
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* CODE GENERATION DIRECTIVES
|
||||
******************************************************************************/
|
||||
|
||||
.text
|
||||
.align 2
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* size_t cpu_intrpt_save(void);
|
||||
* void cpu_intrpt_restore(size_t psr);
|
||||
******************************************************************************/
|
||||
|
||||
.type cpu_intrpt_save, %function
|
||||
cpu_intrpt_save:
|
||||
mfcr r0, psr
|
||||
psrclr ie
|
||||
rts
|
||||
|
||||
.type cpu_intrpt_restore, %function
|
||||
cpu_intrpt_restore:
|
||||
mtcr r0, psr
|
||||
rts
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void cpu_intrpt_switch(void);
|
||||
* void cpu_task_switch(void);
|
||||
******************************************************************************/
|
||||
|
||||
.type cpu_task_switch, %function
|
||||
cpu_task_switch:
|
||||
lrw r0, g_intrpt_nested_level
|
||||
ldb r0, (r0)
|
||||
cmpnei r0, 0
|
||||
jbf __task_switch
|
||||
|
||||
lrw r0, g_active_task
|
||||
lrw r1, g_preferred_ready_task
|
||||
ldw r2, (r1)
|
||||
stw r2, (r0)
|
||||
|
||||
rts
|
||||
|
||||
|
||||
.type cpu_intrpt_switch, %function
|
||||
cpu_intrpt_switch:
|
||||
lrw r0, g_active_task
|
||||
lrw r1, g_preferred_ready_task
|
||||
ldw r2, (r1)
|
||||
stw r2, (r0)
|
||||
|
||||
rts
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void cpu_first_task_start(void);
|
||||
******************************************************************************/
|
||||
|
||||
.type cpu_first_task_start, %function
|
||||
cpu_first_task_start:
|
||||
psrclr ie
|
||||
jbr __task_switch_nosave
|
||||
|
||||
/******************************************************************************
|
||||
* Functions:
|
||||
* void __task_switch(void);
|
||||
******************************************************************************/
|
||||
|
||||
.type __task_switch, %function
|
||||
__task_switch:
|
||||
subi sp, 68
|
||||
stm r0-r13, (sp)
|
||||
stw r15, (sp, 56)
|
||||
mfcr r0, psr
|
||||
stw r0, (sp, 60)
|
||||
stw r15, (sp, 64)
|
||||
|
||||
lrw r1, g_active_task
|
||||
ldw r1, (r1)
|
||||
stw sp, (r1)
|
||||
|
||||
#if (YUNOS_CONFIG_TASK_STACK_OVF_CHECK > 0)
|
||||
jbsr krhino_stack_ovf_check
|
||||
#endif
|
||||
|
||||
__task_switch_nosave:
|
||||
|
||||
#ifdef CONFIG_SUPPORT_REE_SCHEDULE_IN_TEE
|
||||
jbsr csky_get_tee_caller_task
|
||||
#endif
|
||||
|
||||
lrw r4, g_preferred_ready_task
|
||||
lrw r5, g_active_task
|
||||
ldw r6, (r4)
|
||||
stw r6, (r5)
|
||||
|
||||
#ifdef CONFIG_SUPPORT_REE_SCHEDULE_IN_TEE
|
||||
jbsr csky_deal_tee_caller_task
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
jbsr csky_set_stackbound
|
||||
#endif
|
||||
ldw sp, (r6)
|
||||
|
||||
#ifdef CONFIG_STACK_GUARD
|
||||
mfcr r3, cr<0, 4>
|
||||
bseti r3, 0
|
||||
bseti r3, 1
|
||||
mtcr r3, cr<0, 4>
|
||||
#endif
|
||||
|
||||
ldw r0, (sp, 64)
|
||||
mtcr r0, epc
|
||||
ldw r0, (sp, 60)
|
||||
mtcr r0, epsr
|
||||
ldw r15, (sp, 56)
|
||||
ldm r0-r13, (sp)
|
||||
addi sp, 68
|
||||
|
||||
rte
|
||||
|
||||
.global tspend_handler
|
||||
.type tspend_handler, %function
|
||||
tspend_handler:
|
||||
bkpt
|
||||
56
Living_SDK/platform/arch/csky/cskyv2-l/trap_c.c
Normal file
56
Living_SDK/platform/arch/csky/cskyv2-l/trap_c.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2016 YunOS Project. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <csi_kernel.h>
|
||||
|
||||
void trap_c(uint32_t *regs)
|
||||
{
|
||||
int i;
|
||||
uint32_t vec = 0;
|
||||
|
||||
asm volatile(
|
||||
"mfcr %0, psr \n"
|
||||
"lsri %0, 16 \n"
|
||||
"sextb %0 \n"
|
||||
:"=r"(vec):);
|
||||
|
||||
printf("CPU Exception : %d", vec);
|
||||
|
||||
if (vec == 2) {
|
||||
printf(",maybe Stack-Guard stopped the invalid behaviors!");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("r%d: %08x\t", i, regs[i]);
|
||||
|
||||
if ((i % 5) == 4) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("epsr: %8x\n", regs[16]);
|
||||
printf("epc : %8x\n", regs[17]);
|
||||
|
||||
// csi_kernel_task_list(NULL, 0);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
4
Living_SDK/platform/arch/csky/cskyv2-l/ucube.py
Normal file
4
Living_SDK/platform/arch/csky/cskyv2-l/ucube.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
src = Split('''
|
||||
''')
|
||||
|
||||
component = aos_component('cskyv2-l', src)
|
||||
10
Living_SDK/platform/arch/linux/cpu_arch_longjmp.h
Normal file
10
Living_SDK/platform/arch/linux/cpu_arch_longjmp.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifdef __i386__
|
||||
#include "cpu_longjmp_32.h"
|
||||
#else
|
||||
#include "cpu_longjmp_64.h"
|
||||
#endif
|
||||
|
||||
39
Living_SDK/platform/arch/linux/cpu_event.h
Normal file
39
Living_SDK/platform/arch/linux/cpu_event.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef CPU_EVENT_H
|
||||
#define CPU_EVENT_H
|
||||
|
||||
typedef void (*cpu_event_handler)(const void *);
|
||||
|
||||
typedef struct {
|
||||
cpu_event_handler handler;
|
||||
const void *arg;
|
||||
} cpu_event_t;
|
||||
|
||||
#ifdef VCALL_RHINO
|
||||
int cpu_notify_event(cpu_event_t *event);
|
||||
void *cpu_event_malloc(int size);
|
||||
void cpu_event_free(void *p);
|
||||
|
||||
static inline int cpu_call_handler(cpu_event_handler handler, const void *arg)
|
||||
{
|
||||
cpu_event_t event = {
|
||||
.handler = handler,
|
||||
.arg = arg,
|
||||
};
|
||||
return cpu_notify_event(&event);
|
||||
}
|
||||
#else
|
||||
#define cpu_event_malloc malloc
|
||||
#define cpu_event_free free
|
||||
static inline int cpu_call_handler(cpu_event_handler handler, const void *arg)
|
||||
{
|
||||
handler(arg);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CPU_EVENT_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue