2 * Copyright 2017-2019 Intel Corporation.
3 * The source code, information and material ("Material") contained herein is
4 * owned by Intel Corporation or its suppliers or licensors, and title to such
5 * Material remains with Intel Corporation or its suppliers or licensors.
6 * The Material contains proprietary information of Intel or its suppliers and
7 * licensors. The Material is protected by worldwide copyright laws and treaty
9 * No part of the Material may be used, copied, reproduced, modified, published,
10 * uploaded, posted, transmitted, distributed or disclosed in any way without
11 * Intel's prior express written permission. No license under any patent,
12 * copyright or other intellectual property rights in the Material is granted to
13 * or conferred upon you, either expressly, by implication, inducement, estoppel
15 * Any license under such intellectual property rights must be express and
16 * approved by Intel in writing.
19 #include "mvnc_data.h"
20 #include "mvnc_tool.h"
22 #define MVLOG_UNIT_NAME ncTool
24 #include "XLinkStringUtils.h"
30 XLinkProtocol_t convertProtocolToXlink(
31 const ncDeviceProtocol_t ncProtocol) {
33 case NC_ANY_PROTOCOL: return X_LINK_ANY_PROTOCOL;
34 case NC_USB: return X_LINK_USB_VSC;
35 case NC_PCIE: return X_LINK_PCIE;
36 default: return X_LINK_ANY_PROTOCOL;
40 ncDeviceProtocol_t convertProtocolToNC(
41 const XLinkProtocol_t xLinkProtocol) {
42 switch (xLinkProtocol) {
43 case X_LINK_ANY_PROTOCOL: return NC_ANY_PROTOCOL;
44 case X_LINK_USB_VSC: return NC_USB;
45 case X_LINK_PCIE: return NC_PCIE;
47 mvLog(MVLOG_WARN, "This convertation not supported, set to ANY_PROTOCOL");
48 return NC_ANY_PROTOCOL;
52 XLinkPlatform_t convertPlatformToXlink(
53 const ncDevicePlatform_t ncProtocol) {
55 case NC_ANY_PLATFORM: return X_LINK_ANY_PLATFORM;
56 case NC_MYRIAD_2: return X_LINK_MYRIAD_2;
57 case NC_MYRIAD_X: return X_LINK_MYRIAD_X;
58 default: return X_LINK_ANY_PLATFORM;
62 ncDevicePlatform_t convertPlatformToNC(
63 const XLinkPlatform_t xLinkProtocol) {
64 switch (xLinkProtocol) {
65 case X_LINK_ANY_PLATFORM: return NC_ANY_PLATFORM;
66 case X_LINK_MYRIAD_2: return NC_MYRIAD_2;
67 case X_LINK_MYRIAD_X: return NC_MYRIAD_X;
69 mvLog(MVLOG_WARN, "This convertation not supported, set to NC_ANY_PLATFORM");
70 return NC_ANY_PLATFORM;
74 int copyNcDeviceDescrToXLink(const struct ncDeviceDescr_t *in_ncDeviceDesc,
75 deviceDesc_t *out_deviceDesc) {
76 CHECK_HANDLE_CORRECT(in_ncDeviceDesc);
77 CHECK_HANDLE_CORRECT(out_deviceDesc);
79 out_deviceDesc->protocol = convertProtocolToXlink(in_ncDeviceDesc->protocol);
80 out_deviceDesc->platform = convertPlatformToXlink(in_ncDeviceDesc->platform);
81 mv_strncpy(out_deviceDesc->name, XLINK_MAX_NAME_SIZE, in_ncDeviceDesc->name, XLINK_MAX_NAME_SIZE - 1);
86 int copyXLinkDeviceDescrToNc(const deviceDesc_t *in_DeviceDesc,
87 struct ncDeviceDescr_t *out_ncDeviceDesc) {
88 CHECK_HANDLE_CORRECT(in_DeviceDesc);
89 CHECK_HANDLE_CORRECT(out_ncDeviceDesc);
91 out_ncDeviceDesc->protocol = convertProtocolToNC(in_DeviceDesc->protocol);
92 out_ncDeviceDesc->platform = convertPlatformToNC(in_DeviceDesc->platform);
93 mv_strncpy(out_ncDeviceDesc->name, XLINK_MAX_NAME_SIZE, in_DeviceDesc->name, XLINK_MAX_NAME_SIZE - 1);
98 static ncStatus_t readFirmware(const char* binaryPath, char** out_firmware, size_t* out_length) {
99 CHECK_HANDLE_CORRECT(binaryPath);
100 CHECK_HANDLE_CORRECT(out_firmware);
101 CHECK_HANDLE_CORRECT(out_length);
103 *out_firmware = NULL;
105 FILE* firmwareFile = fopen(binaryPath, "rb");
107 if(firmwareFile == NULL) {
108 mvLog(MVLOG_ERROR, "Fail to open file by path %s", binaryPath);
112 fseek(firmwareFile, 0, SEEK_END);
113 long fileSize = ftell(firmwareFile);
115 mvLog(MVLOG_ERROR, "Fail to get file size or firmware is empty. fileSize = %ld", fileSize);
116 fclose(firmwareFile);
119 rewind(firmwareFile);
121 char* firmware = malloc(fileSize * sizeof(char));
122 if(firmware == NULL) {
123 mvLog(MVLOG_ERROR, "Fail to allocate memory for firmware");
124 fclose(firmwareFile);
128 size_t readCount = fread(firmware, sizeof(char), fileSize, firmwareFile);
129 if(readCount != fileSize)
131 mvLog(MVLOG_ERROR, "Fail to read firmware by path %s. readCount = %zu", binaryPath, readCount);
132 fclose(firmwareFile);
137 fclose(firmwareFile);
139 *out_firmware = firmware;
140 *out_length = (size_t )fileSize;
145 static ncStatus_t patchFirmware(char **firmware, size_t *length, size_t commandLocationId,
146 const char command[], const size_t commandSize, const char value) {
147 CHECK_HANDLE_CORRECT(firmware);
148 CHECK_HANDLE_CORRECT(length);
149 CHECK_HANDLE_CORRECT(command);
151 char* currFirmware = *firmware;
152 size_t currLength = *length;
154 size_t patchedFirmwareLen = currLength + commandSize + 1;
155 char* patchedFirmware = malloc(patchedFirmwareLen);
156 if(patchedFirmware == NULL) {
157 mvLog(MVLOG_ERROR, "Fail to allocate memory for patched firmware");
161 memcpy(patchedFirmware, currFirmware, commandLocationId);
163 memcpy(patchedFirmware + commandLocationId,
164 command, commandSize);
165 memcpy(patchedFirmware + commandLocationId + commandSize,
168 size_t currentPos = commandLocationId + commandSize + 1;
169 size_t tailSize = currLength - commandLocationId;
170 memcpy(patchedFirmware + currentPos,
171 currFirmware + commandLocationId, tailSize);
174 *firmware = patchedFirmware;
175 *length = patchedFirmwareLen;
180 // 0x98 the write command for 8bit
181 // {0x00, 0x00, 0x20, 0x80} == 0x80200000 the address of watchdog flag
183 const char g_setWdSwitchCommandMX[] = {0x98, 0x00, 0x00, 0x20, 0x80};
184 const char g_executeCommand = 0xa4;
186 static ncStatus_t patchSetWdSwitchCommand(char **firmware, size_t *length, const char wdEnable) {
187 CHECK_HANDLE_CORRECT(firmware);
188 CHECK_HANDLE_CORRECT(length);
190 char* currFirmware = *firmware;
191 size_t currLength = *length;
192 size_t executeCommandIdx = 0;
193 char executeCommandFound = 0;
196 for (i = currLength - 1; i >= 0; i--) {
197 if(currFirmware[i] == g_executeCommand) {
198 executeCommandIdx = i;
199 executeCommandFound = 1;
204 if(!executeCommandFound) {
205 mvLog(MVLOG_WARN, "Fail to find execute command");
208 return patchFirmware(firmware, length, executeCommandIdx,
209 g_setWdSwitchCommandMX, sizeof(g_setWdSwitchCommandMX), wdEnable);
212 // 0x98 the write command for 8bit
213 // {0x00, 0x0c, 0x20, 0x70} == 0x70200c00 the address of memory type for ddrInit application
214 const char g_setMemTypeCommandMX[] = {0x98, 0x00, 0x0c, 0x20, 0x70};
215 const char g_callCommand[] = {0xba, 0x78, 0xe9, 0x00, 0x70};
217 static ncStatus_t patchSetMemTypeCommand(char **firmware, size_t *length, const char memType) {
218 CHECK_HANDLE_CORRECT(firmware);
219 CHECK_HANDLE_CORRECT(length);
221 char* currFirmware = *firmware;
222 size_t currLength = *length;
223 size_t callCommandIdx = 0;
224 char callCommandFound = 0;
226 size_t callCommandLen = sizeof(g_callCommand);
228 for (i = 0; i < currLength; i++) {
230 for (j = 0; j < callCommandLen; j++) {
231 if(currFirmware[i + j] != g_callCommand[j]) {
236 if(j == callCommandLen) {
238 callCommandFound = 1;
242 if(!callCommandFound) {
243 mvLog(MVLOG_WARN, "Fail to find call command");
246 return patchFirmware(firmware, length, callCommandIdx,
247 g_setMemTypeCommandMX, sizeof(g_setMemTypeCommandMX), memType);
250 ncStatus_t bootDevice(deviceDesc_t* deviceDescToBoot,
251 const char* mv_cmd_file_path, const bootOptions_t bootOptions) {
253 CHECK_HANDLE_CORRECT(deviceDescToBoot);
255 char* firmware = NULL;
257 ncStatus_t sc = readFirmware(mv_cmd_file_path, &firmware, &length);
259 mvLog(MVLOG_ERROR, "Fail to read firmware by path %s. sc = %d", mv_cmd_file_path, sc);
263 if(deviceDescToBoot->platform == X_LINK_MYRIAD_X) {
264 if(deviceDescToBoot->protocol != X_LINK_PCIE) {
265 sc = patchSetWdSwitchCommand(&firmware, &length, bootOptions.wdEnable);
267 mvLog(MVLOG_WARN, "Fail to patch \"Set wd switch value\" command for firmware sc = %d", sc);
270 sc = patchSetMemTypeCommand(&firmware, &length, bootOptions.memType);
272 mvLog(MVLOG_WARN, "Fail to patch \"Set memory type\" command for firmware sc = %d", sc);
277 XLinkError_t rc = XLinkBootFirmware(deviceDescToBoot, firmware, (unsigned long)length);