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    SUBS    R0, R0, #0x24
123    STM     R0, {R4-R11, LR}
124
125    @g_active_task->task_stack = context region
126    LDR     R1, =g_active_task
127    LDR     R1, [R1]
128    STR     R0, [R1]
129
130#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0)
131    BL      krhino_stack_ovf_check
132#endif
133#if (RHINO_CONFIG_SYS_STATS > 0)
134    BL      krhino_task_sched_stats_get
135#endif
136
137.thumb_func
138_pendsv_handler_nosave:
139    LDR     R0, =g_active_task
140    LDR     R1, =g_preferred_ready_task
141    LDR     R2, [R1]
142    STR     R2, [R0]
143    @R0 = g_active_task->task_stack = context region
144    LDR     R0, [R2]
145
146    @restore context
147    LDM     R0, {R4-R11, LR}
148    ADDS    R0, R0, #0x24
149
150    @return stack = PSP
151    MSR     PSP, R0
152
153    CPSIE   I
154    @hardware restore R0~R3,R12,LR,PC,xPSR
155    BX      LR
156
157.thumb_func
158_first_task_restore:
159    @set MSP to the base of system stack
160    LDR     R0, =SCB_VTOR
161    LDR     R0, [R0]
162    LDR     R0, [R0]
163    MSR     MSP, R0
164
165    B       _pendsv_handler_nosave
166
167.end
168
169