829 lines
28 KiB
C
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;
|
|
}
|