KL520_SDK_2.2/mdw/usb_companion/kdp2_cmd_handler_520.c
2025-12-17 15:55:25 +08:00

829 lines
28 KiB
C

// #define FIFO_CMD_DBG
#include <string.h>
#include <stdlib.h>
#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;
}