-
Notifications
You must be signed in to change notification settings - Fork 1
/
rtos_portable.asm
194 lines (168 loc) · 4.58 KB
/
rtos_portable.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
;-----------------------------------------------------------
; Global symbols defined in this file
;-----------------------------------------------------------
.def _osport_idle
.def _osport_breakpoint
.def _osport_enable_int
.def _osport_disable_int
.def _osport_contextsw_req
.def _osport_start
.def _ISR_RTOSINT
.def _ISR_USER1
;-----------------------------------------------------------
; Global symbols referenced in this file
;-----------------------------------------------------------
.ref __stack
.ref _g_sch
.ref _CPUTIMER2
.sect ".text"
;-----------------------------------------------------------
; The do nothing function
; Puts the CPU into a low power sleep mode unitl interrupt
;-----------------------------------------------------------
_osport_idle:
$L1:
IDLE
B $L1, UNC
;-----------------------------------------------------------
; Halts the debugger
;-----------------------------------------------------------
_osport_breakpoint:
ESTOP1
LRETR
;-----------------------------------------------------------
; Disables interrupts
;-----------------------------------------------------------
_osport_disable_int:
; cache flushed automatically
DINT
LRETR
;-----------------------------------------------------------
; Enables interrupts
;-----------------------------------------------------------
_osport_enable_int:
EINT
LRETR
;-----------------------------------------------------------
; Request a context switch
; The context switcher is implemented as RTOSINT, trigger
; the interrupt.
;-----------------------------------------------------------
_osport_contextsw_req:
; set the interrupt flag of RTOSINT
OR IFR, #0x8000
LRETR
;-----------------------------------------------------------
; Start the operating system kernel
;-----------------------------------------------------------
_osport_start:
PUSH ST1 ; save EALLOW status
PUSH DP
EALLOW ; enable modification
MOVW DP, #_CPUTIMER2+4 ; load data page of CPUTIMER2 TCR
AND @_CPUTIMER2+4, #0xFFEF ; clear bit 4 of CPUTIMER2 TCR
POP DP
POP ST1 ; restore EALLOW status
; generate interrupt #20 (USER1)
TRAP #20
LRETR
;-----------------------------------------------------------
; USER1 interrupt handler, prepare the CPU for multithreading
;-----------------------------------------------------------
_ISR_USER1:
; interrupt disabled automatically here
; load the first thread's control block
MOVW DP, #_g_sch ; load data page of g_sch
MOVL XAR0, @_g_sch ; XAR0 <- &(g_sch.p_current->p_sp)
MOVL ACC, *+XAR0[0] ; ACC <- g_sch.p_current->p_sp
MOV SP, ACC ; SP <- ACC
; pop the registers not automatically
; popped by hardware on interrupt return
; FPU registers
MOV32 R7H, *--SP
MOV32 R6H, *--SP
MOV32 R5H, *--SP
MOV32 R4H, *--SP
MOV32 R3H, *--SP
MOV32 R2H, *--SP
MOV32 R1H, *--SP
MOV32 R0H, *--SP
MOV32 STF, *--SP
POP RB
; regular cpu registers
POP XT
POP XAR7
POP XAR6
POP XAR5
POP XAR4
POP XAR3
POP XAR2
POP AR1H:AR0H
POP RPC
IRET
; interrupts enabled automatically here
;-----------------------------------------------------------
; RTOSINT handler
; The context switcher
;-----------------------------------------------------------
_ISR_RTOSINT:
; interrupts disabled automatically here
; context save, CPU registers
PUSH RPC
PUSH AR1H:AR0H
PUSH XAR2
PUSH XAR3
PUSH XAR4
PUSH XAR5
PUSH XAR6
PUSH XAR7
PUSH XT
; context save, FPU registers
PUSH RB
MOV32 *SP++, STF
MOV32 *SP++, R0H
MOV32 *SP++, R1H
MOV32 *SP++, R2H
MOV32 *SP++, R3H
MOV32 *SP++, R4H
MOV32 *SP++, R5H
MOV32 *SP++, R6H
MOV32 *SP++, R7H
; store a snapshot of the stack pointer into
; current thread's TCB block
MOVW DP, #_g_sch ; load data page of g_sch
MOVL XAR0, @_g_sch ; XAR0 <- &(g_sch.p_current->p_sp)
MOVZ AR1, SP ; XAR1 <- SP
MOVL *+XAR0[0], XAR1 ; g_sch.p_current->p_sp = XAR1
; load the next thread's control block
MOVW DP, #_g_sch+2 ; load data page of g_sch+2
MOVL XAR0, @_g_sch+2 ; XAR0 <- &(g_sch.p_next->p_sp)
MOVL ACC, *+XAR0[0] ; ACC <- g_sch.p_next->p_sp
MOV SP, ACC ; SP <- ACC
MOVW DP, #_g_sch ; load data page of g_sch
MOVL @_g_sch, XAR0 ; g_sch->p_current = XAR0
; pop the registers not automatically
; popped by hardware on interrupt return
; FPU registers
MOV32 R7H, *--SP
MOV32 R6H, *--SP
MOV32 R5H, *--SP
MOV32 R4H, *--SP
MOV32 R3H, *--SP
MOV32 R2H, *--SP
MOV32 R1H, *--SP
MOV32 R0H, *--SP
MOV32 STF, *--SP
POP RB
; regular cpu registers
POP XT
POP XAR7
POP XAR6
POP XAR5
POP XAR4
POP XAR3
POP XAR2
POP AR1H:AR0H
POP RPC
IRET
; interrupts enabled automatically here