comparison chipsetsw/os/nucleus/tct.s @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:509db1a7b7b8
1 ;/*************************************************************************/
2 ;/* */
3 ;/* Copyright (c) 1993-1994 Accelerated Technology, Inc. */
4 ;/* */
5 ;/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the */
6 ;/* subject matter of this material. All manufacturing, reproduction, */
7 ;/* use, and sales rights pertaining to this subject matter are governed */
8 ;/* by the license agreement. The recipient of this software implicitly */
9 ;/* accepts the terms of the license. */
10 ;/* */
11 ;/*************************************************************************/
12 ;
13 ;/*************************************************************************/
14 ;/* */
15 ;/* FILE NAME VERSION */
16 ;/* */
17 ;/* tct.s PLUS/THUMB/T 1.2 */
18 ;/* */
19 ;/* COMPONENT */
20 ;/* */
21 ;/* TC - Thread Control */
22 ;/* */
23 ;/* DESCRIPTION */
24 ;/* */
25 ;/* This file contains the target processor dependent routines for */
26 ;/* performing target-dependent scheduling functions. */
27 ;/* */
28 ;/* AUTHOR */
29 ;/* */
30 ;/* Barry Sellew, Accelerated Technology, Inc. */
31 ;/* */
32 ;/* DATA STRUCTURES */
33 ;/* */
34 ;/* None */
35 ;/* */
36 ;/* FUNCTIONS */
37 ;/* */
38 ;/* TCT_Control_Interrupts Enable / disable interrupts */
39 ;/* by changing */
40 ;/* TCD_Interrupt_Level */
41 ;/* TCT_Local_Control_Interrupts Enable/disable interrupts */
42 ;/* by not changing */
43 ;/* TCD_Interrupt_Level */
44 ;/* TCT_Restore_Interrupts Restores interrupts to the */
45 ;/* level in TCD_Interrupt_Level */
46 ;/* TCT_Build_Task_Stack Build initial task stack */
47 ;/* TCT_Build_HISR_Stack Build initial HISR stack */
48 ;/* TCT_Build_Signal_Frame Build signal handler frame */
49 ;/* TCT_Check_Stack Check current stack */
50 ;/* TCT_Schedule Schedule the next thread */
51 ;/* TCT_Control_To_Thread Transfer control to a thread */
52 ;/* TCT_Control_To_System Transfer control from thread */
53 ;/* TCT_Signal_Exit Exit from signal handler */
54 ;/* TCT_Current_Thread Returns a pointer to current */
55 ;/* thread */
56 ;/* TCT_Set_Execute_Task Sets TCD_Execute_Task under */
57 ;/* protection from interrupts */
58 ;/* TCT_Protect Protect critical section */
59 ;/* TCT_Unprotect Unprotect critical section */
60 ;/* TCT_Unprotect_Specific Release specific protection */
61 ;/* TCT_Set_Current_Protect Set the thread's current */
62 ;/* protection field */
63 ;/* TCT_Protect_Switch Switch to protected thread */
64 ;/* TCT_Schedule_Protected Schedule the protected thread*/
65 ;/* TCT_Interrupt_Context_Save Save interrupted context */
66 ;/* TCT_Interrupt_Context_Restore Restore interrupted context */
67 ;/* TCT_Activate_HISR Activate a HISR */
68 ;/* TCT_HISR_Shell HISR execution shell */
69 ;/* */
70 ;/* DEPENDENCIES */
71 ;/* */
72 ;/* cs_extr.h Common Service functions */
73 ;/* tc_extr.h Thread Control functions */
74 ;/* */
75 ;/* HISTORY */
76 ;/* */
77 ;/* NAME DATE REMARKS */
78 ;/* */
79 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
80 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
81 ;/* B. Sellew 04-19-1996 Added saving and restoring of */
82 ;/* v5, v6, and ip, resulting in */
83 ;/* version 1.2 (spr103) */
84 ;/* P. Roussel (TI) 07-21-1999 Modified TCT_Schedule for GSM */
85 ;/* small sleep implementation */
86 ;/* */
87 ;/*************************************************************************/
88 ;#define NU_SOURCE_FILE
89 ;
90 ;#include "cs_extr.h" /* Common service functions */
91 ;#include "tc_extr.h" /* Thread control functions */
92 ;
93 ;/* Define constants used in low-level initialization. */
94 ;
95 ;
96 LOCKOUT .equ 00C0h ; Interrupt lockout value
97 LOCK_MSK .equ 00C0h ; Interrupt lockout mask value
98 MODE_MASK .equ 001Fh ; Processor Mode Mask
99 SUP_MODE .equ 0013h ; Supervisor Mode (SVC)
100 IRQ_MODE .equ 0012h ; Interrupt Mode (IRQ)
101 FIQ_MODE .equ 0011h ; Fast Interrupt Mode (FIQ)
102 ;
103 ;
104 ;
105 ;/* Define a variable for saving the system stack limit in. This value is
106 ; intialized in INT.S and is in effect whenever the system stack is in
107 ; use. */
108 ;
109 ;VOID *TCT_System_Limit;
110 ;
111 ;/* Define internal variables so the C compiler can provide meaningful
112 ; code with offsets into data structures. Typically, this section is
113 ; removed after this file is compiled down to assembly language. */
114 ;
115 ;BYTE_PTR REG_Stack_Base;
116 ;BYTE_PTR REG_Stack_End;
117 ;BYTE_PTR REG_Stack_Ptr;
118 ;UNSIGNED REG_Stack_Size;
119 ;TC_TCB *REG_Thread_Ptr;
120 ;TC_HCB *REG_HISR_Ptr;
121 ;TC_PROTECT *REG_Protect_Ptr;
122 ;VOID *REG_Function_Ptr;
123 ;
124 .def _TCT_System_Limit
125 .bss _TCT_System_Limit, 4, 4
126 ;
127 ;
128 .text
129 ;
130 ;/* Define external inner-component global data references. */
131 ;
132 ;extern TC_TCB *TCD_Execute_Task;
133 ;extern TC_HCB *TCD_Execute_HISR;
134 ;extern VOID *TCD_Current_Thread;
135 ;extern VOID *TCD_System_Stack;
136 ;extern INT TCD_Interrupt_Count;
137 ;extern TC_HCB *TCD_Active_HISR_Heads[TC_HISR_PRIORITIES];
138 ;extern TC_HCB *TCD_Active_HISR_Tails[TC_HISR_PRIORITIES];
139 ;extern INT TCD_Interrupt_Level;
140 ;extern UNSIGNED TMD_Time_Slice;
141 ;extern INT TMD_Time_Slice_State;
142 ;
143 .ref _TCD_Execute_Task
144 .ref _TCD_Execute_HISR
145 .ref _TCD_Current_Thread
146 .ref _TCD_System_Stack
147 .ref _TCD_Interrupt_Count
148 .ref _TCD_Active_HISR_Heads
149 .ref _TCD_Active_HISR_Tails
150 .ref _TCD_Interrupt_Level
151 .ref _TMD_Time_Slice
152 .ref _TMD_Time_Slice_State
153 ;
154 ;
155 ;/* Define external function references. */
156 ;VOID TCC_Task_Shell(VOID);
157 ;VOID TCC_Signal_Shell(VOID);
158 ;VOID TCT_HISR_Shell(VOID);
159 ;VOID ERC_System_Error(INT error);
160 ;
161 .ref $TCC_Task_Shell
162 .ref $TCC_Signal_Shell
163 .ref $ERC_System_Error
164 .ref IND_CALL
165 ;
166 ;/* Define internal function references. */
167 ;VOID TCT_Schedule_Protected(VOID *thread);
168 ;
169 .def _TCT_Schedule_Protected
170 ;
171 ;
172 ;/*************************************************************************/
173 ;/* */
174 ;/* FUNCTION */
175 ;/* */
176 ;/* TCT_Control_Interrupts */
177 ;/* */
178 ;/* DESCRIPTION */
179 ;/* */
180 ;/* This function enables and disables interrupts as specified by */
181 ;/* the caller. Interrupts disabled by this call are left disabled */
182 ;/* until the another call is made to enable them. */
183 ;/* */
184 ;/* AUTHOR */
185 ;/* */
186 ;/* Barry Sellew, Accelerated Technology, Inc. */
187 ;/* */
188 ;/* CALLED BY */
189 ;/* */
190 ;/* Application */
191 ;/* */
192 ;/* CALLS */
193 ;/* */
194 ;/* None */
195 ;/* */
196 ;/* INPUTS */
197 ;/* */
198 ;/* new_level New interrupt enable level */
199 ;/* */
200 ;/* OUTPUTS */
201 ;/* */
202 ;/* old_level Previous interrupt enable */
203 ;/* level */
204 ;/* */
205 ;/* HISTORY */
206 ;/* */
207 ;/* NAME DATE REMARKS */
208 ;/* */
209 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
210 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
211 ;/* */
212 ;/*************************************************************************/
213 ;INT TCT_Control_Interrupts (INT new_level)
214 ;{
215 .def $TCT_Control_Interrupts
216 $TCT_Control_Interrupts ; Dual-state interworking veneer
217 .state16
218 BX pc
219 NOP
220 .state32
221 B _TCT_Control_Interrupts
222 ;
223 .def _TCT_Control_Interrupts
224 _TCT_Control_Interrupts
225 ;
226 ;INT old_level; /* Old interrupt level */
227 ;
228 ; /* lock out all interrupts before any checking or changing */
229 ;
230 ; /* Obtain the current interrupt lockout posture. */
231 ; old_level = TCD_Interrupt_Level;
232 ;
233 ; /* Setup new interrupt lockout posture. */
234 ; TCD_Interrupt_Level = new_level;
235 ;
236 ; /* renable interrupts for the specified lockout */
237 ;
238 ; /* Return old interrupt lockout level. */
239 ; return(old_level);
240 ;
241 MRS a3,CPSR ; Pickup current CPSR
242 ORR a3,a3,#LOCKOUT ; Build lockout CPSR
243 MSR CPSR,a3 ; Lockout interrupts temporarily
244 LDR a2,Int_Level ; Pickup interrupt level
245 LDR a4,[a2, #0] ; Pickup current interrupt lockout
246 BIC a3,a3,#LOCK_MSK ; Clear lockout mask
247 ORR a3,a3,a1 ; Build new CPSR with appropriate
248 ; interrupts locked out
249 STR a1,[a2,#0] ; Save current lockout
250 MSR CPSR,a3 ; Setup new CPSR lockout bits
251 MOV a1,a4 ; Return previous lockout
252 BX lr ; Return to caller
253 ;}
254 ;
255 ;
256 ;
257 ;/*************************************************************************/
258 ;/* */
259 ;/* FUNCTION */
260 ;/* */
261 ;/* TCT_Local_Control_Interrupts */
262 ;/* */
263 ;/* DESCRIPTION */
264 ;/* */
265 ;/* This function enables and disables interrupts as specified by */
266 ;/* the caller. */
267 ;/* */
268 ;/* AUTHOR */
269 ;/* */
270 ;/* Barry Sellew, Accelerated Technology, Inc. */
271 ;/* */
272 ;/* CALLED BY */
273 ;/* */
274 ;/* Application */
275 ;/* */
276 ;/* CALLS */
277 ;/* */
278 ;/* None */
279 ;/* */
280 ;/* INPUTS */
281 ;/* */
282 ;/* new_level New interrupt enable level */
283 ;/* */
284 ;/* OUTPUTS */
285 ;/* */
286 ;/* old_level Previous interrupt enable */
287 ;/* level */
288 ;/* */
289 ;/* HISTORY */
290 ;/* */
291 ;/* NAME DATE REMARKS */
292 ;/* */
293 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
294 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
295 ;/* */
296 ;/*************************************************************************/
297 ;INT TCT_Local_Control_Interrupts (INT new_level)
298 ;{
299 .def $TCT_Local_Control_Interrupts
300 $TCT_Local_Control_Interrupts ; Dual-state interworking veneer
301 .state16
302 BX pc
303 NOP
304 .state32
305 B _TCT_Local_Control_Interrupts
306 ;
307 .def _TCT_Local_Control_Interrupts
308 _TCT_Local_Control_Interrupts
309 ;
310 ;INT old_level; /* Old interrupt level */
311 ;
312 ; /* read in the old level */
313 ; old_level = current interrupt level of processor;
314 ;
315 MRS a3,CPSR ; Pickup current CPSR
316 MOV a4,a3 ; save the old level
317 ;
318 ; /* clear out the old level and set the new level */
319 ; current interrupt level of processor &= ~LOCKOUT;
320 ; current interrupt level of processor |= new_level;
321 ;
322 BIC a3,a3,#LOCK_MSK ; Clear all current interrupts
323 ORR a3,a3,a1 ; Build new CPSR with new
324 ; interrupt level
325 MSR CPSR,a3 ; Setup new CPSR interrupt bits
326 ;
327 ; /* Return old interrupt lockout level. */
328 ; return(old_level);
329 ;
330 MOV a1,a4 ; Return previous lockout
331 BX lr ; Return to caller
332 ;}
333 ;
334 ;
335 ;
336 ;/*************************************************************************/
337 ;/* */
338 ;/* FUNCTION */
339 ;/* */
340 ;/* TCT_Restore_Interrupts */
341 ;/* */
342 ;/* DESCRIPTION */
343 ;/* */
344 ;/* This function restores interrupts to that specified in the global*/
345 ;/* TCD_Interrupt_Level variable. */
346 ;/* */
347 ;/* AUTHOR */
348 ;/* */
349 ;/* Barry Sellew, Accelerated Technology, Inc. */
350 ;/* */
351 ;/* CALLED BY */
352 ;/* */
353 ;/* Application */
354 ;/* */
355 ;/* CALLS */
356 ;/* */
357 ;/* None */
358 ;/* */
359 ;/* INPUTS */
360 ;/* */
361 ;/* None. */
362 ;/* */
363 ;/* OUTPUTS */
364 ;/* */
365 ;/* None. */
366 ;/* */
367 ;/* HISTORY */
368 ;/* */
369 ;/* NAME DATE REMARKS */
370 ;/* */
371 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
372 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
373 ;/* */
374 ;/*************************************************************************/
375 ;VOID TCT_Restore_Interrupts (VOID)
376 ;{
377 .def $TCT_Restore_Interrupts
378 $TCT_Restore_Interrupts ; Dual-state interworking veneer
379 .state16
380 BX pc
381 NOP
382 .state32
383 B _TCT_Restore_Interrupts
384 ;
385 .def _TCT_Restore_Interrupts
386 _TCT_Restore_Interrupts
387 ;
388 ; /* lock out all interrupts before any checking or changing */
389 ;
390 ; /* Obtain the current interrupt lockout posture. */
391 ;
392 ; /* reload the level base on the TCD_Interrupt_Level variable */
393 ;
394 ;
395 MRS a2,CPSR ; Pickup current CPSR
396 MOV a3,a2 ; save the CPSR value
397 ORR a2,a2,#LOCKOUT ; Build lockout CPSR
398 MSR CPSR,a2 ; Lockout interrupts temporarily
399 BIC a3,a3,#LOCK_MSK ; Clear current interrupt levels
400 LDR a2,Int_Level ; Load address of TCD_Interrupt_Level
401 LDR a1,[a2, #0] ; Pickup current interrupt lockout
402 ORR a3,a3,a1 ; Build new CPSR with appropriate
403 ; interrupts locked out
404 MSR CPSR,a3 ; Setup new CPSR lockout bits
405 BX lr ; Return to caller
406 ;}
407 ;
408 ;
409 ;
410 ;/*************************************************************************/
411 ;/* */
412 ;/* FUNCTION */
413 ;/* */
414 ;/* TCT_Build_Task_Stack */
415 ;/* */
416 ;/* DESCRIPTION */
417 ;/* */
418 ;/* This function builds an initial stack frame for a task. The */
419 ;/* initial stack contains information concerning initial values of */
420 ;/* registers and the task's point of entry. Furthermore, the */
421 ;/* initial stack frame is in the same form as an interrupt stack */
422 ;/* frame. */
423 ;/* */
424 ;/* AUTHOR */
425 ;/* */
426 ;/* Barry Sellew, Accelerated Technology, Inc. */
427 ;/* */
428 ;/* CALLED BY */
429 ;/* */
430 ;/* TCC_Create_Task Create a new task */
431 ;/* TCC_Reset_Task Reset the specified task */
432 ;/* */
433 ;/* CALLS */
434 ;/* */
435 ;/* None */
436 ;/* */
437 ;/* INPUTS */
438 ;/* */
439 ;/* task Task control block pointer */
440 ;/* */
441 ;/* OUTPUTS */
442 ;/* */
443 ;/* None */
444 ;/* */
445 ;/* HISTORY */
446 ;/* */
447 ;/* NAME DATE REMARKS */
448 ;/* */
449 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
450 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
451 ;/* */
452 ;/*************************************************************************/
453 ;VOID TCT_Build_Task_Stack(TC_TCB *task)
454 ;{
455 .def $TCT_Build_Task_Stack
456 $TCT_Build_Task_Stack ; Dual-state interworking veneer
457 .state16
458 BX pc
459 NOP
460 .state32
461 B _TCT_Build_Task_Stack
462 ;
463 .def _TCT_Build_Task_Stack
464 _TCT_Build_Task_Stack
465 ;
466 ; /* Pickup the stack base. */
467 ; REG_Stack_Base = (BYTE_PTR) task -> tc_stack_start;
468 ;
469 LDR a3,[a1,#24h] ; Pickup the stack starting address
470 ;
471 ; /* Pickup the stack size. */
472 ; REG_Stack_Size = task -> tc_stack_size;
473 ;
474 LDR a2,[a1,#30h] ; Pickup the stack size in bytes
475 ;
476 ; /* Calculate the stack ending address. */
477 ; REG_Stack_End = REG_Stack_Base + REG_Stack_Size - 1;
478 ;
479 ADD a4,a2,a3 ; Compute the beginning of stack
480 BIC a4,a4,#3 ; Insure word alignment
481 SUB a4,a4,#4 ; Reserve a word
482 ;
483 ; /* Save the stack ending address. */
484 ; task -> tc_stack_end = REG_Stack_End;
485 ;
486 STR a4,[a1,#28h] ; Save the stack ending address
487 ;
488 ; /* Reference the task shell. */
489 ; REG_Function_Ptr = (VOID *) TCC_Task_Shell;
490 ;
491 ; /* Build an initial stack. This initial stack frame facilitates an
492 ; interrupt return to the TCC_Task_Shell function, which in turn
493 ; invokes the application task. The initial stack frame has the
494 ; following format:
495 ;
496 ; (Lower Address) Stack Top -> 1 (Interrupt stack type)
497 ; CPSR Saved CPSR
498 ; a1 Saved a1
499 ; a2 Saved a2
500 ; a3 Saved a3
501 ; a4 Saved a4
502 ; v1 Saved v1
503 ; v2 Saved v2
504 ; v3 Saved v3
505 ; v4 Saved v4
506 ; v5 Saved v5
507 ; v6 Saved v6
508 ; v7 Saved v7
509 ; v8 Saved v8
510 ; ip Saved ip
511 ; sp Saved sp
512 ; lr Saved lr
513 ; (Higher Address) Stack Bottom-> pc Saved pc
514 ; */
515 ;
516 LDR a3,Task_Shell ; Pickup address of shell entry
517 STR a3,[a4], #-4 ; Store entry address on stack
518 MOV a3,#0 ; Clear value for initial registers
519 STR a3,[a4], #-4 ; Store initial lr
520 ADD a3,a4,#8h ; Compute initial sp
521 STR a3,[a4], #-4 ; Store initial sp (Stack Bottom)
522 STR ip,[a4], #-4 ; Store ip
523 STR a3,[a4], #-4 ; Store initial v8
524 LDR a3,[a1,#24h] ; Pickup the stack starting address
525 STR a3,[a4], #-4 ; Store initial v7
526 MOV a3,#0 ; Clear value for initial registers
527 STR v6,[a4], #-4 ; Store v6
528 STR v5,[a4], #-4 ; Store v5
529 STR a3,[a4], #-4 ; Store initial v4
530 STR a3,[a4], #-4 ; Store initial v3
531 STR a3,[a4], #-4 ; Store initial v2
532 STR a3,[a4], #-4 ; Store initial v1
533 STR a3,[a4], #-4 ; Store initial a4
534 STR a3,[a4], #-4 ; Store initial a3
535 STR a3,[a4], #-4 ; Store initial a2
536 STR a3,[a4], #-4 ; Store initial a1
537 MSR CPSR_FLG,a3 ; Clear the flags
538 MRS a3,CPSR ; Pickup the CPSR
539 BIC a3,a3,#LOCK_MSK ; Clear initial interrupt lockout
540 ORR a3,a3,#20h ; Set to Thumb state
541 STR a3,[a4], #-4 ; Store CPSR on the initial stack
542 MOV a3,#1 ; Build interrupt stack type (1)
543 STR a3,[a4, #0] ; Store stack type on the top
544 ;
545 ; /* Save the minimum amount of remaining stack memory. */
546 ; task -> tc_stack_minimum = REG_Stack_Size - 72;
547 ;
548 MOV a3,#72 ; Size of interrupt stack frame
549 SUB a2,a2,a3 ; Compute minimum available bytes
550 STR a2,[a1, #34h] ; Save in minimum stack area
551 ;
552 ; /* Save the new stack pointer into the task's control block. */
553 ; task -> tc_stack_pointer = (VOID *) Stack_Top;
554 ;
555 STR a4,[a1, #2Ch] ; Save stack pointer
556 BX lr
557 ;}
558 ;
559 ;
560 ;
561 ;/*************************************************************************/
562 ;/* */
563 ;/* FUNCTION */
564 ;/* */
565 ;/* TCT_Build_HISR_Stack */
566 ;/* */
567 ;/* DESCRIPTION */
568 ;/* */
569 ;/* This function builds an HISR stack frame that allows quick */
570 ;/* scheduling of the HISR. */
571 ;/* */
572 ;/* AUTHOR */
573 ;/* */
574 ;/* Barry Sellew, Accelerated Technology, Inc. */
575 ;/* */
576 ;/* CALLED BY */
577 ;/* */
578 ;/* TCC_Create_HISR Create HISR function */
579 ;/* */
580 ;/* CALLS */
581 ;/* */
582 ;/* None */
583 ;/* */
584 ;/* INPUTS */
585 ;/* */
586 ;/* hisr HISR control block pointer */
587 ;/* */
588 ;/* OUTPUTS */
589 ;/* */
590 ;/* None */
591 ;/* */
592 ;/* HISTORY */
593 ;/* */
594 ;/* NAME DATE REMARKS */
595 ;/* */
596 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
597 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
598 ;/* */
599 ;/*************************************************************************/
600 ;VOID TCT_Build_HISR_Stack(TC_HCB *hisr)
601 ;{
602 .def $TCT_Build_HISR_Stack
603 $TCT_Build_HISR_Stack ; Dual-state interworking veneer
604 .state16
605 BX pc
606 NOP
607 .state32
608 B _TCT_Build_HISR_Stack
609 ;
610 .def _TCT_Build_HISR_Stack
611 _TCT_Build_HISR_Stack
612 ;
613 ; /* Pickup the stack base. */
614 ; REG_Stack_Base = (BYTE_PTR) hisr -> tc_stack_start;
615 ;
616 LDR a3,[a1,#24h] ; Pickup the stack starting address
617 ;
618 ; /* Pickup the stack size. */
619 ; REG_Stack_Size = hisr -> tc_stack_size;
620 ;
621 LDR a2,[a1,#30h] ; Pickup the stack size in bytes
622 ;
623 ; /* Calculate the stack ending address. */
624 ; REG_Stack_End = REG_Stack_Base + REG_Stack_Size;
625 ;
626 ADD a4,a2,a3 ; Compute the beginning of stack
627 BIC a4,a4,#3 ; Insure word alignment
628 SUB a4,a4,#4 ; Reserve a word
629 ;
630 ; /* Save the stack ending address. */
631 ; hisr -> tc_stack_end = REG_Stack_End;
632 ;
633 STR a4,[a1,#28h] ; Save the stack ending address
634 ;
635 ; /* Reference the HISR shell. */
636 ; REG_Function_Ptr = (VOID *) TCT_HISR_Shell;
637 ;
638 ; /* Build an initial stack. This initial stack frame facilitates an
639 ; solicited return to the TCT_HISR_Shell function, which in turn
640 ; invokes the appropriate HISR. The initial HISR stack frame has the
641 ; following format:
642 ;
643 ; (Lower Address) Stack Top -> 0 (Solicited stack type)
644 ; 0/0x20 Saved state mask
645 ; v1 Saved v1
646 ; v2 Saved v2
647 ; v3 Saved v3
648 ; v4 Saved v4
649 ; v5 Saved v5
650 ; v6 Saved v6
651 ; v7 Saved v7
652 ; v8 Saved v8
653 ; ip Saved ip
654 ; (Higher Address) Stack Bottom-> pc Saved pc
655 ; */
656 ;
657 LDR a3,HISR_Shell ; Pickup address of shell entry
658 STR a3,[a4], #-4 ; Store entry address on stack
659 ADD a3,a4,#4h ; Compute initial sp
660 STR ip,[a4], #-4 ; Store ip
661 STR a3,[a4], #-4 ; Store initial v8
662 LDR a3,[a1,#24h] ; Pickup the stack starting address
663 STR a3,[a4], #-4 ; Store initial v7
664 MOV a3,#0 ; Clear value for initial registers
665 STR v6,[a4], #-4 ; Store v6
666 STR v5,[a4], #-4 ; Store v5
667 STR a3,[a4], #-4 ; Store initial v4
668 STR a3,[a4], #-4 ; Store initial v3
669 STR a3,[a4], #-4 ; Store initial v2
670 STR a3,[a4], #-4 ; Store initial v1
671 STR a3,[a4], #-4 ; Store initial state mask
672 STR a3,[a4, #0] ; Store solicited stack type on the
673 ; top of the stack
674 ;
675 ; /* Save the minimum amount of remaining stack memory. */
676 ; hisr -> tc_stack_minimum = REG_Stack_Size - 44;
677 ;
678 MOV a3,#44 ; Size of solicited stack frame
679 SUB a2,a2,a3 ; Compute minimum available bytes
680 STR a2,[a1, #34h] ; Save in minimum stack area
681 ;
682 ; /* Save the new stack pointer into the task's control block. */
683 ; hisr -> tc_stack_pointer = (VOID *) Stack_Top;
684 ;
685 STR a4,[a1, #2Ch] ; Save stack pointer
686 BX lr ; Return to caller
687 ;}
688 ;
689 ;
690 ;
691 ;/*************************************************************************/
692 ;/* */
693 ;/* FUNCTION */
694 ;/* */
695 ;/* TCT_Build_Signal_Frame */
696 ;/* */
697 ;/* DESCRIPTION */
698 ;/* */
699 ;/* This function builds a frame on top of the task's stack to */
700 ;/* cause the task's signal handler to execute the next time */
701 ;/* the task is executed. */
702 ;/* */
703 ;/* AUTHOR */
704 ;/* */
705 ;/* Barry Sellew, Accelerated Technology, Inc. */
706 ;/* */
707 ;/* CALLED BY */
708 ;/* */
709 ;/* TCC_Send_Signals Send signals to a task */
710 ;/* */
711 ;/* CALLS */
712 ;/* */
713 ;/* None */
714 ;/* */
715 ;/* INPUTS */
716 ;/* */
717 ;/* task Task control block pointer */
718 ;/* */
719 ;/* OUTPUTS */
720 ;/* */
721 ;/* None */
722 ;/* */
723 ;/* HISTORY */
724 ;/* */
725 ;/* NAME DATE REMARKS */
726 ;/* */
727 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
728 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
729 ;/* */
730 ;/*************************************************************************/
731 ;VOID TCT_Build_Signal_Frame(TC_TCB *task)
732 ;{
733 .def $TCT_Build_Signal_Frame
734 $TCT_Build_Signal_Frame ; Dual-state interworking veneer
735 .state16
736 BX pc
737 NOP
738 .state32
739 B _TCT_Build_Signal_Frame
740 ;
741 .def _TCT_Build_Signal_Frame
742 _TCT_Build_Signal_Frame
743 ;
744 ; /* Pickup the stack pointer. */
745 ; REG_Stack_Ptr = (BYTE_PTR) task -> tc_stack_pointer;
746 ;
747 LDR a4,[a1,#2ch] ; Pickup the current stack pointer
748 ;
749 ; /* Reference the Signal shell. */
750 ; REG_Function_Ptr = (VOID *) TCC_Signal_Shell;
751 ;
752 ; /* Build a signal stack. This signal stack frame facilitates an
753 ; solicited return to the TCC_Signal_Shell function, which in turn
754 ; invokes the appropriate signal handler. The initial HISR stack frame
755 ; has the following format:
756 ;
757 ; (Lower Address) Stack Top -> 0 (Solicited stack type)
758 ; 0/0x20 Saved state mask
759 ; v1 Saved v1
760 ; v2 Saved v2
761 ; v3 Saved v3
762 ; v4 Saved v4
763 ; v5 Saved v5
764 ; v6 Saved v6
765 ; v7 Saved v7
766 ; v8 Saved v8
767 ; ip Saved ip
768 ; (Higher Address) Stack Bottom-> pc Saved pc
769 ; */
770 ;
771 LDR a3,Signal_Shell ; Pickup address of shell entry
772 STR a3,[a4], #-4 ; Store entry address on stack
773 ADD a3,a4,#4h ; Compute initial sp
774 STR ip,[a4], #-4 ; Store ip
775 STR a3,[a4], #-4 ; Store initial v8
776 LDR a3,[a1,#24h] ; Pickup the stack starting address
777 STR a3,[a4], #-4 ; Store initial v7
778 MOV a3,#0 ; Clear value for initial registers
779 STR v6,[a4], #-4 ; Store v6
780 STR v5,[a4], #-4 ; Store v5
781 STR a3,[a4], #-4 ; Store initial v4
782 STR a3,[a4], #-4 ; Store initial v3
783 STR a3,[a4], #-4 ; Store initial v2
784 STR a3,[a4], #-4 ; Store initial v1
785 MOV a2,#20h ; Get initial state mask
786 STR a2,[a4, #0] ; Store initial state mask
787 STR a3,[a4, #0] ; Store solicited stack type on the
788 ; top of the stack
789 ;
790 ; /* Save the new stack pointer into the task's control block. */
791 ; task -> tc_stack_pointer = (VOID *) (REG_Stack_Ptr - REG_Stack_Size);
792 ;
793 STR a4,[a1, #2Ch] ; Save stack pointer
794 BX lr ; Return to caller
795 ;}
796 ;
797 ;
798 ;
799 ;/*************************************************************************/
800 ;/* */
801 ;/* FUNCTION */
802 ;/* */
803 ;/* TCT_Check_Stack */
804 ;/* */
805 ;/* DESCRIPTION */
806 ;/* */
807 ;/* This function checks the current stack for overflow conditions. */
808 ;/* Additionally, this function keeps track of the minimum amount */
809 ;/* of stack space for the calling thread and returns the current */
810 ;/* available stack space. */
811 ;/* */
812 ;/* AUTHOR */
813 ;/* */
814 ;/* Barry Sellew, Accelerated Technology, Inc. */
815 ;/* */
816 ;/* CALLED BY */
817 ;/* */
818 ;/* TCC_Send_Signals Send signals to a task */
819 ;/* */
820 ;/* CALLS */
821 ;/* */
822 ;/* ERC_System_Error System error handler */
823 ;/* */
824 ;/* INPUTS */
825 ;/* */
826 ;/* None */
827 ;/* */
828 ;/* OUTPUTS */
829 ;/* */
830 ;/* available bytes in stack */
831 ;/* */
832 ;/* HISTORY */
833 ;/* */
834 ;/* NAME DATE REMARKS */
835 ;/* */
836 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
837 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
838 ;/* */
839 ;/*************************************************************************/
840 ;UNSIGNED TCT_Check_Stack(void)
841 ;{
842 .def $TCT_Check_Stack
843 $TCT_Check_Stack ; Dual-state interworking veneer
844 .state16
845 BX pc
846 NOP
847 .state32
848 B _TCT_Check_Stack
849 ;
850 .def _TCT_Check_Stack
851 _TCT_Check_Stack
852 ;
853 ;TC_TCB *thread;
854 ;UNSIGNED remaining;
855 ;
856 ; /* Pickup the current task/HISR pointer. */
857 ; thread = (TC_TCB *) TCD_Current_Thread;
858 ;
859 LDR a1,Current_Thread ; Pickup address of thread pointer
860 LDR a1,[a1,#0] ; Pickup thread pointer
861 ;
862 ; /* Determine if there is a current thread. */
863 ; if (thread)
864 ; {
865 ;
866 CMP a1,#0 ; Determine if a thread is active
867 MOV a4,#0 ; Default remaining value
868 BEQ TCT_Skip_Stack_Check ; If NU_NULL, skip stack checking
869 ;
870 ; /* Determine if the stack pointers are out of range. */
871 ; if ((thread -> tc_stack_pointer < thread -> tc_stack_start) ||
872 ; (thread -> tc_stack_pointer > thread -> tc_stack_end))
873 ;
874 LDR a3,[a1,#24h] ; Pickup start of stack area
875 CMP sp,a3 ; Compare with current stack ptr
876 BLT TCT_Stack_Range_Error ; If less, stack is out of range
877 LDR a2,[a1,#28h] ; Pickup end of stack area
878 CMP sp,a2 ; Compare with current stack ptr
879 BLE TCT_Stack_Range_Okay ; If less, stack range is okay
880 ;
881 ; /* Stack overflow condition exits. */
882 ; ERC_System_Error(NU_STACK_OVERFLOW);
883 ;
884 TCT_Stack_Range_Error
885 ;
886 STR lr,[sp, #4]! ; Store lr on the stack
887 MOV a1,#3 ; Build NU_STACK_OVERFLOW code
888 LDR a4,System_Error ; Call system error handler. Note:
889 BX a4 ; control is not returned!
890 ; Examine stack to find return
891 ; address of this routine.
892 TCT_Stack_Range_Okay
893 ;
894 ; /* Calculate the amount of available space on the stack. */
895 ; remaining = (BYTE_PTR) thread -> tc_stack_pointer -
896 ; (BYTE_PTR) thread -> tc_stack_start;
897 ;
898 SUB a4,sp,a3 ; Calculate remaining stack size
899 ;
900 ; /* Determine if there is enough memory on the stack to save all of the
901 ; registers. */
902 ; if (remaining < 80)
903 ;
904 CMP a4,#80 ; Is there enough room for an
905 ; interrupt frame?
906 BCS TCT_No_Stack_Error ; If so, no stack overflow yet
907 ;
908 ; /* Stack overflow condition is about to happen. */
909 ; ERC_System_Error(NU_STACK_OVERFLOW);
910 ;
911 STR lr,[sp, #4]! ; Store lr on the stack
912 MOV a1,#3 ; Build NU_STACK_OVERFLOW code
913 LDR a4,System_Error ; Call system error handler. Note:
914 BX a4 ; control is not returned!
915 ; Examine stack to find return
916 ; address of this routine.
917 TCT_No_Stack_Error
918 ;
919 ; /* Determine if this is a new minimum amount of stack space. */
920 ; if (remaining < thread -> tc_stack_minimum)
921 ;
922 LDR a3,[a1,#34h]
923 CMP a4,a3
924 STRCC a4,[a1,#34h]
925 ;
926 ; /* Save the new stack minimum. */
927 ; thread -> tc_stack_minimum = remaining;
928 ; }
929 ; else
930 ;
931 ; /* Set the remaining bytes to 0. */
932 ; remaining = 0;
933 ;
934 ; /* Return the remaining number of bytes on the stack. */
935 ; return(remaining);
936 ;
937 TCT_Skip_Stack_Check
938 MOV a1,a4 ; Return remaining bytes
939 BX lr ; Return to caller
940 ;}
941 ;
942 ;
943 ;
944 ;/*************************************************************************/
945 ;/* */
946 ;/* FUNCTION */
947 ;/* */
948 ;/* TCC_Schedule */
949 ;/* */
950 ;/* DESCRIPTION */
951 ;/* */
952 ;/* This function waits for a thread to become ready. Once a thread */
953 ;/* is ready, this function initiates a transfer of control to that */
954 ;/* thread. */
955 ;/* */
956 ;/* AUTHOR */
957 ;/* */
958 ;/* Barry Sellew, Accelerated Technology, Inc. */
959 ;/* */
960 ;/* CALLED BY */
961 ;/* */
962 ;/* INC_Initialize Main initialization routine */
963 ;/* */
964 ;/* CALLS */
965 ;/* */
966 ;/* TCT_Control_To_Thread Transfer control to a thread */
967 ;/* INT_Small_Sleep GSM small sleep */
968 ;/* INPUTS */
969 ;/* */
970 ;/* TCD_Execute_Task Pointer to task to execute */
971 ;/* */
972 ;/* OUTPUTS */
973 ;/* */
974 ;/* None */
975 ;/* */
976 ;/* HISTORY */
977 ;/* */
978 ;/* NAME DATE REMARKS */
979 ;/* */
980 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
981 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
982 ;/* P. Roussel (TI) 07-21-1999 Call GSM small sleep */
983 ;/* */
984 ;/*************************************************************************/
985 ;VOID TCT_Schedule(void)
986 ;{
987 .def $TCT_Schedule
988 $TCT_Schedule ; Dual-state interworking veneer
989 .state16
990 BX pc
991 NOP
992 .state32
993 B _TCT_Schedule
994 ;
995 .def _TCT_Schedule
996 _TCT_Schedule
997 ;
998 ; /* Restore interrupts according to the value contained in
999 ; TCD_Interrupt_Level. */
1000 ;
1001 LDR a2,Int_Level ; Build address of interrupt level
1002 MRS a1,CPSR ; Pickup current CPSR
1003 LDR a3,[a2, #0] ; Pickup current interrupt lockout
1004 BIC a1,a1,#LOCK_MSK ; Clear the interrupt lockout bits
1005 ORR a1,a1,a3 ; Build new interrupt lockout CPSR
1006 MSR CPSR,a1 ; Setup new CPSR
1007 LDR a3,Execute_HISR ; Pickup TCD_Execute_HISR address
1008 LDR a4,Execute_Task ; Pickup TCD_Execute_Task address
1009 ;
1010 ; /* Wait until a thread (task or HISR) is available to execute. */
1011 ; do
1012 ; {
1013 .def TCT_Schedule_Loop
1014 TCT_Schedule_Loop
1015 ;
1016 ; } while ((!TCD_Execute_HISR) && (!TCD_Execute_Task));
1017 ;
1018 LDR a1,[a3, #0] ; Pickup highest priority HISR ptr
1019 CMP a1,#0 ; Is there a HISR active?
1020 BNE TCT_Schedule_Thread ; Found an HISR
1021 LDR a1,[a4, #0] ; Pickup highest priority Task ptr
1022 CMP a1,#0 ; Is there a task active?
1023
1024 .ref INT_Small_Sleep
1025 BEQ INT_Small_Sleep ; No, enter the GSM Small Sleep mode
1026
1027 ;
1028 ; /* Yes, either a task or an HISR is ready to execute. Lockout
1029 ; interrupts while the thread is transferred to. */
1030 ;
1031 TCT_Schedule_Thread
1032 MRS a2,CPSR ; Pickup CPSR again
1033 ORR a2,a2,#LOCKOUT ; Build interrupt lockout value
1034 MSR CPSR,a2 ; Lockout interrupts
1035 ;
1036 ; /* Transfer control to the thread by falling through to the following
1037 ; routine. */
1038 ;}
1039 ;
1040 ;
1041 ;
1042 ;/*************************************************************************/
1043 ;/* */
1044 ;/* FUNCTION */
1045 ;/* */
1046 ;/* TCT_Control_To_Thread */
1047 ;/* */
1048 ;/* DESCRIPTION */
1049 ;/* */
1050 ;/* This function transfers control to the specified thread. Each */
1051 ;/* time control is transferred to a thread, its scheduled counter */
1052 ;/* is incremented. Additionally, time-slicing for task threads is */
1053 ;/* enabled in this routine. The TCD_Current_Thread pointer is */
1054 ;/* setup by this function. */
1055 ;/* */
1056 ;/* AUTHOR */
1057 ;/* */
1058 ;/* Barry Sellew, Accelerated Technology, Inc. */
1059 ;/* */
1060 ;/* CALLED BY */
1061 ;/* */
1062 ;/* TCT_Schedule Indirectly called */
1063 ;/* TCT_Protect Protection task switch */
1064 ;/* */
1065 ;/* CALLS */
1066 ;/* */
1067 ;/* None */
1068 ;/* */
1069 ;/* INPUTS */
1070 ;/* */
1071 ;/* thread Thread control block pointer */
1072 ;/* */
1073 ;/* OUTPUTS */
1074 ;/* */
1075 ;/* None */
1076 ;/* */
1077 ;/* HISTORY */
1078 ;/* */
1079 ;/* NAME DATE REMARKS */
1080 ;/* */
1081 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1082 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1083 ;/* */
1084 ;/*************************************************************************/
1085 ;VOID TCT_Control_To_Thread(TC_TCB *thread)
1086 ;{
1087 ;
1088 _TCT_Control_To_Thread
1089 ;
1090 ; /* Setup the current thread pointer. */
1091 ; TCD_Current_Thread = (VOID *) thread;
1092 ;
1093 LDR a2,Current_Thread ; Pickup current thread ptr address
1094 LDR a3,[a1, #1ch] ; Pickup scheduled count
1095 STR a1,[a2, #0] ; Setup current thread pointer
1096 ; TI CODE : Call the Function that log the Current Thread.
1097
1098 .if OP_L1_STANDALONE = 0
1099 .if TI_NUC_MONITOR = 1
1100 .global _ti_nuc_monitor_Thread_log
1101 STMFD sp!,{r0-r5}
1102 BL _ti_nuc_monitor_Thread_log ; Call the Thread Log function.
1103 LDMFD sp!,{r0-r5}
1104 .endif
1105 .endif
1106 ;
1107 ; /* Increment the thread scheduled counter. */
1108 ; thread -> tc_scheduled++;
1109 ;
1110 LDR a4,[a1, #20h] ; Pickup time slice value
1111 ADD a3,a3,#1 ; Increment the scheduled count
1112 STR a3,[a1, #1ch] ; Store new scheduled count
1113 ;
1114 ; /* Check for time slice option. */
1115 ; if (thread -> tc_cur_time_slice)
1116 ; {
1117 CMP a4,#0 ; Is there a time slice?
1118 BEQ TCT_No_Start_TS_1 ; If 0, there is no time slice
1119 ;
1120 ; /* Start a time slice. */
1121 ; TMD_Time_Slice = thread -> tc_cur_time_slice;
1122 ; TMD_Time_Slice_State = 0;
1123 ;
1124 LDR a3,Time_Slice ; Pickup address of TMD_Time_Slice
1125 LDR a2,Slice_State ; Pickup address of
1126 ; TMD_Time_Slice_State
1127 STR a4,[a3,#0] ; Setup the time slice
1128 MOV a3,#0 ; Build active state flag
1129 STR a3,[a2,#0] ; Set the active flag
1130 ; }
1131 TCT_No_Start_TS_1
1132 ;
1133 ; /* Pickup the stack pointer and resume the thread. */
1134 ; REG_Stack_Ptr = thread -> tc_stack_pointer;
1135 ;
1136 LDR sp,[a1, #2ch] ; Switch to thread's stack pointer
1137 ;
1138 ; /* Pop off the saved information associated with the thread. After we
1139 ; determine which type of stack is present. A 1 on the top of the
1140 ; stack indicates an interrupt stack, while a 0 on the top of the
1141 ; stack indicates a solicited type of stack. */
1142 ;
1143 ; /* Remember that the interrupt level that is restored must represent
1144 ; the interrupt level in TCD_Interrupt_Level. */
1145 ;
1146 LDR a2,[sp], #4 ; Pop off the stack type
1147 CMP a2,#1 ; See if it is an interrupt stack
1148 BEQ TCT_Interrupt_Resume ; If so, an interrupt resume of
1149 ; thread is required
1150 LDR a2,Int_Level ; Pickup address of interrupt
1151 ; lockout
1152 MRS a1,CPSR ; Pickup current CPSR
1153 BIC a1,a1,#LOCK_MSK ; Clear lockout mask
1154 LDR a3,[a2, #0] ; Pickup interrupt lockout mask
1155 ORR a1,a1,a3 ; Build new interrupt lockout mask
1156 LDR a3,[sp], #4 ; Pop off the state mask
1157 ORR a1,a1,a3 ; Set appropriate state
1158 MSR SPSR,a1 ; Place in the SPSR
1159 LDMIA sp!,{v1-ip,pc}^ ; A solicited return is required.
1160 ;
1161 TCT_Interrupt_Resume
1162 LDR a1,[sp],#4 ; Pop off the CPSR
1163 LDR a2,Int_Level ; Pickup address of interrupt
1164 ; lockout
1165 BIC a1,a1,#LOCK_MSK ; Clear lockout mask
1166 LDR a3,[a2, #0] ; Pickup interrupt lockout mask
1167 ORR a1,a1,a3 ; Build new interrupt lockout mask
1168 MSR SPSR,a1 ; Place it into the SPSR
1169 LDMIA sp,{a1-pc}^ ; Recover all registers and resume
1170 ; at point of interrupt
1171 ;}
1172 ;
1173 ;
1174 ;
1175 ;/*************************************************************************/
1176 ;/* */
1177 ;/* FUNCTION */
1178 ;/* */
1179 ;/* TCT_Control_To_System */
1180 ;/* */
1181 ;/* DESCRIPTION */
1182 ;/* */
1183 ;/* This function returns control from a thread to the system. Note */
1184 ;/* that this service is called in a solicited manner, i.e. it is */
1185 ;/* not called from an interrupt thread. Registers required by the */
1186 ;/* compiler to be preserved across function boundaries are saved by */
1187 ;/* this routine. Note that this is usually a sub-set of the total */
1188 ;/* number of available registers. */
1189 ;/* */
1190 ;/* AUTHOR */
1191 ;/* */
1192 ;/* Barry Sellew, Accelerated Technology, Inc. */
1193 ;/* */
1194 ;/* CALLED BY */
1195 ;/* */
1196 ;/* Other Components */
1197 ;/* */
1198 ;/* CALLS */
1199 ;/* */
1200 ;/* TCT_Schedule Schedule the next thread */
1201 ;/* */
1202 ;/* INPUTS */
1203 ;/* */
1204 ;/* None */
1205 ;/* */
1206 ;/* OUTPUTS */
1207 ;/* */
1208 ;/* None */
1209 ;/* */
1210 ;/* HISTORY */
1211 ;/* */
1212 ;/* NAME DATE REMARKS */
1213 ;/* */
1214 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1215 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1216 ;/* */
1217 ;/*************************************************************************/
1218 ;VOID TCT_Control_To_System(void)
1219 ;{
1220 .def $TCT_Control_To_System
1221 $TCT_Control_To_System ; Dual-state interworking veneer
1222 .state16
1223 BX pc
1224 NOP
1225 .state32
1226 B _TCT_Control_To_System
1227 ;
1228 .def _TCT_Control_To_System
1229 _TCT_Control_To_System
1230 ;
1231 ; /* Lockout interrupts. */
1232 ;
1233 MRS a1,CPSR ; Pickup current CPSR
1234 ORR a1,a1,#LOCKOUT ; Build interrupt lockout value
1235 MSR CPSR,a1 ; Lockout interrupts
1236 ;
1237 ; /* Save a minimal context of the thread. */
1238 ;
1239 STMDB sp!,{v1-ip,lr} ; Save minimal context of thread on
1240 ; the current stack
1241 MOV a3,lr ; Determine what state the
1242 MOV a3,a3,LSL #31 ; caller was in and build an
1243 MOV a3,a3,LSR #26 ; appropriate state mask
1244 STR a3,[sp, #-4]! ; Place it on the stack
1245 MOV a3,#0 ; Build solicited stack type value
1246 ; and NU_NULL value
1247 STR a3,[sp, #-4]! ; Place it on the top of the stack
1248 ;
1249 ; /* Setup a pointer to the thread control block. */
1250 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
1251 ;
1252 LDR a2,Current_Thread ; Pickup current thread ptr address
1253 LDR a1,[a2, #0] ; Pickup current thread pointer
1254 ;
1255 ; /* Clear the current thread control block pointer. */
1256 ; TCD_Current_Thread = NU_NULL;
1257 ;
1258 LDR a4,Slice_State ; Pickup time slice state address
1259 STR a3,[a2, #0] ; Set current thread pointer to
1260 ; NU_NULL
1261 ;
1262 ; /* Check to see if a time slice is active. If so, copy the original time
1263 ; slice into the current time slice field of the task's control block. */
1264 ; if (TMD_Time_Slice_State == 0)
1265 ; {
1266 LDR a2,[a4, #0] ; Pickup time slice state flag
1267 CMP a2,#0 ; Compare with active value
1268 BNE TCT_No_Stop_TS_1 ; If non-active, don't disable
1269 ;
1270 ;
1271 ; /* Insure that the next time the task runs it gets a fresh time
1272 ; slice. */
1273 ; REG_Thread_Ptr -> tc_cur_time_slice = REG_Thread_Ptr -> tc_time_slice;
1274 ;
1275 LDR a2,[a1, #40h] ; Pickup original time slice
1276 ;
1277 ; /* Clear any active time slice by setting the state to NOT_ACTIVE. */
1278 ; TMD_Time_Slice_State = 1;
1279 ;
1280 MOV a3,#1 ; Build disable value
1281 STR a3,[a4, #0] ; Disable time slice
1282 STR a2,[a1, #20h] ; Reset current time slice
1283 ; }
1284 TCT_No_Stop_TS_1
1285 ;
1286 ; /* Save off the current stack pointer in the control block. */
1287 ; REG_Thread_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr;
1288 ;
1289 STR sp,[a1, #2ch] ; Save the thread's stack pointer
1290 ;
1291 ; /* Clear the task's current protection. */
1292 ; (REG_Thread_Ptr -> tc_current_protect) -> tc_tcb_pointer = NU_NULL;
1293 ; REG_Thread_Ptr -> tc_current_protect = NU_NULL;
1294 ;
1295 LDR a2,[a1, #38h] ; Pickup current thread pointer
1296 MOV a3,#0 ; Build NU_NULL value
1297 STR a3,[a1, #38h] ; Clear the protect pointer field
1298 STR a3,[a2, #0] ; Release the actual protection
1299 ;
1300 ; /* Switch to the system stack. */
1301 ; REG_Stack_Ptr = TCD_System_Stack;
1302 ;
1303 LDR a2,System_Stack ; Pickup address of stack pointer
1304 LDR a3,System_Limit ; Pickup address of stack limit ptr
1305 LDR sp,[a2, #0] ; Switch to system stack
1306 LDR v7,[a3, #0] ; Setup system stack limit
1307 ;
1308 ; /* Finished, return to the scheduling loop. */
1309 ;
1310 B _TCT_Schedule ; Return to scheduling loop
1311 ;}
1312 ;
1313 ;
1314 ;
1315 ;/*************************************************************************/
1316 ;/* */
1317 ;/* FUNCTION */
1318 ;/* */
1319 ;/* TCT_Signal_Exit */
1320 ;/* */
1321 ;/* DESCRIPTION */
1322 ;/* */
1323 ;/* This function exits from a signal handler. The primary purpose */
1324 ;/* of this function is to clear the scheduler protection and switch */
1325 ;/* the stack pointer back to the normal task's stack pointer. */
1326 ;/* */
1327 ;/* AUTHOR */
1328 ;/* */
1329 ;/* Barry Sellew, Accelerated Technology, Inc. */
1330 ;/* */
1331 ;/* CALLED BY */
1332 ;/* */
1333 ;/* TCC_Signal_Shell Signal handling shell func */
1334 ;/* */
1335 ;/* CALLS */
1336 ;/* */
1337 ;/* TCT_Schedule Scheduler */
1338 ;/* */
1339 ;/* INPUTS */
1340 ;/* */
1341 ;/* None */
1342 ;/* */
1343 ;/* OUTPUTS */
1344 ;/* */
1345 ;/* None */
1346 ;/* */
1347 ;/* HISTORY */
1348 ;/* */
1349 ;/* NAME DATE REMARKS */
1350 ;/* */
1351 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1352 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1353 ;/* */
1354 ;/*************************************************************************/
1355 ;VOID TCT_Signal_Exit(void)
1356 ;{
1357 .def $TCT_Signal_Exit
1358 $TCT_Signal_Exit ; Dual-state interworking veneer
1359 .state16
1360 BX pc
1361 NOP
1362 .state32
1363 B _TCT_Signal_Exit
1364 ;
1365 .def _TCT_Signal_Exit
1366 _TCT_Signal_Exit
1367 ;
1368 ; /* Lockout interrupts. */
1369 ;
1370 MRS a4,CPSR ; Pickup current CPSR
1371 ORR a4,a4,#LOCKOUT ; Build lockout value
1372 MSR CPSR,a4 ; Lockout interrupts
1373 ;
1374 ; /* Setup a pointer to the thread control block. */
1375 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
1376 ;
1377 LDR a2,Current_Thread ; Pickup address of thread pointer
1378 MOV a3,#0 ; Build NU_NULL value
1379 LDR a1,[a2,#0] ; Pickup current thread pointer
1380 ;
1381 ; /* Clear the current thread control block. */
1382 ; TCD_Current_Thread = NU_NULL;
1383 ;
1384 LDR a4,Slice_State ; Pickup time slice state address
1385 STR a3,[a2, #0] ; Clear current thread pointer
1386 ;
1387 ; /* Check to see if a time slice is active. If so, copy the original time
1388 ; slice into the current time slice field of the task's control block. */
1389 ; if (TMD_Time_Slice_State == 0)
1390 ; {
1391 ;
1392 LDR a2,[a4, #0] ; Pickup time slice state flag
1393 CMP a2,#0 ; Compare with active value
1394 BNE TCT_No_Stop_TS_2 ; If non-active, don't disable
1395 ;
1396 ; /* Insure that the next time the task runs it gets a fresh time
1397 ; slice. */
1398 ; REG_Thread_Ptr -> tc_cur_time_slice = REG_Thread_Ptr -> tc_time_slice;
1399 ;
1400 LDR a2,[a1, #40h] ; Pickup original time slice
1401 ;
1402 ; /* Clear any active time slice by setting the state to NOT_ACTIVE. */
1403 ; TMD_Time_Slice_State = 1;
1404 ;
1405 MOV a3,#1 ; Build disable value
1406 STR a3,[a4, #0] ; Disable time slice
1407 STR a2,[a1, #20h] ; Reset current time slice
1408 ; }
1409 TCT_No_Stop_TS_2
1410 ;
1411 ; /* Switch back to the saved stack. The saved stack pointer was saved
1412 ; before the signal frame was built. */
1413 ; REG_Thread_Ptr -> tc_stack_pointer =
1414 ; REG_Thread_Ptr -> tc_saved_stack_ptr;
1415 ;
1416 LDR a2,[a1, #3ch] ; Pickup saved stack pointer
1417 STR a2,[a1, #2ch] ; Place in current stack pointer
1418 ;
1419 ; /* Clear the task's current protection. */
1420 ; (REG_Thread_Ptr -> tc_current_protect) -> tc_tcb_pointer = NU_NULL;
1421 ; REG_Thread_Ptr -> tc_current_protect = NU_NULL;
1422 ;
1423 LDR a2,[a1, #38h] ; Pickup current thread pointer
1424 MOV a3,#0 ; Build NU_NULL value
1425 STR a3,[a1, #38h] ; Clear the protect pointer field
1426 STR a3,[a2, #0] ; Release the actual protection
1427 ;
1428 ; /* Switch to the system stack. */
1429 ; REG_Stack_Ptr = (BYTE_PTR) TCD_System_Stack;
1430 ;
1431 LDR a2,System_Stack ; Pickup address of stack pointer
1432 LDR a3,System_Limit ; Pickup address of stack limit ptr
1433 LDR sp,[a2, #0] ; Switch to system stack
1434 LDR v7,[a3, #0] ; Setup system stack limit
1435 ;
1436 ; /* Finished, return to the scheduling loop. */
1437 ;
1438 B _TCT_Schedule ; Return to scheduling loop
1439 ;}
1440 ;
1441 ;
1442 ;
1443 ;/*************************************************************************/
1444 ;/* */
1445 ;/* FUNCTION */
1446 ;/* */
1447 ;/* TCT_Current_Thread */
1448 ;/* */
1449 ;/* DESCRIPTION */
1450 ;/* */
1451 ;/* This function returns the current thread pointer. */
1452 ;/* */
1453 ;/* AUTHOR */
1454 ;/* */
1455 ;/* Barry Sellew, Accelerated Technology, Inc. */
1456 ;/* */
1457 ;/* CALLED BY */
1458 ;/* */
1459 ;/* Application */
1460 ;/* System Components */
1461 ;/* */
1462 ;/* CALLS */
1463 ;/* */
1464 ;/* None */
1465 ;/* */
1466 ;/* INPUTS */
1467 ;/* */
1468 ;/* None */
1469 ;/* */
1470 ;/* OUTPUTS */
1471 ;/* */
1472 ;/* Pointer to current thread */
1473 ;/* */
1474 ;/* HISTORY */
1475 ;/* */
1476 ;/* NAME DATE REMARKS */
1477 ;/* */
1478 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1479 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1480 ;/* */
1481 ;/*************************************************************************/
1482 ;VOID *TCT_Current_Thread(void)
1483 ;{
1484 .def $TCT_Current_Thread
1485 $TCT_Current_Thread ; Dual-state interworking veneer
1486 .state16
1487 BX pc
1488 NOP
1489 .state32
1490 B _TCT_Current_Thread
1491 ;
1492 .def _TCT_Current_Thread
1493 _TCT_Current_Thread
1494 ;
1495 ; /* Return the current thread pointer. */
1496 ; return(TCD_Current_Thread);
1497 ;
1498 LDR a1,Current_Thread ; Pickup address of thread pointer
1499 LDR a1,[a1, #0] ; Pickup current thread pointer
1500 BX lr ; Return to caller
1501 ;}
1502 ;
1503 ;
1504 ;
1505 ;/*************************************************************************/
1506 ;/* */
1507 ;/* FUNCTION */
1508 ;/* */
1509 ;/* TCT_Set_Execute_Task */
1510 ;/* */
1511 ;/* DESCRIPTION */
1512 ;/* */
1513 ;/* This function sets the current task to execute variable under */
1514 ;/* protection against interrupts. */
1515 ;/* */
1516 ;/* AUTHOR */
1517 ;/* */
1518 ;/* Barry Sellew, Accelerated Technology, Inc. */
1519 ;/* */
1520 ;/* CALLED BY */
1521 ;/* */
1522 ;/* TCC Scheduling Routines */
1523 ;/* */
1524 ;/* CALLS */
1525 ;/* */
1526 ;/* None */
1527 ;/* */
1528 ;/* INPUTS */
1529 ;/* */
1530 ;/* task Pointer to task control block*/
1531 ;/* */
1532 ;/* OUTPUTS */
1533 ;/* */
1534 ;/* TCD_Execute_Task Modified variable */
1535 ;/* */
1536 ;/* HISTORY */
1537 ;/* */
1538 ;/* NAME DATE REMARKS */
1539 ;/* */
1540 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1541 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1542 ;/* */
1543 ;/*************************************************************************/
1544 ;VOID TCT_Set_Execute_Task(TC_TCB *task)
1545 ;{
1546 .def $TCT_Set_Execute_Task
1547 $TCT_Set_Execute_Task ; Dual-state interworking veneer
1548 .state16
1549 BX pc
1550 NOP
1551 .state32
1552 B _TCT_Set_Execute_Task
1553 ;
1554 .def _TCT_Set_Execute_Task
1555 _TCT_Set_Execute_Task
1556 ;
1557 ; /* Now setup the TCD_Execute_Task pointer. */
1558 ; TCD_Execute_Task = task;
1559 ;
1560 LDR a2,Execute_Task ; Pickup execute task ptr address
1561 STR a1,[a2,#0] ; Setup new task to execute
1562 BX lr ; Return to caller
1563 ;}
1564 ;
1565 ;
1566 ;
1567 ;/*************************************************************************/
1568 ;/* */
1569 ;/* FUNCTION */
1570 ;/* */
1571 ;/* TCT_Protect */
1572 ;/* */
1573 ;/* DESCRIPTION */
1574 ;/* */
1575 ;/* This function protects against multiple thread access. */
1576 ;/* */
1577 ;/* AUTHOR */
1578 ;/* */
1579 ;/* Barry Sellew, Accelerated Technology, Inc. */
1580 ;/* */
1581 ;/* CALLED BY */
1582 ;/* */
1583 ;/* Application */
1584 ;/* System Components */
1585 ;/* */
1586 ;/* CALLS */
1587 ;/* */
1588 ;/* None */
1589 ;/* */
1590 ;/* INPUTS */
1591 ;/* */
1592 ;/* protect Pointer to protection block */
1593 ;/* */
1594 ;/* OUTPUTS */
1595 ;/* */
1596 ;/* None */
1597 ;/* */
1598 ;/* HISTORY */
1599 ;/* */
1600 ;/* NAME DATE REMARKS */
1601 ;/* */
1602 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1603 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1604 ;/* */
1605 ;/*************************************************************************/
1606 ;VOID TCT_Protect(TC_PROTECT *protect)
1607 ;{
1608 .def $TCT_Protect
1609 $TCT_Protect ; Dual-state interworking veneer
1610 .state16
1611 BX pc
1612 NOP
1613 .state32
1614 B _TCT_Protect
1615 ;
1616 .def _TCT_Protect
1617 _TCT_Protect
1618 ;
1619 ; /* Determine if the caller is in a task or HISR thread. */
1620 ; if (TCD_Current_Thread)
1621 ; {
1622 ;
1623 LDR a2,Current_Thread ; Pickup current thread ptr address
1624 LDR a4,[a2, #0] ; Pickup current thread pointer
1625 CMP a4,#0 ; Check to see if it is non-NULL
1626 BEQ TCT_Skip_Protect ; If NULL, skip protection
1627 ;
1628 ; /* Lockout interrupts. */
1629 ;
1630 MRS a2,CPSR ; Pickup current CPSR
1631 ORR a2,a2,#LOCKOUT ; Place lockout value in
1632 MSR CPSR,a2 ; Lockout interrupts
1633 ;
1634 ; /* Wait until the protect structure is available. */
1635 ; while (protect -> tc_tcb_pointer != NU_NULL)
1636 ; {
1637 ;
1638 TCT_Protect_Loop
1639 LDR a2,[a1, #0] ; Pickup protection owner field
1640 CMP a2,#0 ; Is there any protection?
1641 BEQ TCT_Protect_Available ; If NU_NULL, no current protection
1642 ;
1643 ; /* Protection structure is not available. */
1644 ;
1645 ; /* Indicate that another thread is waiting. */
1646 ; protect -> tc_thread_waiting = 1;
1647 ;
1648 MOV a3,#1 ; Build thread waiting flag
1649 STR a3,[a1, #4] ; Set waiting field
1650 ;
1651 ; /* Directly schedule the thread waiting. */
1652 ; TCT_Schedule_Protected(protect -> tc_tcb_pointer);
1653 ;
1654 STR a1,[sp, #-4]! ; Save a1 on the stack
1655 STR lr,[sp, #-4]! ; Save lr on the stack
1656 MOV a1,a4 ; Place current thread into a1
1657 BL _TCT_Schedule_Protected ; Call routine to schedule the
1658 ; owner of the thread
1659 ;
1660 LDR lr,[sp], #4 ; Recover saved lr
1661 LDR a1,[sp], #4 ; Recover saved a1
1662 ;
1663 ; /* Lockout interrupts. */
1664 ;
1665 LDR a2,Current_Thread ; Pickup current thread ptr address
1666 LDR a4,[a2, #0] ; Pickup current thread pointer
1667 MRS a2,CPSR ; Pickup current CPSR
1668 ORR a2,a2,#LOCKOUT ; Place lockout value in
1669 MSR CPSR,a2 ; Lockout interrupts
1670 B TCT_Protect_Loop ; Examine protect flags again
1671 ; }
1672 TCT_Protect_Available
1673 ;
1674 ; /* Protection structure is available. */
1675 ;
1676 ; /* Indicate that this thread owns the protection. */
1677 ; protect -> tc_tcb_pointer = TCD_Current_Thread;
1678 ;
1679 STR a4,[a1, #0] ; Indicate calling thread owns this
1680 ; protection
1681 ;
1682 ; /* Clear the thread waiting flag. */
1683 ; protect -> tc_thread_waiting = 0;
1684 ;
1685 MOV a3,#0 ; Clear value
1686 STR a3,[a1, #4] ; Clear the thread waiting flag
1687 ;
1688 ; /* Save the protection pointer in the thread's control block. Note
1689 ; that both task and HISR threads share the same control block
1690 ; format. */
1691 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
1692 ; REG_Thread_Ptr -> tc_current_protect = protect;
1693 ;
1694 STR a1,[a4, #38h] ; Setup current protection
1695 ;
1696 ; /* Restore interrupts. */
1697 ;
1698 LDR a3,Int_Level ; Pickup address of interrupt level
1699 MRS a2,CPSR ; Pickup current CPSR
1700 LDR a4,[a3, #0] ; Pickup interrupt lockout level
1701 BIC a2,a2,#LOCK_MSK ; Clear lockout bits
1702 ORR a2,a2,a4 ; Build new interrupt lockout
1703 MSR CPSR,a2 ; Setup CPSR appropriately
1704 ; }
1705 ;
1706 TCT_Skip_Protect
1707 BX lr ; Return to caller
1708 ;}
1709 ;
1710 ;
1711 ;
1712 ;/*************************************************************************/
1713 ;/* */
1714 ;/* FUNCTION */
1715 ;/* */
1716 ;/* TCT_Unprotect */
1717 ;/* */
1718 ;/* DESCRIPTION */
1719 ;/* */
1720 ;/* This function releases protection of the currently active */
1721 ;/* thread. If the caller is not an active thread, then this */
1722 ;/* request is ignored. */
1723 ;/* */
1724 ;/* AUTHOR */
1725 ;/* */
1726 ;/* Barry Sellew, Accelerated Technology, Inc. */
1727 ;/* */
1728 ;/* CALLED BY */
1729 ;/* */
1730 ;/* Application */
1731 ;/* System Components */
1732 ;/* */
1733 ;/* CALLS */
1734 ;/* */
1735 ;/* None */
1736 ;/* */
1737 ;/* INPUTS */
1738 ;/* */
1739 ;/* None */
1740 ;/* */
1741 ;/* OUTPUTS */
1742 ;/* */
1743 ;/* None */
1744 ;/* */
1745 ;/* HISTORY */
1746 ;/* */
1747 ;/* NAME DATE REMARKS */
1748 ;/* */
1749 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1750 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1751 ;/* */
1752 ;/*************************************************************************/
1753 ;VOID TCT_Unprotect(void)
1754 ;{
1755 .def $TCT_Unprotect
1756 $TCT_Unprotect ; Dual-state interworking veneer
1757 .state16
1758 BX pc
1759 NOP
1760 .state32
1761 B _TCT_Unprotect
1762 ;
1763 .def _TCT_Unprotect
1764 _TCT_Unprotect
1765 ;
1766 ;
1767 ; /* Determine if the caller is in a task or HISR thread. */
1768 ; if (TCD_Current_Thread)
1769 ; {
1770 ;
1771 LDR a2,Current_Thread ; Pickup current thread ptr address
1772 LDR a4,[a2, #0] ; Pickup current thread pointer
1773 CMP a4,#0 ; Check to see if it is non-NULL
1774 BEQ TCT_Skip_Unprotect ; If NULL, skip unprotection
1775 ;
1776 ; /* Setup a thread control block pointer. */
1777 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
1778 ;
1779 ; /* Determine if there is a currently active protection. */
1780 ; if (REG_Thread_Ptr -> tc_current_protect)
1781 ; {
1782 ;
1783 LDR a1,[a4, #38h] ; Pickup current protect field
1784 CMP a1,#0 ; Is there a protection in force?
1785 BEQ TCT_Skip_Unprotect ; If not, nothing is protected
1786 ;
1787 ; /* Lockout interrupts. */
1788 ;
1789 MRS a2,CPSR ; Pickup current CPSR
1790 ORR a2,a2,#LOCKOUT ; Place lockout value in
1791 MSR CPSR,a2 ; Lockout interrupts
1792 ;
1793 ; /* Yes, this thread still has this protection structure. */
1794 ; REG_Protect_Ptr = REG_Thread_Ptr -> tc_current_protect;
1795 ;
1796 ; /* Is there a higher priority thread waiting for the protection
1797 ; structure? */
1798 ; if (REG_Protect_Ptr -> tc_thread_waiting)
1799 ;
1800 LDR a3,[a1, #4] ; Pickup thread waiting flag
1801 CMP a3,#0 ; Are there any threads waiting?
1802 BEQ TCT_Not_Waiting_Unpr ; If not, just release protection
1803 ;
1804 ; /* Transfer control to the system. Note that this
1805 ; automatically clears the current protection and it returns
1806 ; to the caller of this routine instead of this routine. */
1807 ; TCT_Control_To_System();
1808 ;
1809 B _TCT_Control_To_System ; Return control to the system
1810 ;
1811 ; else
1812 ; {
1813 TCT_Not_Waiting_Unpr
1814 ;
1815 ; /* Clear the protection. */
1816 ; REG_Thread_Ptr -> tc_current_protect = NU_NULL;
1817 ; REG_Protect_Ptr -> tc_tcb_pointer = NU_NULL;
1818 ;
1819 MOV a3,#0 ; Build NU_NULL value
1820 STR a3,[a1, #0] ; Release the protection
1821 STR a3,[a4, #38h] ; Clear protection pointer in the
1822 ; control block
1823 ;
1824 ; }
1825 ;
1826 TCT_Not_Protected
1827 ; /* Restore interrupts again. */
1828 ;
1829 LDR a3,Int_Level ; Pickup address of interrupt level
1830 MRS a2,CPSR ; Pickup current CPSR
1831 LDR a4,[a3, #0] ; Pickup interrupt lockout level
1832 BIC a2,a2,#LOCK_MSK ; Clear lockout bits
1833 ORR a2,a2,a4 ; Build new interrupt lockout
1834 MSR CPSR,a2 ; Setup CPSR appropriately
1835 ;
1836 ; }
1837 ; }
1838 TCT_Skip_Unprotect
1839 BX lr ; Return to caller
1840 ;}
1841 ;
1842 ;
1843 ;
1844 ;/*************************************************************************/
1845 ;/* */
1846 ;/* FUNCTION */
1847 ;/* */
1848 ;/* TCT_Unprotect_Specific */
1849 ;/* */
1850 ;/* DESCRIPTION */
1851 ;/* */
1852 ;/* This function releases a specific protection structure. */
1853 ;/* */
1854 ;/* AUTHOR */
1855 ;/* */
1856 ;/* Barry Sellew, Accelerated Technology, Inc. */
1857 ;/* */
1858 ;/* CALLED BY */
1859 ;/* */
1860 ;/* Application */
1861 ;/* System Components */
1862 ;/* */
1863 ;/* CALLS */
1864 ;/* */
1865 ;/* None */
1866 ;/* */
1867 ;/* INPUTS */
1868 ;/* */
1869 ;/* protect Pointer to protection block */
1870 ;/* */
1871 ;/* OUTPUTS */
1872 ;/* */
1873 ;/* None */
1874 ;/* */
1875 ;/* HISTORY */
1876 ;/* */
1877 ;/* NAME DATE REMARKS */
1878 ;/* */
1879 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1880 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1881 ;/* */
1882 ;/*************************************************************************/
1883 ;VOID TCT_Unprotect_Specific(TC_PROTECT *protect)
1884 ;{
1885 .def $TCT_Unprotect_Specific
1886 $TCT_Unprotect_Specific ; Dual-state interworking veneer
1887 .state16
1888 BX pc
1889 NOP
1890 .state32
1891 B _TCT_Unprotect_Specific
1892 ;
1893 .def _TCT_Unprotect_Specific
1894 _TCT_Unprotect_Specific
1895 ;
1896 ; /* Determine if the caller is in a task or HISR thread. */
1897 ; if (TCD_Current_Thread)
1898 ; {
1899 ;
1900 LDR a2,Current_Thread ; Pickup current thread ptr address
1901 LDR a4,[a2, #0] ; Pickup current thread pointer
1902 CMP a4,#0 ; Check to see if it is non-NULL
1903 BEQ TCT_Skip_Unprot_Spec ; If NULL, skip unprotect specific
1904 ;
1905 ; /* Lockout interrupts. */
1906 ;
1907 MRS a2,CPSR ; Pickup current CPSR
1908 ORR a2,a2,#LOCKOUT ; Place lockout value in
1909 MSR CPSR,a2 ; Lockout interrupts
1910 ;
1911 ; /* Clear the protection pointer. */
1912 ; protect -> tc_tcb_pointer = NU_NULL;
1913 ;
1914 MOV a3,#0 ; Build NU_NULL value
1915 STR a3,[a1, #0] ; Clear protection ownership
1916 ;
1917 ; /* Determine if a thread is waiting. */
1918 ; if (protect -> tc_thread_waiting)
1919 ; {
1920 ;
1921 LDR a2,[a1, #4] ; Pickup the waiting field
1922 CMP a2,#0 ; Is there another thread waiting?
1923 BEQ TCT_Not_Waiting_Unspec ; No, restore interrupts and return
1924 ;
1925 ; /* A higher-priority thread is waiting. */
1926 ;
1927 ; /* Save a minimal context of the thread. */
1928 ;
1929 STMDB sp!,{v1-ip,lr} ; Save minimal context of thread on
1930 ; the current stack
1931 MOV a3,lr ; Determine what state the
1932 MOV a3,a3,LSL #31 ; caller was in and build an
1933 MOV a3,a3,LSR #26 ; appropriate state mask
1934 STR a3,[sp, #-4]! ; Place it on the stack
1935 MOV a3,#0 ; Build solicited stack type value
1936 ; and NU_NULL value
1937 STR a3,[sp, #-4]! ; Place it on the top of the stack
1938 ;
1939 ; /* Setup a pointer to the thread control block. */
1940 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
1941 ;
1942 LDR a2,Current_Thread ; Pickup current thread ptr address
1943 LDR a1,[a2, #0] ; Pickup current thread pointer
1944 ;
1945 ; /* Clear the current thread control block pointer. */
1946 ; TCD_Current_Thread = NU_NULL;
1947 ;
1948 LDR a4,Slice_State ; Pickup time slice state address
1949 STR a3,[a2, #0] ; Set current thread pointer to
1950 ; NU_NULL
1951 ;
1952 ; /* Check to see if a time slice is active. If so, copy the
1953 ; original time slice into the current time slice field of the
1954 ; thread's control block. */
1955 ; if (TMD_Time_Slice_State == 0)
1956 ; {
1957 ;
1958 LDR a2,[a4, #0] ; Pickup time slice state flag
1959 CMP a2,#0 ; Compare with active value
1960 BNE TCT_No_Stop_TS_3 ; If non-active, don't disable
1961 ;
1962 ; /* Insure that the next time the task runs it gets a fresh time
1963 ; slice. */
1964 ; REG_Thread_Ptr -> tc_cur_time_slice =
1965 ; REG_Thread_Ptr -> tc_time_slice;
1966 ;
1967 LDR a2,[a1, #40h] ; Pickup original time slice
1968 ;
1969 ; /* Clear any active time slice by setting the state to
1970 ; NOT_ACTIVE. */
1971 ; TMD_Time_Slice_State = 1;
1972 ;
1973 MOV a3,#1 ; Build disable value
1974 STR a3,[a4, #0] ; Disable time slice
1975 STR a2,[a1, #20h] ; Reset current time slice
1976 ; }
1977 ;
1978 TCT_No_Stop_TS_3
1979 ;
1980 ; /* Save off the current stack pointer in the control block. */
1981 ; REG_Thread_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr;
1982 ;
1983 STR sp,[a1, #2ch] ; Save the thread's stack pointer
1984 ;
1985 ; /* Switch to the system stack. */
1986 ; REG_Stack_Ptr = TCD_System_Stack;
1987 ;
1988 LDR a2,System_Stack ; Pickup address of stack pointer
1989 LDR a3,System_Limit ; Pickup address of stack limit ptr
1990 LDR sp,[a2, #0] ; Switch to system stack
1991 LDR v7,[a3, #0] ; Setup system stack limit
1992 ;
1993 ; /* Finished, return to the scheduling loop. */
1994 ;
1995 B _TCT_Schedule ; Return to scheduling loop
1996 ;
1997 ; }
1998 ; else
1999 ; {
2000 TCT_Not_Waiting_Unspec
2001 ;
2002 ; /* No higher-priority thread is waiting. */
2003 ;
2004 ; /* Restore interrupts. */
2005 ;
2006 LDR a3,Int_Level ; Pickup address of interrupt level
2007 MRS a2,CPSR ; Pickup current CPSR
2008 LDR a4,[a3, #0] ; Pickup interrupt lockout level
2009 BIC a2,a2,#LOCK_MSK ; Clear lockout bits
2010 ORR a2,a2,a4 ; Build new interrupt lockout
2011 MSR CPSR,a2 ; Setup CPSR appropriately
2012 ;
2013 ; }
2014 ; }
2015 ;
2016 TCT_Skip_Unprot_Spec
2017 BX lr ; Return to caller
2018 ;}
2019 ;
2020 ;
2021 ;
2022 ;/*************************************************************************/
2023 ;/* */
2024 ;/* FUNCTION */
2025 ;/* */
2026 ;/* TCT_Set_Current_Protect */
2027 ;/* */
2028 ;/* DESCRIPTION */
2029 ;/* */
2030 ;/* This function sets the current protection field of the current */
2031 ;/* thread's control block to the specified protection pointer. */
2032 ;/* */
2033 ;/* AUTHOR */
2034 ;/* */
2035 ;/* Barry Sellew, Accelerated Technology, Inc. */
2036 ;/* */
2037 ;/* CALLED BY */
2038 ;/* */
2039 ;/* TCC_Resume_Task Resume task function */
2040 ;/* */
2041 ;/* CALLS */
2042 ;/* */
2043 ;/* None */
2044 ;/* */
2045 ;/* INPUTS */
2046 ;/* */
2047 ;/* protect Pointer to protection block */
2048 ;/* */
2049 ;/* OUTPUTS */
2050 ;/* */
2051 ;/* None */
2052 ;/* */
2053 ;/* HISTORY */
2054 ;/* */
2055 ;/* NAME DATE REMARKS */
2056 ;/* */
2057 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
2058 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
2059 ;/* */
2060 ;/*************************************************************************/
2061 ;VOID TCT_Set_Current_Protect(TC_PROTECT *protect)
2062 ;{
2063 .def $TCT_Set_Current_Protect
2064 $TCT_Set_Current_Protect ; Dual-state interworking veneer
2065 .state16
2066 BX pc
2067 NOP
2068 .state32
2069 B _TCT_Set_Current_Protect
2070 ;
2071 .def _TCT_Set_Current_Protect
2072 _TCT_Set_Current_Protect
2073 ;
2074 ; /* Determine if the caller is in a task or HISR thread. */
2075 ; if (TCD_Current_Thread)
2076 ; {
2077 ;
2078 LDR a2,Current_Thread ; Pickup current thread ptr address
2079 LDR a4,[a2, #0] ; Pickup current thread pointer
2080 CMP a4,#0 ; Check to see if a thread is
2081 ; active
2082 ;
2083 ; /* Point at the current thread control block. */
2084 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
2085 ;
2086 ; /* Modify the current protection. */
2087 ; REG_Thread_Ptr -> tc_current_protect = protect;
2088 ;
2089 STRNE a1,[a4, #38h] ; Setup new protection
2090 ; }
2091 ;
2092 BX lr ; Return to caller
2093 ;}
2094 ;
2095 ;
2096 ;
2097 ;/*************************************************************************/
2098 ;/* */
2099 ;/* FUNCTION */
2100 ;/* */
2101 ;/* TCT_Protect_Switch */
2102 ;/* */
2103 ;/* DESCRIPTION */
2104 ;/* */
2105 ;/* This function waits until a specific task no longer has any */
2106 ;/* protection associated with it. This is necessary since task's */
2107 ;/* cannot be suspended or terminated unless they have released all */
2108 ;/* of their protection. */
2109 ;/* */
2110 ;/* AUTHOR */
2111 ;/* */
2112 ;/* Barry Sellew, Accelerated Technology, Inc. */
2113 ;/* */
2114 ;/* CALLED BY */
2115 ;/* */
2116 ;/* System Components */
2117 ;/* */
2118 ;/* CALLS */
2119 ;/* */
2120 ;/* None */
2121 ;/* */
2122 ;/* INPUTS */
2123 ;/* */
2124 ;/* thread Pointer to thread control blk */
2125 ;/* */
2126 ;/* OUTPUTS */
2127 ;/* */
2128 ;/* None */
2129 ;/* */
2130 ;/* HISTORY */
2131 ;/* */
2132 ;/* NAME DATE REMARKS */
2133 ;/* */
2134 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
2135 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
2136 ;/* */
2137 ;/*************************************************************************/
2138 ;VOID TCT_Protect_Switch(VOID *thread)
2139 ;{
2140 .def $TCT_Protect_Switch
2141 $TCT_Protect_Switch ; Dual-state interworking veneer
2142 .state16
2143 BX pc
2144 NOP
2145 .state32
2146 B _TCT_Protect_Switch
2147 ;
2148 .def _TCT_Protect_Switch
2149 _TCT_Protect_Switch
2150 ;
2151 ; /* Lockout interrupts. */
2152 ;
2153 MRS a2,CPSR ; Pickup current CPSR
2154 ORR a2,a2,#LOCKOUT ; Place lockout value in
2155 MSR CPSR,a2 ; Lockout interrupts
2156 ;
2157 ; REG_Thread_Ptr = (TC_TCB *) thread;
2158 ;
2159 ; /* Wait until the specified task has no protection associated with it. */
2160 ; while (REG_Thread_Ptr -> tc_current_protect)
2161 ; {
2162 ;
2163 LDR a2,[a1, #38h] ; Pickup protection of specified
2164 ; thread
2165 CMP a2,#0 ; Does the specified thread have
2166 ; an active protection?
2167 BEQ TCT_Switch_Done ; If not, protect switch is done
2168 ;
2169 ; /* Let the task run again in an attempt to clear its protection. */
2170 ;
2171 ; /* Indicate that a higher priority thread is waiting. */
2172 ; (REG_Thread_Ptr -> tc_current_protect) -> tc_thread_waiting = 1;
2173 ;
2174 MOV a3,#1 ; Build waiting flag value
2175 STR a3,[a2, #4] ; Set waiting flag of the
2176 ; protection owned by the other
2177 ; thread
2178 ;
2179 ; /* Directly schedule the thread waiting. */
2180 ; TCT_Schedule_Protected((REG_Thread_Ptr -> tc_current_protect)
2181 ; -> tc_tcb_pointer);
2182 ;
2183 LDR a3,Current_Thread ; Pickup current thread ptr address
2184 STR a1,[sp, #-4]! ; Save a1 on the stack
2185 STR lr,[sp, #-4]! ; Save lr on the stack
2186 MOV a2,a1 ; Move new thread into a2
2187 LDR a1,[a3, #0] ; Pickup current thread pointer
2188 BL _TCT_Schedule_Protected ; Call routine to schedule the
2189 ; owner of the thread
2190 ;
2191 LDR lr,[sp], #4 ; Recover saved lr
2192 LDR a1,[sp], #4 ; Recover saved a1
2193 ;
2194 ; /* Lockout interrupts. */
2195 ;
2196 B _TCT_Protect_Switch ; Branch to top of routine and
2197 ; start over
2198 ; }
2199 TCT_Switch_Done
2200 ;
2201 ; /* Restore interrupts. */
2202 ;
2203 LDR a3,Int_Level ; Pickup address of interrupt level
2204 MRS a2,CPSR ; Pickup current CPSR
2205 LDR a4,[a3, #0] ; Pickup interrupt lockout level
2206 BIC a2,a2,#LOCK_MSK ; Clear lockout bits
2207 ORR a2,a2,a4 ; Build new interrupt lockout
2208 MSR CPSR,a2 ; Setup CPSR appropriately
2209 ;
2210 BX lr ; Return to caller
2211 ;}
2212 ;
2213 ;
2214 ;
2215 ;/*************************************************************************/
2216 ;/* */
2217 ;/* FUNCTION */
2218 ;/* */
2219 ;/* TCT_Schedule_Protected */
2220 ;/* */
2221 ;/* DESCRIPTION */
2222 ;/* */
2223 ;/* This function saves the minimal context of the thread and then */
2224 ;/* directly schedules the thread that has protection over the */
2225 ;/* the thread that called this routine. */
2226 ;/* */
2227 ;/* AUTHOR */
2228 ;/* */
2229 ;/* Barry Sellew, Accelerated Technology, Inc. */
2230 ;/* */
2231 ;/* CALLED BY */
2232 ;/* */
2233 ;/* TCT_Protect */
2234 ;/* TCT_Protect_Switch */
2235 ;/* */
2236 ;/* CALLS */
2237 ;/* */
2238 ;/* TCT_Control_To_Thread Transfer control to protected*/
2239 ;/* thread */
2240 ;/* */
2241 ;/* INPUTS */
2242 ;/* */
2243 ;/* None */
2244 ;/* */
2245 ;/* OUTPUTS */
2246 ;/* */
2247 ;/* None */
2248 ;/* */
2249 ;/* HISTORY */
2250 ;/* */
2251 ;/* NAME DATE REMARKS */
2252 ;/* */
2253 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
2254 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
2255 ;/* */
2256 ;/*************************************************************************/
2257 ;VOID TCT_Schedule_Protected(VOID *thread)
2258 ;{
2259 ;
2260 _TCT_Schedule_Protected
2261 ;
2262 ; /* Interrupts are already locked out by the caller. */
2263 ;
2264 ; /* Save minimal context required by the system. */
2265 ;
2266 STMDB sp!,{v1-ip,lr} ; Save minimal context of thread on
2267 ; the current stack
2268 MOV a3,lr ; Determine what state the
2269 MOV a3,a3,LSL #31 ; caller was in and build an
2270 MOV a3,a3,LSR #26 ; appropriate state mask
2271 STR a3,[sp, #-4]! ; Place it on the stack
2272 MOV a3,#0 ; Build solicited stack type value
2273 ; and NU_NULL value
2274 STR a3,[sp, #-4]! ; Place it on the top of the stack
2275 MOV v1,a2 ; Save thread to schedule
2276 ;
2277 ; /* Setup a pointer to the thread control block. */
2278 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
2279 ;
2280 LDR a2,Current_Thread ; Pickup current thread ptr address
2281 ;
2282 ; /* Clear the current thread control block. */
2283 ; TCD_Current_Thread = NU_NULL;
2284 ;
2285 LDR a4,Slice_State ; Pickup time slice state address
2286 STR a3,[a2, #0] ; Set current thread pointer to
2287 ; NU_NULL
2288 ;
2289 ; /* Check to see if a time slice is active. If so, copy the original time
2290 ; slice into the current time slice field of the task's control block. */
2291 ; if (TMD_Time_Slice_State == 0)
2292 ; {
2293 ;
2294 LDR a2,[a4, #0] ; Pickup time slice state flag
2295 CMP a2,#0 ; Compare with active value
2296 BNE TCT_No_Stop_TS_4 ; If non-active, don't disable
2297 ;
2298 ; /* Insure that the next time the task runs it gets a fresh time
2299 ; slice. */
2300 ; REG_Thread_Ptr -> tc_cur_time_slice = REG_Thread_Ptr -> tc_time_slice;
2301 ;
2302 LDR a2,[a1, #40h] ; Pickup original time slice
2303 ;
2304 ; /* Clear any active time slice by setting the state to NOT_ACTIVE. */
2305 ; TMD_Time_Slice_State = 1;
2306 ;
2307 MOV a3,#1 ; Build disable value
2308 STR a3,[a4, #0] ; Disable time slice
2309 STR a2,[a1, #20h] ; Reset current time slice
2310 ;
2311 ; }
2312 TCT_No_Stop_TS_4
2313 ;
2314 ; /* Save off the current stack pointer in the control block. */
2315 ; REG_Thread_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr;
2316 ;
2317 STR sp,[a1, #2ch] ; Save the thread's stack pointer
2318 ;
2319 ; /* Switch to the system stack. */
2320 ; TCD_System_Stack = (VOID *) REG_Stack_Ptr;
2321 ;
2322 LDR a2,System_Stack ; Pickup address of stack pointer
2323 LDR a3,System_Limit ; Pickup address of stack limit ptr
2324 LDR sp,[a2, #0] ; Switch to system stack
2325 LDR v7,[a3, #0] ; Setup system stack limit
2326 ;
2327 ; /* Transfer control to the specified thread directly. */
2328 ; TCT_Control_To_Thread(thread);
2329 ;
2330 LDR a3,Int_Level ; Pickup address of interrupt level
2331 MRS a2,CPSR ; Pickup current CPSR
2332 LDR a4,[a3, #0] ; Pickup interrupt lockout level
2333 BIC a2,a2,#LOCK_MSK ; Clear lockout bits
2334 ORR a2,a2,a4 ; Build new interrupt lockout
2335 MOV a1,v1 ; Indicate thread to schedule
2336 MSR CPSR,a2 ; Setup CPSR appropriately
2337 ORR a2,a2,#LOCKOUT ; Build lockout value again
2338 MSR CPSR,a2 ; Lockout interrupts again
2339 B _TCT_Control_To_Thread ; Schedule the thread indirectly
2340 ;}
2341 ;
2342 ;
2343 ;
2344 ;/*************************************************************************/
2345 ;/* */
2346 ;/* FUNCTION */
2347 ;/* */
2348 ;/* TCT_Interrupt_Context_Save */
2349 ;/* */
2350 ;/* DESCRIPTION */
2351 ;/* */
2352 ;/* This function saves the interrupted thread's context. Nested */
2353 ;/* interrupts are also supported. If a task or HISR thread was */
2354 ;/* interrupted, the stack pointer is switched to the system stack */
2355 ;/* after the context is saved. */
2356 ;/* */
2357 ;/* AUTHOR */
2358 ;/* */
2359 ;/* Barry Sellew, Accelerated Technology, Inc. */
2360 ;/* */
2361 ;/* CALLED BY */
2362 ;/* */
2363 ;/* Application ISRs Assembly language ISRs */
2364 ;/* INT_Interrupt_Shell Interrupt handler shell */
2365 ;/* */
2366 ;/* CALLS */
2367 ;/* */
2368 ;/* None */
2369 ;/* */
2370 ;/* INPUTS */
2371 ;/* */
2372 ;/* vector Interrupt's vector number */
2373 ;/* */
2374 ;/* OUTPUTS */
2375 ;/* */
2376 ;/* None */
2377 ;/* */
2378 ;/* HISTORY */
2379 ;/* */
2380 ;/* NAME DATE REMARKS */
2381 ;/* */
2382 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
2383 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
2384 ;/* */
2385 ;/*************************************************************************/
2386 ;VOID TCT_Interrupt_Context_Save(INT vector)
2387 ;{
2388 .def $TCT_Interrupt_Context_Save
2389 $TCT_Interrupt_Context_Save ; Dual-state interworking veneer
2390 .state16
2391 BX pc
2392 NOP
2393 .state32
2394 B _TCT_Interrupt_Context_Save
2395 ;
2396 .def _TCT_Interrupt_Context_Save
2397 _TCT_Interrupt_Context_Save
2398 ;
2399 ; /* This routine is designed to handle THUMB IRQ interrupts. The IRQ
2400 ; stack is used as a temporary area. Actual context is saved either
2401 ; on the interrupted thread's stack or the system stack- both of which
2402 ; are in the Supervisor (SVC) mode. Note: upon entry to this routine
2403 ; a1-a4 are saved on the current stack and a4 contains the original
2404 ; (interrupt return address) lr value. The current lr contains the
2405 ; ISR return address. */
2406 ;
2407 ; /* Determine if this is a nested interrupt. */
2408 ; if (TCD_Interrupt_Count++)
2409 ; {
2410 ;
2411 LDR a1,Int_Count ; Pickup address of interrupt count
2412 LDR a2,[a1, #0] ; Pickup interrupt counter
2413 CMP a2,#0 ; Is it the first interrupt?
2414 BEQ TCT_Not_Nested_Save ; If so, not a nested interrupt
2415 ;
2416 ; /* Nested interrupt. Save complete context on the current stack. */
2417 ;
2418 ADD a2,a2,#1 ; Increment the interrupt counter
2419 STR a2,[a1, #0] ; Store in interrupt counter
2420 STMDB sp!,{v1-v3} ; Save more registers on current
2421 ; stack
2422 MRS v1,SPSR ; Pickup and save current SPSR
2423 MOV v2,lr ; Save current lr
2424 MOV v3,sp ; Save current sp
2425 ADD sp,sp,#28 ; Adjust sp for future interrupts
2426 MRS a1,CPSR ; Pickup current CPSR
2427 BIC a1,a1,#MODE_MASK ; Clear the mode bits
2428 ORR a1,a1,#SUP_MODE ; Prepare to switch to supervisor
2429 ; mode (SVC)
2430 MSR CPSR,a1 ; Switch to SVC mode
2431 MOV a2,sp ; Use a non sp register
2432 NOP ;
2433 STR a4,[a2, #-4]! ; Save interrupted pc on sys stack
2434 STMDB a2!,{v4-lr} ; Save v4-lr on the system stack
2435 MOV sp,a2 ; Setup sp again
2436 LDMIA v3!,{v4-v6} ; Recover v1-v3 from int stack
2437 STMDB sp!,{v4-v6} ; Save v1-v3 on the system stack
2438 LDMIA v3,{a1-a4} ; Recover a1-a4
2439 STMDB sp!,{a1-a4} ; Save a1-a4 on the system stack
2440 STR v1,[sp, #-4]! ; Save CPSR on the stack
2441 BX v2 ; Return to calling ISR
2442 ; }
2443 ; else
2444 ; {
2445 TCT_Not_Nested_Save
2446 ;
2447 ADD a2,a2,#1 ; Increment the interrupt counter
2448 STR a2,[a1, #0] ; Store in interrupt counter
2449 ;
2450 ; /* Determine if a thread was interrupted. */
2451 ; if (TCD_Current_Thread)
2452 ; {
2453 ;
2454 LDR a2,Current_Thread ; Pickup current thread ptr address
2455 LDR a2,[a2, #0] ; Pickup the current thread pointer
2456 CMP a2,#0 ; Is it NU_NULL?
2457 BEQ TCT_Idle_Context_Save ; If no, no real save is necessary
2458
2459 ;
2460 ; /* Yes, a thread was interrupted. Save complete context on the
2461 ; thread's stack. */
2462 ;
2463 STMDB sp!,{v1-v3} ; Save more registers on temp stack
2464 MOV v2,lr ; Save interrupt lr in v2
2465 MRS v1,SPSR ; Save interrupt SPSR in v1
2466 MOV v3,sp ; Save current sp in v3
2467 ADD sp,sp,#28 ; Adjust sp for future interrupts
2468 MRS a1,CPSR ; Pickup current CPSR
2469 BIC a1,a1,#MODE_MASK ; Clear the mode bits
2470 ORR a1,a1,#SUP_MODE ; Prepare to switch to supervisor
2471 ; mode (SVC)
2472 MSR CPSR,a1 ; Switch to supervisor mode (SVC)
2473 MOV a2,sp ; Use a non-stack pointer register
2474 NOP ;
2475 STR a4,[a2, #-4]! ; Save interrupted pc on the stack
2476 STMDB a2!,{v4-lr} ; Save v4-lr on the stack
2477 MOV sp,a2 ; Setup sp again
2478 LDMIA v3!,{v4-v6} ; Recover v1-v3 into v4-v6
2479 STMDB sp!,{v4-v6} ; Save v1-v3 on the stack
2480 LDMIA v3,{a1-a4} ; Recover a1-a4
2481 STMDB sp!,{a1-a4} ; Save a1-a4 on the stack
2482 STR v1,[sp, #-4]! ; Save CPSR on the stack
2483 MOV a2,#1 ; Interrupt stack type
2484 STR a2,[sp, #-4]! ; Put interrupt stack type on top
2485 ; of stack
2486 ;
2487 ; /* Save the thread's stack pointer in the control block. */
2488 ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
2489 ; REG_Thread_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr;
2490 ;
2491 LDR a2,Current_Thread ; Pickup current thread ptr address
2492 LDR a1,[a2, #0] ; Pickup current thread pointer
2493 LDR a4,Slice_State ; Pickup time slice state address
2494 STR sp,[a1, #2ch] ; Save stack pointer
2495 ;
2496 ; /* Switch to the system stack. */
2497 ; REG_Stack_Ptr = TCD_System_Stack;
2498 ;
2499 LDR a2,System_Stack ; Pickup address of stack pointer
2500 LDR a3,System_Limit ; Pickup address of stack limit ptr
2501 LDR sp,[a2, #0] ; Switch to system stack
2502 LDR v7,[a3, #0] ; Setup system stack limit
2503 ;
2504 ; /* Return to caller ISR. */
2505 ;
2506 BX v2 ; Return to caller ISR
2507 ;
2508 ; }
2509 ;
2510 TCT_Idle_Context_Save
2511 ;
2512 MOV v2,lr ; Save lr in v2
2513 ADD sp,sp,#16 ; Adjust sp for future interrupts
2514 MRS a1,CPSR ; Pickup current CPSR
2515 BIC a1,a1,#MODE_MASK ; Clear the current mode
2516 ORR a1,a1,#SUP_MODE ; Prepare to switch to supervisor
2517 ; mode (SVC)
2518 MSR CPSR,a1 ; Switch to supervisor mode (SVC)
2519 BX v2 ; Return to caller ISR
2520 ; }
2521 ;}
2522 ;
2523 ;
2524 ;
2525 ;/*************************************************************************/
2526 ;/* */
2527 ;/* FUNCTION */
2528 ;/* */
2529 ;/* TCT_Interrupt_Context_Restore */
2530 ;/* */
2531 ;/* DESCRIPTION */
2532 ;/* */
2533 ;/* This function restores the interrupt context if a nested */
2534 ;/* interrupt condition is present. Otherwise, this routine */
2535 ;/* transfers control to the scheduling function. */
2536 ;/* */
2537 ;/* AUTHOR */
2538 ;/* */
2539 ;/* Barry Sellew, Accelerated Technology, Inc. */
2540 ;/* */
2541 ;/* CALLED BY */
2542 ;/* */
2543 ;/* Application ISRs Assembly language ISRs */
2544 ;/* INT_Interrupt_Shell Interrupt handler shell */
2545 ;/* */
2546 ;/* CALLS */
2547 ;/* */
2548 ;/* TCT_Schedule Thread scheduling function */
2549 ;/* */
2550 ;/* INPUTS */
2551 ;/* */
2552 ;/* None */
2553 ;/* */
2554 ;/* OUTPUTS */
2555 ;/* */
2556 ;/* None */
2557 ;/* */
2558 ;/* HISTORY */
2559 ;/* */
2560 ;/* NAME DATE REMARKS */
2561 ;/* */
2562 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
2563 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
2564 ;/* */
2565 ;/*************************************************************************/
2566 ;VOID TCT_Interrupt_Context_Restore(void)
2567 ;{
2568 .def $TCT_Interrupt_Context_Restore
2569 $TCT_Interrupt_Context_Restore ; Dual-state interworking veneer
2570 .state16
2571 BX pc
2572 NOP
2573 .state32
2574 B _TCT_Interrupt_Context_Restore
2575 ;
2576 .def _TCT_Interrupt_Context_Restore
2577 _TCT_Interrupt_Context_Restore
2578 ;
2579 ; /* It is assumed that anything pushed on the stack by ISRs has been
2580 ; removed upon entry into this routine. */
2581 ;
2582 ; /* Lockout interrupts. */
2583 ;
2584 MRS a2,CPSR ; Pickup current CPSR
2585 ORR a2,a2,#LOCKOUT ; Build lockout value
2586 MSR CPSR,a2 ; Lockout interrupts
2587 ;
2588 ; /* Decrement and check for nested interrupt conditions. */
2589 ; if (--TCD_Interrupt_Count)
2590 ; {
2591 ;
2592 LDR a1,Int_Count ; Pickup address of interrupt count
2593 LDR a2,[a1, #0] ; Pickup interrupt counter
2594 SUB a2,a2,#1 ; Decrement interrupt counter
2595 STR a2,[a1, #0] ; Store interrupt counter
2596 CMP a2,#0 ; Is this a nested interrupt?
2597 BEQ TCT_Not_Nested_Restore ; If not, skip nested interrupt
2598 ; restoration
2599 ;
2600 ; /* Restore previous context. */
2601 ;
2602 LDR a1,[sp], #4 ; Pickup the saved CPSR
2603 MSR SPSR,a1 ; Put in SPSR
2604 LDMIA sp,{a1-pc}^ ; Return to the point of interrupt
2605 ;
2606 ; }
2607 ; else
2608 ; {
2609 ;
2610 TCT_Not_Nested_Restore
2611 ;
2612 ; /* Determine if a thread is active. */
2613 ; if (TCD_Current_Thread)
2614 ; {
2615 ;
2616 LDR a2,Current_Thread ; Pickup current thread ptr address
2617 LDR a1,[a2, #0] ; Pickup current thread pointer
2618 CMP a1,#0 ; Determine if a thread is active
2619 BEQ TCT_Idle_Context_Restore ; If not, idle system restore
2620 ;
2621 ; /* Clear the current thread pointer. */
2622 ; TCD_Current_Thread = NU_NULL;
2623 ;
2624 LDR a4,Slice_State ; Pickup time slice state address
2625 MOV a3,#0 ; Build NU_NULL value
2626 STR a3,[a2, #0] ; Set current thread ptr to NU_NULL
2627 ;
2628 ; /* Determine if a time slice is active. If so, the remaining
2629 ; time left on the time slice must be saved in the task's
2630 ; control block. */
2631 ; if (TMD_Time_Slice_State == 0)
2632 ; {
2633 ;
2634 LDR a2,[a4, #0] ; Pickup time slice state
2635 CMP a2,#0 ; Determine if time slice active
2636 BNE TCT_Idle_Context_Restore ; If not, skip time slice reset
2637 ;
2638 ; /* Pickup the remaining portion of the time slice and save it
2639 ; in the task's control block. */
2640 ; REG_Thread_Ptr -> tc_cur_time_slice = TMD_Time_Slice;
2641 ; TMD_Time_Slice_State = 1;
2642 ;
2643 LDR a3,Time_Slice ; Pickup address of time slice left
2644 MOV a2,#1 ; Build disable time slice value
2645 LDR a3,[a3, #0] ; Pickup remaining time slice
2646 STR a2,[a4, #0] ; Disable time slice
2647 STR a3,[a1, #20h] ; Store remaining time slice
2648 ;
2649 ; }
2650 ; }
2651 TCT_Idle_Context_Restore
2652 ;
2653 ; /* Reset the system stack pointer. */
2654 ;
2655 LDR a2,System_Stack ; Pickup address of stack pointer
2656 LDR a3,System_Limit ; Pickup address of stack limit ptr
2657 LDR sp,[a2, #0] ; Switch to system stack
2658 LDR v7,[a3, #0] ; Setup system stack limit
2659 ;
2660 ; /* Return to scheduler. */
2661 ;
2662 B _TCT_Schedule ; Return to scheduling loop
2663 ;
2664 ; }
2665 ;}
2666 ;
2667 ;
2668 ;
2669 ;/*************************************************************************/
2670 ;/* */
2671 ;/* FUNCTION */
2672 ;/* */
2673 ;/* TCT_Activate_HISR */
2674 ;/* */
2675 ;/* DESCRIPTION */
2676 ;/* */
2677 ;/* This function activates the specified HISR. If the HISR is */
2678 ;/* already activated, the HISR's activation count is simply */
2679 ;/* incremented. Otherwise, the HISR is placed on the appropriate */
2680 ;/* HISR priority list in preparation for execution. */
2681 ;/* */
2682 ;/* AUTHOR */
2683 ;/* */
2684 ;/* Barry Sellew, Accelerated Technology, Inc. */
2685 ;/* */
2686 ;/* CALLED BY */
2687 ;/* */
2688 ;/* Application LISRs */
2689 ;/* */
2690 ;/* CALLS */
2691 ;/* */
2692 ;/* None */
2693 ;/* */
2694 ;/* INPUTS */
2695 ;/* */
2696 ;/* hisr Pointer to HISR to activate */
2697 ;/* */
2698 ;/* OUTPUTS */
2699 ;/* */
2700 ;/* NU_SUCCESS Successful completion */
2701 ;/* */
2702 ;/* HISTORY */
2703 ;/* */
2704 ;/* NAME DATE REMARKS */
2705 ;/* */
2706 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
2707 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
2708 ;/* */
2709 ;/*************************************************************************/
2710 ;STATUS TCT_Activate_HISR(TC_HCB *hisr)
2711 ;{
2712 .def $TCT_Activate_HISR
2713 $TCT_Activate_HISR ; Dual-state interworking veneer
2714 .state16
2715 BX pc
2716 NOP
2717 .state32
2718 B _TCT_Activate_HISR
2719 ;
2720 .def _TCT_Activate_HISR
2721 _TCT_Activate_HISR
2722 ;
2723 ;INT priority;
2724 ;
2725 ;
2726 ; /* Lockout interrupts. */
2727 ;
2728 STR v1,[sp, #-4]! ; Save v1
2729 MRS v1,CPSR ; Pickup current CPSR
2730 ORR a2,v1,#LOCKOUT ; Build interrupt lockout value
2731 MSR CPSR,a2 ; Lockout interrupts
2732 ;
2733 ; /* Determine if the HISR is already active. */
2734 ; if (hisr -> tc_activation_count)
2735 ; {
2736 ;
2737 LDR a2,[a1,#40h] ; Pickup current activation count
2738 CMP a2,#0 ; Is it the first activation?
2739 BEQ TCT_First_Activate ; Yes, place it on the correct list
2740 ;
2741 ; /* Increment the activation count. Make sure that it does not go
2742 ; to zero. */
2743 ; hisr -> tc_activation_count++;
2744 ;
2745 ADDS a2,a2,#1 ; Increment the activation count
2746 STR a2,[a1,#40h] ; Store new activation count
2747 ;
2748 ; if (hisr -> tc_activation_count == 0)
2749 ;
2750 ; hisr -> tc_activation_count = 0xFFFFFFFFUL;
2751 ;
2752 MVNEQ a2,#0 ; If counter rolled-over reset
2753 STREQ a2,[a1,#40h] ; Store all ones count
2754 B TCT_Activate_Done ; Finished with activation
2755 ; }
2756 ; else
2757 ; {
2758 TCT_First_Activate
2759 ;
2760 ;
2761 ; /* Set the activation count to 1. */
2762 ; hisr -> tc_activation_count = 1;
2763 ;
2764 MOV a2,#1 ; Initial activation count
2765 STR a2,[a1,#40h] ; Store initial activation count
2766 ;
2767 ; /* Pickup the HISR's priority. */
2768 ; priority = hisr -> tc_priority;
2769 ;
2770 ; /* Determine if there is something in the given priority list. */
2771 ; if (TCD_Active_HISR_Tails[priority])
2772 ; {
2773 ;
2774 LDRB a2,[a1,#1ah] ; Pickup priority of HISR
2775 LDR a3,HISR_Tails ; Pickup tail pointer base
2776 LDR a4,[a3,a2,LSL #2] ; Pickup tail pointer for priority
2777 CMP a4,#0 ; Is this first HISR at priority?
2778 BEQ TCT_First_HISR ; No, append to end of HISR list
2779 ;
2780 ; /* Something is already on this list. Add after the tail. */
2781 ; (TCD_Active_HISR_Tails[priority]) -> tc_active_next = hisr;
2782 ; TCD_Active_HISR_Tails[priority] = hisr;
2783 ;
2784 STR a1,[a4,#3ch] ; Setup the active next pointer
2785 STR a1,[a3,a2,LSL #2] ; Setup the tail pointer
2786 B TCT_Activate_Done ; Finished with activate processing
2787 ; }
2788 ; else
2789 ; {
2790 TCT_First_HISR
2791 ;
2792 ; /* Nothing is on this list. */
2793 ; TCD_Active_HISR_Heads[priority] = hisr;
2794 ; TCD_Active_HISR_Tails[priority] = hisr;
2795 ;
2796 LDR a4,HISR_Heads ; Pickup address of head pointers
2797 STR a1,[a3,a2,LSL #2] ; Set tail pointer to this HISR
2798 STR a1,[a4,a2,LSL #2] ; Set head pointer to this HISR
2799 ;
2800 ; /* Determine the highest priority HISR. */
2801 ; if (TCD_Active_HISR_Heads[0])
2802 ; TCD_Execute_HISR = TCD_Active_HISR_Heads[0];
2803 ; else if (TCD_Active_HISR_Heads[1])
2804 ; TCD_Execute_HISR = TCD_Active_HISR_Heads[1];
2805 ; else
2806 ; TCD_Execute_HISR = TCD_Active_HISR_Heads[2];
2807 ;
2808 LDR a2,[a4,#0] ; Pickup priority 0 head pointer
2809 LDR a1,Execute_HISR ; Build address to execute HISR ptr
2810 CMP a2,#0 ; Is priority 0 active?
2811 LDREQ a2,[a4,#4] ; If not, pickup priority 1 head
2812 CMPEQ a2,#0 ; Is priority 1 active?
2813 LDREQ a2,[a4,#8] ; Else, must be priority 2 active
2814 STR a2,[a1,#0] ; Store which ever priority is the
2815 ; active one
2816 ; }
2817 ; }
2818 TCT_Activate_Done
2819 ;
2820 MSR CPSR,v1 ; Restore interrupt lockout
2821 LDR v1,[sp], #4 ; Restore corrupted v1
2822 ;
2823 ; return(NU_SUCCESS);
2824 ;
2825 MOV a1,#0 ; Always return NU_SUCCESS
2826 BX lr ; Return to caller
2827 ;}
2828 ;
2829 ;
2830 ;
2831 ;/*************************************************************************/
2832 ;/* */
2833 ;/* FUNCTION */
2834 ;/* */
2835 ;/* TCT_HISR_Shell */
2836 ;/* */
2837 ;/* DESCRIPTION */
2838 ;/* */
2839 ;/* This function is the execution shell of each and every HISR. If */
2840 ;/* the HISR has completed its processing, this shell routine exits */
2841 ;/* back to the system. Otherwise, it sequentially calls the HISR */
2842 ;/* routine until the activation count goes to zero. */
2843 ;/* */
2844 ;/* AUTHOR */
2845 ;/* */
2846 ;/* Barry Sellew, Accelerated Technology, Inc. */
2847 ;/* */
2848 ;/* CALLED BY */
2849 ;/* */
2850 ;/* HISR Scheduling */
2851 ;/* */
2852 ;/* CALLS */
2853 ;/* */
2854 ;/* hisr -> tc_entry Actual entry function of HISR*/
2855 ;/* */
2856 ;/* INPUTS */
2857 ;/* */
2858 ;/* None */
2859 ;/* */
2860 ;/* OUTPUTS */
2861 ;/* */
2862 ;/* None */
2863 ;/* */
2864 ;/* HISTORY */
2865 ;/* */
2866 ;/* NAME DATE REMARKS */
2867 ;/* */
2868 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
2869 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
2870 ;/* */
2871 ;/*************************************************************************/
2872 ;VOID TCT_HISR_Shell(void)
2873 ;{
2874 .def $TCT_HISR_Shell
2875 $TCT_HISR_Shell ; Dual-state interworking veneer
2876 .state16
2877 BX pc
2878 NOP
2879 .state32
2880 B _TCT_HISR_Shell
2881 ;
2882 .def _TCT_HISR_Shell
2883 _TCT_HISR_Shell
2884 ;
2885 ; /* Point at the HISR. */
2886 ; REG_HISR_Ptr = (TC_HCB *) TCD_Current_Thread;
2887 ;
2888 LDR a1,Current_Thread ; Build address of thread pointer
2889 LDR v2,[a1, #0] ; Pickup control block pointer
2890 ;
2891 ; do
2892 ; {
2893 TCT_HISR_Loop
2894 ;
2895 ; /* Call the HISR's entry routine. */
2896 ; (*(REG_HISR_Ptr -> tc_entry)) ();
2897 ;
2898 LDR v1,[v2,#44h] ; Call HISR entry function
2899 BL IND_CALL ; indirectly
2900 ;
2901 ; /* Lockout interrupts. */
2902 ;
2903 MRS a2,CPSR ; Pickup current CPSR
2904 ORR a2,a2,#LOCKOUT ; Build interrupt lockout
2905 MSR CPSR,a2 ; Lockout interrupts
2906 ;
2907 ; /* On return, decrement the activation count and check to see if
2908 ; it is 0. Once it reaches 0, the HISR should be made inactive. */
2909 ; REG_HISR_Ptr -> tc_activation_count--;
2910 ;
2911 LDR a1,[v2, #40h] ; Pickup current activation count
2912 SUBS a1,a1,#1 ; Subtract and set condition codes
2913 STR a1,[v2, #40h] ; Store new activation count
2914 BEQ TCT_HISR_Finished ; Finished processing HISR
2915
2916 ; /* Restore interrupts. */
2917 ;
2918 LDR a3,Int_Level ; Pickup address of interrupt level
2919 MRS a2,CPSR ; Pickup current CPSR
2920 LDR a4,[a3, #0] ; Pickup interrupt lockout level
2921 BIC a2,a2,#LOCK_MSK ; Clear lockout bits
2922 ORR a2,a2,a4 ; Build new interrupt lockout
2923 MSR CPSR,a2 ; Setup CPSR appropriately
2924 B TCT_HISR_Loop ; Return to HISR loop
2925 ; }
2926 ; while (REG_HISR_Ptr -> tc_activation_count);
2927 ;
2928 TCT_HISR_Finished
2929 ;
2930 ; /* At this point, the HISR needs to be made inactive. */
2931 ;
2932 ; /* Determine if this is the only HISR on the given priority list. */
2933 ; if (REG_HISR_Ptr == TCD_Active_HISR_Tails[REG_HISR_Ptr -> tc_priority])
2934 ; {
2935 ;
2936 LDR lr,HISR_Tails ; Pickup tail pointers address
2937 LDRB a4,[v2,#1ah] ; Pickup priority
2938 LDR v3,[lr,a4,LSL #2] ; Pickup this priority tail pointer
2939 LDR a3,Execute_HISR ; Build address to execute HISR ptr
2940 MOV a1,#0 ; Clear a1
2941 LDR a2,HISR_Heads ; Pickup head pointers address
2942 CMP v3,v2 ; Is this priority tail the same as
2943 ; the current HISR?
2944 BNE TCT_More_HISRs ; If not, more HISRs at this
2945 ; priority
2946 ;
2947 ; /* The only HISR on the list. Clean up the list and check for the
2948 ; highest priority HISR. */
2949 ; TCD_Active_HISR_Heads[REG_HISR_Ptr -> tc_priority] = NU_NULL;
2950 ; TCD_Active_HISR_Tails[REG_HISR_Ptr -> tc_priority] = NU_NULL;
2951 ;
2952 STR a1,[a2,a4,LSL #2] ; Set head pointer to NU_NULL
2953 STR a1,[lr,a4,LSL #2] ; Set tail pointer to NU_NULL
2954 ;
2955 ; /* Determine the highest priority HISR. */
2956 ; if (TCD_Active_HISR_Heads[0])
2957 ; TCD_Execute_HISR = TCD_Active_HISR_Heads[0];
2958 ; else if (TCD_Active_HISR_Heads[1])
2959 ; TCD_Execute_HISR = TCD_Active_HISR_Heads[1];
2960 ; else
2961 ; TCD_Execute_HISR = TCD_Active_HISR_Heads[2];
2962 ;
2963 LDR a4,[a2,#0] ; Pickup priority 0 head pointer
2964 CMP a4,#0 ; Is there an HISR active?
2965 LDREQ a4,[a2,#4] ; If not, pickup priority 1 pointer
2966 CMPEQ a4,#0 ; Is there an HISR active?
2967 LDREQ a4,[a2,#8] ; If not, pickup priority 2 pointer
2968 STR a4,[a3,#0] ; Setup execute HISR pointer
2969 B TCT_HISR_Exit ; Exit HISR processing
2970 ; }
2971 ; else
2972 ; {
2973 ;
2974 TCT_More_HISRs
2975 ;
2976 ; /* Move the head pointer to the next HISR in the list. */
2977 ; TCD_Active_HISR_Heads[REG_HISR_Ptr -> tc_priority] =
2978 ; REG_HISR_Ptr -> tc_active_next;
2979 ;
2980 ; /* Also set the TCD_Execute_HISR pointer. */
2981 ; TCD_Execute_HISR = REG_HISR_Ptr -> tc_active_next;
2982 ;
2983 LDR lr,[v2,#3ch] ; Pickup next HISR to activate
2984 STR lr,[a2,a4,LSL #2] ; Setup new head pointer
2985 STR lr,[a3, #0] ; Setup execute HISR pointer
2986 ; }
2987 ;
2988 TCT_HISR_Exit
2989 ;
2990 ; /* Build fake return to the top of this loop. The next time the HISR
2991 ; is activated, it will return to the top of this function. */
2992 ;
2993 LDR lr,HISR_Shell ; Pickup address of shell entry
2994 STMDB sp!,{v1-ip,lr} ; Save minimal context of thread on
2995 ; the current stack
2996 MOV a3,#0 ; Build solicited stack type value
2997 ; and NU_NULL value
2998 STR a3,[sp, #-4]! ; Save state mask
2999 STR a3,[sp, #-4]! ; Place it on the top of the stack
3000 ;
3001 ; /* Clear the current thread control block. */
3002 ; TCD_Current_Thread = NU_NULL;
3003 ;
3004 LDR a2,Current_Thread ; Pickup current thread ptr address
3005 STR a3,[a2, #0] ; Set current thread pointer to
3006 ; NU_NULL
3007 ;
3008 ; /* Save off the current stack pointer in the control block. */
3009 ; REG_HISR_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr;
3010 ;
3011 STR sp,[v2, #2ch] ; Save the thread's stack pointer
3012 ;
3013 ; /* Switch to the system stack. */
3014 ; REG_Stack_Ptr = (BYTE_PTR) TCD_System_Stack;
3015 ;
3016 LDR a2,System_Stack ; Pickup address of stack pointer
3017 LDR a3,System_Limit ; Pickup address of stack limit ptr
3018 LDR sp,[a2, #0] ; Switch to system stack
3019 LDR v7,[a3, #0] ; Setup system stack limit
3020 ;
3021 ; /* Transfer control to the main scheduling loop. */
3022 ;
3023 B _TCT_Schedule ; Return to main scheduling loop
3024 ;}
3025 ;
3026 ;/* Define the global addresses used in this section */
3027 ;
3028 System_Limit
3029 .word _TCT_System_Limit
3030 ;
3031 Int_Level
3032 .word _TCD_Interrupt_Level
3033 ;
3034 Task_Shell
3035 .word $TCC_Task_Shell
3036 ;
3037 HISR_Shell
3038 .word _TCT_HISR_Shell
3039 ;
3040 Signal_Shell
3041 .word $TCC_Signal_Shell
3042 ;
3043 Current_Thread
3044 .word _TCD_Current_Thread
3045 ;
3046 Execute_HISR
3047 .word _TCD_Execute_HISR
3048 ;
3049 Execute_Task
3050 .word _TCD_Execute_Task
3051 ;
3052 Time_Slice
3053 .word _TMD_Time_Slice
3054 ;
3055 Slice_State
3056 .word _TMD_Time_Slice_State
3057 ;
3058 System_Stack
3059 .word _TCD_System_Stack
3060 ;
3061 Int_Count
3062 .word _TCD_Interrupt_Count
3063 ;
3064 HISR_Tails
3065 .word _TCD_Active_HISR_Tails
3066 ;
3067 HISR_Heads
3068 .word _TCD_Active_HISR_Heads
3069 ;
3070 System_Error
3071 .word $ERC_System_Error
3072 ;
3073 .end