]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - marte_non_local_jump/non_local_jump.ads
a9af143ddf299dea085e07357f68ea90a94e82e8
[frescor/fosa.git] / marte_non_local_jump / non_local_jump.ads
1 ------------------------------------------------------------------------------
2 --  ------------------         M a R T E   O S         -------------------  --
3 ------------------------------------------------------------------------------
4 --                                                             {MARTE_VERSION}
5 --
6 --                      'N o n _ L o c a l _ J u m p'
7 --
8 --                                  Spec
9 --
10 --  File 'non_local_jump.ads'                                          By MAR
11 --
12 --  Non-local jumps for preempted tasks.
13 --
14 --  IMPORTANT: it must be compiled without any optimization!!
15 --
16 --  {MARTE_COPYRIGHT}
17 --
18 ------------------------------------------------------------------------------
19 --  {<MAR}
20 --
21 --  02-08-07:version operativa.
22 --
23 --  {MAR>} -------------------------------------------------------------------
24 with System;
25 with Basic_Integer_Types;
26
27 package Non_Local_Jump is
28    pragma Optimize (Off);
29
30    type Jmp_Context is private;
31
32    -------------------
33    -- Save_Context --
34    -------------------
35    --
36    --  Context stores the information required to modify the stack of a
37    --  preempted task with 'Change_Return_Context_Of_Preempted_Task'.
38    --
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
43    --
44    procedure Save_Context (Context : access Jmp_Context);
45    pragma Export (C, Save_Context, "marte_nonlocaljmp_savecontext");
46
47    ------------------
48    --  After_Jump  --
49    ------------------
50    --
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");
58
59    ---------------------
60    -- Restore_Context --
61    ---------------------
62    --
63    --  This procedure changes the return context of a preempted task.
64    --
65    --                    |        |               |       |
66    --  TCB_Ac.Stack_Ptr->|  Regs  |               |       |
67    --                    |        |               |       |
68    --                       ...                      ...
69    --                    |        |               |  ret  |<-TCB_Ac.Stack_Ptr
70    --                    |        |               |  ebp  |
71    --                    |        |<-Context.Esp->|  SC*  |
72    --                    |        |               |  SC*  |
73    --                    |        |               |  SC*  |
74    --                    |        |               |       |
75    --                      before                   after
76    --  SC*: stack frame of 'Save_Context'.
77    --
78    --  The next time the task is scheduled will execute the final part of
79    --  Save_Context.
80    --
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");
96
97 private
98
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
105
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'.
114
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;
122
123       Esp                : Basic_Integer_Types.Unsigned_32;  -- top of stack
124
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.
128
129       Context_Stack  : Save_Context_Stack;
130       --  Stack frame of 'Save_Context' funcion
131
132    end record;
133    pragma Volatile (Jmp_Context);
134    type Jmp_Context_Ac is access Jmp_Context;
135
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;
140    end record;
141    type Preempted_Task_Restore_Context_Stack_Ac is
142      access Preempted_Task_Restore_Context_Stack;
143
144 end Non_Local_Jump;