2 * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.
\r
3 * Copyright (c) 2004-2005 Mellanox Technologies Ltd. All rights reserved.
\r
5 * This software is available to you under the OpenIB.org BSD license
\r
8 * Redistribution and use in source and binary forms, with or
\r
9 * without modification, are permitted provided that the following
\r
10 * conditions are met:
\r
12 * - Redistributions of source code must retain the above
\r
13 * copyright notice, this list of conditions and the following
\r
16 * - Redistributions in binary form must reproduce the above
\r
17 * copyright notice, this list of conditions and the following
\r
18 * disclaimer in the documentation and/or other materials
\r
19 * provided with the distribution.
\r
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
25 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
26 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
34 #include "flint-tools.h"
\r
35 #include <complib/cl_byteswap.h>
\r
37 bool DebugMode = false;
\r
38 bool DisableBestDevice = false;
\r
40 static uint32_t TAVOR_TYPE = 23108;
\r
41 static uint32_t ARBEL_TYPE = 25208;
\r
42 static int mellanox_mode = 0;
\r
43 static uint32_t devRevision;
\r
44 static uint32_t devType;
\r
45 static uint32_t devId;
\r
46 static char bestDev[MAXPATHLEN];
\r
48 char *techSupportMessage = "Use the --force option to skip this check. This operation\n"
\r
49 "allows any firmware to be placed on the HCA device, but could cause the\n"
\r
50 "the device to cease functioning. If this occurs, please contact\n"
\r
51 "technical support.\n";
\r
54 #define M_DEBUG printf
\r
55 #define LOCK_FILE_NAME "C:\\fwupdate.lck"
\r
57 static int file_lock;
\r
58 static int FwUpdateLock(void);
\r
59 static void FwUpdateUnlock(void);
\r
63 u_int32_t g_fw_dbg_lvl = CL_DBG_ERROR ;
\r
65 #define BE2CPU32(s) __be32_to_cpu(s)
\r
66 #define TOCPU1(s) s = __be32_to_cpu(s)
\r
68 #define TOCPU(s,bsz) do { \
\r
69 uint32_t *p = (uint32_t *)(s); \
\r
70 for (uint32_t ii=0; ii<bsz/sizeof(uint32_t); ii++,p++) \
\r
71 *p = __be32_to_cpu(*p); \
\r
73 #define TOCPUBY(s, bsz) do { \
\r
74 uint32_t *p = (uint32_t *)(&s); \
\r
75 for (uint32_t ii=0; ii<bsz/sizeof(uint32_t); ii++,p++) \
\r
76 *p = __be32_to_cpu(*p); \
\r
78 #define CRC(c, s, bsz) do { \
\r
79 uint32_t *p = (uint32_t *)(s); \
\r
80 for (uint32_t ii=0; ii<bsz/sizeof(uint32_t); ii++) \
\r
83 #define CRCBY(c, s, bsz) do { \
\r
84 uint32_t *p = (uint32_t *)(&s); \
\r
85 for (uint32_t ii=0; ii<bsz/sizeof(uint32_t); ii++) \
\r
88 #define CRC1(c, s,bsz) do { \
\r
89 uint32_t *p = (uint32_t *)(s); \
\r
90 for (uint32_t ii=0; ii<bsz/sizeof(uint32_t) - 1; ii++) \
\r
93 #define CRC1BY(c, s, bsz) do { \
\r
94 uint32_t *p = (uint32_t *)(&s); \
\r
95 for (uint32_t ii=0; ii<bsz/sizeof(uint32_t) - 1; ii++) \
\r
98 #define CHECKB2(f,b,o,n,p) do { if (!checkBoot2(f,b,o,n,p)) return false; } while (0)
\r
99 #define CHECKGN(f,b,o,n,p) do { if (!checkGen(f,b,o,n,p)) return false; } while (0)
\r
100 #define CHECKLS(f,o,p) do { if (!checkList(f,o,p)) return false; } while(0)
\r
101 #define READBUF(f,o,d,l,p) do { if (!f.read(o,d,l)) { \
\r
102 printf("%s - read error (%s)\n", p, f._err); \
\r
103 return false; }} while (0)
\r
104 enum { SIGNATURE=0x5a445a44, SECT_SIZE=0x10000 };
\r
108 uint32_t signature;
\r
109 uint32_t fw_reserved[5];
\r
112 uint32_t as_uint32[4];
\r
115 uint32_t branch_to;
\r
139 typedef struct hca_dev {
\r
140 ib_al_handle_t *ph_al;
\r
141 ib_al_handle_t h_al;
\r
142 ib_ca_handle_t *ph_ca;
\r
143 ib_ca_handle_t h_ca;
\r
144 ib_net64_t *ca_guid;
\r
146 size_t ca_guids_count;
\r
151 #define MST_MAX_FLASH (512*1024) // 512K
\r
152 #define READ4(f,o,d,p) do { if (!f.read(o,d)) { \
\r
153 printf("%s - read error (%s)\n", p, f._err); \
\r
154 return false; }} while (0)
\r
156 // forward function declaration
\r
157 uint32_t HcaDevnameToDevId(const char *devname);
\r
158 uint32_t HcaDevnameToDevType(const char *devname);
\r
159 bool probePciBusForHcaDevice(const char *devname);
\r
160 bool isMstLoaded(void);
\r
161 bool getGUID(const char *s, uint64_t *guid);
\r
162 bool extractGUIDptr(uint32_t sign, uint32_t *buf, uint32_t buf_len, char *pref, uint32_t *ind, uint32_t *nguids);
\r
163 void printStatus(const uint32_t status);
\r
164 void printPercent(const uint32_t percent, const uint32_t reset);
\r
166 ////////////////////////////////////////////////////////////////////////
\r
168 // ****************************************************************** //
\r
169 // CRC16 CALCULATION //
\r
170 // ****************************************************************** //
\r
172 ////////////////////////////////////////////////////////////////////////
\r
176 Crc16(bool d = false) : _debug(d) { clear(); }
\r
177 uint16_t get() { return _crc; }
\r
178 void clear() { _crc = 0xffff; }
\r
179 void operator<<(uint32_t val) { add(val); }
\r
180 void add(uint32_t val);
\r
187 ////////////////////////////////////////////////////////////////////////
\r
188 void Crc16::add(uint32_t o)
\r
191 printf("Crc16::add(%08"PRIx32")\n", o);
\r
192 for (uint32_t i=0; i<32; i++)
\r
195 _crc = (((_crc<<1) | (o>>31)) ^ 0x100b) & 0xffff;
\r
197 _crc=((_crc<<1) | (o>>31)) & 0xffff;
\r
198 o = (o<<1) & 0xffffffff;
\r
203 ////////////////////////////////////////////////////////////////////////
\r
204 void Crc16::finish()
\r
206 for (uint32_t i=0; i<16; i++)
\r
209 _crc=((_crc<<1) ^ 0x100b) & 0xffff;
\r
211 _crc=(_crc<<1) & 0xffff;
\r
214 // Revert 16 low bits
\r
215 _crc = _crc ^ 0xffff;
\r
220 ////////////////////////////////////////////////////////////////////////
\r
222 // ****************************************************************** //
\r
224 // ****************************************************************** //
\r
226 ////////////////////////////////////////////////////////////////////////
\r
227 //#define FUJITSU_BYTE_MODE
\r
229 // Common base class for Flash and for FImage
\r
233 FBase() {m_debug=false;}
\r
235 virtual bool open(const char *) = 0;
\r
236 virtual void close() = 0;
\r
237 virtual bool read(uint32_t addr, uint32_t *data) = 0;
\r
238 virtual bool read(uint32_t addr, void *data, uint32_t len) = 0;
\r
239 virtual bool dump() = 0;
\r
240 virtual uint32_t getClassType() = 0;
\r
242 void setDebug(bool on) { m_debug = on; };
\r
243 bool isDebug() { return m_debug; };
\r
251 // Flash image (RO)
\r
252 class FImage : public FBase
\r
255 FImage() : _buf(0) { }
\r
256 FImage(bool debug) : _buf(0) { setDebug(debug); }
\r
257 virtual ~FImage() { close(); }
\r
259 enum { RawImageFileType = 1 };
\r
261 uint32_t *getBuf() { return _buf; }
\r
262 uint32_t getBufLength() { return _len; }
\r
263 virtual bool open(const char *fname);
\r
264 virtual void close();
\r
265 virtual bool read(uint32_t addr, uint32_t *data);
\r
266 virtual bool read(uint32_t addr, void *data, uint32_t len);
\r
267 virtual bool dump();
\r
268 virtual uint32_t getClassType() { return RawImageFileType; };
\r
275 // Flash access (R/W)
\r
276 class Flash : public FBase
\r
279 enum GPIO_STATE { High, Low };
\r
281 Flash() : curr_sector(0xffffffff), m_curr_bank(0xffffffff), m_gpio_state(Flash::Low) {}
\r
282 virtual ~Flash() { close(); };
\r
284 enum { SECT_SIZE = 0x10000, SECT_MASK = 0xffff0000, FlashDeviceType = 2 };
\r
285 enum { FW_READ = 0x00,
\r
287 FW_READ_CMD = 0x08,
\r
288 FW_WRITE_CMD= 0x09,
\r
290 FW_CLOSE_IF = 0x7e };
\r
291 uint32_t curr_sector;
\r
293 virtual bool open(const char *);
\r
294 virtual void close();
\r
295 virtual bool read(uint32_t addr, uint32_t *data);
\r
296 virtual bool read(uint32_t addr, void *data, uint32_t len);
\r
297 virtual bool dump();
\r
298 virtual uint32_t getClassType() { return FlashDeviceType; };
\r
299 void setGPIOState(GPIO_STATE state);
\r
301 bool write(uint32_t addr, uint32_t data);
\r
302 bool write(uint32_t addr, void *data, uint32_t cnt,
\r
303 bool noerase = false, bool noverify = false);
\r
304 bool write_image(uint32_t addr, void *data, uint32_t cnt, bool eraseInvariant = false, bool report=false);
\r
305 bool erase_sector(uint32_t addr);
\r
307 ib_api_status_t access(hca_dev_t *mf, u_int32_t offset, void *data, u_int32_t length, u_int32_t operation);
\r
310 uint32_t m_curr_bank;
\r
311 GPIO_STATE m_gpio_state;
\r
317 bool hca_open (void);
\r
319 bool set_bank(uint32_t bank);
\r
320 bool write_internal(uint32_t addr, uint8_t data);
\r
322 enum FlashCmds {IDLE=0,
\r
327 enum { TRANS = 4096 };
\r
328 enum { BANK_SHIFT = 19,
\r
329 BANK_MASK = 0xfff80000
\r
332 enum { FLASH = 0xf01a4,
\r
333 ADDR_MSK=0x7ffffUL,
\r
334 CMD_MASK=0xe0000000UL
\r
337 enum { CPUMODE = 0xf0150,
\r
338 CPUMODE_MSK=0xc0000000UL,
\r
342 enum { SEMAP63 = 0xf03fc,
\r
343 GPIO_DIR_L = 0xf008c,
\r
344 GPIO_POL_L = 0xf0094,
\r
345 GPIO_MOD_L = 0xf009c,
\r
346 GPIO_DAT_L = 0xf0084,
\r
347 GPIO_DATACLEAR_L = 0xf00d4,
\r
348 GPIO_DATASET_L = 0xf00dc
\r
352 enum { FLASH_CMD_CNT = 5000, // Number of reads till flash cmd is zeroed
\r
353 ERASE_DELAY = 20000, // Delay between reads when wating for sector erase
\r
354 ERASE_CNT = 80, // Maximal number of reads when wating for sector erase
\r
355 READ_CNT_FAST = 5000, // Number of fast reads after write byte
\r
356 READ_CNT_SLOW = 50, // Number of slow reads after write byte
\r
357 READ_DELAY = 10000, // Delay between slow reads after write byte
\r
358 WR_REPORT_FAST = 256, // Report frequency when write (fast interfaces)
\r
359 WR_REPORT_SLOW = 4, // Report frequency when write (slow interfaces)
\r
360 RD_REPORT_FAST = 4096, // Report frequency when read (fast interfaces)
\r
361 RD_REPORT_SLOW = 64, // Report frequency when read (slow interfaces)
\r
362 GPIO_SEM_TRIES = 10240 // Number of tries to obtain a GPIO sem.
\r
367 bool FImage::dump()
\r
370 uint32_t position = 0;
\r
374 if (!this->read(position, &word))
\r
379 if ((position % 16) == 0)
\r
381 printf("\n%08"PRIx32": ", position);
\r
383 printf(" %08"PRIx32"", word);
\r
385 position = position + 4;
\r
391 ////////////////////////////////////////////////////////////////////////
\r
392 bool FImage::open(const char *fname)
\r
394 struct _stat stat_buf;
\r
397 uint32_t fd = _open(fname, _O_BINARY | _O_RDONLY, S_IREAD);
\r
400 sprintf(_msg, "Can't open file \"%s\" - %s\n", fname,
\r
405 if (_fstat(fd, &stat_buf) < 0)
\r
407 sprintf(_msg, "Can't stat file \"%s\" - %s\n", fname,
\r
412 if (stat_buf.st_size & 0x3)
\r
414 _err = "Image size should be 4-bytes aligned.";
\r
418 _buf = new uint32_t[stat_buf.st_size/4];
\r
419 if ((r_cnt = _read(fd, _buf, stat_buf.st_size)) != stat_buf.st_size)
\r
422 sprintf(_msg, "Read error on file \"%s\" - %s\n",
\r
423 fname, strerror(errno));
\r
425 sprintf(_msg, "Read error on file \"%s\" - read only %d bytes (from %ld)\n",
\r
426 fname, r_cnt, stat_buf.st_size);
\r
431 _len = stat_buf.st_size;
\r
436 ////////////////////////////////////////////////////////////////////////
\r
437 void FImage::close()
\r
443 ////////////////////////////////////////////////////////////////////////
\r
444 bool FImage::read(uint32_t addr, uint32_t *data)
\r
448 _err = "Address should be 4-bytes aligned.";
\r
453 _err = "Not opened";
\r
458 sprintf(_msg, "Address (0x%x) is out of image limits\n", addr);
\r
462 *data = _buf[addr/4];
\r
466 ////////////////////////////////////////////////////////////////////////
\r
467 bool FImage::read(uint32_t addr, void *data, uint32_t len)
\r
471 _err = "Address should be 4-bytes aligned.";
\r
476 _err = "Length should be 4-bytes aligned.";
\r
481 _err = "Not opened";
\r
485 uint32_t *p = (uint32_t *)data;
\r
486 for (uint32_t i=0; i<len/4; i++)
\r
488 if (!read(addr, p++))
\r
497 void __cdecl catch_signal( int sig );
\r
500 ////////////////////////////////////////////////////////////////////////
\r
501 #define MWRITE4(offs,val, cmd) access(&m_mf, offs, val, 4, cmd )
\r
502 #define MREAD4(offs,val, cmd) access(&m_mf, offs, val, 4, cmd )
\r
504 void Flash::setGPIOState(GPIO_STATE state)
\r
506 m_gpio_state = state;
\r
512 uint32_t position = 0;
\r
513 uint32_t max_size = 0;
\r
516 this->read(SECT_SIZE, &ps, sizeof(ps));
\r
518 TOCPUBY(ps,sizeof(ps));
\r
521 if (ps.signature != SIGNATURE)
\r
523 max_size = MST_MAX_FLASH;
\r
526 max_size = ps.fi_size;
\r
529 while (position < max_size )
\r
531 if (!this->read(position, &word))
\r
536 if ((position % 16) == 0)
\r
538 printf("\n%08"PRIx32": ", position);
\r
540 printf(" %08"PRIx32"", word);
\r
542 position = position + 4;
\r
548 bool Flash::format()
\r
550 uint32_t position = 0;
\r
551 uint32_t max_size = 0;
\r
553 uint32_t percent = 0;
\r
555 this->read(SECT_SIZE, &ps, sizeof(ps));
\r
557 TOCPUBY(ps, sizeof(ps));
\r
560 if (ps.signature != SIGNATURE)
\r
562 max_size = MST_MAX_FLASH;
\r
565 max_size = ps.fi_size;
\r
570 while (position < max_size )
\r
572 this->erase_sector(position);
\r
573 percent = (uint32_t)(((float)position / (float)max_size) * 100.00);
\r
574 if (percent != prev)
\r
575 printPercent(percent,0);
\r
577 position = position + SECT_SIZE; // increment by 65k sectors
\r
579 printPercent(100,0);
\r
584 ////////////////////////////////////////////////////////////////////////
\r
585 bool Flash::open(const char *device )
\r
588 bool status = false;
\r
591 M_DEBUG("Specify HCA to work with\n");
\r
594 m_mf.ph_al = (ib_al_handle_t *)(intn_t)&m_mf.h_al;
\r
595 m_mf.ph_ca = (ib_ca_handle_t *)(intn_t)&m_mf.h_ca;
\r
596 if ( !(hca_open()))
\r
598 M_DEBUG("Failed to open HCA \n");
\r
602 //M_DEBUG("Open HCA GUID %"PRIx64"\n", cl_ntoh64(*m_mf.ca_guid));
\r
604 m_curr_bank = 0xffffffff;
\r
606 // Obtain GPIO Semaphore
\r
610 MREAD4(FLASH, &word, FW_OPEN_IF );
\r
614 MREAD4(SEMAP63, &word, FW_READ_CMD);
\r
620 if (++cnt > GPIO_SEM_TRIES)
\r
622 _err = "cannot obtain GPIO semaophore (63)";
\r
629 MREAD4(FLASH, &word, FW_CLOSE_IF );
\r
633 //M_DEBUG("Acquired GPIO sempahore.\n");
\r
636 MREAD4(GPIO_DIR_L, &m_dir, FW_READ_CMD);
\r
637 MREAD4(GPIO_POL_L, &m_pol, FW_READ_CMD);
\r
638 MREAD4(GPIO_MOD_L, &m_mod, FW_READ_CMD);
\r
639 MREAD4(GPIO_DAT_L, &m_data, FW_READ_CMD);
\r
641 //M_DEBUG("Read GPIO information.\n");
\r
643 // Set Direction=1, Polarity=0, Mode=0 for 3 GPIO lower bits
\r
648 dir = m_dir | 0x70;
\r
649 pol = m_pol & ~0x70;
\r
650 mod = m_mod & ~0x70;
\r
652 MWRITE4(GPIO_DIR_L, &dir, FW_WRITE_CMD);
\r
653 MWRITE4(GPIO_POL_L, &pol, FW_WRITE_CMD);
\r
654 MWRITE4(GPIO_MOD_L, &mod, FW_WRITE_CMD);
\r
656 // M_DEBUG("Set GPIO bits.\n");
\r
659 MREAD4(CPUMODE, &word, FW_READ_CMD);
\r
660 word &= ~CPUMODE_MSK;
\r
661 word |= 1 << CPUMODE_SHIFT;
\r
662 MWRITE4(CPUMODE, &word, FW_WRITE_CMD);
\r
665 //M_DEBUG("Set cpu mode.\n");
\r
668 status = write_internal(0, 0xf0);
\r
669 M_DEBUG("Flash Open %s\n", ((status)?"OK":"FAIL"));
\r
673 ////////////////////////////////////////////////////////////////////////
\r
674 void Flash::close()
\r
681 m_gpio_state = Flash::Low;
\r
684 // Restore origin values
\r
685 MWRITE4(GPIO_DIR_L, &m_dir, FW_WRITE_CMD);
\r
686 MWRITE4(GPIO_POL_L, &m_pol, FW_WRITE_CMD);
\r
687 MWRITE4(GPIO_MOD_L, &m_mod, FW_WRITE_CMD);
\r
688 MWRITE4(GPIO_DAT_L, &m_data, FW_WRITE_CMD);
\r
690 // Free GPIO Semaphore
\r
691 MWRITE4(SEMAP63, &data, FW_WRITE_CMD);
\r
693 // free kernel BusInterface
\r
694 MREAD4(FLASH, &data, FW_CLOSE_IF );
\r
698 m_curr_bank = 0xffffffff;
\r
701 ////////////////////////////////////////////////////////////////////////
\r
702 bool Flash::set_bank(uint32_t bank)
\r
704 uint32_t data = 0x70;
\r
707 _err = "Not opened";
\r
711 //printf("\n*** Flash::set_bank(0x%"PRIx32") : 0x%"PRIx32"\n", bank, (BANK_SHIFT-4) & 0x70);
\r
712 MWRITE4(GPIO_DATACLEAR_L, &data, FW_WRITE_CMD);
\r
713 if (m_gpio_state == Flash::Low)
\r
715 data &= (bank >> (BANK_SHIFT-4));
\r
716 MWRITE4(GPIO_DATASET_L, &data, FW_WRITE_CMD );
\r
719 data |= (bank >> (BANK_SHIFT-4));
\r
720 MWRITE4(GPIO_DATASET_L, &data, FW_WRITE_CMD);
\r
724 } // Flash::set_bank
\r
726 ////////////////////////////////////////////////////////////////////////
\r
727 bool Flash::read(uint32_t addr, uint32_t *data)
\r
731 _err = "Not opened";
\r
738 _err = "Address should be 4-bytes aligned.";
\r
742 uint32_t bank = addr & BANK_MASK;
\r
743 if (bank != m_curr_bank)
\r
745 m_curr_bank = bank;
\r
746 if (!set_bank(bank))
\r
749 MREAD4(addr, &cmd, FW_READ ); // new read
\r
750 cmd = __be32_to_cpu(cmd);
\r
751 memcpy(data, &cmd, sizeof(uint32_t));
\r
756 ////////////////////////////////////////////////////////////////////////
\r
757 bool Flash::read(uint32_t addr, void *data, uint32_t len)
\r
761 _err = "Address should be 4-bytes aligned.";
\r
766 _err = "Length should be 4-bytes aligned.";
\r
770 uint32_t *p = (uint32_t *)data;
\r
771 for (uint32_t i=0; i<len/4; i++)
\r
773 if (!read(addr, p++))
\r
778 } // Flash::flash_read
\r
780 ////////////////////////////////////////////////////////////////////////
\r
781 bool Flash::write_internal(uint32_t addr, uint8_t data)
\r
783 MWRITE4(addr, &data, FW_WRITE);
\r
785 } // Flash::write_internal
\r
787 ////////////////////////////////////////////////////////////////////////
\r
788 bool Flash::erase_sector(uint32_t addr)
\r
793 // Just to insure zeroes because erase completion waits for ones
\r
794 if (!write(addr, &word, sizeof(word), true))
\r
797 // erase sector sequence
\r
798 #ifdef FUJITSU_BYTE_MODE
\r
799 if (!write_internal(0xaaa, 0xaa))
\r
801 if (!write_internal(0x555, 0x55))
\r
803 if (!write_internal(0xaaa, 0x80))
\r
805 if (!write_internal(0xaaa, 0xaa))
\r
807 if (!write_internal(0x555, 0x55))
\r
809 if (!write_internal(addr, 0x30))
\r
811 #else /* FUJITSU_WORD_MODE */
\r
812 if (!write_internal(0x555, 0xaa))
\r
814 if (!write_internal(0x2aa, 0x55))
\r
816 if (!write_internal(0x555, 0x80))
\r
818 if (!write_internal(0x555, 0xaa))
\r
820 if (!write_internal(0x2aa, 0x55))
\r
822 if (!write_internal(addr, 0x30))
\r
826 // Wait while erase completes
\r
830 if (++cnt > ERASE_CNT)
\r
832 _err = "Flash erase sector timeout";
\r
835 if (!read(addr, &word))
\r
838 //printf("erase_sector: addr:%08"PRIx32", %08"PRIx32"\n", addr, word);
\r
839 Sleep(ERASE_DELAY/1000);
\r
840 } while (word != 0xffffffff);
\r
843 } // Flash::erase_sector
\r
845 ////////////////////////////////////////////////////////////////////////
\r
846 bool Flash::write(uint32_t addr, uint32_t data)
\r
850 _err = "Not opened";
\r
855 _err = "Address should be 4-bytes aligned.";
\r
860 uint32_t sector = addr & SECT_MASK;
\r
861 uint32_t word_in_sector = (addr & ~SECT_MASK)/sizeof(uint32_t);
\r
863 if (!read(addr, &word))
\r
866 return true; // already there
\r
868 uint32_t buff[SECT_SIZE/sizeof(uint32_t)];
\r
869 if (!read(sector, buff, SECT_SIZE))
\r
871 buff[word_in_sector] = data;
\r
872 return write(sector, buff, SECT_SIZE);
\r
875 ////////////////////////////////////////////////////////////////////////
\r
876 bool Flash::write(uint32_t addr, void *data, uint32_t cnt,
\r
877 bool noerase, bool noverify)
\r
881 _err = "Not opened";
\r
886 _err = "Address should be 4-bytes aligned.";
\r
893 char *p = (char *)data;
\r
895 for (uint32_t i=0; i<cnt; i++,addr++)
\r
901 uint32_t bank = addr & BANK_MASK;
\r
902 if (bank != m_curr_bank)
\r
904 m_curr_bank = bank;
\r
905 if (!set_bank(bank))
\r
911 uint32_t sector = addr & SECT_MASK;
\r
912 if (sector != curr_sector)
\r
914 curr_sector = sector;
\r
915 if (!erase_sector(curr_sector))
\r
920 #ifdef FUJITSU_BYTE_MODE
\r
921 if (!write_internal(0xaaa, 0xaa))
\r
923 if (!write_internal(0x555, 0x55))
\r
925 if (!write_internal(0xaaa, 0xa0))
\r
927 #else /* FUJITSU_WORD_MODE */
\r
928 if (!write_internal(0x555, 0xaa))
\r
930 if (!write_internal(0x2aa, 0x55))
\r
932 if (!write_internal(0x555, 0xa0))
\r
936 if (!write_internal(addr, *p++))
\r
941 if ( !read (addr &~3, &word) )
\r
943 #if __BYTE_ORDER == __LITTLE_ENDIAN
\r
944 act = (word >> ((addr & 3) * 8)) & 0xff;
\r
945 #elif __BYTE_ORDER == __BIG_ENDIAN
\r
946 act = (word >> ((3 - (addr & 3)) * 8)) & 0xff;
\r
948 exp = *(p-1) & 0xff;
\r
951 M_DEBUG("Flash write error - read value %#x doesn't written value %#x", act, exp);
\r
959 void Flash::hca_close (void)
\r
963 ib_close_ca( m_mf.h_ca, NULL );
\r
965 ib_close_al( m_mf.h_al);
\r
967 bool Flash::hca_open(void)
\r
969 ib_api_status_t ib_status = IB_SUCCESS;
\r
972 ib_status = ib_open_al( m_mf.ph_al );
\r
973 if ( ib_status != IB_SUCCESS )
\r
975 M_DEBUG("Failed ot open AL status %#x\n", ib_status);
\r
979 ib_status = ib_get_ca_guids ( *m_mf.ph_al, NULL, &m_mf.ca_guids_count );
\r
980 if (m_mf.ca_guids_count == 0)
\r
982 M_DEBUG("FOUND NO GUIDS\n");
\r
986 m_mf.ca_guid =(ib_net64_t *)cl_zalloc(m_mf.ca_guids_count*sizeof(ib_net64_t));
\r
987 if(m_mf.ca_guid == NULL)
\r
989 M_DEBUG("Failed to allocate memory for CA GUID table\n");
\r
993 ib_status = ib_get_ca_guids (*m_mf.ph_al, m_mf.ca_guid, &m_mf.ca_guids_count );
\r
994 if (ib_status != IB_SUCCESS)
\r
996 M_DEBUG("Failed to get CA GUIDs\n");
\r
1000 ib_status = ib_open_ca( *m_mf.ph_al, m_mf.ca_guid[0], NULL, &m_mf, m_mf.ph_ca );
\r
1001 if (ib_status != IB_SUCCESS)
\r
1003 M_DEBUG("Failed to open CA\n");
\r
1010 #define STR_LEN 128
\r
1011 void printPercent(const uint32_t percent, const uint32_t reset)
\r
1013 #define PRECISION 2
\r
1014 #define NO_OF_PARTS (100 / (PRECISION))
\r
1015 /*"12345678901234567890123456789012345678901234567890"*/
\r
1016 char markerBar[NO_OF_PARTS+1] = " ";
\r
1017 static uint32_t prevNoOfXs = 0;
\r
1018 uint32_t noOfXs = 0;
\r
1020 char str[STR_LEN];
\r
1021 cl_memset(str,0,STR_LEN);
\r
1023 markerBar[NO_OF_PARTS+1] = '\0';
\r
1027 sprintf(str,"|%s| %3d%%", markerBar, percent);
\r
1032 noOfXs = percent / PRECISION;
\r
1033 for (x = 0; x < NO_OF_PARTS; x++)
\r
1036 markerBar[x] = '*';
\r
1038 if (noOfXs>prevNoOfXs)
\r
1040 sprintf(str,"|%s| %3d%%", markerBar, percent);
\r
1041 //printf("|%s| %3d%%", markerBar, percent);
\r
1042 prevNoOfXs = noOfXs;
\r
1045 printf("\r%s",str);
\r
1049 void printStatus(const uint32_t status)
\r
1051 printf("[%s]\n",((status == 0)?"SUCCESS":"FAILED"));
\r
1054 ////////////////////////////////////////////////////////////////////////
\r
1055 bool Flash::write_image(uint32_t addr, void *data, uint32_t cnt, bool eraseInvariant, bool report)
\r
1057 uint8_t *p = (uint8_t *)data;
\r
1058 uint32_t curr_addr = addr;
\r
1059 uint32_t towrite = cnt;
\r
1060 uint32_t perc = 0xffffffff;
\r
1061 bool noerase = false;
\r
1063 curr_sector = 0xffffffff; // Erase sector first time
\r
1066 printf("writing: ");
\r
1067 printPercent(0,1);
\r
1074 uint32_t trans = (towrite > (uint32_t)TRANS) ? (uint32_t)TRANS : towrite;
\r
1076 if (eraseInvariant)
\r
1081 if (curr_addr < SECT_SIZE)
\r
1092 if (!write(curr_addr, p, trans, noerase, true))
\r
1099 curr_addr += trans;
\r
1105 uint32_t new_perc = ((cnt - towrite) * 100) / cnt;
\r
1106 if (new_perc != perc)
\r
1108 printPercent(new_perc,0);
\r
1117 printPercent(100,0);
\r
1123 } // Flash::write_image
\r
1128 for read - data return in native Endian mode,
\r
1129 for write - data should be written in BigEndian mode
\r
1130 check where data is actually converted !!!!
\r
1132 ib_api_status_t Flash::access(hca_dev_t *dev, u_int32_t offset, void *p_data, uint32_t length, uint32_t operation )
\r
1136 ib_api_status_t ib_status;
\r
1141 ci_op.buf_size = length;
\r
1142 ci_op.p_buf = p_data;
\r
1143 ci_op.buf_info = offset;
\r
1144 ci_op.num_bytes_ret = sizeof (ib_ci_op_t);
\r
1145 ci_op.command = operation;
\r
1147 ib_status = ib_ci_call (m_mf.h_ca, NULL, 0, &ci_op);
\r
1149 if ( ib_status != IB_SUCCESS )
\r
1151 FW_TRACE (FW_DBG_ERROR,("Failed ib_ci_call return status %#x\n", ib_status ));
\r
1154 return IB_SUCCESS;
\r
1157 bool getGUIDsFromFlash(FBase &device, uint64_t guids[GUIDS])
\r
1159 uint32_t NODE_GUIDH, NODE_GUIDL;
\r
1160 uint32_t PORT1_GUIDH, PORT1_GUIDL;
\r
1161 uint32_t PORT2_GUIDH, PORT2_GUIDL;
\r
1162 uint32_t prim_ptr;
\r
1163 uint32_t signature;
\r
1165 bool isFailSafe = false;
\r
1167 READ4(device, 0x24, &signature, "Signature");
\r
1168 TOCPU1(signature);
\r
1170 if (signature == SIGNATURE)
\r
1172 // Fail Safe image
\r
1174 // Assume flash has been verified, and both images have the same guids, therefore,
\r
1175 // we only need to read the primary image's guids
\r
1176 device.read(SECT_SIZE, &ps, sizeof(ps));
\r
1177 TOCPUBY(ps,sizeof(ps));
\r
1178 READ4(device, ps.fi_addr+0x24, &prim_ptr, "Primary Section");
\r
1179 M_DEBUG("Firmware Address : 0x%"PRIx32"\n", ps.fi_addr);
\r
1180 M_DEBUG("Node GUID Offset : 0x%"PRIx32"\n", prim_ptr);
\r
1181 prim_ptr = BE2CPU32(prim_ptr)+ps.fi_addr;
\r
1182 isFailSafe = true;
\r
1187 prim_ptr = signature;
\r
1190 printf("Found valid GUID pointer : %08"PRIx32"\n", prim_ptr);
\r
1191 if (prim_ptr < MST_MAX_FLASH || isFailSafe)
\r
1193 READ4(device, prim_ptr, &NODE_GUIDH, "Node GUID High");
\r
1194 READ4(device, prim_ptr+4, &NODE_GUIDL, "Node GUID Low");
\r
1195 guids[0] = BE2CPU32(NODE_GUIDH);
\r
1196 guids[0] = (guids[0]<<32) | BE2CPU32(NODE_GUIDL);
\r
1197 READ4(device, prim_ptr+8, &PORT1_GUIDH, "Port 1 GUID High");
\r
1198 READ4(device, prim_ptr+12, &PORT1_GUIDL, "Port 1 GUID Low");
\r
1199 guids[1] = BE2CPU32(PORT1_GUIDH);
\r
1200 guids[1] = (guids[1]<<32) | BE2CPU32(PORT1_GUIDL);
\r
1201 READ4(device, prim_ptr+16, &PORT2_GUIDH, "Port 2 GUID High");
\r
1202 READ4(device, prim_ptr+20, &PORT2_GUIDL, "Port 2 GUID Low");
\r
1203 guids[2] = BE2CPU32(PORT2_GUIDH);
\r
1204 guids[2] = (guids[2]<<32) | BE2CPU32(PORT2_GUIDL);
\r
1206 guids[3] = guids[0];
\r
1207 printf("Found device's existing GUIDs:\n");
\r
1208 printf("Node GUID : 0x%016"PRIx64"\n", guids[0]);
\r
1209 printf("Port1 GUID : 0x%016"PRIx64"\n", guids[1]);
\r
1210 printf("Port2 GUID : 0x%016"PRIx64"\n", guids[2]);
\r
1213 printf("Found an invalid GUID pointer!\n");
\r
1220 bool getGUIDs(char *guidString, uint64_t guids[GUIDS])
\r
1222 uint32_t PORT1_GUIDH, PORT1_GUIDL;
\r
1223 uint32_t PORT2_GUIDH, PORT2_GUIDL;
\r
1224 uint64_t GUID; //strtoull(guidString, (char **)NULL, 0);
\r
1225 uint32_t NODE_GUIDH;
\r
1226 uint32_t NODE_GUIDL;
\r
1228 if (!getGUID(guidString, &GUID))
\r
1233 NODE_GUIDH = (uint32_t)(GUID >> 32);
\r
1234 NODE_GUIDL = (uint32_t)GUID;
\r
1236 if ((NODE_GUIDH & 0xffffffff) == 0x00066a00
\r
1237 && ((NODE_GUIDL & 0xf8000000) == 0x98000000
\r
1238 || (NODE_GUIDL & 0xf8000000) == 0xb0000000))
\r
1240 // Always make it a InfiniCon NODE GUID
\r
1241 NODE_GUIDL = (NODE_GUIDL & 0x0FFFFFFF) | 0x98000000;
\r
1243 // Convert to the InfiniCon Node Guid Convention.
\r
1244 PORT1_GUIDH = NODE_GUIDH;
\r
1245 PORT1_GUIDL = (NODE_GUIDL & 0x07ffffff) | 0xa0000000;
\r
1246 PORT2_GUIDH = NODE_GUIDH | 1;
\r
1247 PORT2_GUIDL = (NODE_GUIDL & 0x07ffffff) | 0xa0000000;
\r
1249 // Treat everything else as a Mellanox Node Guid Convention.
\r
1250 PORT1_GUIDH=NODE_GUIDH;
\r
1251 PORT1_GUIDL=NODE_GUIDL+1;
\r
1252 if ( PORT1_GUIDL==0 ) {
\r
1255 PORT2_GUIDH=PORT1_GUIDH;
\r
1256 PORT2_GUIDL=PORT1_GUIDL+1;
\r
1257 if ( PORT2_GUIDL==0 ) {
\r
1262 guids[0] = NODE_GUIDH;
\r
1263 guids[0] = (guids[0]<<32) | NODE_GUIDL;
\r
1265 guids[1] = PORT1_GUIDH;
\r
1266 guids[1] = (guids[1]<<32) | PORT1_GUIDL;
\r
1268 guids[2] = PORT2_GUIDH;
\r
1269 guids[2] = (guids[2]<<32) | PORT2_GUIDL;
\r
1271 guids[3] = guids[0];
\r
1273 printf("Using user specified GUIDs :\n");
\r
1274 printf("Node GUID : 0x%016"PRIx64"\n", guids[0]);
\r
1275 printf("Port 1 GUID : 0x%016"PRIx64"\n", guids[1]);
\r
1276 printf("Port 2 GUID : 0x%016"PRIx64"\n", guids[2]);
\r
1280 bool _silent = false;
\r
1281 #define report printf
\r
1283 ////////////////////////////////////////////////////////////////////////
\r
1284 bool isInvariantSectionEqual(FBase& f1, FBase& f2)
\r
1288 uint32_t beg = 0x0;
\r
1289 uint32_t offs = 0x28;
\r
1290 const char* pr = "isInvariantSectionEqual";
\r
1293 bool status = true;
\r
1296 READ4(f1, offs+beg+4, &size1, pr);
\r
1297 READ4(f2, offs+beg+4, &size2, pr);
\r
1301 // M_DEBUG("Invariant sector size1: %"PRId32"\n", size1);
\r
1302 // M_DEBUG("Invariant sector size2: %"PRId32"\n", size2);
\r
1304 if (size1 != size2)
\r
1306 M_DEBUG("Invariant sector sizes do not match.\n");
\r
1310 buf1 = (uint32_t *)cl_zalloc((size1+4)*4);
\r
1313 cl_dbg_out("Failed to allocate memory size =%d", size1+4 );
\r
1316 buf2 = (uint32_t *)cl_zalloc( (size2+4)*4);
\r
1320 cl_dbg_out("Failed to allocate memory size =%d", size2+4 );
\r
1324 READBUF(f1, offs+beg, buf1, (size1+4)*4, pr);
\r
1325 READBUF(f2, offs+beg, buf2, (size2+4)*4, pr);
\r
1327 if ( cl_memcmp(buf1, buf2, (size1+4)*4) )
\r
1329 // M_DEBUG("Invariant sections are not equal.\n");
\r
1335 } // isInvariantSectionEqual
\r
1337 ////////////////////////////////////////////////////////////////////////
\r
1338 bool checkBoot2(FBase& f, uint32_t beg, uint32_t offs, uint32_t& next, const char *pref)
\r
1343 uint32_t *safe_buf;
\r
1344 //sprintf(pr, "%s /0x%08"PRIx32"/ (BOOT2)", pref, offs+beg);
\r
1347 READ4(f, offs+beg+4, &size, pr);
\r
1350 if (size > 1048576 || size < 4)
\r
1352 report("%s /0x%08"PRIx32"/ - unexpected size (0x%x)\n", pr, offs+beg+4, size);
\r
1356 //sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (BOOT2)", pref, offs+beg, offs+beg+(size+4)*4-1, (size+4)*4);
\r
1360 buff = (uint32_t*)cl_zalloc((size+4)*4);
\r
1363 READBUF(f, offs+beg, buff, (size+4)*4, pr);
\r
1364 TOCPU(buff, (size+4)*4 );
\r
1365 CRC1(crc, buff, (size+4)*4 );
\r
1367 uint32_t crc_act = *(buff+size+3);
\r
1368 if (crc.get() != crc_act)
\r
1370 report("%s /0x%08"PRIx32"/ - wrong CRC (exp:0x%x, act:0x%x)\n",
\r
1371 pr, offs+beg, crc.get(), crc_act);
\r
1372 cl_free(safe_buf);
\r
1376 //report("%s - OK\n", pr);
\r
1377 next = offs + (size+4)*4;
\r
1378 cl_free(safe_buf);
\r
1382 static uint32_t part_cnt;
\r
1384 ////////////////////////////////////////////////////////////////////////
\r
1385 bool checkGen(FBase& f, uint32_t beg,
\r
1386 uint32_t offs, uint32_t& next, const char *pref)
\r
1391 cl_memset(pr,0,1024);
\r
1393 sprintf(pr, "%s /0x%08"PRIx32"/ (GeneralHeader)", pref, offs+beg);
\r
1394 READBUF(f, offs+beg, &gph, sizeof(GPH), pr);
\r
1395 TOCPUBY(gph, sizeof(GPH));
\r
1402 if (gph.type < H_FIRST || gph.type > H_LAST)
\r
1406 report("%s /0x%"PRIx32"/ - Invalid partition type (%"PRIx32")\n",
\r
1407 pref, offs+beg, gph.type);
\r
1411 return checkBoot2(f, beg, offs, next, pref);
\r
1414 // All partitions here
\r
1419 size = gph.size * sizeof(uint32_t);
\r
1420 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (DDR)",
\r
1421 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1424 size = gph.size * sizeof(uint32_t);
\r
1425 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (Configuration)",
\r
1426 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1429 size = gph.size * sizeof(uint32_t);
\r
1430 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (Jump addresses)",
\r
1431 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1435 size = (size + 3) / 4 * 4;
\r
1436 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (EMT Service)",
\r
1437 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1440 size = gph.size * sizeof(uint32_t);
\r
1441 sprintf(pr, "%s /0x%08x-0x%08x (0x%06x)/ (FW Configuration)",
\r
1442 pref, offs, offs+size+(uint32_t)sizeof(gph)+3,
\r
1443 size+(uint32_t)sizeof(gph)+4);
\r
1446 size = gph.size * sizeof(uint32_t);
\r
1447 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (ROM)",
\r
1448 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1451 size = gph.size * sizeof(uint32_t);
\r
1452 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (GUID)",
\r
1453 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1456 size = gph.size * sizeof(uint32_t);
\r
1457 sprintf(pr, "%s /0x%08x-0x%08x (0x%06x)/ (User Data)",
\r
1458 pref, offs, offs+size+(uint32_t)sizeof(gph)+3,
\r
1459 size+(uint32_t)sizeof(gph)+4);
\r
1462 size = gph.size * sizeof(uint32_t);
\r
1463 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (Board ID)",
\r
1464 pref, offs, offs+size+(unsigned)sizeof(gph)+3,size+(u_int32_t)sizeof(gph)+4);
\r
1467 // For forward compatibility, try analyzing even if section type is uncknown
\r
1468 // Assuming the size is in DW, like all other sections (except emt service).
\r
1469 // If this assumption is wrong, CRC calc would fail - no harm done.
\r
1470 size = gph.size * sizeof(uint32_t);
\r
1471 sprintf(pr, "%s /0x%08x-0x%08x (0x%06x)/ (UNKNOWN SECTION TYPE (%d))",
\r
1472 pref, offs, offs+size+(uint32_t)sizeof(gph)+3,
\r
1473 size+(uint32_t)sizeof(gph)+4, gph.type);
\r
1479 buff = (uint32_t*)cl_zalloc(size);
\r
1480 READBUF(f, offs+sizeof(gph), buff, size, pr);
\r
1482 CRCBY(crc, gph, sizeof(GPH));
\r
1483 CRC(crc, buff,size);
\r
1486 READ4(f, offs+sizeof(gph)+size, &crc_act, pr);
\r
1488 if (crc.get() != crc_act)
\r
1490 report("%s /0x%08"PRIx32"/ - wrong CRC (exp:0x%x, act:0x%x)\n",
\r
1491 pr, offs, crc.get(), crc_act);
\r
1496 report("%s - OK\n", pr);
\r
1502 ////////////////////////////////////////////////////////////////////////
\r
1503 bool checkPS(FBase& f, uint32_t offs, uint32_t& next, const char *pref)
\r
1507 f.read(offs, &ps, sizeof(ps));
\r
1508 TOCPUBY(ps, sizeof(ps));
\r
1511 if (ps.signature != SIGNATURE)
\r
1513 report("%s Pointer Sector /0x%08"PRIx32"/ - wrong signature (%08"PRIx32")\n",
\r
1514 pref, offs, ps.signature);
\r
1519 CRC1BY(crc, ps, sizeof(PS));
\r
1521 if (crc.get() != ps.crc016)
\r
1523 report("%s Pointer Sector /0x%08"PRIx32"/ - wrong CRC (exp:0x%"PRIx32", act:0x%x)\n",
\r
1524 pref, offs, ps.crc016, crc.get());
\r
1528 next = ps.fi_addr;
\r
1529 report("%s Image /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ - OK\n", pref, offs,
\r
1530 offs+(unsigned)sizeof(ps)-1, (unsigned)sizeof(ps));
\r
1534 ////////////////////////////////////////////////////////////////////////
\r
1535 bool checkList(FBase& f, uint32_t offs, const char *pref)
\r
1537 uint32_t next_ptr;
\r
1539 CHECKB2(f, offs, 0x28, next_ptr, pref);
\r
1541 while (next_ptr && next_ptr != 0xff000000)
\r
1542 CHECKGN(f, offs, next_ptr, next_ptr, pref);
\r
1546 ////////////////////////////////////////////////////////////////////////
\r
1547 bool FBase::verify()
\r
1549 uint32_t prim_ptr, scnd_ptr;
\r
1550 uint32_t signature;
\r
1552 READ4((*this), 0x24, &signature, "Signature");
\r
1553 TOCPU1(signature);
\r
1554 if (signature == SIGNATURE)
\r
1557 report("\nFailsafe image:\n\n");
\r
1558 CHECKB2((*this), 0, 0x28, prim_ptr, "Invariant ");
\r
1560 if (checkPS((*this), SECT_SIZE, prim_ptr, "Primary "))
\r
1561 CHECKLS((*this), prim_ptr, " ");
\r
1563 if (checkPS((*this), SECT_SIZE * 2, scnd_ptr, "Secondary"))
\r
1564 CHECKLS((*this), scnd_ptr, " ");
\r
1569 report("\nShort image:\n");
\r
1570 CHECKLS((*this), 0, " ");
\r
1577 ////////////////////////////////////////////////////////////////////////
\r
1579 // ****************************************************************** //
\r
1580 // GUIDs TREATMENT //
\r
1581 // ****************************************************************** //
\r
1583 ////////////////////////////////////////////////////////////////////////
\r
1584 #define GETGUID(s, g) do { if (!getGUID(s,g)) return 1; } while (0)
\r
1585 #define GETBSN(s, g) do { if (!getBSN(s,g)) return 1; } while (0)
\r
1587 #define BSN_RET do { \
\r
1588 printf("Invalid BSN. Should be MTxxxxxRddmmyy-nnn[-cc]\n"); \
\r
1591 #define BSN_RET1(s) do { \
\r
1592 printf("Valid BSN format is: MTxxxxxRddmmyy-nnn[-cc]\n%s.\n",s); \
\r
1595 uint32_t BSN_subfield(const char *s, uint32_t beg, uint32_t len)
\r
1598 strncpy(buf, &s[beg], len);
\r
1600 return strtoul(&buf[0], 0, 10);
\r
1602 bool getBSN(char *s, uint64_t *guid)
\r
1604 const uint64_t COMPANY_ID = 0x0002c9;
\r
1605 const uint64_t TYPE = 1;
\r
1606 bool cc_present = false;
\r
1610 // Convert to lowercase
\r
1611 for (p = s; *p; p++)
\r
1612 *p = (char)tolower(*p);
\r
1616 if (strncmp(p, "mt", 2)) // MT
\r
1619 for (i=0; i<5; i++)
\r
1620 if (!isdigit(*p++)) // xxxxx
\r
1622 if (*p < 'a' || *p > 'z') // R
\r
1625 for (i=0; i<6; i++) // ddmmyy
\r
1626 if (!isdigit(*p++))
\r
1628 if (*p++ != '-') // -
\r
1630 for (i=0; i<3; i++) // nnn
\r
1631 if (!isdigit(*p++))
\r
1635 cc_present = true;
\r
1636 if (*p++ != '-') // -
\r
1638 for (i=0; i<2; i++) // cc
\r
1639 if (!isdigit(*p++))
\r
1643 uint32_t dd = BSN_subfield(s, 8, 2);
\r
1645 BSN_RET1("Day (dd) should not exceed 31");
\r
1647 BSN_RET1("Day (dd) can't be zero");
\r
1648 uint32_t mm = BSN_subfield(s, 10, 2);
\r
1650 BSN_RET1("Months (mm) should not exceed 12");
\r
1652 BSN_RET1("Months (mm) can't be zero");
\r
1653 uint32_t yy = BSN_subfield(s, 12, 2);
\r
1655 BSN_RET1("Year (yy) should not exceed 99");
\r
1657 BSN_RET1("Year (yy) can't be zero");
\r
1658 uint32_t num = BSN_subfield(s, 15, 3);
\r
1660 BSN_RET1("Number (num) should not exceed 999");
\r
1662 BSN_RET1("Number (num) can't be zero");
\r
1666 cc = BSN_subfield(s, 19, 2);
\r
1668 BSN_RET1("Chip number (cc) should not exceed 14");
\r
1670 BSN_RET1("Chip number (cc) can't be zero");
\r
1672 uint64_t id = ((((yy*12+mm-1)*31+ dd-1) * 1000) + num-1) * 112;
\r
1674 *guid = (COMPANY_ID << 40) | (TYPE << 32) | id;
\r
1678 bool getGUID(const char *s, uint64_t *guid)
\r
1680 char str[17], *endp;
\r
1683 memset(str, '0', 15);
\r
1686 for (i=(int)strlen(s)-1,j=15;i >= 0 && j >= 0 ; i-- )
\r
1688 if (isxdigit(s[i]))
\r
1691 l = strtoul(&str[8], &endp, 16);
\r
1694 printf("Invalid GUID syntax (%s)\n", &str[8]);
\r
1698 h = strtoul(&str[0], &endp, 16);
\r
1701 printf("Invalid GUID syntax (%s)\n", str);
\r
1704 *guid = ((uint64_t)h << 32) | l;
\r
1708 ////////////////////////////////////////////////////////////////////////
\r
1709 bool extractGUIDptr(uint32_t sign, uint32_t *buf, uint32_t buf_len,
\r
1710 char *pref, uint32_t *ind, uint32_t *nguids)
\r
1712 uint32_t offs = 0;
\r
1714 // Check signature
\r
1717 uint32_t signature = buf[(sign + 8)/4];
\r
1718 TOCPU1(signature);
\r
1719 if (signature != SIGNATURE)
\r
1721 printf("%s pointer section not valid\n", pref);
\r
1724 offs = buf[sign/4];
\r
1729 *ind = buf[(offs+0x24)/4];
\r
1732 if (*ind >= (uint32_t)buf_len)
\r
1734 printf("%s image - insane GUID pointer (%08"PRIx32")\n", pref, *ind);
\r
1737 *nguids = buf[*ind/4 - 3];
\r
1741 // More sanity check
\r
1742 if (*nguids > GUIDS)
\r
1744 printf("%s image - insane number of GUIDs (%d)\n", pref, *nguids);
\r
1749 } // extractGUIDptr
\r
1751 ////////////////////////////////////////////////////////////////////////
\r
1752 void patchGUIDsSection(
\r
1755 uint64_t guids[GUIDS],
\r
1759 uint32_t new_buf[GUIDS*2];
\r
1762 // Form new GUID section
\r
1763 for (i=0; i<(uint32_t)nguids; i++)
\r
1765 new_buf[i*2] = (uint32_t)(guids[i] >> 32);
\r
1766 new_buf[i*2+1] = (uint32_t)(guids[i] & 0xffffffff);
\r
1769 // Calculate new CRC16
\r
1770 for (i=ind/4 - 4; i<ind/4; i++)
\r
1776 for (i=0; i<(uint32_t)nguids*2; i++)
\r
1777 crc << new_buf[i];
\r
1780 TOCPU(new_buf,GUIDS*2*4);
\r
1781 memcpy(&buf[ind/4], &new_buf[0], nguids * 2 * sizeof(uint32_t));
\r
1787 buf[ind/4 + nguids*2] = word;
\r
1788 } // patchGUIDsSection
\r
1790 ////////////////////////////////////////////////////////////////////////
\r
1791 bool patchGUIDs(FImage& f, uint64_t guids[GUIDS],
\r
1794 uint64_t old_guids[GUIDS];
\r
1795 uint32_t *buf = f.getBuf();
\r
1796 uint32_t buf_len = f.getBufLength();
\r
1797 uint32_t signature = buf[0x24/4];
\r
1798 uint32_t ind1=0,ind2=0;
\r
1799 uint32_t nguid1, nguid2;
\r
1801 TOCPU1(signature);
\r
1802 if (signature == SIGNATURE)
\r
1805 M_DEBUG("Extracting GUIDs from PPS : ");
\r
1806 if (!extractGUIDptr(SECT_SIZE, buf, buf_len, "Primary", &ind1, &nguid1))
\r
1808 M_DEBUG("Failed\n");
\r
1812 M_DEBUG("[SUCCESS]\n");
\r
1814 M_DEBUG("Extracting GUIDs from SPS : ");
\r
1815 if (!extractGUIDptr(SECT_SIZE*2, buf, buf_len, "Secondary", &ind2,
\r
1818 M_DEBUG("Failed\n");
\r
1821 M_DEBUG("[SUCCESS]\n");
\r
1826 M_DEBUG("Extracting GUIDs from PS : ");
\r
1827 if (!extractGUIDptr(0, buf, buf_len, "Primary", &ind1, &nguid1))
\r
1829 M_DEBUG("Failed\n");
\r
1833 M_DEBUG("[SUCCESS]\n");
\r
1836 // Print old GUIDs and get confirmation
\r
1839 bool old_guids_fmt = nguid1 < GUIDS;
\r
1840 for (uint32_t i=0; i<GUIDS; i++)
\r
1842 uint32_t h = buf[ind1/4 + i*2];
\r
1844 uint32_t l = buf[ind1/4 + i*2 + 1];
\r
1846 old_guids[i] = ((uint64_t)h << 32) | l;
\r
1848 if ( !(old_guids[0] == guids[0]) || !(old_guids[1] == guids[1]) || !(old_guids[2] == guids[2]))
\r
1850 if (old_guids_fmt)
\r
1851 printf(" Old image!!!! Only %d GUIDs may be set.\n", nguid1);
\r
1852 printf(" Old GUIDs (inside image) are:\n");
\r
1853 printf(" Node: %016"PRIx64"\n", old_guids[0]);
\r
1854 printf(" Port1: %016"PRIx64"\n", old_guids[1]);
\r
1855 printf(" Port2: %016"PRIx64"\n", old_guids[2]);
\r
1856 if (!old_guids_fmt)
\r
1857 printf(" Sys.Image: %016"PRIx64"\n", old_guids[3]);
\r
1858 printf("\n You are about to change them to the following GUIDs:\n");
\r
1859 printf(" Node: %016"PRIx64"\n", guids[0]);
\r
1860 printf(" Port1: %016"PRIx64"\n", guids[1]);
\r
1861 printf(" Port2: %016"PRIx64"\n", guids[2]);
\r
1862 if (!old_guids_fmt)
\r
1863 printf(" Sys.Image: %016"PRIx64"\n", guids[3]);
\r
1864 printf("\n Is it OK ? (y/n) [n] : ");
\r
1866 char c = (char)getchar();
\r
1868 while (getchar() != '\n');
\r
1874 // Path GUIDs section
\r
1875 patchGUIDsSection(buf, ind1, guids, nguid1);
\r
1877 M_DEBUG("Inserting GUIDs into PPS : [SUCCESS]\n");
\r
1881 M_DEBUG("Inserting GUIDs into SPS : [SUCCESS]\n");
\r
1882 patchGUIDsSection(buf, ind2, guids, nguid2);
\r
1888 void patchVSDSection(
\r
1889 uint32_t *buffer,
\r
1890 uint32_t pointerSectorOffset,
\r
1891 uint32_t companyid,
\r
1895 uint32_t i, x, word, offset=0;
\r
1896 uint32_t newbuffer[sizeof(PS)];
\r
1900 memcpy(newbuffer, (buffer+pointerSectorOffset/sizeof(uint32_t)), sizeof(PS));
\r
1902 memcpy(&ps, newbuffer, sizeof(PS));
\r
1903 ps.vsd[0] = __cpu_to_be32(companyid);
\r
1904 // Currently time_t is 32 bits, but this will only last until the
\r
1905 // year 2037. Therefore, I am leaving 64bits for when the time_t
\r
1906 // size is increased which will probably provide an Epoch time far larger
\r
1907 // than man will exist. Note: Although, I have provided the space for a
\r
1908 // larger time_t this code will need to be modified to handle the 64bit
\r
1909 // Epoch time before 2037.
\r
1911 *((uint64_t*)&ps.vsd[1]) = cl_ntoh64(timestamp);
\r
1913 ps.vsd[1] = (uint32_t)0;
\r
1914 ps.vsd[2] = __cpu_to_be32(timestamp);
\r
1917 if (NULL != revision)
\r
1921 memcpy(&ps.vsd[x], revision+offset, sizeof(uint32_t));
\r
1922 ps.vsd[x] = __cpu_to_be32(ps.vsd[x]);
\r
1923 offset = offset + 4;
\r
1926 memcpy(newbuffer, &ps, sizeof(PS));
\r
1928 // Calculate new CRC16
\r
1929 for (i=0; i<((sizeof(PS)/sizeof(uint32_t))-1); i++)
\r
1931 word = newbuffer[i];
\r
1941 memcpy(newbuffer, &ps, sizeof(PS));
\r
1942 // patch VSD in buffer
\r
1943 memcpy(buffer+pointerSectorOffset/sizeof(uint32_t), newbuffer, sizeof(PS));
\r
1945 } // patchGUIDsSection
\r
1947 bool patchVSDs(FImage &image, char *revision)
\r
1949 uint32_t signature;
\r
1950 uint32_t companyid = 0x0000066A; // InfiniCon
\r
1952 READ4(image, 0x24, &signature, "Signature");
\r
1953 TOCPU1(signature);
\r
1955 if (signature == SIGNATURE)
\r
1959 etime = time(NULL);
\r
1961 (device.getClassType()==Flash::FlashDeviceType?"Burn Date : ":"Creation : "),
\r
1962 asctime(localtime(&etime)));
\r
1963 patchVSDSection(image.getBuf(), SECT_SIZE , companyid, etime, revision);
\r
1964 patchVSDSection(image.getBuf(), SECT_SIZE*2, companyid, etime, revision);
\r
1969 //printf("Can not inject VSD into a Short Image.\n");
\r
1974 bool burnImageToFlash(FlashCommandLine cl)
\r
1977 uint64_t guids[GUIDS];
\r
1978 bool insertGUIDs = false;
\r
1979 uint32_t Fhardwareversion=0;
\r
1980 uint32_t Ihardwareversion=0;
\r
1981 uint32_t Fsignature=0;
\r
1982 uint32_t Isignature=0;
\r
1984 if (!device.open(cl.getDeviceName()))
\r
1986 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
1990 // We are always able to get the revision from the pci bus.
\r
1991 device.read(0x10, &Fhardwareversion, sizeof(Fhardwareversion));
\r
1992 TOCPU1(Fhardwareversion);
\r
1993 Fhardwareversion >>=24;
\r
1995 if (Fhardwareversion > 0xA0)
\r
1997 device.read(0x24, &Fsignature, sizeof(Fsignature));
\r
1998 TOCPU1(Fsignature);
\r
2001 if (!cl.isOption(FlashCommandLine::force))
\r
2003 if (Fhardwareversion != 0xA1 && Fhardwareversion != 0xA0)
\r
2005 printf("!!!WARNING!!!\n"
\r
2006 "Unable to determine the device\'s %s firmware revision (unknown rev %x)!\n"
\r
2007 "It could be a corrupted firmware or an unsupported board revision.\n"
\r
2009 "Aborting operation.\n",
\r
2010 cl.getDeviceName(),
\r
2012 techSupportMessage);
\r
2017 printf("!!!WARNING!!! Skipping flash device hardware revision integrity check.\n");
\r
2020 M_DEBUG("Open raw file.\n");
\r
2022 if (!image.open(cl.getRawFileName()))
\r
2024 printf("Error: %s %s\n", image._err, cl.getRawFileName());
\r
2028 M_DEBUG("Verify raw file.\n");
\r
2031 if (!image.verify())
\r
2033 printf("%s is not a valid image\n", cl.getRawFileName());
\r
2037 image.read(0x24, &Isignature);
\r
2038 TOCPU1(Isignature);
\r
2040 image.read(0x10, &Ihardwareversion, sizeof(Ihardwareversion));
\r
2041 TOCPU1(Ihardwareversion);
\r
2042 Ihardwareversion >>=24;
\r
2044 M_DEBUG("Verify hardware and signature information.\n");
\r
2046 if (!cl.isOption(FlashCommandLine::force))
\r
2048 if (Ihardwareversion != 0xA1 && Ihardwareversion != 0xA0)
\r
2050 printf("!!!WARNING!!!\n"
\r
2051 "Unable to determine the image\'s %s firmware revision (unknown rev %x)!\n"
\r
2052 "It could be a corrupted image or an unsupported board revision.\n"
\r
2054 "Aborting operation.\n",
\r
2055 cl.getDeviceName(),
\r
2057 techSupportMessage);
\r
2060 else if (Fhardwareversion != Ihardwareversion)
\r
2062 printf("!!!WARNING!!! "
\r
2063 "An HCA Rev %X firmware can not be used with HCA Rev %X device!!!\n"
\r
2064 "Aborting operation.\n",
\r
2066 Fhardwareversion);
\r
2070 if (Fhardwareversion == 0xA0)
\r
2072 if (Isignature == SIGNATURE)
\r
2074 printf("!!!WARNING!!! "
\r
2075 "Rev A0 HCA's will not work with a fail safe image!!!\n"
\r
2077 "Aborting operation.\n", techSupportMessage);
\r
2084 printf("!!!DANGER!!!! Skipping image file hardware revision integrity check.\n");
\r
2087 printf("HCA Rev : %"PRIX32"\n", Fhardwareversion);
\r
2088 printf("Image Rev : %"PRIX32"\n", Ihardwareversion);
\r
2090 if (!cl.useFlashNodeGUID())
\r
2091 { // the user specified the guid at the command line
\r
2092 if (!getGUIDs(cl.getNodeGUID(),guids))
\r
2094 printf("Aborting burn operation.\n");
\r
2098 insertGUIDs = true;
\r
2101 // should we query the flash device for the guids
\r
2102 // If we don't query the flash for the guids, and
\r
2103 // we don't specify the guids at the command line
\r
2104 // then we will use the guids supplied in the raw
\r
2106 M_DEBUG("Query the flash device\n");
\r
2107 if (!cl.isOption(FlashCommandLine::noquery))
\r
2109 // obtain the guids from the flash
\r
2110 if (!getGUIDsFromFlash(device, guids))
\r
2112 printf("The image on the flash device appears corrupted!\n"
\r
2113 "Unable to determine the GUIDs from the flash device %s.\n"
\r
2114 "Try the -n <0xGUID> option. If this fails, then contact\n"
\r
2115 "SilverStorm Technologies technical support.\n",
\r
2116 cl.getDeviceName());
\r
2120 insertGUIDs = true;
\r
2126 if (cl.isOption(FlashCommandLine::no_prompts))
\r
2128 interactive=false;
\r
2132 interactive = (_isatty(_fileno( stdin )) > 0 ? true: false);
\r
2135 bool eraseInvariant = false;
\r
2137 if (cl.isOption(FlashCommandLine::burn_invariant_section))
\r
2139 M_DEBUG("Always burn invariant section.\n");
\r
2140 eraseInvariant = true;
\r
2141 } else // only burn the invariant section if it differs
\r
2143 if (isInvariantSectionEqual(device, image))
\r
2145 M_DEBUG("The invariant sections are equal.\n");
\r
2146 eraseInvariant = false;
\r
2149 M_DEBUG("The invariant sections differ.\n");
\r
2150 eraseInvariant = true;
\r
2154 M_DEBUG("Patch GUIDs.\n");
\r
2157 if (insertGUIDs && !patchGUIDs(image, guids, interactive))
\r
2159 printf("Aborting burn operation at user request.\n");
\r
2163 M_DEBUG("Patch VSDs.\n");
\r
2166 if (!patchVSDs(image, NULL))
\r
2168 // if this fails it means it's a short image, and we should just continue on
\r
2171 M_DEBUG("Write firmware.\n");
\r
2174 if (!device.write_image(0, image.getBuf(), image.getBufLength(), eraseInvariant, (_isatty(_fileno( stdin )) > 0? true: false)) )
\r
2176 printf("Error: %s\n", device._err);
\r
2186 bool patchVSDToRawImage(FlashCommandLine cl)
\r
2188 printf("Attempting to insert VSD section into the %s file: \n", cl.getRawFileName());
\r
2190 if (!image.open(cl.getRawFileName()))
\r
2192 printf("Error: %s\n", image._err);
\r
2193 printf("Aborting operation.\n");
\r
2197 if (!patchVSDs(image, cl.getRevisionString()))
\r
2199 printf("Failed.\n"
\r
2201 "Unable to inject the VSD into a Short Image.\n"
\r
2202 "Short images do not support the VSD section.\n"
\r
2203 "Only Fail Safe images support the VSD section.\n"
\r
2204 "Aborting operation.\n");
\r
2209 void *write_buffer;
\r
2210 uint32_t buflen = image.getBufLength();
\r
2212 // it is necessary to close the file prior to re-opening for write privileges
\r
2213 // this allows us to write to the same file without using a temporary file
\r
2214 write_buffer = malloc(buflen);
\r
2215 memcpy(write_buffer, image.getBuf(), buflen);
\r
2218 // only open the file, if any things fails, then the image verify
\r
2219 // will indicate issues
\r
2220 if ((fd = fopen(cl.getRawFileName(),"w")) != NULL)
\r
2222 fwrite(write_buffer, buflen, 1, fd);
\r
2226 printf("Failed.\n"
\r
2227 "Unable to write to raw image file %s.\n", cl.getRawFileName());
\r
2229 if (!image.verify()) // verify file integrity
\r
2231 printf("!!!WARNING!!! "
\r
2232 "The file appears to have been corrupted!!!\n");
\r
2236 printf("File appears to be valid, but the VSD injection failed.\n");
\r
2243 // ok to free the buffer now
\r
2244 free(write_buffer);
\r
2246 if (!image.open(cl.getRawFileName()))
\r
2248 printf("Error: %s\n", image._err);
\r
2249 printf("Aborting operation.\n");
\r
2253 if (!image.verify()) // verify file integrity
\r
2255 printf("Failed Verification.\n"
\r
2256 "The file %s appears to have been corrupted\n", cl.getRawFileName());
\r
2261 printf("Insertion : [SUCCESS]\n");
\r
2262 printf("Done.\n");
\r
2266 bool showInfo(FBase &device, FlashCommandLine cl)
\r
2268 uint32_t NODE_GUIDH, NODE_GUIDL;
\r
2269 uint32_t PORT1_GUIDH, PORT1_GUIDL;
\r
2270 uint32_t PORT2_GUIDH, PORT2_GUIDL;
\r
2271 uint32_t hardwareversion;
\r
2273 uint32_t signature;
\r
2277 bool isFailSafe = false;
\r
2278 uint64_t guids[GUIDS];
\r
2279 char revision[FlashCommandLine::revisionStringLength];
\r
2281 READ4(device, 0x24, &signature, "Signature");
\r
2282 TOCPU1(signature);
\r
2292 if (signature == SIGNATURE)
\r
2294 uint8_t offset =0, x=0;
\r
2295 // Fail Safe image
\r
2297 // verify the image invariant section
\r
2298 if (!checkBoot2(device, 0, 0x28, psptr, "Invariant\t"))
\r
2300 printf("Invariant section is not valid!");
\r
2305 if (!checkPS(device, SECT_SIZE, psptr, "Primary\t"))
\r
2307 M_DEBUG("Primary section is not valid\n");
\r
2308 // If the primary is invalid then try secondary section
\r
2309 if (!checkPS(device, SECT_SIZE*2, psptr, "Secondary\t"))
\r
2311 printf("Firmware is corrupted. Unable to display information.\n");
\r
2315 section=2; // secondary is valid, use it
\r
2318 device.read(0x10, &hardwareversion, sizeof(hardwareversion));
\r
2319 TOCPU1(hardwareversion);
\r
2320 hardwareversion >>=24;
\r
2321 device.read(SECT_SIZE*section, &ps, sizeof(ps));
\r
2322 TOCPUBY(ps,sizeof(ps));
\r
2323 printf("PSID : %s\n",ps.psid.as_str);
\r
2324 printf("Image Type : Fail Safe\n");
\r
2325 if (hardwareversion != 0xA0 && hardwareversion != 0xA1)
\r
2327 printf("Hardware Version : 0xInvalid\n");
\r
2331 printf("Hardware Version : 0x%"PRIX32"\n", hardwareversion);
\r
2333 printf("Company : %s\n", ps.vsd[0]==0x00066A?"SilverStorm Technologies":"Mellanox, Inc");
\r
2335 myTime = ps.vsd[2];
\r
2336 printf("%s Date : %s", (device.getClassType()==Flash::FlashDeviceType?"Burn ":"Creation"), asctime(localtime(&myTime)));
\r
2340 memcpy(revision+offset, &ps.vsd[x], sizeof(uint32_t));
\r
2341 offset = offset + 4;
\r
2343 revision[FlashCommandLine::revisionStringLength-1]='\0';
\r
2344 printf("Firmware Revision : %s\n", revision);
\r
2345 READ4(device, ps.fi_addr+0x24, &psptr, "pointer section");
\r
2346 printf("Firmware Address : 0x%"PRIx32"\n", ps.fi_addr);
\r
2347 printf("Node GUID Offset : 0x%"PRIx32"\n", psptr);
\r
2348 psptr = BE2CPU32(psptr)+ps.fi_addr;
\r
2349 isFailSafe = true;
\r
2353 if (!checkList(device, 0,""))
\r
2355 printf("Firmware is not valid. Can not display information.\n");
\r
2360 // Assume flash has been verified, and both images have the same guids, therefore,
\r
2361 // we only need to read the primary image's guids
\r
2362 device.read(0x10, &hardwareversion, sizeof(hardwareversion));
\r
2363 TOCPU1(hardwareversion);
\r
2364 hardwareversion >>=24;
\r
2365 printf("Image Type : Short\n");
\r
2366 if (hardwareversion != 0xA0 && hardwareversion != 0xA1)
\r
2368 printf("Hardware Version : 0xInvalid\n");
\r
2372 printf("Hardware Version : 0x%X\n", hardwareversion);
\r
2374 printf("Company : Unknown\n");
\r
2375 printf("%s Date : Unknown\n", (device.getClassType()==Flash::FlashDeviceType?"Burn ":"Creation"));
\r
2376 printf("Firmware Revision : Unknown\n");
\r
2377 printf("Firmware Address : 0xUnknown\n");
\r
2378 psptr = signature;
\r
2379 if (psptr < MST_MAX_FLASH )
\r
2381 printf("Node GUID Offset : 0x%"PRIx32"\n", psptr);
\r
2384 printf("Node GUID Offset : 0x%"PRIx32" !!! Error: Invalid !!!\n", psptr);
\r
2389 if (psptr < MST_MAX_FLASH || isFailSafe)
\r
2391 READ4(device, psptr, &NODE_GUIDH, "Node GUID High");
\r
2392 READ4(device, psptr+4, &NODE_GUIDL, "Node GUID Low");
\r
2393 guids[0] = BE2CPU32(NODE_GUIDH);
\r
2394 guids[0] = (guids[0]<<32) | BE2CPU32(NODE_GUIDL);
\r
2395 READ4(device, psptr+8, &PORT1_GUIDH, "Port 1 GUID High");
\r
2396 READ4(device, psptr+12, &PORT1_GUIDL, "Port 1 GUID Low");
\r
2397 guids[1] = BE2CPU32(PORT1_GUIDH);
\r
2398 guids[1] = (guids[1]<<32) | BE2CPU32(PORT1_GUIDL);
\r
2399 READ4(device, psptr+16, &PORT2_GUIDH, "Port 2 GUID High");
\r
2400 READ4(device, psptr+20, &PORT2_GUIDL, "Port 2 GUID Low");
\r
2401 guids[2] = BE2CPU32(PORT2_GUIDH);
\r
2402 guids[2] = (guids[2]<<32) | BE2CPU32(PORT2_GUIDL);
\r
2404 guids[3] = guids[0];
\r
2405 printf("Node GUID : 0x%016"PRIx64"\n", guids[0]);
\r
2406 printf("Port1 GUID : 0x%016"PRIx64"\n", guids[1]);
\r
2407 printf("Port2 GUID : 0x%016"PRIx64"\n", guids[2]);
\r
2410 printf("Node GUID : 0xInvalid\n");
\r
2411 printf("Port1 GUID : 0xInvalid\n");
\r
2412 printf("Port2 GUID : 0xInvalid\n");
\r
2413 printf("!!! WARNING: The flash %s is corrupted.\n"
\r
2414 "You must use the -n <0xGUID> and --force option to update this device.\n",
\r
2415 cl.getDeviceName());
\r
2423 ////////////////////////////////////////////////////////////////////////
\r
2425 // ****************************************************************** //
\r
2427 // ****************************************************************** //
\r
2429 ////////////////////////////////////////////////////////////////////////
\r
2431 main(uint32_t ac, char *av[])
\r
2433 FlashCommandLine cl;
\r
2435 //try to get lock on box
\r
2436 if (FwUpdateLock() != 0 )
\r
2439 // register unlock func in exit
\r
2440 _onexit((_onexit_t)FwUpdateUnlock);
\r
2444 if (cl.isOption(FlashCommandLine::debug))
\r
2450 if (cl.isOption(FlashCommandLine::disable_bestdevice))
\r
2452 DisableBestDevice = true;
\r
2456 if (cl.isOption(FlashCommandLine::flash_format))
\r
2458 if (!device.open(cl.getDeviceName()))
\r
2460 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2468 if (cl.isOption(FlashCommandLine::show_image_info))
\r
2470 if (!image.open(cl.getRawFileName()))
\r
2472 printf("Error: %s\n", image._err);
\r
2476 showInfo(image, cl);
\r
2480 if (cl.isOption(FlashCommandLine::show_flash_info))
\r
2482 if (!device.open(cl.getDeviceName()))
\r
2484 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2488 showInfo(device, cl);
\r
2492 if (cl.isOption(FlashCommandLine::dump_image))
\r
2494 if (!image.open(cl.getRawFileName()))
\r
2496 printf("Error: %s\n", image._err);
\r
2504 if (cl.isOption(FlashCommandLine::dump_flash))
\r
2506 if (!device.open(cl.getDeviceName()))
\r
2508 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2515 if (cl.isOption(FlashCommandLine::verify_image))
\r
2517 if (!image.open(cl.getRawFileName()))
\r
2519 printf("Error: %s\n", image._err);
\r
2526 if (cl.isOption(FlashCommandLine::verify_flash))
\r
2528 if (!device.open(cl.getDeviceName()))
\r
2530 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2537 if (cl.isOption(FlashCommandLine::write_file))
\r
2539 if (!patchVSDToRawImage(cl))
\r
2545 if (cl.isOption(FlashCommandLine::burn))
\r
2547 if (!burnImageToFlash(cl))
\r
2552 // For A0 HCAs we need to write to both banks of the flash.
\r
2553 if ((devType == TAVOR_TYPE) && (devRevision == 0xA0))
\r
2555 device.setGPIOState(Flash::High);
\r
2557 if (!burnImageToFlash(cl))
\r
2567 bool probePciBusForHcaDevice(const char *device)
\r
2570 char output[MAXPATHLEN];
\r
2571 char tmpRevision[5];
\r
2574 devId = HcaDevnameToDevId(device);
\r
2575 devType = HcaDevnameToDevType(device);
\r
2577 sprintf(output,"lspci -m -n | grep 15b3 | grep %x",devType);
\r
2578 stream = _popen(output, "r");
\r
2580 if (NULL == stream)
\r
2582 printf("Error probing the PCI bus for HCA devcies.\n");
\r
2585 M_DEBUG("Probing PCI bus for HCA devices.\n");
\r
2587 while (fgets(output, MAXPATHLEN, stream))
\r
2589 if (mellanox_mode)
\r
2591 if (i++ != devId) continue;
\r
2594 if (++i != devId) continue;
\r
2597 if (strlen(output)>1)
\r
2598 output[strlen(output)-1]='\0';
\r
2600 tmpRevision[0] = '0';
\r
2601 tmpRevision[1] = 'x';
\r
2602 tmpRevision[2] = output[37];
\r
2603 tmpRevision[3] = output[38];
\r
2604 tmpRevision[4] = '\0';
\r
2606 // probably should check errno in case of an invalid revision
\r
2607 devRevision = strtol(tmpRevision, (char**)NULL, 0);
\r
2609 sprintf(bestDev, "/dev/mst/mt%d_pci_cr%d", devType, devId);
\r
2611 M_DEBUG("Trying device %s.\n", bestDev);
\r
2613 if (NULL != fopen(bestDev, "r"))
\r
2615 M_DEBUG("HCA %d (Rev. %"PRIx32") using device name %s.\n", devId, devRevision, bestDev);
\r
2618 sprintf(bestDev, "/dev/mst/mt%d_pciconf%d", devType, devId);
\r
2619 M_DEBUG("Trying device %s.\n", bestDev);
\r
2621 if (NULL != fopen(bestDev, "r"))
\r
2623 M_DEBUG("HCA %d (Rev. %"PRIx32") using device name %s.\n", devId, devRevision, bestDev);
\r
2626 printf("We found HCA %d on the PCI bus, but it does not appear to be operating properly.\n", devId);
\r
2627 printf("Please verify the mst device driver is running without errors. If the problem persist,\n"
\r
2628 "then contact technical support.\n");
\r
2637 printf("Specified device %d not found.\n", devId);
\r
2638 printf("Found %d device%s of type mt%d\n",i,(i==1)?"":"s",devType);
\r
2643 uint32_t HcaDevnameToDevId(const char *devname)
\r
2645 if (strlen(devname) >= 1)
\r
2647 if (isdigit(devname[strlen(devname)-1]))
\r
2649 return ((uint8_t)devname[strlen(devname)-1])-48;
\r
2652 M_DEBUG("Device name should end with a numeric value between 1 and 9.\n");
\r
2657 M_DEBUG("Device name is too short.\n");
\r
2660 M_DEBUG("Invalid device name using default device 1.\n");
\r
2664 uint32_t HcaDevnameToDevType(const char *devname)
\r
2666 uint32_t type = 0;
\r
2669 str = strstr(devname, "mt");
\r
2673 type = strtol(str, NULL, 10);
\r
2675 if ((type != TAVOR_TYPE) && (type != ARBEL_TYPE))
\r
2677 M_DEBUG("Device name should contain device type, using mt23108.\n");
\r
2678 type = TAVOR_TYPE;
\r
2683 bool isMstLoaded(void)
\r
2686 char output[MAXPATHLEN];
\r
2688 /* Check for infinicon-compiled mst driver. */
\r
2689 stream = _popen("/sbin/lsmod | grep mst |cut -d\" \" -f1", "r");
\r
2691 if (NULL == stream)
\r
2694 fgets(output, MAXPATHLEN, stream);
\r
2696 if (strlen(output)>1)
\r
2697 output[strlen(output)-1]='\0';
\r
2701 if ((NULL != output) && (strncmp("mst", output, MAXPATHLEN) == 0))
\r
2704 /* That failed - check for mellanox-compiled mst driver. */
\r
2705 stream = _popen("/sbin/lsmod | grep mst_pci |cut -d\" \" -f1", "r");
\r
2707 if (NULL == stream)
\r
2710 fgets(output, MAXPATHLEN, stream);
\r
2712 if (strlen(output)>1)
\r
2713 output[strlen(output)-1]='\0';
\r
2717 if ((NULL != output) && (strncmp("mst_pci", output, MAXPATHLEN) == 0))
\r
2719 mellanox_mode = 1;
\r
2726 void __cdecl catch_signal( int sig )
\r
2728 //fprintf( stdout, "\nProgram Interrupted. Closing devices.\n" );
\r
2735 FwUpdateLock(void)
\r
2738 if ((file_lock = _open( LOCK_FILE_NAME, _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE )) == -1 )
\r
2740 printf("One instance is running already\n");
\r
2746 FwUpdateUnlock(void)
\r
2748 if ((_close(file_lock)) != -1 )
\r
2750 if ((_unlink(LOCK_FILE_NAME)) != -1 )
\r
2755 printf("Unlock can not release lock\n");
\r