1: /*
2: *----------------------------------------------------------------------
3: * micro T-Kernel 3.00.01
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 2020/05/29.
10: *
11: *----------------------------------------------------------------------
12: */
13:
14: #include <sys/machine.h>
15: #ifdef CPU_CORE_RXV2
16:
17: /*
18: * dispatch.S (RXv2 core)
19: * Dispatcher
20: */
21:
22: #define _in_asm_source_
23:
24: #include <sys/machine.h>
25: #include <tk/errno.h>
26: #include <sys/sysdef.h>
27: #include <sys/knldef.h>
28:
29: #include "offset.h"
30:
31: .extern Csym(knl_tmp_stack)
32: .extern Csym(knl_dispatch_disabled)
33: .extern Csym(knl_ctxtsk)
34: .extern Csym(knl_schedtsk)
35: .extern Csym(knl_lowpow_discnt)
36: .extern Csym(low_pow)
37:
38: /* ------------------------------------------------------------------------*/
39: /*
40: * Dispatcher
41: * dispatch_to_schedtsk:
42: * Destroys the current context and forces dispatch to "schedtsk".
43: * Called directly by a jump (jmp), but does not return.
44: * Called with an undefined stack state (undefined 'ssp').
45: * Called when interrupts are disabled.
46: * dispatch_entry:
47: * Normal dispatch processing.
48: * ret_int_dispatch:
49: * Called when dispatch is required with "tk_ret_int ()".
50: *
51: * Contexts to save
52: * Saves registers other than SP to the stack. Save the SP to TCB.
53: *
54: * High Address +---------------+
55: * | SPSW(32bit) | Saved by interrupt entry
56: * | SPC(32bit) | routines until here.
57: * +---------------+
58: * | R15 |
59: * | R14 |
60: * | R13 |
61: * | : |
62: * | R3 |
63: * | R2 |
64: * Saved to TCB SP => | R1 |-> If USE_FPU, | R1 |-> If USE_DSP, | R1 |
65: * Low Address +---------------+ SP => | FPSW | | ACC1 |
66: * Low Address +---------------+ SP => | ACC0 |
67: * Low Address +---------------+
68: */
69: .globl Csym(knl_dispatch_to_schedtsk)
70: .globl Csym(knl_dispatch_entry)
71: .globl Csym(ret_int_dispatch)
72:
73: .section .text
74: Csym(knl_dispatch_to_schedtsk): // Forces dispatch entry
75: ; During interrupt disable (PSW.I=0)
76: mov.l #(Csym(knl_tmp_stack) + TMP_STACK_SIZE), r0 // Set temporal stack
77:
78: mov.l #Csym(knl_dispatch_disabled), r1
79: mov.l #1, [r1] // Dispatch disable
80:
81: mov.l #Csym(knl_ctxtsk), r7
82: #if USE_DBGSPT != 0
83: mov.l [r7], r2 // r2 := ctxtsk
84: #endif
85: mov.l #0, [r7] // ctxtsk = NULL
86: mvtipl #0 // IPL = 0 (Lowest level)
87: bra l_dispatch1
88:
89: Csym(knl_dispatch_entry): // Normal dispatch entry
90: // During interrupt disable (PSW.I=0).
91: mvfc psw, r1
92: bset #16, r1 // PSW compensation (I=1)
93: xchg [r0], r1
94: push.l r1
95:
96: Csym(ret_int_dispatch): // tk_ret_int() dispatch entry
97: // During interrupt disable (PSW.I=0).
98: pushm r14-r15
99: mov.l #Csym(knl_dispatch_disabled), r15
100: mov.l #1, [r15] // Dispatch disable
101: pushm r1-r13 // Context save
102:
103: #if USE_FPU // Save FPU registers
104: mvfc fpsw, r1
105: push.l r1
106: #endif
107:
108: #if USE_DSP // Save DSP registers
109: mvfaclo #0,a1,r2
110: mvfachi #0,a1,r3
111: mvfacgu #0,a1,r4
112: pushm r2-r4
113: mvfaclo #0,a0,r2
114: mvfachi #0,a0,r3
115: mvfacgu #0,a0,r4
116: pushm r2-r4
117: #endif
118: mov.l #Csym(knl_ctxtsk), r7
119: mov.l [r7], r2
120: mov.l r0, (TCB_tskctxb + CTXB_ssp)[r2] // Save SSP to ctxtsk's TCB
121:
122: mvtipl #0 // IPL = 0 (Lowest level)
123: l_dispatch1:
124: clrpsw I // Interrupt disable
125:
126: mov.l #Csym(knl_schedtsk), r2
127: mov.l [r2], r6
128: cmp #0, r6 // ? schedtsk == NULL
129: bne l_dispatch2 // No. goto l_dispatch2
130: // Yes.
131: // Move to power saving mode because there are no tasks to perform.
132: mov.l #Csym(knl_lowpow_discnt), r1
133: mov.l [r1], r1 // Is 'low_pow' disabled?
134: cmp #0, r1
135: bne l_dispatch11
136:
137: mov.l #Csym(low_pow), r1
138: jsr r1 // Move to power saving mode. call low_pow().
139: l_dispatch11:
140:
141: setpsw I // Interrupt enable
142: bra l_dispatch1
143:
144: l_dispatch2: // Switch to 'schedtsk'
145: // During interrupt disable (PSW.I=0).
146: mov.l r6, [r7] // ctxtsk := schedtsk
147: mov.l (TCB_tskctxb + CTXB_ssp)[r6], r0 // Restore SSP from TCB
148:
149: mov.l #Csym(knl_dispatch_disabled), r2
150: mov.l #0, [r2] // Dispatch enable
151:
152: #if USE_DSP // Restore DSP register.
153: popm r2-r4
154: mvtacgu r4,a0
155: mvtachi r3,a0
156: mvtaclo r2,a0
157: popm r2-r4
158: mvtacgu r4,a1
159: mvtachi r3,a1
160: mvtaclo r2,a1
161: #endif
162:
163: #if USE_FPU // Restore FPU register.
164: pop r1
165: mvtc r1, fpsw
166: #endif
167:
168: popm r1-r15 // Restore context.
169: rte
170:
171: .end
172:
173: #endif /* CPU_RX231 */