/** * @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; }
/* 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; }
/** * @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(); }
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; }
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; }
/* 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(); }