1: /*
2: *----------------------------------------------------------------------
3: * micro T-Kernel 3.00.03
4: *
5: * Copyright (C) 2006-2020 by Ken Sakamura.
6: * This software is distributed under the T-License 2.2.
7: *----------------------------------------------------------------------
8: *
9: * Released by TRON Forum(http://www.tron.org) at 2021/03/31.
10: *
11: *----------------------------------------------------------------------
12: */
13: #include <sys/machine.h>
14: #ifdef CPU_CORE_ARMV7M
15: /*
16: * dispatch.S (ARMv7-M)
17: * Dispatcher
18: */
19:
20: #define _in_asm_source_
21:
22: #include <sys/machine.h>
23: #include <tk/errno.h>
24: #include <sys/sysdef.h>
25: #include <sys/knldef.h>
26:
27: #include "offset.h"
28:
29: .code 16
30: .syntax unified
31: .thumb
32:
33: /* ------------------------------------------------------------------------ */
34: /*
35: * Dispatcher
36: *
37: * Contexts to save
38: * Save registers except for ssp to a stack. Save 'ssp' to TCB.
39: *
40: * High Address +---------------+
41: * | (fpscr) |
42: * | (S0 - S15) |
43: * +---------------+
44: * | xpsr |
45: * | pc | Return address
46: * | lr |
47: * | R12 |
48: * | R0-R3 |
49: * +---------------+ Save by Exception entry process.
50: * | R4 - R11 |
51: * ssp -> | lr |
52: * +---------------+
53: * | (S16 - S31) |
54: * ssp -> | (ufpu) |
55: * Low Address +---------------+
56: *
57: * ( ) Stacked only while using FPU
58: */
59:
60: #if USE_FPU
61: #define TA_FPU 0x00001000 /* Task attribute - Use FPU */
62: #define EXPRN_NO_FPU 0x00000010 /* FPU usage flag 0:use 1:no use */
63: #endif
64:
65: .text
66: .align 2
67: .thumb
68: .thumb_func
69: .globl Csym(knl_dispatch_entry)
70:
71: Csym(knl_dispatch_entry):
72: /*----------------- Start dispatch processing. -----------------*/
73: ldr r0, =Csym(knl_dispatch_disabled)
74: ldr r1, =1
75: str r1, [r0] // Dispatch disable
76:
77: ldr r0, =Csym(knl_ctxtsk)
78: ldr r1, [r0] // R1 = ctxtsk
79: cmp r1, #0
80: bne l_dispatch_000
81:
82: ldr sp, =(Csym(knl_tmp_stack) + TMP_STACK_SIZE) // Set temporal stack
83: b l_dispatch_100
84:
85: /*----------------- Save "ctxtsk" context. -----------------*/
86: l_dispatch_000:
87: push {r4-r11}
88: push {lr}
89:
90: #if USE_FPU // Save FPU register
91: ldr r2, [r1, #TCB_tskatr]
92: ands r2, r2, #TA_FPU
93: beq l_dispatch_010 // ctxtsk is not a TA_FPU attribute.
94:
95: ands r3,lr, #EXPRN_NO_FPU
96: bne l_dispatch_010 // ctxtsk does not execute FPU instructions.
97:
98: vpush {s16-s31} // Push FPU register (S15-S31)
99: push {r3} //FPU usage flag
100:
101: l_dispatch_010: // End of FPU register save process
102: #endif /* USE_FPU */
103:
104: str sp, [r1, #TCB_tskctxb + CTXB_ssp] // Save 'ssp' to TCB
105:
106: ldr r2, =0
107: str r2, [r0] // ctxtsk = NULL
108:
109:
110: /*----------------- Dispatch from "ctxtsk" to "schedtsk" -----------------*/
111: l_dispatch_100:
112: ldr r5, =Csym(knl_schedtsk) // R5 = &schedtsk
113: ldr r6, =Csym(knl_lowpow_discnt) // R6 = &lowpow_discnt
114:
115: l_dispatch_110:
116: ldr r2, =INTPRI_VAL(INTPRI_MAX_EXTINT_PRI) // Disable interruput
117: msr basepri, r2
118:
119: ldr r8, [r5] // R8 = schedtsk
120: cmp r8, #0 // Is there 'schedtsk'?
121: bne l_dispatch_120
122:
123: /* Moves to power saving mode because there are no tasks that can be run. */
124: ldr ip, [r6] // Is 'low_pow' disabled?
125: cmp ip, #0
126: it eq
127: bleq Csym(low_pow) // call low_pow()
128:
129: ldr r2, =0
130: msr basepri, r2 // Enable interruput
131:
132: b l_dispatch_110
133:
134: l_dispatch_120: // Switch to 'schedtsk'
135: str r8, [r0] // ctxtsk = schedtsk
136: ldr sp, [r8, #TCB_tskctxb + CTXB_ssp] // Restore 'ssp' from TCB
137:
138:
139: /*----------------- Restore "schedtsk" context. -----------------*/
140:
141: #if USE_FPU // Restore FPU context
142: ldr r0, [r8, #TCB_tskatr]
143: ands r0, r0, #TA_FPU
144: beq l_dispatch_200 // schedtsk is not a TA_FPU attribute.
145:
146: ldr r3,[sp] // load FPU usage flag
147: ands r3, r3, #EXPRN_NO_FPU
148: bne l_dispatch_200 // schedtsk does not execute FPU instructions.
149:
150: pop {r3}
151: vpop {s16-s31} // Pop FPU register (S15-S31)
152:
153: l_dispatch_200: // End of FPU register restore process
154: #endif /* USE_FPU */
155:
156: pop {lr}
157: pop {r4-r11}
158:
159: ldr r0, =Csym(knl_dispatch_disabled)
160: ldr r1, =0
161: str r1, [r0] // Dispatch enable
162:
163: msr basepri, r1 // Enable inperrupt
164:
165: bx lr
166:
167: #endif /* CPU_CORE_ARMV7M */