/**
 * @brief The Host sends the event to the SP.
 * Refer to "sh_css_sp.h" for details.
 */
int ia_css_eventq_send(
			ia_css_queue_t *eventq_handle,
			uint8_t evt_id,
			uint8_t evt_payload_0,
			uint8_t evt_payload_1,
			uint8_t evt_payload_2)
{
	uint8_t tmp[4];
	uint32_t sw_event;
	int error = ENOSYS;

	/*
	 * Encode the queue type, the thread ID and
	 * the queue ID into the event.
	 */
	tmp[0] = evt_id;
	tmp[1] = evt_payload_0;
	tmp[2] = evt_payload_1;
	tmp[3] = evt_payload_2;
	ia_css_event_encode(tmp, 4, &sw_event);

	/* queue the software event (busy-waiting) */
	for ( ; ; ) {
		error = ia_css_queue_enqueue(eventq_handle, sw_event);
		if (ENOBUFS != error) {
			/* We were able to successfully send the event
			   or had a real failure. return the status*/
			break;
		}
		/* Wait for the queue to be not full and try again*/
		hrt_sleep();
	}

	return error;
}
Exemple #2
0
/* STORAGE_CLASS_INLINE void irq_wait_for_write_complete( */
static void irq_wait_for_write_complete(
	const irq_ID_t		ID)
{
assert(ID < N_IRQ_ID);
assert(IRQ_BASE[ID] != (hrt_address)-1);
	(void)device_load_uint32(IRQ_BASE[ID] +
		_HRT_IRQ_CONTROLLER_ENABLE_REG_IDX*sizeof(hrt_data));
#ifdef HRT_CSIM
	hrt_sleep();
#endif
return;
}
Exemple #3
0
/**
 * @brief The Host sends the event to the SP.
 * Refer to "sh_css_sp.h" for details.
 */
void
sh_css_sp_snd_event(int evt_id, int evt_payload_0, int evt_payload_1, int evt_payload_2)
{
	uint32_t tmp[4];
	uint32_t sw_event;

	/*
	 * Encode the queue type, the thread ID and
	 * the queue ID into the event.
	 */
	tmp[0] = (uint32_t)evt_id;
	tmp[1] = (uint32_t)evt_payload_0;
	tmp[2] = (uint32_t)evt_payload_1;
	tmp[3] = (uint32_t)evt_payload_2;
	encode_sw_event(tmp, 4, &sw_event);

	/* queue the software event (busy-waiting) */
	while (!host2sp_enqueue_sp_event(sw_event))
		hrt_sleep();
}
Exemple #4
0
void _irq_raise(
	const irq_ID_t				ID,
	const irq_sw_channel_id_t	irq_id)
{
assert(ID == IRQ0_ID);
assert(IRQ_BASE[ID] != (hrt_address)-1);
assert(irq_id < N_IRQ_SW_CHANNEL_ID);
	(void)ID;

/* The SW IRQ pins are remapped to offset zero */
	gp_device_reg_store(GP_DEVICE0_ID,
		_REG_GP_IRQ_REQUEST_ADDR,
		(1U<<(irq_id - hrt_isp_css_irq_sw_0)));
#ifdef HRT_CSIM
	hrt_sleep();
#endif
	gp_device_reg_store(GP_DEVICE0_ID,
		_REG_GP_IRQ_REQUEST_ADDR, 0);
return;
}
Exemple #5
0
enum sh_css_err sh_css_hrt_sp_wait(void)
{
#if defined(HAS_IRQ_MAP_VERSION_2)
	irq_sw_channel_id_t	irq_id = IRQ_SW_CHANNEL0_ID;
#else
	irq_sw_channel_id_t	irq_id = IRQ_SW_CHANNEL2_ID;
#endif
	/*
	 * Wait till SP is idle or till there is a SW2 interrupt
	 * The SW2 interrupt will be used when frameloop runs on SP
	 * and signals an event with similar meaning as SP idle
	 * (e.g. frame_done)
	 */
	while (!sp_ctrl_getbit(SP0_ID, SP_SC_REG, SP_IDLE_BIT) &&
		((irq_reg_load(IRQ0_ID,
			_HRT_IRQ_CONTROLLER_STATUS_REG_IDX) &
			(1U<<(irq_id + IRQ_SW_CHANNEL_OFFSET))) == 0)) {
		hrt_sleep();
	}

return sh_css_success;
}
/* Start the sp, which will start the isp.
*/
enum sh_css_err
sh_css_acc_start(struct sh_css_acc_fw *firmware)
{
	struct sh_css_acc_fw_hdr *header
		= (struct sh_css_acc_fw_hdr *)&firmware->header;
	struct sh_css_acc_sp *sp = &header->sp;
	bool is_extension = header->type != SH_CSS_ACC_STANDALONE;
	const struct sh_css_fw_info *sp_fw = &sp->fw;
	const unsigned char *sp_program;
#if !defined(C_RUN) && !defined(HRT_UNSCHED)
	const unsigned char *isp_program;
#endif

	*(const void **)&sp_fw->blob.text = SH_CSS_ACC_SP_CODE(firmware);
	*(const void **)&sp_fw->blob.data = SH_CSS_ACC_SP_DATA(firmware);

	if (!header->loaded)
		return sh_css_err_invalid_arguments;
	if (is_extension)
		return sh_css_err_invalid_arguments;

	/* NOTE: sp accelerators have their (shared buffer pointer)
	 * arguments flushed in "atomisp_acc_start()"
	 */
	if (is_extension)
		sh_css_flush(firmware);

	sp_program = (const unsigned char *)HOST_ADDRESS(
		sh_css_sp_load_program(sp_fw,
		SH_CSS_ACC_SP_PROG_NAME(firmware),
		(hrt_vaddress)HOST_ADDRESS(sp->code)));
	if (sp_program == NULL)
		return sh_css_err_cannot_allocate_memory;
	sp->code = sp_program;
#if !defined(C_RUN) && !defined(HRT_UNSCHED)
	isp_program = sh_css_acc_upload_isp_code(firmware);
	if (isp_program == NULL)
		return sh_css_err_cannot_allocate_memory;
#endif

#ifdef C_RUN
	sp->init(firmware);
#endif
	sh_css_acc_init(firmware);

	/* Start the firmware on the sp, which will start the isp */
#ifdef C_RUN
	/* No need to run the dmem_init in crun */
	sh_css_sp_do_invalidate_mmu();
	csim_processor_set_crun_func(SP, sp->entry);
	hrt_ctl_run(SP, 1);
	hrt_ctl_start(SP);
	hrt_sleep();
/* MW: sp->entry is a pointer, yet the entry points are relative addresses and thus 32-bit */
#elif defined(HRT_CSIM)
	sh_css_sp_do_invalidate_mmu();
	_hrt_cell_start(SP, HOST_ADDRESS(sp->entry));
#else
	sh_css_sp_start((unsigned int)HOST_ADDRESS(sp->entry));
#endif
	return sh_css_success;
}
Exemple #7
0
/* Wake up ISP ID. */
void isp_wake(isp_ID_t ID)
{
	assert (ID < N_ISP_ID);
	isp_ctrl_setbit(ID, ISP_SC_REG, ISP_START_BIT);
	hrt_sleep();
}