xref: /minix3/minix/lib/libsys/sef_init.c (revision 6c7e614940fdd473417d84d8690a79a672edd083)
1433d6423SLionel Sambuc #include <assert.h>
2433d6423SLionel Sambuc #include <unistd.h>
3433d6423SLionel Sambuc #include <string.h>
4433d6423SLionel Sambuc 
52867e60aSDavid van Moolenbroek #include <machine/vmparam.h>
62867e60aSDavid van Moolenbroek 
72867e60aSDavid van Moolenbroek #include <minix/sysutil.h>
82867e60aSDavid van Moolenbroek 
92867e60aSDavid van Moolenbroek #include "syslib.h"
10433d6423SLionel Sambuc /* SEF Init callbacks. */
11e6f5b0ccSCristiano Giuffrida static struct sef_init_cbs {
12433d6423SLionel Sambuc     sef_cb_init_t                       sef_cb_init_fresh;
13433d6423SLionel Sambuc     sef_cb_init_t                       sef_cb_init_lu;
14433d6423SLionel Sambuc     sef_cb_init_t                       sef_cb_init_restart;
15433d6423SLionel Sambuc     sef_cb_init_response_t              sef_cb_init_response;
16e6f5b0ccSCristiano Giuffrida } sef_init_cbs = {
17433d6423SLionel Sambuc     SEF_CB_INIT_FRESH_DEFAULT,
18433d6423SLionel Sambuc     SEF_CB_INIT_LU_DEFAULT,
19433d6423SLionel Sambuc     SEF_CB_INIT_RESTART_DEFAULT,
20433d6423SLionel Sambuc     SEF_CB_INIT_RESPONSE_DEFAULT
21433d6423SLionel Sambuc };
22433d6423SLionel Sambuc 
23433d6423SLionel Sambuc /* SEF Init prototypes for sef_startup(). */
24433d6423SLionel Sambuc int do_sef_rs_init(endpoint_t old_endpoint);
25433d6423SLionel Sambuc int do_sef_init_request(message *m_ptr);
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc /* Debug. */
28433d6423SLionel Sambuc EXTERN char* sef_debug_header(void);
29433d6423SLionel Sambuc 
30433d6423SLionel Sambuc /* Information about SELF. */
31433d6423SLionel Sambuc EXTERN endpoint_t sef_self_endpoint;
32433d6423SLionel Sambuc EXTERN endpoint_t sef_self_priv_flags;
33d196e2c3SCristiano Giuffrida EXTERN endpoint_t sef_self_init_flags;
34*6c7e6149SDavid van Moolenbroek EXTERN int sef_controlled_crash;
35d196e2c3SCristiano Giuffrida 
36d196e2c3SCristiano Giuffrida #ifndef ST_STACK_REFS_BUFF_SIZE
37d196e2c3SCristiano Giuffrida #define ST_STACK_REFS_BUFF_SIZE           1024
38d196e2c3SCristiano Giuffrida #endif
39433d6423SLionel Sambuc 
40433d6423SLionel Sambuc /*===========================================================================*
41433d6423SLionel Sambuc  *                              process_init             		     *
42433d6423SLionel Sambuc  *===========================================================================*/
process_init(int type,sef_init_info_t * info)43433d6423SLionel Sambuc static int process_init(int type, sef_init_info_t *info)
44433d6423SLionel Sambuc {
45433d6423SLionel Sambuc /* Process initialization. */
46d196e2c3SCristiano Giuffrida   int r, result, debug_result_found, is_def_cb;
47d196e2c3SCristiano Giuffrida   cp_grant_id_t gid;
48433d6423SLionel Sambuc   message m;
49433d6423SLionel Sambuc 
50433d6423SLionel Sambuc   /* Debug. */
51433d6423SLionel Sambuc #if SEF_INIT_DEBUG
52433d6423SLionel Sambuc   sef_init_debug_begin();
53d196e2c3SCristiano Giuffrida   sef_init_dprint("%s. Got a SEF Init request of type %d, flags 0x%08x, rproctab_gid %d, ep %d, old ep %d, restarts %d. About to init.\n",
54d196e2c3SCristiano Giuffrida       sef_debug_header(), type, info->flags, info->rproctab_gid, info->endpoint, info->old_endpoint, info->restarts);
55433d6423SLionel Sambuc   sef_init_debug_end();
56433d6423SLionel Sambuc #endif
57433d6423SLionel Sambuc 
58d196e2c3SCristiano Giuffrida   /* Clear any IPC filter. */
59d196e2c3SCristiano Giuffrida   r = sys_statectl(SYS_STATE_CLEAR_IPC_FILTERS, 0, 0);
60d196e2c3SCristiano Giuffrida   assert(r == OK);
61d196e2c3SCristiano Giuffrida 
62d196e2c3SCristiano Giuffrida   /* Create grant for state transfer. */
63d196e2c3SCristiano Giuffrida   gid = cpf_grant_direct(sef_self_endpoint, 0, ULONG_MAX, CPF_READ);
64d196e2c3SCristiano Giuffrida   if(!GRANT_VALID(gid)) {
65d196e2c3SCristiano Giuffrida       panic("unable to create grant for state transfer");
66d196e2c3SCristiano Giuffrida   }
67d196e2c3SCristiano Giuffrida   if(gid != SEF_STATE_TRANSFER_GID) {
68d196e2c3SCristiano Giuffrida       panic("bad state transfer gid");
69d196e2c3SCristiano Giuffrida   }
70d196e2c3SCristiano Giuffrida 
71d196e2c3SCristiano Giuffrida   /* If debug init flags are allowed, process them first. */
72d196e2c3SCristiano Giuffrida   debug_result_found = 0;
73d196e2c3SCristiano Giuffrida   if(SEF_INIT_ALLOW_DEBUG_INIT_FLAGS) {
74d196e2c3SCristiano Giuffrida       int flags = info->flags;
75d196e2c3SCristiano Giuffrida       if(flags & SEF_INIT_CRASH) {
76d196e2c3SCristiano Giuffrida           result = sef_cb_init_crash(type, info);
77d196e2c3SCristiano Giuffrida           debug_result_found = 1;
78d196e2c3SCristiano Giuffrida       }
79d196e2c3SCristiano Giuffrida       else if(flags & SEF_INIT_FAIL) {
80d196e2c3SCristiano Giuffrida           result = sef_cb_init_fail(type, info);
81d196e2c3SCristiano Giuffrida           debug_result_found = 1;
82d196e2c3SCristiano Giuffrida       }
83d196e2c3SCristiano Giuffrida       else if(flags & SEF_INIT_TIMEOUT) {
84d196e2c3SCristiano Giuffrida           result = sef_cb_init_timeout(type, info);
85d196e2c3SCristiano Giuffrida           debug_result_found = 1;
86d196e2c3SCristiano Giuffrida       }
87d196e2c3SCristiano Giuffrida   }
88d196e2c3SCristiano Giuffrida 
89d196e2c3SCristiano Giuffrida   if(!debug_result_found) {
90433d6423SLionel Sambuc       /* Let the callback code handle the specific initialization type. */
91d196e2c3SCristiano Giuffrida       is_def_cb = info->flags & SEF_INIT_DEFCB;
92433d6423SLionel Sambuc       switch(type) {
93433d6423SLionel Sambuc           case SEF_INIT_FRESH:
94d196e2c3SCristiano Giuffrida               result = is_def_cb ? SEF_CB_INIT_FRESH_DEFAULT(type, info)
95d196e2c3SCristiano Giuffrida                                  : sef_init_cbs.sef_cb_init_fresh(type, info);
96433d6423SLionel Sambuc           break;
97433d6423SLionel Sambuc           case SEF_INIT_LU:
98d196e2c3SCristiano Giuffrida               result = is_def_cb ? SEF_CB_INIT_LU_DEFAULT(type, info)
99d196e2c3SCristiano Giuffrida                                  : sef_init_cbs.sef_cb_init_lu(type, info);
100433d6423SLionel Sambuc           break;
101433d6423SLionel Sambuc           case SEF_INIT_RESTART:
102d196e2c3SCristiano Giuffrida               result = is_def_cb ? SEF_CB_INIT_RESTART_DEFAULT(type, info)
103d196e2c3SCristiano Giuffrida                                  : sef_init_cbs.sef_cb_init_restart(type, info);
104433d6423SLionel Sambuc           break;
105433d6423SLionel Sambuc 
106433d6423SLionel Sambuc           default:
107433d6423SLionel Sambuc               /* Not a valid SEF init type. */
108433d6423SLionel Sambuc               result = EINVAL;
109433d6423SLionel Sambuc           break;
110433d6423SLionel Sambuc       }
111d196e2c3SCristiano Giuffrida   }
112433d6423SLionel Sambuc 
113433d6423SLionel Sambuc   memset(&m, 0, sizeof(m));
114433d6423SLionel Sambuc   m.m_source = sef_self_endpoint;
115433d6423SLionel Sambuc   m.m_type = RS_INIT;
116433d6423SLionel Sambuc   m.m_rs_init.result = result;
117e6f5b0ccSCristiano Giuffrida   r = sef_init_cbs.sef_cb_init_response(&m);
118d196e2c3SCristiano Giuffrida   if (r != OK) {
119d196e2c3SCristiano Giuffrida       return r;
120d196e2c3SCristiano Giuffrida   }
121d196e2c3SCristiano Giuffrida 
122d196e2c3SCristiano Giuffrida   /* See if we need to unmap the initialization buffer. */
123d196e2c3SCristiano Giuffrida   if(info->init_buff_cleanup_start) {
124d196e2c3SCristiano Giuffrida       void *addrstart = info->init_buff_cleanup_start;
125d196e2c3SCristiano Giuffrida       size_t len = info->init_buff_len - (size_t)((char*)info->init_buff_cleanup_start - (char*)info->init_buff_start);
126d196e2c3SCristiano Giuffrida       r = sef_munmap(addrstart, len, VM_MUNMAP);
127d196e2c3SCristiano Giuffrida       if(r != OK) {
128d196e2c3SCristiano Giuffrida           printf("process_init: warning: munmap failed for init buffer\n");
129d196e2c3SCristiano Giuffrida       }
130d196e2c3SCristiano Giuffrida   }
131d196e2c3SCristiano Giuffrida 
132d196e2c3SCristiano Giuffrida   /* Tell the kernel about the grant table. */
133d196e2c3SCristiano Giuffrida   cpf_reload();
134d196e2c3SCristiano Giuffrida 
135d196e2c3SCristiano Giuffrida   /* Tell the kernel about the senda table. */
136d196e2c3SCristiano Giuffrida   r = senda_reload();
137d196e2c3SCristiano Giuffrida   if(r != OK) {
138d196e2c3SCristiano Giuffrida       printf("process_init: warning: senda_reload failed\n");
139d196e2c3SCristiano Giuffrida   }
140d196e2c3SCristiano Giuffrida 
141d196e2c3SCristiano Giuffrida   /* Tell the kernel about the state table. */
142d196e2c3SCristiano Giuffrida   sys_statectl(SYS_STATE_SET_STATE_TABLE, sef_llvm_state_table_addr(), 0);
143433d6423SLionel Sambuc 
144433d6423SLionel Sambuc   return r;
145433d6423SLionel Sambuc }
146433d6423SLionel Sambuc 
147433d6423SLionel Sambuc /*===========================================================================*
148433d6423SLionel Sambuc  *                              do_sef_rs_init             		     *
149433d6423SLionel Sambuc  *===========================================================================*/
do_sef_rs_init(endpoint_t old_endpoint)150433d6423SLionel Sambuc int do_sef_rs_init(endpoint_t old_endpoint)
151433d6423SLionel Sambuc {
152433d6423SLionel Sambuc /* Special SEF Init for RS. */
153433d6423SLionel Sambuc   int r;
154433d6423SLionel Sambuc   int type;
155433d6423SLionel Sambuc   sef_init_info_t info;
156d196e2c3SCristiano Giuffrida   memset(&info, 0, sizeof(info));
157433d6423SLionel Sambuc 
158433d6423SLionel Sambuc   /* Get init parameters from SEF. */
159433d6423SLionel Sambuc   type = SEF_INIT_FRESH;
160433d6423SLionel Sambuc   if(sef_self_priv_flags & LU_SYS_PROC) {
161433d6423SLionel Sambuc       type = SEF_INIT_LU;
162433d6423SLionel Sambuc   }
163433d6423SLionel Sambuc   else if(sef_self_priv_flags & RST_SYS_PROC) {
164433d6423SLionel Sambuc       type = SEF_INIT_RESTART;
165433d6423SLionel Sambuc   }
166d196e2c3SCristiano Giuffrida   info.flags = sef_self_init_flags;
167d196e2c3SCristiano Giuffrida   info.rproctab_gid = GRANT_INVALID;
168433d6423SLionel Sambuc   info.endpoint = sef_self_endpoint;
169433d6423SLionel Sambuc   info.old_endpoint = old_endpoint;
170d196e2c3SCristiano Giuffrida   info.restarts = 0;
171d196e2c3SCristiano Giuffrida 
172d196e2c3SCristiano Giuffrida   /* Get init buffer details from VM. */
173d196e2c3SCristiano Giuffrida   info.init_buff_start = NULL;
174d196e2c3SCristiano Giuffrida   info.init_buff_len = 0;
175d196e2c3SCristiano Giuffrida   if(type != SEF_INIT_FRESH) {
176d196e2c3SCristiano Giuffrida       r = vm_memctl(RS_PROC_NR, VM_RS_MEM_GET_PREALLOC_MAP,
177d196e2c3SCristiano Giuffrida           &info.init_buff_start, &info.init_buff_len);
178d196e2c3SCristiano Giuffrida       if(r != OK) {
179d196e2c3SCristiano Giuffrida           printf("do_sef_rs_init: vm_memctl failed\n");
180d196e2c3SCristiano Giuffrida       }
181d196e2c3SCristiano Giuffrida   }
182d196e2c3SCristiano Giuffrida   info.init_buff_cleanup_start = info.init_buff_start;
183433d6423SLionel Sambuc 
184433d6423SLionel Sambuc   /* Peform initialization. */
185433d6423SLionel Sambuc   r = process_init(type, &info);
186433d6423SLionel Sambuc 
187433d6423SLionel Sambuc   return r;
188433d6423SLionel Sambuc }
189433d6423SLionel Sambuc 
190433d6423SLionel Sambuc /*===========================================================================*
191433d6423SLionel Sambuc  *                            do_sef_init_request             		     *
192433d6423SLionel Sambuc  *===========================================================================*/
do_sef_init_request(message * m_ptr)193433d6423SLionel Sambuc int do_sef_init_request(message *m_ptr)
194433d6423SLionel Sambuc {
195433d6423SLionel Sambuc /* Handle a SEF Init request. */
196433d6423SLionel Sambuc   int r;
197433d6423SLionel Sambuc   int type;
198433d6423SLionel Sambuc   sef_init_info_t info;
199d196e2c3SCristiano Giuffrida   memset(&info, 0, sizeof(info));
200433d6423SLionel Sambuc 
201433d6423SLionel Sambuc   /* Get init parameters from message. */
202433d6423SLionel Sambuc   type = m_ptr->m_rs_init.type;
203d196e2c3SCristiano Giuffrida   info.flags = m_ptr->m_rs_init.flags;
204433d6423SLionel Sambuc   info.rproctab_gid = m_ptr->m_rs_init.rproctab_gid;
205433d6423SLionel Sambuc   info.endpoint = sef_self_endpoint;
206433d6423SLionel Sambuc   info.old_endpoint = m_ptr->m_rs_init.old_endpoint;
207d196e2c3SCristiano Giuffrida   info.restarts = m_ptr->m_rs_init.restarts;
208d196e2c3SCristiano Giuffrida   info.init_buff_start = (void*) m_ptr->m_rs_init.buff_addr;
209d196e2c3SCristiano Giuffrida   info.init_buff_cleanup_start = info.init_buff_start;
210d196e2c3SCristiano Giuffrida   info.init_buff_len = m_ptr->m_rs_init.buff_len;
211728b0e5bSDavid van Moolenbroek   info.prepare_state = m_ptr->m_rs_init.prepare_state;
212433d6423SLionel Sambuc 
213433d6423SLionel Sambuc   /* Peform initialization. */
214433d6423SLionel Sambuc   r = process_init(type, &info);
215433d6423SLionel Sambuc 
216433d6423SLionel Sambuc   return r;
217433d6423SLionel Sambuc }
218433d6423SLionel Sambuc 
219433d6423SLionel Sambuc /*===========================================================================*
220433d6423SLionel Sambuc  *                         sef_setcb_init_fresh                              *
221433d6423SLionel Sambuc  *===========================================================================*/
sef_setcb_init_fresh(sef_cb_init_t cb)222433d6423SLionel Sambuc void sef_setcb_init_fresh(sef_cb_init_t cb)
223433d6423SLionel Sambuc {
224433d6423SLionel Sambuc   assert(cb != NULL);
225e6f5b0ccSCristiano Giuffrida   sef_init_cbs.sef_cb_init_fresh = cb;
226433d6423SLionel Sambuc }
227433d6423SLionel Sambuc 
228433d6423SLionel Sambuc /*===========================================================================*
229433d6423SLionel Sambuc  *                            sef_setcb_init_lu                              *
230433d6423SLionel Sambuc  *===========================================================================*/
sef_setcb_init_lu(sef_cb_init_t cb)231433d6423SLionel Sambuc void sef_setcb_init_lu(sef_cb_init_t cb)
232433d6423SLionel Sambuc {
233433d6423SLionel Sambuc   assert(cb != NULL);
234e6f5b0ccSCristiano Giuffrida   sef_init_cbs.sef_cb_init_lu = cb;
235433d6423SLionel Sambuc }
236433d6423SLionel Sambuc 
237433d6423SLionel Sambuc /*===========================================================================*
238433d6423SLionel Sambuc  *                         sef_setcb_init_restart                            *
239433d6423SLionel Sambuc  *===========================================================================*/
sef_setcb_init_restart(sef_cb_init_t cb)240433d6423SLionel Sambuc void sef_setcb_init_restart(sef_cb_init_t cb)
241433d6423SLionel Sambuc {
242433d6423SLionel Sambuc   assert(cb != NULL);
243e6f5b0ccSCristiano Giuffrida   sef_init_cbs.sef_cb_init_restart = cb;
244433d6423SLionel Sambuc }
245433d6423SLionel Sambuc 
246433d6423SLionel Sambuc /*===========================================================================*
247433d6423SLionel Sambuc  *                         sef_setcb_init_response                           *
248433d6423SLionel Sambuc  *===========================================================================*/
sef_setcb_init_response(sef_cb_init_response_t cb)249433d6423SLionel Sambuc void sef_setcb_init_response(sef_cb_init_response_t cb)
250433d6423SLionel Sambuc {
251433d6423SLionel Sambuc   assert(cb != NULL);
252e6f5b0ccSCristiano Giuffrida   sef_init_cbs.sef_cb_init_response = cb;
253433d6423SLionel Sambuc }
254433d6423SLionel Sambuc 
255433d6423SLionel Sambuc /*===========================================================================*
256433d6423SLionel Sambuc  *      	              sef_cb_init_null                               *
257433d6423SLionel Sambuc  *===========================================================================*/
sef_cb_init_null(int UNUSED (type),sef_init_info_t * UNUSED (info))258433d6423SLionel Sambuc int sef_cb_init_null(int UNUSED(type),
259433d6423SLionel Sambuc    sef_init_info_t *UNUSED(info))
260433d6423SLionel Sambuc {
261433d6423SLionel Sambuc   return OK;
262433d6423SLionel Sambuc }
263433d6423SLionel Sambuc 
264433d6423SLionel Sambuc /*===========================================================================*
265433d6423SLionel Sambuc  *                        sef_cb_init_response_null        		     *
266433d6423SLionel Sambuc  *===========================================================================*/
sef_cb_init_response_null(message * UNUSED (m_ptr))267433d6423SLionel Sambuc int sef_cb_init_response_null(message * UNUSED(m_ptr))
268433d6423SLionel Sambuc {
269433d6423SLionel Sambuc   return ENOSYS;
270433d6423SLionel Sambuc }
271433d6423SLionel Sambuc 
272433d6423SLionel Sambuc /*===========================================================================*
273433d6423SLionel Sambuc  *      	              sef_cb_init_fail                               *
274433d6423SLionel Sambuc  *===========================================================================*/
sef_cb_init_fail(int UNUSED (type),sef_init_info_t * UNUSED (info))275433d6423SLionel Sambuc int sef_cb_init_fail(int UNUSED(type), sef_init_info_t *UNUSED(info))
276433d6423SLionel Sambuc {
277433d6423SLionel Sambuc   return ENOSYS;
278433d6423SLionel Sambuc }
279433d6423SLionel Sambuc 
280433d6423SLionel Sambuc /*===========================================================================*
281433d6423SLionel Sambuc  *      	              sef_cb_init_reset                              *
282433d6423SLionel Sambuc  *===========================================================================*/
sef_cb_init_reset(int UNUSED (type),sef_init_info_t * UNUSED (info))283433d6423SLionel Sambuc int sef_cb_init_reset(int UNUSED(type), sef_init_info_t *UNUSED(info))
284433d6423SLionel Sambuc {
285433d6423SLionel Sambuc   /* Tell RS to reincarnate us, with no old resources, and a new endpoint. */
286433d6423SLionel Sambuc   return ERESTART;
287433d6423SLionel Sambuc }
288433d6423SLionel Sambuc 
289433d6423SLionel Sambuc /*===========================================================================*
290433d6423SLionel Sambuc  *      	              sef_cb_init_crash                              *
291433d6423SLionel Sambuc  *===========================================================================*/
sef_cb_init_crash(int UNUSED (type),sef_init_info_t * UNUSED (info))292433d6423SLionel Sambuc int sef_cb_init_crash(int UNUSED(type), sef_init_info_t *UNUSED(info))
293433d6423SLionel Sambuc {
294e6f5b0ccSCristiano Giuffrida   panic("Simulating a crash at initialization time...\n");
295433d6423SLionel Sambuc 
296433d6423SLionel Sambuc   return OK;
297433d6423SLionel Sambuc }
298433d6423SLionel Sambuc 
299433d6423SLionel Sambuc /*===========================================================================*
300d196e2c3SCristiano Giuffrida  *      	             sef_cb_init_timeout                             *
301d196e2c3SCristiano Giuffrida  *===========================================================================*/
sef_cb_init_timeout(int UNUSED (type),sef_init_info_t * UNUSED (info))302d196e2c3SCristiano Giuffrida int sef_cb_init_timeout(int UNUSED(type), sef_init_info_t *UNUSED(info))
303d196e2c3SCristiano Giuffrida {
304d196e2c3SCristiano Giuffrida   message m;
305d196e2c3SCristiano Giuffrida   int status;
306d196e2c3SCristiano Giuffrida 
307d196e2c3SCristiano Giuffrida   printf("Simulating a timeout at initialization time...\n");
308d196e2c3SCristiano Giuffrida 
309d196e2c3SCristiano Giuffrida   ipc_receive(IDLE, &m, &status);
310d196e2c3SCristiano Giuffrida 
311d196e2c3SCristiano Giuffrida   return EBADCALL;
312d196e2c3SCristiano Giuffrida }
313d196e2c3SCristiano Giuffrida 
314d196e2c3SCristiano Giuffrida /*===========================================================================*
31543065aa3SCristiano Giuffrida  *      	           sef_cb_init_restart_generic                       *
31643065aa3SCristiano Giuffrida  *===========================================================================*/
sef_cb_init_restart_generic(int type,sef_init_info_t * info)31743065aa3SCristiano Giuffrida int sef_cb_init_restart_generic(int type, sef_init_info_t *info)
31843065aa3SCristiano Giuffrida {
31943065aa3SCristiano Giuffrida   /* Always resort to simple identity transfer for self updates. */
32043065aa3SCristiano Giuffrida   if (type == SEF_INIT_LU && (info->flags & SEF_LU_SELF))
32143065aa3SCristiano Giuffrida       return sef_cb_init_identity_state_transfer(type, info);
32243065aa3SCristiano Giuffrida 
32343065aa3SCristiano Giuffrida   /* Can only handle restart otherwise. */
32443065aa3SCristiano Giuffrida   if(type != SEF_INIT_RESTART) {
32543065aa3SCristiano Giuffrida       printf("sef_cb_init_restart_generic: init failed\n");
32643065aa3SCristiano Giuffrida       return ENOSYS;
32743065aa3SCristiano Giuffrida   }
32843065aa3SCristiano Giuffrida 
32943065aa3SCristiano Giuffrida   /* Perform instrumentation-supported checkpoint-restart. */
33043065aa3SCristiano Giuffrida   return sef_llvm_ltckpt_restart(type, info);
33143065aa3SCristiano Giuffrida }
33243065aa3SCristiano Giuffrida 
33343065aa3SCristiano Giuffrida /*===========================================================================*
334d196e2c3SCristiano Giuffrida  *      	       sef_cb_init_identity_state_transfer                   *
335d196e2c3SCristiano Giuffrida  *===========================================================================*/
sef_cb_init_identity_state_transfer(int type,sef_init_info_t * info)336d196e2c3SCristiano Giuffrida int sef_cb_init_identity_state_transfer(int type, sef_init_info_t *info)
337d196e2c3SCristiano Giuffrida {
338d196e2c3SCristiano Giuffrida   extern char *_brksize;
339d196e2c3SCristiano Giuffrida   extern char *_etext;
340d196e2c3SCristiano Giuffrida   int r;
341d196e2c3SCristiano Giuffrida   char *old_brksize, *new_brksize;
342d196e2c3SCristiano Giuffrida   char stack_buff[ST_STACK_REFS_BUFF_SIZE];
343d196e2c3SCristiano Giuffrida   vir_bytes data_start;
344d196e2c3SCristiano Giuffrida   size_t size;
345d196e2c3SCristiano Giuffrida 
346d196e2c3SCristiano Giuffrida   /* Identity state transfer is for crash recovery and self update only. */
347d196e2c3SCristiano Giuffrida   if(type != SEF_INIT_RESTART && (type != SEF_INIT_LU || !(info->flags & SEF_LU_SELF))) {
348d196e2c3SCristiano Giuffrida       printf("sef_cb_init_identity_state_transfer: state transfer failed\n");
349d196e2c3SCristiano Giuffrida       return ENOSYS;
350d196e2c3SCristiano Giuffrida   }
351d196e2c3SCristiano Giuffrida 
352d196e2c3SCristiano Giuffrida   /* Save stack refs. */
353d196e2c3SCristiano Giuffrida   sef_llvm_stack_refs_save(stack_buff);
354d196e2c3SCristiano Giuffrida 
355d196e2c3SCristiano Giuffrida   old_brksize = _brksize;
356d196e2c3SCristiano Giuffrida   data_start = (vir_bytes)&_etext;
357d196e2c3SCristiano Giuffrida #if SEF_ST_DEBUG
358d196e2c3SCristiano Giuffrida   printf("sef_cb_init_identity_state_transfer: _brksize = 0x%08x, _etext = 0x%08x, data_start = 0x%08x\n",
359d196e2c3SCristiano Giuffrida       _brksize, &_etext, data_start);
360d196e2c3SCristiano Giuffrida #endif
361d196e2c3SCristiano Giuffrida 
362d196e2c3SCristiano Giuffrida   /* Transfer data. */
363d196e2c3SCristiano Giuffrida   size = (size_t)(_brksize - data_start);
3642867e60aSDavid van Moolenbroek 
3652867e60aSDavid van Moolenbroek   r = sef_copy_state_region(info, data_start, size, data_start,
3662867e60aSDavid van Moolenbroek     TRUE /*may_have_holes*/);
3672867e60aSDavid van Moolenbroek   if (r != OK)
368d196e2c3SCristiano Giuffrida       return r;
369d196e2c3SCristiano Giuffrida 
370d196e2c3SCristiano Giuffrida   new_brksize = _brksize;
371d196e2c3SCristiano Giuffrida 
372d196e2c3SCristiano Giuffrida   /* Transfer heap if necessary. */
3733f82ac6aSCristiano Giuffrida   if(sef_self_endpoint != VM_PROC_NR && old_brksize != new_brksize) {
374d196e2c3SCristiano Giuffrida 
375d196e2c3SCristiano Giuffrida #if SEF_ST_DEBUG
376d196e2c3SCristiano Giuffrida       printf("sef_cb_init_identity_state_transfer: brk() for new_brksize = 0x%08x\n",
377d196e2c3SCristiano Giuffrida           new_brksize);
378d196e2c3SCristiano Giuffrida #endif
379d196e2c3SCristiano Giuffrida 
380d196e2c3SCristiano Giuffrida       /* Extend heap first. */
381d196e2c3SCristiano Giuffrida       _brksize = old_brksize;
382d196e2c3SCristiano Giuffrida       r = sef_llvm_real_brk(new_brksize);
383d196e2c3SCristiano Giuffrida       if(r != OK) {
384d196e2c3SCristiano Giuffrida           printf("sef_cb_init_identity_state_transfer: brk failed\n");
385d196e2c3SCristiano Giuffrida           return EFAULT;
386d196e2c3SCristiano Giuffrida       }
387d196e2c3SCristiano Giuffrida 
388d196e2c3SCristiano Giuffrida       /* Transfer state on the heap. */
389d196e2c3SCristiano Giuffrida       assert(_brksize == new_brksize);
390d196e2c3SCristiano Giuffrida       size = (size_t)(_brksize - old_brksize);
391d196e2c3SCristiano Giuffrida       r = sef_copy_state_region(info, (vir_bytes) old_brksize, size,
3922867e60aSDavid van Moolenbroek           (vir_bytes) old_brksize, FALSE /*may_have_holes*/);
393d196e2c3SCristiano Giuffrida       if(r != OK) {
394d196e2c3SCristiano Giuffrida           printf("sef_cb_init_identity_state_transfer: extended heap transfer failed\n");
395d196e2c3SCristiano Giuffrida           return r;
396d196e2c3SCristiano Giuffrida       }
397d196e2c3SCristiano Giuffrida   }
398d196e2c3SCristiano Giuffrida 
399d196e2c3SCristiano Giuffrida   /* Restore stack refs. */
400d196e2c3SCristiano Giuffrida   sef_llvm_stack_refs_restore(stack_buff);
401d196e2c3SCristiano Giuffrida 
402*6c7e6149SDavid van Moolenbroek   if (sef_controlled_crash == FALSE) {
403*6c7e6149SDavid van Moolenbroek       printf("SEF(%d): crash was not controlled, "
404*6c7e6149SDavid van Moolenbroek 	"aborting transparent restart\n", sef_self_endpoint);
405*6c7e6149SDavid van Moolenbroek       return EGENERIC; /* actual error code does not matter */
406*6c7e6149SDavid van Moolenbroek   }
407*6c7e6149SDavid van Moolenbroek 
408d196e2c3SCristiano Giuffrida   return OK;
409d196e2c3SCristiano Giuffrida }
410d196e2c3SCristiano Giuffrida 
411d196e2c3SCristiano Giuffrida /*===========================================================================*
412d196e2c3SCristiano Giuffrida  *      	      sef_cb_init_lu_identity_as_restart                     *
413d196e2c3SCristiano Giuffrida  *===========================================================================*/
sef_cb_init_lu_identity_as_restart(int type,sef_init_info_t * info)414d196e2c3SCristiano Giuffrida int sef_cb_init_lu_identity_as_restart(int type, sef_init_info_t *info)
415d196e2c3SCristiano Giuffrida {
416d196e2c3SCristiano Giuffrida   /* Can only handle live update. */
417d196e2c3SCristiano Giuffrida   if(type != SEF_INIT_LU) {
418d196e2c3SCristiano Giuffrida       printf("sef_cb_init_lu_identity_as_restart: init failed\n");
419d196e2c3SCristiano Giuffrida       return ENOSYS;
420d196e2c3SCristiano Giuffrida   }
421d196e2c3SCristiano Giuffrida 
422d196e2c3SCristiano Giuffrida   /* Resort to restart callback only for identity updates, ignore other cases. */
423d196e2c3SCristiano Giuffrida   if(SEF_LU_IS_IDENTITY_UPDATE(info->flags)) {
4243f82ac6aSCristiano Giuffrida       if((info->flags & (SEF_INIT_DEFCB|SEF_INIT_SCRIPT_RESTART))
4253f82ac6aSCristiano Giuffrida           || sef_init_cbs.sef_cb_init_restart == sef_cb_init_reset) {
4263f82ac6aSCristiano Giuffrida           /* Use stateful restart callback when necessary. */
4273f82ac6aSCristiano Giuffrida           return SEF_CB_INIT_RESTART_STATEFUL(type, info);
428d196e2c3SCristiano Giuffrida       }
429d196e2c3SCristiano Giuffrida       return sef_init_cbs.sef_cb_init_restart(type, info);
430d196e2c3SCristiano Giuffrida   }
431d196e2c3SCristiano Giuffrida 
432d196e2c3SCristiano Giuffrida   return ENOSYS;
433d196e2c3SCristiano Giuffrida }
434d196e2c3SCristiano Giuffrida 
435d196e2c3SCristiano Giuffrida /*===========================================================================*
436d196e2c3SCristiano Giuffrida  *      	             sef_cb_init_lu_generic                          *
437d196e2c3SCristiano Giuffrida  *===========================================================================*/
sef_cb_init_lu_generic(int type,sef_init_info_t * info)438d196e2c3SCristiano Giuffrida int sef_cb_init_lu_generic(int type, sef_init_info_t *info)
439d196e2c3SCristiano Giuffrida {
440d196e2c3SCristiano Giuffrida   /* Can only handle live update. */
441d196e2c3SCristiano Giuffrida   if(type != SEF_INIT_LU) {
442d196e2c3SCristiano Giuffrida       printf("sef_cb_init_lu_generic: init failed\n");
443d196e2c3SCristiano Giuffrida       return ENOSYS;
444d196e2c3SCristiano Giuffrida   }
445d196e2c3SCristiano Giuffrida 
446d196e2c3SCristiano Giuffrida   /* Resort to restart callback for identity updates. */
447d196e2c3SCristiano Giuffrida   if(SEF_LU_IS_IDENTITY_UPDATE(info->flags)) {
448d196e2c3SCristiano Giuffrida       return sef_cb_init_lu_identity_as_restart(type, info);
449d196e2c3SCristiano Giuffrida   }
450d196e2c3SCristiano Giuffrida 
451d196e2c3SCristiano Giuffrida   /* Perform state transfer updates in all the other cases. */
452d196e2c3SCristiano Giuffrida   return sef_st_state_transfer(info);
453d196e2c3SCristiano Giuffrida }
454d196e2c3SCristiano Giuffrida 
455d196e2c3SCristiano Giuffrida /*===========================================================================*
456433d6423SLionel Sambuc  *                       sef_cb_init_response_rs_reply        		     *
457433d6423SLionel Sambuc  *===========================================================================*/
sef_cb_init_response_rs_reply(message * m_ptr)458433d6423SLionel Sambuc int sef_cb_init_response_rs_reply(message *m_ptr)
459433d6423SLionel Sambuc {
460433d6423SLionel Sambuc   int r;
461433d6423SLionel Sambuc 
462433d6423SLionel Sambuc   /* Inform RS that we completed initialization with the given result. */
463433d6423SLionel Sambuc   r = ipc_sendrec(RS_PROC_NR, m_ptr);
464433d6423SLionel Sambuc 
465433d6423SLionel Sambuc   return r;
466433d6423SLionel Sambuc }
467433d6423SLionel Sambuc 
46837489f8aSDavid van Moolenbroek /*===========================================================================*
46937489f8aSDavid van Moolenbroek  *                       sef_cb_init_response_rs_asyn_once		     *
47037489f8aSDavid van Moolenbroek  *===========================================================================*/
sef_cb_init_response_rs_asyn_once(message * m_ptr)47137489f8aSDavid van Moolenbroek int sef_cb_init_response_rs_asyn_once(message *m_ptr)
47237489f8aSDavid van Moolenbroek {
47337489f8aSDavid van Moolenbroek /* This response function is used by VM to avoid a boot-time deadlock. */
47437489f8aSDavid van Moolenbroek   int r;
47537489f8aSDavid van Moolenbroek 
47637489f8aSDavid van Moolenbroek   /* Inform RS that we completed initialization, asynchronously. */
47737489f8aSDavid van Moolenbroek   r = asynsend3(RS_PROC_NR, m_ptr, AMF_NOREPLY);
47837489f8aSDavid van Moolenbroek 
47937489f8aSDavid van Moolenbroek   /* Use a blocking reply call next time. */
48037489f8aSDavid van Moolenbroek   sef_setcb_init_response(SEF_CB_INIT_RESPONSE_DEFAULT);
48137489f8aSDavid van Moolenbroek 
48237489f8aSDavid van Moolenbroek   return r;
48337489f8aSDavid van Moolenbroek }
484