// #define FIFO_CMD_DBG #include #include #include "cmsis_os2.h" #include "version.h" #include "project.h" #include "usbd_hal.h" #include "kdrv_scu_ext.h" #include "kdrv_power.h" #include "kdrv_clock.h" #include "kdp_system.h" #include "kmdw_dfu.h" #include "kmdw_console.h" #include "kmdw_model.h" #include "kmdw_memxfer.h" #include "kmdw_ipc.h" // for kp inference debug #include "kdp2_ipc_cmd.h" #include "kdp2_inf_generic_raw.h" #include "kmdw_fifoq_manager.h" #ifdef FIFO_CMD_DBG #define fifo_cmd_dbg(__format__, ...) kmdw_printf("[fifoCmd]"__format__, ##__VA_ARGS__) #else #define fifo_cmd_dbg(__format__, ...) #endif #define USB_NORMAL_TIMEOUT (2 * 1000) // 2 secs #define KP_DEBUG_BUF_SIZE (8 * 1024 * 1024) // FIXME, max is 1920x1080 RGB565 typedef struct { /* Model type */ uint32_t model_type; //defined in model_type.h /* Model version */ uint32_t model_version; /* Input in memory */ uint32_t input_mem_addr; int32_t input_mem_len; /* Output in memory */ uint32_t output_mem_addr; int32_t output_mem_len; /* Working buffer */ uint32_t buf_addr; int32_t buf_len; /* command.bin in memory */ uint32_t cmd_mem_addr; int32_t cmd_mem_len; /* weight.bin in memory */ uint32_t weight_mem_addr; int32_t weight_mem_len; /* setup.bin in memory */ uint32_t setup_mem_addr; int32_t setup_mem_len; } _fw_info_t; // == kdp_model_t /* Structure of CNN Header in setup.bin - copy from kdpio.h */ struct cnn_header_s { uint32_t crc; uint32_t version; uint32_t key_offset; uint32_t model_type; uint32_t app_type; uint32_t dram_start; uint32_t dram_size; uint32_t input_row; uint32_t input_col; uint32_t input_channel; uint32_t cmd_start; uint32_t cmd_size; uint32_t weight_start; uint32_t weight_size; uint32_t input_start; uint32_t input_size; uint32_t input_radix; uint32_t output_nums; }; extern int kdp_memxfer_flash_to_ddr(uint32_t dst, uint32_t src, size_t bytes); extern int kdp_memxfer_ddr_to_flash(u32 dst, u32 src, size_t bytes); static uint32_t _flash_read_callback(uint32_t addr, uint32_t img_size) { fifo_cmd_dbg("[%s]\n", __FUNCTION__); int usb_sts = usbd_hal_bulk_receive(KDP2_USB_ENDPOINT_DATA_OUT, (void *)addr, &img_size, USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) { fifo_cmd_dbg("[%s] receive fw data failed, sts %d\n", __FUNCTION__, usb_sts); return 0; } fifo_cmd_dbg("[%s] received fw data %d bytes\n", __FUNCTION__, img_size); return img_size; } static int _load_model(kdp2_ipc_cmd_load_model_t *cmd_lmd) { fifo_cmd_dbg("[%s] model_size %d fw_info_size %d\n", __FUNCTION__, cmd_lmd->model_size, cmd_lmd->fw_info_size); fifo_cmd_dbg("[%s] num_model = %d\n", __FUNCTION__, cmd_lmd->fw_info[0]); _fw_info_t *first_fwinfo = (_fw_info_t *)(cmd_lmd->fw_info + 4); kmdw_model_fw_info_t *fw_info_p = kmdw_model_get_fw_info(true); memcpy(fw_info_p, (void *)cmd_lmd->fw_info, cmd_lmd->fw_info_size); fifo_cmd_dbg("fw_info_p = 0x%x, fw_info_size = %d, sizeof(_fw_info_t) = %d\n", fw_info_p, cmd_lmd->fw_info_size, sizeof(_fw_info_t)); uint32_t reload_model_info_sts = kmdw_model_reload_model_info(true); uint32_t return_code = (0 < reload_model_info_sts) ? KP_SUCCESS : KP_FW_LOAD_MODEL_FAILED_104; kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] send reload model info statsus failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } if (return_code != KP_SUCCESS) { fifo_cmd_dbg("[%s] reload model info failed, sts %d\n", __FUNCTION__, reload_model_info_sts); return -1; } fifo_cmd_dbg("[%s] receiving model and writing to addr 0x%x\n", __FUNCTION__, first_fwinfo->cmd_mem_addr); uint32_t txLen = cmd_lmd->model_size; // should be acceptable fifo_cmd_dbg("[%s] max model buf size %d\n", __FUNCTION__, txLen); usb_sts = usbd_hal_bulk_receive(KDP2_USB_ENDPOINT_DATA_OUT, (void *)first_fwinfo->cmd_mem_addr, &txLen, 20 * 1000); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] receive model failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } fifo_cmd_dbg("[%s] received model done %d bytes\n", __FUNCTION__, txLen); return 0; } static uint8_t ack_packet[] = {0x35, 0x8A, 0xC, 0, 0x4, 0, 0x8, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static int _update_firmware(kdp_firmware_update_cmd_t *kdp_cmd) { kdrv_status_t usb_sts; uint32_t txLen, txLen2; int fw_id = kdp_cmd->fw_id; bool reboot_after_update = (1 == kdp_cmd->auto_reboot); int dfu_update_sts = -1; fifo_cmd_dbg("[%s] recognized KDP KDP_CMD_UPDATE_FW\n", __FUNCTION__); if ((KDP_UPDATE_MODULE_SCPU == fw_id) || (KDP_UPDATE_MODULE_NCPU == fw_id)) { txLen = sizeof(ack_packet); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)ack_packet, txLen, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] send error ack failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } } else { fifo_cmd_dbg("[%s] error fw_id %d\n", __FUNCTION__, fw_id); // send some error ack back to host txLen = 16; memset((void *)kdp_cmd, 0, txLen); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)kdp_cmd, txLen, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] send ack failed, sts %d\n", __FUNCTION__, usb_sts); } return -1; } // now receive fw content fifo_cmd_dbg("[%s] received fw data %d bytes\n", __FUNCTION__, txLen); if (fw_id == KDP_UPDATE_MODULE_SCPU) { fifo_cmd_dbg("[%s] updateing scpu fw\n", __FUNCTION__); dfu_update_sts = kmdw_dfu_update_scpu(); } else if (fw_id == KDP_UPDATE_MODULE_NCPU) { fifo_cmd_dbg("[%s] updateing ncpu fw\n", __FUNCTION__); dfu_update_sts = kmdw_dfu_update_ncpu(); } // so far so good, give a response to host kdp_firmware_update_response_t kdp_resp = {KDP_MSG_HDR_RSP, 0xc, KDP_CMD_UPDATE_FW_RESPONSE, 8, dfu_update_sts, fw_id}; txLen2 = sizeof(kdp_resp); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&kdp_resp, txLen2, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] send response failed, sts %d\n", __FUNCTION__, usb_sts); } osDelay(1000); if (true == reboot_after_update) kdrv_power_sw_reset(); return 0; } static int _update_model(kdp_model_update_cmd_t *kdp_cmd) { kdrv_status_t usb_sts; uint32_t txLen, txLen2; int fw_info_size = kdp_cmd->fw_info_size; int all_models_size = kdp_cmd->all_models_size; bool reboot_after_update = (1 == kdp_cmd->auto_reboot); fifo_cmd_dbg("[%s] recognized KDP KDP_CMD_UPDATE_MODEL\n", __FUNCTION__); txLen = sizeof(ack_packet); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)ack_packet, txLen, USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) { fifo_cmd_dbg("[%s] send error ack failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } int ret = kmdw_dfu_update_model(fw_info_size, all_models_size); if (0 != ret) { fifo_cmd_dbg("[%s] write model to flash failed, sts %d\n", __FUNCTION__, ret); } // so far so good, give a response to host kdp_model_update_response_t kdp_resp = {KDP_MSG_HDR_RSP, 0xc, KDP_CMD_UPDATE_MODEL_RESPONSE, 8, ret, ret}; txLen2 = sizeof(kdp_resp); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&kdp_resp, txLen2, USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) { fifo_cmd_dbg("[%s] send response failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } fifo_cmd_dbg("[%s] update model done, sts: %d\n", __FUNCTION__, ret); osDelay(1000); if (true == reboot_after_update) { kdrv_power_sw_reset(); } return 0; } static uint8_t _dfu_buf[4 * 1024]; // kmdw_dfu_init() says it need at least 4KB buffer, and it cannot use DDR, really sucks int kdp2_cmd_handler_initialize() { fifo_cmd_dbg("[%s]\n", __FUNCTION__); if(FLASH_TYPE != FLASH_TYPE_NULL) { kmdw_dfu_init(_dfu_buf, _flash_read_callback); // TODO: waste of memory } return 0; } static int _memory_read_write(kdp2_ipc_cmd_memory_read_write_t *cmd_buf) { kdrv_status_t usb_sts; if (cmd_buf->command_id == KDP2_COMMAND_MEMORY_READ) // read mode { fifo_cmd_dbg("[%s] read mode\n", __FUNCTION__); uint32_t return_code = KP_SUCCESS; // FIXME: error handling usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] memory read failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)cmd_buf->start_address, cmd_buf->length, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] memory read failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } } else if (cmd_buf->command_id == KDP2_COMMAND_MEMORY_WRITE) // write mode { fifo_cmd_dbg("[%s] write mode\n", __FUNCTION__); uint32_t rxLen = cmd_buf->length; usb_sts = usbd_hal_bulk_receive(KDP2_USB_ENDPOINT_DATA_OUT, (void *)cmd_buf->start_address, &rxLen, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] memory write failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } uint32_t return_code = KP_SUCCESS; if (rxLen != cmd_buf->length) { return_code = KP_ERROR_RECEIVE_SIZE_MISMATCH_31; fifo_cmd_dbg("[%s] received buffer length is not the same with the length specified in the command, return code %d\n", __FUNCTION__, return_code); } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] memory write failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } } else fifo_cmd_dbg("[%s] unsupported command, should not be here\n", __FUNCTION__); return 0; } static int _get_system_info() { kdrv_status_t usb_sts; kdp2_ipc_response_get_system_info_t response_buf; response_buf.return_code = KP_SUCCESS; // FIXME: error handling response_buf.system_info.kn_number = kdp_sys_get_kn_number(); response_buf.system_info.firmware_version.reserved = 0; response_buf.system_info.firmware_version.major = IMG_FW_MAJOR; response_buf.system_info.firmware_version.minor = IMG_FW_MINOR; response_buf.system_info.firmware_version.update = IMG_FW_UPDATE; response_buf.system_info.firmware_version.build = IMG_FW_BUILD; fifo_cmd_dbg("[%s] kn_number 0x%8X\n", __FUNCTION__, response_buf.system_info.kn_number); fifo_cmd_dbg("[%s] FW: %d.%d.%d-build.%d\n", __FUNCTION__, response_buf.system_info.firmware_version.major, response_buf.system_info.firmware_version.minor, response_buf.system_info.firmware_version.update, response_buf.system_info.firmware_version.build); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&response_buf, sizeof(response_buf), USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] get system info failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } return 0; } static int _load_model_from_flash() { int32_t load_model_sts = kmdw_model_load_model(-1); uint32_t return_code = (0 < load_model_sts) ? KP_SUCCESS : KP_FW_LOAD_MODEL_FAILED_104; kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) { fifo_cmd_dbg("[%s] send reload model info statsus failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } if (KP_SUCCESS != return_code) { fifo_cmd_dbg("[%s] reload model info failed, sts %d\n", __FUNCTION__, load_model_sts); return -1; } return 0; } static int _read_flash(kdp2_ipc_cmd_read_flash_t *cmd_buf) { kdrv_status_t usb_sts; int32_t return_code = KP_SUCCESS; // FIXME: error handling uint32_t buffer = (uint32_t)cmd_buf; uint32_t flash_addr = cmd_buf->flash_offset; uint32_t length = cmd_buf->length; fifo_cmd_dbg("[%s] Read flash on addr %d\n", __FUNCTION__, flash_addr); kdp_memxfer_flash_to_ddr(buffer, flash_addr, length); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] memory read failed, sts %d\n", __FUNCTION__, usb_sts); return_code = -1; goto FUNC_OUT; } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)buffer, length, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] memory read failed, sts %d\n", __FUNCTION__, usb_sts); return_code = -1; goto FUNC_OUT; } FUNC_OUT: return return_code; } static int _write_flash(kdp2_ipc_cmd_write_flash_t *cmd_buf) { kdrv_status_t usb_sts; int32_t return_code = KP_SUCCESS; // FIXME: error handling uint32_t buffer = (uint32_t)cmd_buf; uint32_t flash_addr = cmd_buf->flash_offset; uint32_t length = cmd_buf->length; fifo_cmd_dbg("[%s] Write flash on addr %d\n", __FUNCTION__, flash_addr); usb_sts = usbd_hal_bulk_receive(KDP2_USB_ENDPOINT_DATA_OUT, (void *)buffer, &length, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] receive data failed, sts %d\n", __FUNCTION__, usb_sts); return_code = -1; goto FUNC_OUT; } kdp_memxfer_ddr_to_flash(flash_addr, buffer, length); usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] send return code failed, sts %d\n", __FUNCTION__, usb_sts); return_code = -1; goto FUNC_OUT; } FUNC_OUT: return return_code; } #define OUT_NODE_HEAD_SIZE 20 // node's width, height, channel, radix, scale static int _get_model_info(kdp2_ipc_cmd_get_model_info_t *cmd_buf) { kdrv_status_t usb_sts; kdp2_ipc_response_get_model_info_fw_info_t fw_info_response_buf = {0}; kmdw_model_fw_info_t *fw_info_buf_p = kmdw_model_get_fw_info(false); if (NULL == fw_info_buf_p) { fw_info_response_buf.return_code = KP_FW_GET_MODEL_INFO_FAILED_109; fw_info_response_buf.fw_info_size = 0; fw_info_response_buf.target_chip = KP_MODEL_TARGET_CHIP_KL520; } else { fw_info_response_buf.return_code = KP_SUCCESS; fw_info_response_buf.fw_info_size = sizeof(kmdw_model_fw_info_t) - sizeof(struct kdp_model_s) + (fw_info_buf_p->model_count * sizeof(struct kdp_model_s)) + sizeof(kmdw_model_fw_info_ext_t); fw_info_response_buf.target_chip = KP_MODEL_TARGET_CHIP_KL520; } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&fw_info_response_buf, sizeof(fw_info_response_buf), USB_NORMAL_TIMEOUT); if ((usb_sts != KDRV_STATUS_OK) || (fw_info_response_buf.return_code != KP_SUCCESS)) { fifo_cmd_dbg("[%s] get model info send fw_info response failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)fw_info_buf_p, fw_info_response_buf.fw_info_size, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] get model info send fw_info data failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } kdp2_ipc_response_get_model_info_setup_t all_setup_response_buf = {0}; kdp2_ipc_response_get_model_info_setup_t single_setup_response_buf = {0}; struct kdp_model_s *model_info = NULL; all_setup_response_buf.setup_size = 0; all_setup_response_buf.return_code = KP_SUCCESS; for (int i = 0; i < fw_info_buf_p->model_count; i++) { model_info = kmdw_model_get_model_info(i); if (NULL != model_info) { all_setup_response_buf.setup_size += model_info->setup_mem_len; } else { all_setup_response_buf.return_code = KP_FW_GET_MODEL_INFO_FAILED_109; fifo_cmd_dbg("[%s] get model info failed, invalid model info in ddr\n", __FUNCTION__); break; } } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&all_setup_response_buf, sizeof(all_setup_response_buf), USB_NORMAL_TIMEOUT); if ((usb_sts != KDRV_STATUS_OK) || (all_setup_response_buf.return_code != KP_SUCCESS)) { fifo_cmd_dbg("[%s] get model info send all setup response failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } for (int i = 0; i < fw_info_buf_p->model_count; i++) { model_info = kmdw_model_get_model_info(i); if (NULL != model_info) { single_setup_response_buf.setup_size = model_info->setup_mem_len; single_setup_response_buf.return_code = KP_SUCCESS; } else { single_setup_response_buf.setup_size = 0; single_setup_response_buf.return_code = KP_FW_GET_MODEL_INFO_FAILED_109; } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&single_setup_response_buf, sizeof(single_setup_response_buf), USB_NORMAL_TIMEOUT); if ((usb_sts != KDRV_STATUS_OK) || (single_setup_response_buf.return_code != KP_SUCCESS)) { fifo_cmd_dbg("[%s] get model info send single setup response failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)model_info->setup_mem_addr, model_info->setup_mem_len, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] get model info send setup data entry %d failed, sts %d\n", __FUNCTION__, i, usb_sts); return -1; } } return 0; } #define NCPU_IRAM_ADDR (0x28000000) #define NCPU_IRAM_SIZE (64 * 1024) static int _load_firmware(kdp2_ipc_cmd_upload_firmware_t *cmd_buf) { uint32_t txLen = NCPU_IRAM_SIZE; uint32_t recv_buf; static bool isNCPU_loaded = false; if (isNCPU_loaded == false) recv_buf = NCPU_IRAM_ADDR; else // useless, just to recv it recv_buf = (uint32_t)cmd_buf + sizeof(kdp2_ipc_cmd_upload_firmware_t); kdrv_status_t usb_sts = usbd_hal_bulk_receive(KDP2_USB_ENDPOINT_DATA_OUT, (uint32_t *)recv_buf, &txLen, USB_NORMAL_TIMEOUT); if (usb_sts != KDRV_STATUS_OK) { fifo_cmd_dbg("[%s] receive fw failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } if (isNCPU_loaded) return 0; kmdw_printf("recv ncpu fw %d\n", txLen); osDelay(10); SCU_EXTREG_CM4_NCPU_CTRL_SET_wakeup(1); // restart ncpu isNCPU_loaded = true; return 0; } static int _set_ckey(kdp2_ipc_cmd_set_ckey_t *cmd_buf) { kdrv_status_t usb_sts; uint32_t ckey = cmd_buf->ckey; uint32_t status = 0; int32_t resp = 0; fifo_cmd_dbg("[%s] set ckey : 0x%08X\n", __FUNCTION__, ckey); status = kdp_sys_program_key(ckey); switch (status) { case 0x1: resp = KP_FW_EFUSE_CAN_NOT_BURN_300; break; case 0x2: resp = KP_FW_EFUSE_PROTECTED_301; break; case 0x0: resp = KP_SUCCESS; break; default: resp = KP_FW_EFUSE_OTHER_302; break; } usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&resp, sizeof(int32_t), USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) { fifo_cmd_dbg("[%s] send response failed, sts %d\n", __FUNCTION__, usb_sts); return -1; } fifo_cmd_dbg("[%s] set ckey done, sts: %d\n", __FUNCTION__, resp); return 0; } static int _set_dbg_checkpoint(kdp2_ipc_cmd_set_dbg_checkpoint_t *cmd_buf) { // kp inference debug code struct scpu_to_ncpu_s *out_comm = kmdw_ipc_get_output(); int32_t return_code = KP_SUCCESS; if (out_comm->kp_dbg_buffer == NULL) { out_comm->kp_dbg_buffer = (void *)kmdw_ddr_reserve(KP_DEBUG_BUF_SIZE); if (out_comm->kp_dbg_buffer == NULL) { return_code = KP_FW_DDR_MALLOC_FAILED_102; } } kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) fifo_cmd_dbg("[%s] send ack failed, sts %d\n", __FUNCTION__, usb_sts); uint32_t checkponit_flags = out_comm->kp_dbg_checkpoinots; if (cmd_buf->enable) checkponit_flags |= cmd_buf->checkpoint_flags; else checkponit_flags &= ~cmd_buf->checkpoint_flags; out_comm->kp_dbg_checkpoinots = checkponit_flags; return 0; } static int _set_dbg_profile(kdp2_ipc_cmd_set_profile_enable_t *cmd_buf) { struct scpu_to_ncpu_s *out_comm = kmdw_ipc_get_output(); out_comm->kp_dbg_enable_profile = (cmd_buf->enable) ? 1 : 0; if (cmd_buf->enable) { kp_model_profile_t *profile_recs = (kp_model_profile_t *)out_comm->kp_model_profile_records; memset(profile_recs, 0, MULTI_MODEL_MAX * sizeof(kp_model_profile_t)); } int32_t return_code = KP_SUCCESS; kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&return_code, sizeof(uint32_t), USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) fifo_cmd_dbg("[%s] send ack failed, sts %d\n", __FUNCTION__, usb_sts); return 0; } static int _get_dbg_profile(kdp2_ipc_cmd_get_profile_statics_t *cmd_buf) { struct scpu_to_ncpu_s *out_comm = kmdw_ipc_get_output(); kp_profile_data_t pd = {0}; kp_model_profile_t *profile_recs = (kp_model_profile_t *)out_comm->kp_model_profile_records; for (int i = 0; i < MULTI_MODEL_MAX; i++) { if (profile_recs[i].model_id == 0) break; pd.num_model_profiled++; pd.model_st[i].model_id = profile_recs[i].model_id; pd.model_st[i].inf_count = profile_recs[i].sum_frame_count; pd.model_st[i].cpu_op_count = profile_recs[i].sum_cpu_op_count / profile_recs[i].sum_frame_count; pd.model_st[i].avg_pre_process_ms = (float)profile_recs[i].sum_ticks_preprocess / profile_recs[i].sum_frame_count; pd.model_st[i].avg_inference_ms = (float)profile_recs[i].sum_ticks_inference / profile_recs[i].sum_frame_count; pd.model_st[i].avg_cpu_op_ms = (float)profile_recs[i].sum_ticks_cpu_op / profile_recs[i].sum_frame_count; pd.model_st[i].avg_cpu_op_per_cpu_node_ms = (float)profile_recs[i].sum_ticks_cpu_op / (0 == profile_recs[i].sum_cpu_op_count ? 1 : profile_recs[i].sum_cpu_op_count); pd.model_st[i].avg_post_process_ms = (float)profile_recs[i].sum_ticks_postprocess / profile_recs[i].sum_frame_count; } kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&pd, sizeof(kp_profile_data_t), USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) fifo_cmd_dbg("[%s] send ack failed, sts %d\n", __FUNCTION__, usb_sts); return 0; } static int _get_ddr_config(kdp2_ipc_cmd_get_available_ddr_config_t *cmd_buf) { kp_available_ddr_config_t ddr_config = {0}; ddr_config.ddr_available_begin = DDR_BEGIN; ddr_config.ddr_available_end = kmdw_ddr_get_heap_tail(); ddr_config.ddr_model_end = kmdw_model_get_model_end_addr(true); ddr_config.ddr_fifoq_allocated = (true == kmdw_fifoq_manager_get_fifoq_allocated()) ? 1 : 0; kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&ddr_config, sizeof(kp_available_ddr_config_t), USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) fifo_cmd_dbg("[%s] send ack failed, sts %d\n", __FUNCTION__, usb_sts); return 0; } static int _get_fifo_queue_config(kdp2_ipc_cmd_get_fifo_queue_config_t *cmd_buf) { kp_fifo_queue_config_t fifo_queue_config = {0}; if (true == kmdw_fifoq_manager_get_fifoq_allocated()) { kmdw_fifoq_manager_get_fifoq_config(&fifo_queue_config.fifoq_input_buf_count, &fifo_queue_config.fifoq_input_buf_size, &fifo_queue_config.fifoq_result_buf_count, &fifo_queue_config.fifoq_result_buf_size); } kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)&fifo_queue_config, sizeof(kp_fifo_queue_config_t), USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) fifo_cmd_dbg("[%s] send ack failed, sts %d\n", __FUNCTION__, usb_sts); return 0; } int kdp2_cmd_handle_kp_command(uint32_t command_buffer) { int ret = -1; kp_inference_header_stamp_t *header_stamp = (kp_inference_header_stamp_t *)command_buffer; uint32_t command_id = header_stamp->job_id; switch (command_id) { case KDP2_COMMAND_LOAD_MODEL: ret = _load_model((kdp2_ipc_cmd_load_model_t *)command_buffer); break; case KDP2_COMMAND_MEMORY_READ: case KDP2_COMMAND_MEMORY_WRITE: ret = _memory_read_write((kdp2_ipc_cmd_memory_read_write_t *)command_buffer); break; case KDP2_COMMAND_GET_SYSTEM_INFO: ret = _get_system_info(); // no need to pass argument since we already parsed all useful info break; case KDP2_COMMAND_LOAD_MODEL_FROM_FLASH: ret = _load_model_from_flash(); // no need to pass argument since we already parsed all useful info break; case KDP2_COMMAND_READ_FLASH: ret = _read_flash((kdp2_ipc_cmd_read_flash_t *)command_buffer); break; case KDP2_COMMAND_WRITE_FLASH: ret = _write_flash((kdp2_ipc_cmd_write_flash_t *)command_buffer); break; case KDP2_COMMAND_GET_MODEL_INFO: ret = _get_model_info((kdp2_ipc_cmd_get_model_info_t *)command_buffer); break; case KDP2_COMMAND_LOAD_FIRMWARE: ret = _load_firmware((kdp2_ipc_cmd_upload_firmware_t *)command_buffer); break; case KDP2_COMMAND_SET_CKEY: ret = _set_ckey((kdp2_ipc_cmd_set_ckey_t *)command_buffer); break; case KDP2_COMMAND_SET_DBG_CHECKPOINT: ret = _set_dbg_checkpoint((kdp2_ipc_cmd_set_dbg_checkpoint_t *)command_buffer); break; case KDP2_COMMAND_SET_PROFILE_ENABLE: ret = _set_dbg_profile((kdp2_ipc_cmd_set_profile_enable_t *)command_buffer); break; case KDP2_COMMAND_GET_PROFILE_STATISTICS: ret = _get_dbg_profile((kdp2_ipc_cmd_get_profile_statics_t *)command_buffer); break; case KDP2_COMMAND_GET_DDR_CONFIG: ret = _get_ddr_config((kdp2_ipc_cmd_get_available_ddr_config_t *)command_buffer); break; case KDP2_COMMAND_GET_FIFOQ_CONFIG: ret = _get_fifo_queue_config((kdp2_ipc_cmd_get_fifo_queue_config_t *)command_buffer); break; default: kmdw_printf("error ! unknown command id %d\n", command_id); break; } return ret; } int kdp2_cmd_handle_legend_kdp_command(uint32_t command_buffer) { fifo_cmd_dbg("[%s]\n", __FUNCTION__); int Ret = -1; uint16_t cmd = *((uint16_t *)command_buffer + 2); fifo_cmd_dbg("kdp_cmd->cmd: %d\n", cmd); switch (cmd) { case KDP_CMD_UPDATE_FW: Ret = _update_firmware((kdp_firmware_update_cmd_t *)command_buffer); break; case KDP_CMD_UPDATE_MODEL: Ret = _update_model((kdp_model_update_cmd_t *)command_buffer); break; default: fifo_cmd_dbg("[%s] not recognized KDP command %d, refused to handle it !\n", __FUNCTION__, cmd); // send some error ack back to host uint32_t txLen = 16; memset((void *)command_buffer, 0, txLen); kdrv_status_t usb_sts = usbd_hal_bulk_send(KDP2_USB_ENDPOINT_DATA_IN, (void *)command_buffer, txLen, USB_NORMAL_TIMEOUT); if (KDRV_STATUS_OK != usb_sts) { fifo_cmd_dbg("[%s] send ack failed, sts %d\n", __FUNCTION__, usb_sts); } break; } return Ret; }