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;
}
Пример #2
0
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;
}