* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
- * Version: $Id: flint.cpp 7187 2011-07-05 11:53:16Z orenk $
+ * Version: $Id: flint.cpp 7425 2011-10-03 15:26:25Z mohammad $
*
*/
#include <fcntl.h>
#include <assert.h>
#include <time.h>
-#include <termios.h>
#include "tools_version.h"
-#ifndef NO_ZLIB
- #include <zlib.h>
-#endif
#include <signal.h>
#define vsnprintf(buf, len, format, args) (vsprintf(buf, format, args))
#else // Linux GCC
-
+ #include <termios.h>
#include <byteswap.h>
#include <endian.h>
#include <alloca.h>
#define sleep(x) Sleep((x)*1000)
#define vsnprintf _vsnprintf
- #define strtoull _strtoui64
#define isatty _isatty
#define COMP_CDECL __cdecl
#define __BYTE_ORDER __LITTLE_ENDIAN
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define bswap_32(x) ntohl(x)
#else
#error windows is assumed to run a on little endian architecture
#endif
+ // MINGW
+ #if defined(__MINGW32__) || (__MINGW64__)
+ #define strtoull strtoull
+ #define _UNISTD_H // Zlib includes unistd.h which causes some compilation errors.
+
+ #else
+ #define strtoull _strtoui64
+ #endif
#endif // __WIN__
+#ifndef NO_ZLIB
+ #include <zlib.h>
+#endif
+
+
#include <memory>
#include <vector>
}
#define FLASH_PARAMS_OPTS "<type,log2size,num_of_flashes>"
#define MAX_NUM_SUPP_HW_IDS 200
+#define MAX_NUM_SUPP_HW_LIST_STR (MAX_NUM_SUPP_HW_IDS * 40)
#define MAC_SPACES " "
#define GUID_SPACES " "
#define GUID_FORMAT "%8.8x%8.8x"
bool CheckMatchingDevId(u_int32_t hwDevId, u_int32_t imageDevId);
bool CheckMatchingExpRomDevId(Operations::ImageInfo* info);
bool HwDevIdToSw(u_int32_t hw_dev_id, u_int32_t& sw_dev_id);
+ bool HWIdRevToName(u_int32_t hw_id, u_int8_t rev_id, char *hw_name);
+
// Image operations:
bool Verify (FBase& f, ImageInfo* info, bool both_images = false);
bool VerifyFs2 (FBase& f, ImageInfo* info, bool both_images = false, bool only_get_start = false,
const u_int32_t swDevIds[MAX_SW_DEVICES_PER_HW];
};
+ struct HwDev2Str {
+ const char* name;
+ u_int32_t hwDevId;
+ u_int8_t revId;
+ };
+
bool FwVerLessThan(u_int16_t r1[3], u_int16_t r2[3]) {
int i;
for (i = 0; i < 3 ; i++)
bool _is_full_verify;
bool _ignore_tty;
static const HwDevData hwDevData[];
+ static const HwDev2Str hwDev2Str[];
std::vector<u_int8_t> _fw_conf_sect;
std::vector<u_int8_t> _hash_file_sect;
0x100000,
0x200000
};
-#define CX3_HW_ID 501
+#define CX3_HW_ID 501
+#define CX_HW_ID 400
+#define IS_HW_ID 435
+#define BRIDGEX_HW_ID 6100
+#define IS4_HW_ID 435
+#define TAVOR_HW_ID 23108
+#define ARBEL_HW_ID 25208
+#define SINAI_HW_ID 25204
+
const Operations::HwDevData Operations::hwDevData[] = {
- { "InfiniHost", 23108, 2, {23108, 0}},
- { "InfiniHost III Ex", 25208, 2, {25208, 25218, 0}},
- { "InfiniHost III Lx", 25204, 1, {25204, 0}},
- { "ConnectX", 400, 2, {25408, 25418, 26418, 26438,
- 26428, 25448, 26448, 26468,
- 25458, 26458, 26478, 26488,
- 4097, 4098, 4100,
- 4101, 4102, 4103, 4104,
- 4105, 4106, 4107, 4108,
- 4109, 4110, 4111, 4112, 0}},
- { "ConnectX3", CX3_HW_ID, 2, {4099}},
- { "InfiniScale IV", 435, 0, {48436, 48437, 48438, 0}},
- { "BridgeX", 6100, 0, {64102, 64112, 64122, 0}},
+ { "InfiniHost", TAVOR_HW_ID, 2, {23108, 0}},
+ { "InfiniHost III Ex", ARBEL_HW_ID, 2, {25208, 25218, 0}},
+ { "InfiniHost III Lx", SINAI_HW_ID, 1, {25204, 0}},
+ { "ConnectX", CX_HW_ID, 2, {25408, 25418, 26418, 26438,
+ 26428, 25448, 26448, 26468,
+ 25458, 26458, 26478, 26488,
+ 4097, 4098, 0}},
+ { "ConnectX3", CX3_HW_ID, 2, {4099, 4100, 4101, 4102,
+ 4103, 4104, 4105, 4106,
+ 4107, 4108, 4109, 4110,
+ 4111, 4112, 0}},
+ { "InfiniScale IV", IS4_HW_ID, 0, {48436, 48437, 48438, 0}},
+ { "BridgeX", BRIDGEX_HW_ID, 0, {64102, 64112, 64122, 0}},
{ "SwitchX", SWITCHX_HW_ID, 0, {51000, 0}},
{ NULL , 0, 0, {0}},// zero devid terminator
};
+const Operations::HwDev2Str Operations::hwDev2Str[] = {
+ {"ConnectX", CX_HW_ID, 0xA0},
+ {"ConnectX-2", CX_HW_ID, 0xB0},
+ {"ConnectX-3 A0", CX3_HW_ID, 0x00},
+ {"ConnectX-3 A1", CX3_HW_ID, 0x01},
+ {"SwitchX A0", SWITCHX_HW_ID, 0x00},
+ {"SwitchX A1", SWITCHX_HW_ID, 0x01},
+ {"BridgeX", BRIDGEX_HW_ID, 0xA0},
+ {"InfiniScale IV A0", IS4_HW_ID, 0xA0},
+ {"InfiniScale IV A1", IS4_HW_ID, 0xA1},
+ {"InfiniHost A0", TAVOR_HW_ID, 0xA0},
+ {"InfiniHost A1", TAVOR_HW_ID, 0xA1},
+ {"InfiniHost III Lx", SINAI_HW_ID, 0xA0},
+ {"InfiniHost III Ex", ARBEL_HW_ID, 0xA0},
+ { NULL , 0, 0x00}, // zero devid terminator
+};
+
//
// Asks user a yes/no question.
// Returns true if user chose Y, false if user chose N.
}
return errmsg("Unknown Hw ID: %#x\n", hw_dev_id);
}
+#define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0])
+#define MAX_HW_NAME_LEN 100
+bool Operations::HWIdRevToName(u_int32_t hw_id, u_int8_t rev_id, char *hw_name)
+{
+ int i;
+
+ for (i = 0; hwDev2Str[i].hwDevId != 0; i++) {
+ const HwDev2Str *hwDev2StrMem = &(hwDev2Str[i]);
+
+ if (hwDev2StrMem->hwDevId == hw_id && hwDev2StrMem->revId == rev_id) {
+ int len = strlen(hwDev2StrMem->name);
+ if (len >= MAX_HW_NAME_LEN) {
+ return errmsg("Internal error: Length of device name: %d exceeds the maximum allowed size: %d", len, MAX_HW_NAME_LEN - 1);
+ }
+ strcpy(hw_name, hwDev2StrMem->name);
+ return true;
+ }
+ }
+ // When the device or rev is unknown we use the hw ID and rev to display it.
+ sprintf(hw_name, "MT%d-%02X", hw_id, rev_id);
+ return true;
+}
// This function gets the HW ID of the target device and the dev ID from
// the image. It then matches the 2 IDs and returns an error in case of
bool Operations::CheckMatchingHwDevId(u_int32_t hwDevId, u_int32_t rev_id, Operations::ImageInfo& info) {
int i;
- u_int32_t sw_dev_id;
+ char supp_hw_id_list[MAX_NUM_SUPP_HW_LIST_STR] = {'\0'};
+ char curr_hw_id_name[MAX_HW_NAME_LEN];
- if (!HwDevIdToSw(hwDevId, sw_dev_id)) {
- return false;
- }
- u_int32_t hw_dev_rev = (hwDevId & 0xffff) | ((rev_id & 0xff) << 16);
for (i = 0; i < info.supportedHwIdNum; i++) {
- //printf("-D- hw_dev_rev: %#x, supported_hw_id[%d]: %#x\n", hw_dev_rev, i, supported_hw_id[i]);
- if (info.supportedHwId[i] == hw_dev_rev) {
+ u_int32_t currSupportedHwId = info.supportedHwId[i];
+ u_int32_t supp_hw_id = currSupportedHwId & 0xffff;
+ u_int32_t supp_rev_id = (currSupportedHwId >> 16) & 0xff;
+ u_int32_t tmp_size_of_list;
+ char hw_name[MAX_HW_NAME_LEN];
+
+ if (currSupportedHwId == 0) {
+ break;
+ }
+ // Check if device is supported!
+ if ( supp_hw_id == hwDevId && supp_rev_id == rev_id) {
return true;
}
+ // Append checked to list of supported device in order to print it in the error if we this device is not supported
+
+ // Get the HW name of current supported HW ID
+ if (!HWIdRevToName(supp_hw_id, supp_rev_id, hw_name)) {
+ return false;
+ }
+ // Check if we don't exceed the array size we have
+ tmp_size_of_list = strlen(supp_hw_id_list) + strlen(hw_name) + 2;
+ if (tmp_size_of_list >= MAX_NUM_SUPP_HW_LIST_STR) {
+ return errmsg("Internal error: Size of supported devs list: %d exceeds the maximum allowed size: %d",
+ tmp_size_of_list, MAX_NUM_SUPP_HW_LIST_STR - 1);
+ }
+
+ if (supp_hw_id_list[0] == '\0') {
+ sprintf(supp_hw_id_list, "%s", hw_name);
+ } else {
+ sprintf(supp_hw_id_list, "%s, %s", supp_hw_id_list, hw_name);
+ }
+ }
+ // If we get here, this FW cannot be burnt in the current device.
+ // Get the Device name
+ if (!HWIdRevToName(hwDevId, rev_id, curr_hw_id_name)) {
+ return false;
}
- return errmsg("FW image file for device MT%d%X can not be programmed to device MT%d%X",
- info.devType, info.devRev, sw_dev_id, rev_id);
-}
+ return errmsg("FW image file cannot be programmed to device %s, it is intended for: %s only",
+ curr_hw_id_name, supp_hw_id_list);
+}
bool Operations::CheckMatchingDevId(u_int32_t hwDevId, u_int32_t imageDevId) {
int i, j;
const HwDevData* devData = NULL;
(const Bytef *)&(file_sect[0]), file_sect.size());
if (rc != Z_OK) {
- return errmsg("Failed uncompressing FW configuration section. uncompress returnes %d", rc);
+ return errmsg("Failed uncompressing FW configuration section. uncompress returns %d", rc);
}
dest.resize(destLen);
return strtoul(&buf[0], 0, 10);
}
-#define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0])
bool Operations::getFlashParams(char *flash_arg, flash_params_t *flash_params)
{
" to ensure failsafe burning even when an invariant sector difference is detected.\n"
" See the specific FW release notes for more details.\n"
"\n"
- " -byte_mode - Shift address when accessing flash internal registers. May\n"
- " be required for burn/write commands when accessing certain\n"
- " flash types.\n"
- "\n"
" -no_flash_verify - Do not verify each write on the flash.\n"
"\n"
#if 0
}\
}
+#define MAX_PASSWORD_LEN 256
+#ifndef __WIN__
int mygetch(void)
{
struct termios oldt,
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
-#define MAX_PASSWORD_LEN 256
// TODO: Move this function to the tools common file.
int GetPasswordFromUser(char *pre_str, char buffer[MAX_PASSWORD_LEN])
{
return true;
}
+#else
+int GetPasswordFromUser(char *pre_str, char buffer[MAX_PASSWORD_LEN])
+{
+ printf("%s: ", pre_str);
+ scanf("%s", buffer);
+ return true;
+}
+
+#endif
+
int main(int ac, char *av[])
{
#define __cpu_to_be32(val) (val)
#endif
#endif
+#define OP_NOT_SUPPORTED EOPNOTSUPP
#else // __WIN__
#define inline __inline
#define __cpu_to_be32(val) SWAPL(val) // Win is only run on LE CPUS
+#define OP_NOT_SUPPORTED EINVAL
+
#endif // __WIN__
#endif
#else
#define MREAD4(offs, val) do { if (mread4 (mfl->mf, offs, val) != 4) { \
fprintf(stderr, "-E- Cr read (0x%08x) failed: %s(%d)\n", (u_int32_t)(offs), strerror(errno), (u_int32_t)errno); \
- exit(2); } /*printf("-D- mread4: offs = %#x, val = %#x\n", offs, val);*/ \
+ exit(2); } /*printf("-D- %s:%d mread4: offs = %#x, val = %#x\n", __FUNCTION__, __LINE__, offs, val);*/ \
} while (0)
#define MWRITE4(offs, val) do { if (mwrite4(mfl->mf, offs, val) != 4) { \
fprintf(stderr, "-E- Cr write (0x%08x, 0x%08x) failed: %s(%d)\n", (u_int32_t)(offs), (u_int32_t)(val), strerror(errno), (u_int32_t)errno); \
- mclose(mfl->mf); exit(2); } /*printf("-D- %s mwrite4: offs = %#x, val = %#x\n", __FUNCTION__, offs, val);*/ \
+ mclose(mfl->mf); exit(2); } /*printf("-D- %s:%d mwrite4: offs = %#x, val = %#x\n", __FUNCTION__, __LINE__, offs, val);*/ \
} while (0)
#endif
#define CR_FLASH 0xf01a4
#define ADDR_MSK 0x7ffffUL
#define CMD_MASK 0xe0000000UL
-#define STATUS_REG_VAL 0x80000000
+
+#define SST_STATUS_REG_VAL 0x80000000
+#define ATMEL_STATUS_REG_VAL 0x0
#define CPUMODE_MSK 0xc0000000UL
#define CPUMODE_SHIFT 30
int cntx_spi_get_type(mflash* mfl, u_int8_t op_type, u_int8_t *vendor, u_int8_t *type, u_int8_t *capacity);
-int cntx_sst_spi_write_status_reg(mflash* mfl);
+int cntx_spi_write_status_reg(mflash* mfl, u_int32_t status_reg);
int spi_get_num_of_flashes(int prev_num_of_flashes);
#define SST_FLASH_NAME "SST25VFxx"
#define WINBOND_NAME "W25QxxBV"
+#define ATMEL_NAME "AT25DFxxx"
#define FMT_ST_M25P_NAME
typedef enum flash_vendor {
FV_ST = 0x20,
FV_SST = 0xbf,
FV_WINBOND = 0xef,
+ FV_ATMEL = 0x1f,
} flash_vendor_t;
typedef enum flash_memory_type {
FMT_ST_M25PX = 0x71,
FMT_SST_25 = 0x25,
FMT_WINBOND = 0x40,
+ FMT_ATMEL = 0x2,
} flash_memory_type;
{"M25Pxx", FV_ST, FMT_ST_M25P, MCS_STSPI, SFC_SE, 0x10000},
{SST_FLASH_NAME, FV_SST, FMT_SST_25, MCS_SSTSPI, SFC_SE, 0x10000},
{WINBOND_NAME, FV_WINBOND, FMT_WINBOND, MCS_STSPI, SFC_SSE, 0x1000},
-
+ {ATMEL_NAME, FV_ATMEL, FMT_ATMEL, MCS_STSPI, SFC_SSE, 0x1000},
};
int cntx_sst_get_log2size(u_int8_t capacity, int* log2spi_size)
} else {
rc = compare_flash_params(flash_params, spi_sel, type_name, log2size); CHECK_RC(rc);
}
-
// Init SST flash.
if (flash_info->vendor == FV_SST && flash_info->type == FMT_SST_25) {
- rc = cntx_sst_spi_write_status_reg(mfl); CHECK_RC(rc);
+ rc = cntx_spi_write_status_reg(mfl, SST_STATUS_REG_VAL); CHECK_RC(rc);
+ } else if (flash_info->vendor == FV_ATMEL && flash_info->type == FMT_ATMEL) {
+ rc = cntx_spi_write_status_reg(mfl, ATMEL_STATUS_REG_VAL); CHECK_RC(rc);
}
flash_params->num_of_flashes++;
gw_cmd = MERGE(gw_cmd, 1, HBO_FLASH_ENABLE, 1);
gw_cmd = MERGE(gw_cmd, (u_int32_t)mfl->curr_bank,
HBO_CHIP_SELECT, HBS_CHIP_SELECT);
+ // printf("-D- cntx_exec_cmd: %s\n", msg);
MWRITE4(CR_FLASH_GW, gw_cmd);
return ih3lx_wait_ready(mfl, msg);
}
return MFE_OK;
}
+int get_flash_info_for_atmel(u_int32_t jededc_id, u_int8_t* type, u_int8_t* capacity)
+{
+ u_int8_t tmp_cap;
+
+ tmp_cap = EXTRACT(jededc_id, 8, 5);
+ *type = EXTRACT(jededc_id, 13, 3);
+ switch (tmp_cap) {
+ case 0x4:
+ *capacity = 0x13;
+ break;
+ case 0x5:
+ *capacity = 0x14;
+ break;
+ case 0x6:
+ *capacity = 0x15;
+ break;
+ case 0x7:
+ *capacity = 0x16;
+ break;
+ default:
+ return MFE_UNSUPPORTED_FLASH_TOPOLOGY;
+ }
+
+ return MFE_OK;
+
+}
int get_info_from_jededc_id(u_int32_t jededc_id, u_int8_t *vendor, u_int8_t* type, u_int8_t* capacity)
{
+ int rc;
+
*vendor = EXTRACT(jededc_id, 0, 8);
- *type = EXTRACT(jededc_id, 8, 8);
- *capacity = EXTRACT(jededc_id, 16, 8);
+ if (*vendor == FV_ATMEL) {
+ rc = get_flash_info_for_atmel(jededc_id, type, capacity); CHECK_RC(rc);
+ } else {
+ *type = EXTRACT(jededc_id, 8, 8);
+ *capacity = EXTRACT(jededc_id, 16, 8);
+ }
+
return MFE_OK;
}
rc = cntx_int_spi_get_status_data(mfl, op_type, &flash_data, 3); CHECK_RC(rc);
flash_data = __be32_to_cpu(flash_data);
-
+ // printf("-D- flash_data = %#x\n", flash_data);
// Get type and some other info from jededc_id
get_info_from_jededc_id(flash_data, vendor, type, capacity);
+ // printf("-D- cntx_spi_get_type: vendor = %#x, type = %#x, capacity = %#x\n", *vendor, *type, *capacity);
return MFE_OK;
}
-int cntx_sst_spi_write_status_reg(mflash* mfl)
+int cntx_spi_write_status_reg(mflash* mfl, u_int32_t status_reg)
{
int rc;
u_int32_t gw_cmd = 0;
gw_cmd = MERGE(gw_cmd, SFC_WRSR, HBO_CMD, HBS_CMD);
- MWRITE4(HCR_FLASH_DATA, STATUS_REG_VAL);
+ MWRITE4(HCR_FLASH_DATA, status_reg);
return cntx_exec_cmd(mfl, gw_cmd, "Write-Status-Register");
}
if (msw_reset(mfl->mf)) {
if (errno == EPERM) {
return MFE_CMD_SUPPORTED_INBAND_ONLY;
- } else if (errno == EOPNOTSUPP) {
+ } else if (errno == OP_NOT_SUPPORTED) {
return MFE_MANAGED_SWITCH_NOT_SUPPORTED;
} else {