u32 vcd_init_device_context(struct vcd_drv_ctxt_type_t *p_drv_ctxt, u32 n_ev_code) { struct vcd_dev_ctxt_type *p_dev_ctxt = &p_drv_ctxt->dev_ctxt; struct sched_init_param_type sched_init; u32 rc; struct ddl_init_config_type ddl_init; VCD_MSG_LOW("vcd_init_device_context:"); p_dev_ctxt->e_pending_cmd = VCD_CMD_NONE; rc = vcd_power_event(p_dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_BEGIN); VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_INIT_BEGIN failed"); VCD_MSG_HIGH("Device powered ON and clocked"); sched_init.n_perf_lvl = p_dev_ctxt->n_max_perf_lvl; rc = vcd_map_sched_status(sched_create (&sched_init, &p_dev_ctxt->sched_hdl)); if (VCD_FAILED(rc)) { VCD_MSG_ERROR("rc = 0x%x. Failed: sched_create", rc); (void)vcd_power_event(p_dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_FAIL); return rc; } VCD_MSG_HIGH("Created scheduler instance."); ddl_init.p_core_virtual_base_addr = p_dev_ctxt->p_device_base_addr; ddl_init.pf_interrupt_clr = p_dev_ctxt->config.pf_interrupt_clr; ddl_init.ddl_callback = vcd_ddl_callback; rc = ddl_device_init(&ddl_init, NULL); if (VCD_FAILED(rc)) { VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_init", rc); (void)sched_destroy(p_dev_ctxt->sched_hdl); p_dev_ctxt->sched_hdl = NULL; (void)vcd_power_event(p_dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_FAIL); } else { vcd_device_timer_start(p_dev_ctxt); vcd_do_device_state_transition(p_drv_ctxt, VCD_DEVICE_STATE_INITING, n_ev_code); } return rc; }
act_t * act_register(reg_frame_t *frame, queue_t *queue, const char *name, status_e create_in_status, act_control_t *parent, size_t base) { (void)parent; KERNEL_TRACE("act", "Registering activation %s", name); if(kernel_next_act >= MAX_ACTIVATIONS) { kernel_panic("no act slot"); } act_t * act = kernel_acts + kernel_next_act; act->image_base = base; //TODO bit of a hack. the kernel needs to know what namespace service to use if(kernel_next_act == namespace_num_namespace) { KERNEL_TRACE("act", "found namespace"); ns_ref = act_create_sealed_ref(act); } #ifndef __LITE__ /* set name */ kernel_assert(ACT_NAME_MAX_LEN > 0); int name_len = 0; if(VCAP(name, 1, VCAP_R)) { name_len = imin(cheri_getlen(name), ACT_NAME_MAX_LEN-1); } for(int i = 0; i < name_len; i++) { char c = name[i]; act->name[i] = c; /* todo: sanitize the name if we do not trust it */ } act->name[name_len] = '\0'; #endif /* set status */ act->status = create_in_status; /*Some "documentation" for the interface between the kernel and activation start * * These fields are setup by the caller of act_register * * * * a0 : user GP argument (goes to main) * * c3 : user Cap argument (goes to main) * * * * These fields are setup by act_register itself. Although the queue is an argument to the function * * * * c21 : self control reference * * c23 : namespace reference (may be null for init and namespace) * * c24 : kernel interface table * * c25 : queue */ /* set namespace */ frame->cf_c21 = (capability)act_create_sealed_ctrl_ref(act); frame->cf_c23 = (capability)ns_ref; frame->cf_c24 = (capability)get_if(); frame->cf_c25 = (capability)queue; /* set queue */ msg_queue_init(act, queue); /* set expected sequence to not expecting */ act->sync_state.sync_token = 0; act->sync_state.sync_condition = 0; /* set scheduling status */ sched_create(act); /*update next_act */ kernel_next_act++; KERNEL_TRACE("register", "image base of %s is %lx", act->name, act->image_base); KERNEL_TRACE("act", "%s OK! ", __func__); return act; }