1 ------------------------------------------------------------------------------
2 -- ------------------ M a R T E O S ------------------- --
3 ------------------------------------------------------------------------------
6 -- 'N o n _ L o c a l _ J u m p'
10 -- File 'non_local_jump.ads' By MAR
12 -- Non-local jumps for preempted tasks.
14 -- IMPORTANT: it must be compiled without any optimization!!
18 ------------------------------------------------------------------------------
21 -- 02-08-07:version operativa.
23 -- {MAR>} -------------------------------------------------------------------
25 with Basic_Integer_Types;
27 package Non_Local_Jump is
28 pragma Optimize (Off);
30 type Jmp_Context is private;
36 -- Context stores the information required to modify the stack of a
37 -- preempted task with 'Change_Return_Context_Of_Preempted_Task'.
39 -- This function stores in 'Context' the registers and its stack frame. This
40 -- information can be used for 'Restore_Context' to change the stack of the
41 -- task (when it is preempted) so that when it is scheduled again it returns
42 -- to the end of this function
44 procedure Save_Context (Context : access Jmp_Context);
45 pragma Export (C, Save_Context, "marte_nonlocaljmp_savecontext");
51 -- To be invoked after 'Save_Context'. If invoked after a direct invocation
52 -- to 'Save_Context', 'After_Jump' shall return 0 (False). If invoked after
53 -- returning from 'Save_Context' due to a call to 'Restore_Context',
54 -- 'After_Jump' shall return 1 (True).
55 function After_Jump (Context : access Jmp_Context)
56 return Basic_Integer_Types.Unsigned_32;
57 pragma Export (C, After_Jump, "marte_nonlocaljmp_afterjmp");
63 -- This procedure changes the return context of a preempted task.
66 -- TCB_Ac.Stack_Ptr->| Regs | | |
69 -- | | | ret |<-TCB_Ac.Stack_Ptr
71 -- | |<-Context.Esp->| SC* |
76 -- SC*: stack frame of 'Save_Context'.
78 -- The next time the task is scheduled will execute the final part of
81 -- The full process is the following: 'Save_Context' stores the registers
82 -- and its stack frame in 'Jmp_Context'. 'Restore_Context' restores that
83 -- context placing the stored frame in the same position of the stack it was
84 -- originally. Over this frame it is placed the value of the ebp register
85 -- and the address of label "1:" in 'Save_Context'.
86 -- When the task is scheduled again, the first instruction it executes is
87 -- "ret" in 'Processor_Registers.Context_Switch' and then the address of
88 -- label "1:" in 'Save_Context' is popped from the stack. Once in
89 -- 'Save_Context', the ebp register is also popped and, with this
90 -- instruction, the registers and stack are in the same situation it was the
91 -- time that the contexts was stored, and then the final part of
92 -- 'Save_Context' can be executed successfully.
93 procedure Restore_Context (TCB_Ac : System.Address;
94 Context : access Jmp_Context);
95 pragma Export (C, Restore_Context, "marte_nonlocaljmp_restorecontext");
99 type Save_Context_Stack is array (1 .. 29) of -- 17->2005, 29->2007
100 Basic_Integer_Types.Unsigned_32;
101 type Save_Context_Stack_Ac is access Save_Context_Stack;
102 -- Stack of 'Save_Context' funcion. The frame created by 'Save_Context' is
103 -- 16/28 integers long when no optimization is used for this function. The
104 -- total size is 17/29 because ebp register is also stored in the stack
106 -- A change in this record could affect the type
107 -- 'marte_nonlocaljmp_context_t' defined in
108 -- 'x86_arch/include/misc/marte_non_local_jmp.h'
109 type Jmp_Context is record
110 Return_Address : System.Address;
111 -- The address of label "1:" inside 'Save_Context'. The task jumps to
112 -- this instruction from the 'ret' instruction in
113 -- 'Processor_Registers.Context_Switch'.
115 Ebx : Basic_Integer_Types.Unsigned_32;
116 Ecx : Basic_Integer_Types.Unsigned_32;
117 Edx : Basic_Integer_Types.Unsigned_32;
118 Esi : Basic_Integer_Types.Unsigned_32;
119 Edi : Basic_Integer_Types.Unsigned_32;
120 Ebp : Basic_Integer_Types.Unsigned_32;
121 Eax : Basic_Integer_Types.Unsigned_32;
123 Esp : Basic_Integer_Types.Unsigned_32; -- top of stack
125 After_Jmp : Basic_Integer_Types.Unsigned_32;
126 -- 0 (False) after a direct invocation to 'Save_Context'. 1 (True) if
127 -- 'Restore_Context' has been invoked.
129 Context_Stack : Save_Context_Stack;
130 -- Stack frame of 'Save_Context' funcion
133 pragma Volatile (Jmp_Context);
134 type Jmp_Context_Ac is access Jmp_Context;
136 type Preempted_Task_Restore_Context_Stack is record
137 Return_Address : System.Address;
138 Ebp : Basic_Integer_Types.Unsigned_32;
139 Context_Stack : Save_Context_Stack;
141 type Preempted_Task_Restore_Context_Stack_Ac is
142 access Preempted_Task_Restore_Context_Stack;