1#include <k_config.h>
2
3@******************************************************************************
4@                            EXTERN PARAMETERS
5@******************************************************************************
6.extern g_active_task
7.extern g_preferred_ready_task
8.extern krhino_stack_ovf_check
9.extern krhino_task_sched_stats_get
10
11@******************************************************************************
12@                            EXPORT FUNCTIONS
13@******************************************************************************
14.global cpu_intrpt_save
15.global cpu_intrpt_restore
16.global cpu_task_switch
17.global cpu_intrpt_switch
18.global cpu_first_task_start
19
20.global PendSV_Handler
21.global _first_task_restore
22
23@******************************************************************************
24@                                 EQUATES
25@******************************************************************************
26.equ SCB_ICSR,        0xE000ED04 @ Interrupt Control and State Register.
27.equ SCB_VTOR,        0xE000ED08 @ Vector Table Offset Register.
28.equ ICSR_PENDSVSET,  0x10000000 @ Value to trigger PendSV exception.
29
30.equ SHPR3_PRI_14,    0xE000ED22 @ System Handler Priority Register 3 (PendSV).
31.equ PRI_LVL_PENDSV,  0xFF       @ PendSV priority level (lowest).
32.equ SHPR3_PRI_15,    0xE000ED23 @ System Handler Priority Register 3 (Systick).
33.equ PRI_LVL_SYSTICK, 0xFF       @ SYstick priority level (lowest).
34
35@******************************************************************************
36@                        CODE GENERATION DIRECTIVES
37@******************************************************************************
38.text
39.align 2
40.thumb
41.syntax unified
42
43@******************************************************************************
44@ Functions:
45@     size_t cpu_intrpt_save(void);
46@     void cpu_intrpt_restore(size_t cpsr);
47@******************************************************************************
48.thumb_func
49cpu_intrpt_save:
50    MRS     R0, PRIMASK
51    CPSID   I
52    BX      LR
53
54.thumb_func
55cpu_intrpt_restore:
56    MSR     PRIMASK, R0
57    BX      LR
58
59@******************************************************************************
60@ Functions:
61@     void cpu_intrpt_switch(void);
62@     void cpu_task_switch(void);
63@******************************************************************************
64.thumb_func
65cpu_task_switch:
66    LDR     R0, =SCB_ICSR
67    LDR     R1, =ICSR_PENDSVSET
68    STR     R1, [R0]
69    BX      LR
70
71.thumb_func
72cpu_intrpt_switch:
73    LDR     R0, =SCB_ICSR
74    LDR     R1, =ICSR_PENDSVSET
75    STR     R1, [R0]
76    BX      LR
77
78@******************************************************************************
79@ Functions:
80@     void cpu_first_task_start(void);
81@******************************************************************************
82.thumb_func
83cpu_first_task_start:
84    @set PendSV prority to the lowest
85    LDR     R0, =SHPR3_PRI_14
86    LDR     R1, =PRI_LVL_PENDSV
87    STRB    R1, [R0]
88
89    @set Systick prority to the lowest
90    LDR     R0, =SHPR3_PRI_15
91    LDR     R1, =PRI_LVL_SYSTICK
92    STRB    R1, [R0]
93
94    @indicate PendSV_Handler branch to _pendsv_handler_nosave
95    MOVS    R0, #0
96    MSR     PSP, R0
97
98    @make PendSV exception pending
99    LDR     R0, =SCB_ICSR
100    LDR     R1, =ICSR_PENDSVSET
101    STR     R1, [R0]
102
103    @goto PendSV_Handler
104    CPSIE   I
105    B       .
106
107@******************************************************************************
108@ Functions:
109@     void krhino_pendsv_handler(void);
110@******************************************************************************
111.thumb_func
112PendSV_Handler:
113    CPSID   I
114    MRS     R0, PSP
115    @branch if cpu_first_task_start
116    CMP     R0, #0
117    BEQ     _first_task_restore
118
119    @hardware saved R0~R3,R12,LR,PC,xPSR
120
121    @save context
122    #if (defined(__VFP_FP__) && !defined(__SOFTFP__))
123    @if the switchout task use FPU, save the FPU regs
124    TST     LR, #0x10
125    IT      EQ
126    VSTMDBEQ R0!, {D8 - D15}
127    @hardware saved D0~D7, FPSCR
128    #endif
129
130    SUBS    R0, R0, #0x24
131    STM     R0, {R4-R11, LR}
132
133    @g_active_task->task_stack = context region
134    LDR     R1, =g_active_task
135    LDR     R1, [R1]
136    STR     R0, [R1]
137
138#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
139    BL      krhino_stack_ovf_check
140#endif
141#if (RHINO_CONFIG_SYS_STATS > 0)
142    BL      krhino_task_sched_stats_get
143#endif
144
145.thumb_func
146_pendsv_handler_nosave:
147    LDR     R0, =g_active_task
148    LDR     R1, =g_preferred_ready_task
149    LDR     R2, [R1]
150    STR     R2, [R0]
151    @R0 = g_active_task->task_stack = context region
152    LDR     R0, [R2]
153
154    @restore context
155    LDM     R0, {R4-R11, LR}
156    ADDS    R0, R0, #0x24
157
158    #if (defined(__VFP_FP__) && !defined(__SOFTFP__))
159    @if the switchin task use FPU, save the FPU regs
160    TST     LR, #0x10
161    IT      EQ
162    VLDMIAEQ R0!, {D8 - D15}
163    @hardware will restore D0~D7, FPSCR
164    #endif
165
166    @return stack = PSP
167    MSR     PSP, R0
168
169    CPSIE   I
170    @hardware restore R0~R3,R12,LR,PC,xPSR
171    BX      LR
172
173.thumb_func
174_first_task_restore:
175    @set MSP to the base of system stack
176    LDR     R0, =SCB_VTOR
177    LDR     R0, [R0]
178    LDR     R0, [R0]
179    MSR     MSP, R0
180
181    B       _pendsv_handler_nosave
182
183.end
184
185