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