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
111 uint32_t branch_to;
\r
114 enum { H_FIRST=1, H_DDR=1, H_CNF=2, H_JMP=3, H_EMT=4, H_ROM=5, H_GUID=6,
\r
115 H_BOARD_ID=7, H_LAST=7 };
\r
123 typedef struct hca_dev {
\r
124 ib_al_handle_t *ph_al;
\r
125 ib_al_handle_t h_al;
\r
126 ib_ca_handle_t *ph_ca;
\r
127 ib_ca_handle_t h_ca;
\r
128 ib_net64_t *ca_guid;
\r
130 size_t ca_guids_count;
\r
135 #define MST_MAX_FLASH (512*1024) // 512K
\r
136 #define READ4(f,o,d,p) do { if (!f.read(o,d)) { \
\r
137 printf("%s - read error (%s)\n", p, f._err); \
\r
138 return false; }} while (0)
\r
140 // forward function declaration
\r
141 uint32_t HcaDevnameToDevId(const char *devname);
\r
142 uint32_t HcaDevnameToDevType(const char *devname);
\r
143 bool probePciBusForHcaDevice(const char *devname);
\r
144 bool isMstLoaded(void);
\r
145 bool getGUID(const char *s, uint64_t *guid);
\r
146 bool extractGUIDptr(uint32_t sign, uint32_t *buf, uint32_t buf_len, char *pref, uint32_t *ind, uint32_t *nguids);
\r
147 void printStatus(const uint32_t status);
\r
148 void printPercent(const uint32_t percent, const uint32_t reset);
\r
150 ////////////////////////////////////////////////////////////////////////
\r
152 // ****************************************************************** //
\r
153 // CRC16 CALCULATION //
\r
154 // ****************************************************************** //
\r
156 ////////////////////////////////////////////////////////////////////////
\r
160 Crc16(bool d = false) : _debug(d) { clear(); }
\r
161 uint16_t get() { return _crc; }
\r
162 void clear() { _crc = 0xffff; }
\r
163 void operator<<(uint32_t val) { add(val); }
\r
164 void add(uint32_t val);
\r
171 ////////////////////////////////////////////////////////////////////////
\r
172 void Crc16::add(uint32_t o)
\r
175 printf("Crc16::add(%08"PRIx32")\n", o);
\r
176 for (uint32_t i=0; i<32; i++)
\r
179 _crc = (((_crc<<1) | (o>>31)) ^ 0x100b) & 0xffff;
\r
181 _crc=((_crc<<1) | (o>>31)) & 0xffff;
\r
182 o = (o<<1) & 0xffffffff;
\r
187 ////////////////////////////////////////////////////////////////////////
\r
188 void Crc16::finish()
\r
190 for (uint32_t i=0; i<16; i++)
\r
193 _crc=((_crc<<1) ^ 0x100b) & 0xffff;
\r
195 _crc=(_crc<<1) & 0xffff;
\r
198 // Revert 16 low bits
\r
199 _crc = _crc ^ 0xffff;
\r
204 ////////////////////////////////////////////////////////////////////////
\r
206 // ****************************************************************** //
\r
208 // ****************************************************************** //
\r
210 ////////////////////////////////////////////////////////////////////////
\r
211 //#define FUJITSU_BYTE_MODE
\r
213 // Common base class for Flash and for FImage
\r
217 FBase() {m_debug=false;}
\r
219 virtual bool open(const char *) = 0;
\r
220 virtual void close() = 0;
\r
221 virtual bool read(uint32_t addr, uint32_t *data) = 0;
\r
222 virtual bool read(uint32_t addr, void *data, uint32_t len) = 0;
\r
223 virtual bool dump() = 0;
\r
224 virtual uint32_t getClassType() = 0;
\r
226 void setDebug(bool on) { m_debug = on; };
\r
227 bool isDebug() { return m_debug; };
\r
235 // Flash image (RO)
\r
236 class FImage : public FBase
\r
239 FImage() : _buf(0) { }
\r
240 FImage(bool debug) : _buf(0) { setDebug(debug); }
\r
241 virtual ~FImage() { close(); }
\r
243 enum { RawImageFileType = 1 };
\r
245 uint32_t *getBuf() { return _buf; }
\r
246 uint32_t getBufLength() { return _len; }
\r
247 virtual bool open(const char *fname);
\r
248 virtual void close();
\r
249 virtual bool read(uint32_t addr, uint32_t *data);
\r
250 virtual bool read(uint32_t addr, void *data, uint32_t len);
\r
251 virtual bool dump();
\r
252 virtual uint32_t getClassType() { return RawImageFileType; };
\r
259 // Flash access (R/W)
\r
260 class Flash : public FBase
\r
263 enum GPIO_STATE { High, Low };
\r
265 Flash() : curr_sector(0xffffffff), m_curr_bank(0xffffffff), m_gpio_state(Flash::Low) {}
\r
266 virtual ~Flash() { close(); };
\r
268 enum { SECT_SIZE = 0x10000, SECT_MASK = 0xffff0000, FlashDeviceType = 2 };
\r
269 enum { FW_READ = 0x00,
\r
271 FW_READ_CMD = 0x08,
\r
272 FW_WRITE_CMD= 0x09,
\r
274 FW_CLOSE_IF = 0x7e };
\r
275 uint32_t curr_sector;
\r
277 virtual bool open(const char *);
\r
278 virtual void close();
\r
279 virtual bool read(uint32_t addr, uint32_t *data);
\r
280 virtual bool read(uint32_t addr, void *data, uint32_t len);
\r
281 virtual bool dump();
\r
282 virtual uint32_t getClassType() { return FlashDeviceType; };
\r
283 void setGPIOState(GPIO_STATE state);
\r
285 bool write(uint32_t addr, uint32_t data);
\r
286 bool write(uint32_t addr, void *data, uint32_t cnt,
\r
287 bool noerase = false, bool noverify = false);
\r
288 bool write_image(uint32_t addr, void *data, uint32_t cnt, bool eraseInvariant = false, bool report=false);
\r
289 bool erase_sector(uint32_t addr);
\r
291 ib_api_status_t access(hca_dev_t *mf, u_int32_t offset, void *data, u_int32_t length, u_int32_t operation);
\r
294 uint32_t m_curr_bank;
\r
295 GPIO_STATE m_gpio_state;
\r
301 bool hca_open (void);
\r
303 bool set_bank(uint32_t bank);
\r
304 bool write_internal(uint32_t addr, uint8_t data);
\r
306 enum FlashCmds {IDLE=0,
\r
311 enum { TRANS = 4096 };
\r
312 enum { BANK_SHIFT = 19,
\r
313 BANK_MASK = 0xfff80000
\r
316 enum { FLASH = 0xf01a4,
\r
317 ADDR_MSK=0x7ffffUL,
\r
318 CMD_MASK=0xe0000000UL
\r
321 enum { CPUMODE = 0xf0150,
\r
322 CPUMODE_MSK=0xc0000000UL,
\r
326 enum { SEMAP63 = 0xf03fc,
\r
327 GPIO_DIR_L = 0xf008c,
\r
328 GPIO_POL_L = 0xf0094,
\r
329 GPIO_MOD_L = 0xf009c,
\r
330 GPIO_DAT_L = 0xf0084,
\r
331 GPIO_DATACLEAR_L = 0xf00d4,
\r
332 GPIO_DATASET_L = 0xf00dc
\r
336 enum { FLASH_CMD_CNT = 5000, // Number of reads till flash cmd is zeroed
\r
337 ERASE_DELAY = 20000, // Delay between reads when wating for sector erase
\r
338 ERASE_CNT = 80, // Maximal number of reads when wating for sector erase
\r
339 READ_CNT_FAST = 5000, // Number of fast reads after write byte
\r
340 READ_CNT_SLOW = 50, // Number of slow reads after write byte
\r
341 READ_DELAY = 10000, // Delay between slow reads after write byte
\r
342 WR_REPORT_FAST = 256, // Report frequency when write (fast interfaces)
\r
343 WR_REPORT_SLOW = 4, // Report frequency when write (slow interfaces)
\r
344 RD_REPORT_FAST = 4096, // Report frequency when read (fast interfaces)
\r
345 RD_REPORT_SLOW = 64, // Report frequency when read (slow interfaces)
\r
346 GPIO_SEM_TRIES = 10240 // Number of tries to obtain a GPIO sem.
\r
351 bool FImage::dump()
\r
354 uint32_t position = 0;
\r
358 if (!this->read(position, &word))
\r
363 if ((position % 16) == 0)
\r
365 printf("\n%08"PRIx32": ", position);
\r
367 printf(" %08"PRIx32"", word);
\r
369 position = position + 4;
\r
375 ////////////////////////////////////////////////////////////////////////
\r
376 bool FImage::open(const char *fname)
\r
378 struct _stat stat_buf;
\r
381 uint32_t fd = _open(fname, _O_BINARY | _O_RDONLY, S_IREAD);
\r
384 sprintf(_msg, "Can't open file \"%s\" - %s\n", fname,
\r
389 if (_fstat(fd, &stat_buf) < 0)
\r
391 sprintf(_msg, "Can't stat file \"%s\" - %s\n", fname,
\r
396 if (stat_buf.st_size & 0x3)
\r
398 _err = "Image size should be 4-bytes aligned.";
\r
402 _buf = new uint32_t[stat_buf.st_size/4];
\r
403 if ((r_cnt = _read(fd, _buf, stat_buf.st_size)) != stat_buf.st_size)
\r
406 sprintf(_msg, "Read error on file \"%s\" - %s\n",
\r
407 fname, strerror(errno));
\r
409 sprintf(_msg, "Read error on file \"%s\" - read only %d bytes (from %ld)\n",
\r
410 fname, r_cnt, stat_buf.st_size);
\r
415 _len = stat_buf.st_size;
\r
420 ////////////////////////////////////////////////////////////////////////
\r
421 void FImage::close()
\r
427 ////////////////////////////////////////////////////////////////////////
\r
428 bool FImage::read(uint32_t addr, uint32_t *data)
\r
432 _err = "Address should be 4-bytes aligned.";
\r
437 _err = "Not opened";
\r
442 sprintf(_msg, "Address (0x%x) is out of image limits\n", addr);
\r
446 *data = _buf[addr/4];
\r
450 ////////////////////////////////////////////////////////////////////////
\r
451 bool FImage::read(uint32_t addr, void *data, uint32_t len)
\r
455 _err = "Address should be 4-bytes aligned.";
\r
460 _err = "Length should be 4-bytes aligned.";
\r
465 _err = "Not opened";
\r
469 uint32_t *p = (uint32_t *)data;
\r
470 for (uint32_t i=0; i<len/4; i++)
\r
472 if (!read(addr, p++))
\r
481 void __cdecl catch_signal( int sig );
\r
484 ////////////////////////////////////////////////////////////////////////
\r
485 #define MWRITE4(offs,val, cmd) access(&m_mf, offs, val, 4, cmd )
\r
486 #define MREAD4(offs,val, cmd) access(&m_mf, offs, val, 4, cmd )
\r
488 void Flash::setGPIOState(GPIO_STATE state)
\r
490 m_gpio_state = state;
\r
496 uint32_t position = 0;
\r
497 uint32_t max_size = 0;
\r
500 this->read(SECT_SIZE, &ps, sizeof(ps));
\r
502 TOCPUBY(ps,sizeof(ps));
\r
505 if (ps.signature != SIGNATURE)
\r
507 max_size = MST_MAX_FLASH;
\r
510 max_size = ps.fi_size;
\r
513 while (position < max_size )
\r
515 if (!this->read(position, &word))
\r
520 if ((position % 16) == 0)
\r
522 printf("\n%08"PRIx32": ", position);
\r
524 printf(" %08"PRIx32"", word);
\r
526 position = position + 4;
\r
532 bool Flash::format()
\r
534 uint32_t position = 0;
\r
535 uint32_t max_size = 0;
\r
537 uint32_t percent = 0;
\r
539 this->read(SECT_SIZE, &ps, sizeof(ps));
\r
541 TOCPUBY(ps, sizeof(ps));
\r
544 if (ps.signature != SIGNATURE)
\r
546 max_size = MST_MAX_FLASH;
\r
549 max_size = ps.fi_size;
\r
554 while (position < max_size )
\r
556 this->erase_sector(position);
\r
557 percent = (uint32_t)(((float)position / (float)max_size) * 100.00);
\r
558 if (percent != prev)
\r
559 printPercent(percent,0);
\r
561 position = position + SECT_SIZE; // increment by 65k sectors
\r
563 printPercent(100,0);
\r
568 ////////////////////////////////////////////////////////////////////////
\r
569 bool Flash::open(const char *device )
\r
572 bool status = false;
\r
575 M_DEBUG("Specify HCA to work with\n");
\r
578 m_mf.ph_al = (ib_al_handle_t *)(intn_t)&m_mf.h_al;
\r
579 m_mf.ph_ca = (ib_ca_handle_t *)(intn_t)&m_mf.h_ca;
\r
580 if ( !(hca_open()))
\r
582 M_DEBUG("Failed to open HCA \n");
\r
586 //M_DEBUG("Open HCA GUID %"PRIx64"\n", cl_ntoh64(*m_mf.ca_guid));
\r
588 m_curr_bank = 0xffffffff;
\r
590 // Obtain GPIO Semaphore
\r
594 MREAD4(FLASH, &word, FW_OPEN_IF );
\r
598 MREAD4(SEMAP63, &word, FW_READ_CMD);
\r
604 if (++cnt > GPIO_SEM_TRIES)
\r
606 _err = "cannot obtain GPIO semaophore (63)";
\r
613 MREAD4(FLASH, &word, FW_CLOSE_IF );
\r
617 //M_DEBUG("Acquired GPIO sempahore.\n");
\r
620 MREAD4(GPIO_DIR_L, &m_dir, FW_READ_CMD);
\r
621 MREAD4(GPIO_POL_L, &m_pol, FW_READ_CMD);
\r
622 MREAD4(GPIO_MOD_L, &m_mod, FW_READ_CMD);
\r
623 MREAD4(GPIO_DAT_L, &m_data, FW_READ_CMD);
\r
625 //M_DEBUG("Read GPIO information.\n");
\r
627 // Set Direction=1, Polarity=0, Mode=0 for 3 GPIO lower bits
\r
632 dir = m_dir | 0x70;
\r
633 pol = m_pol & ~0x70;
\r
634 mod = m_mod & ~0x70;
\r
636 MWRITE4(GPIO_DIR_L, &dir, FW_WRITE_CMD);
\r
637 MWRITE4(GPIO_POL_L, &pol, FW_WRITE_CMD);
\r
638 MWRITE4(GPIO_MOD_L, &mod, FW_WRITE_CMD);
\r
640 // M_DEBUG("Set GPIO bits.\n");
\r
643 MREAD4(CPUMODE, &word, FW_READ_CMD);
\r
644 word &= ~CPUMODE_MSK;
\r
645 word |= 1 << CPUMODE_SHIFT;
\r
646 MWRITE4(CPUMODE, &word, FW_WRITE_CMD);
\r
649 //M_DEBUG("Set cpu mode.\n");
\r
652 status = write_internal(0, 0xf0);
\r
653 M_DEBUG("Flash Open %s\n", ((status)?"OK":"FAIL"));
\r
657 ////////////////////////////////////////////////////////////////////////
\r
658 void Flash::close()
\r
665 m_gpio_state = Flash::Low;
\r
668 // Restore origin values
\r
669 MWRITE4(GPIO_DIR_L, &m_dir, FW_WRITE_CMD);
\r
670 MWRITE4(GPIO_POL_L, &m_pol, FW_WRITE_CMD);
\r
671 MWRITE4(GPIO_MOD_L, &m_mod, FW_WRITE_CMD);
\r
672 MWRITE4(GPIO_DAT_L, &m_data, FW_WRITE_CMD);
\r
674 // Free GPIO Semaphore
\r
675 MWRITE4(SEMAP63, &data, FW_WRITE_CMD);
\r
677 // free kernel BusInterface
\r
678 MREAD4(FLASH, &data, FW_CLOSE_IF );
\r
682 m_curr_bank = 0xffffffff;
\r
685 ////////////////////////////////////////////////////////////////////////
\r
686 bool Flash::set_bank(uint32_t bank)
\r
688 uint32_t data = 0x70;
\r
691 _err = "Not opened";
\r
695 //printf("\n*** Flash::set_bank(0x%"PRIx32") : 0x%"PRIx32"\n", bank, (BANK_SHIFT-4) & 0x70);
\r
696 MWRITE4(GPIO_DATACLEAR_L, &data, FW_WRITE_CMD);
\r
697 if (m_gpio_state == Flash::Low)
\r
699 data &= (bank >> (BANK_SHIFT-4));
\r
700 MWRITE4(GPIO_DATASET_L, &data, FW_WRITE_CMD );
\r
703 data |= (bank >> (BANK_SHIFT-4));
\r
704 MWRITE4(GPIO_DATASET_L, &data, FW_WRITE_CMD);
\r
708 } // Flash::set_bank
\r
710 ////////////////////////////////////////////////////////////////////////
\r
711 bool Flash::read(uint32_t addr, uint32_t *data)
\r
715 _err = "Not opened";
\r
722 _err = "Address should be 4-bytes aligned.";
\r
726 uint32_t bank = addr & BANK_MASK;
\r
727 if (bank != m_curr_bank)
\r
729 m_curr_bank = bank;
\r
730 if (!set_bank(bank))
\r
733 MREAD4(addr, &cmd, FW_READ ); // new read
\r
734 cmd = __be32_to_cpu(cmd);
\r
735 memcpy(data, &cmd, sizeof(uint32_t));
\r
740 ////////////////////////////////////////////////////////////////////////
\r
741 bool Flash::read(uint32_t addr, void *data, uint32_t len)
\r
745 _err = "Address should be 4-bytes aligned.";
\r
750 _err = "Length should be 4-bytes aligned.";
\r
754 uint32_t *p = (uint32_t *)data;
\r
755 for (uint32_t i=0; i<len/4; i++)
\r
757 if (!read(addr, p++))
\r
762 } // Flash::flash_read
\r
764 ////////////////////////////////////////////////////////////////////////
\r
765 bool Flash::write_internal(uint32_t addr, uint8_t data)
\r
767 MWRITE4(addr, &data, FW_WRITE);
\r
769 } // Flash::write_internal
\r
771 ////////////////////////////////////////////////////////////////////////
\r
772 bool Flash::erase_sector(uint32_t addr)
\r
777 // Just to insure zeroes because erase completion waits for ones
\r
778 if (!write(addr, &word, sizeof(word), true))
\r
781 // erase sector sequence
\r
782 #ifdef FUJITSU_BYTE_MODE
\r
783 if (!write_internal(0xaaa, 0xaa))
\r
785 if (!write_internal(0x555, 0x55))
\r
787 if (!write_internal(0xaaa, 0x80))
\r
789 if (!write_internal(0xaaa, 0xaa))
\r
791 if (!write_internal(0x555, 0x55))
\r
793 if (!write_internal(addr, 0x30))
\r
795 #else /* FUJITSU_WORD_MODE */
\r
796 if (!write_internal(0x555, 0xaa))
\r
798 if (!write_internal(0x2aa, 0x55))
\r
800 if (!write_internal(0x555, 0x80))
\r
802 if (!write_internal(0x555, 0xaa))
\r
804 if (!write_internal(0x2aa, 0x55))
\r
806 if (!write_internal(addr, 0x30))
\r
810 // Wait while erase completes
\r
814 if (++cnt > ERASE_CNT)
\r
816 _err = "Flash erase sector timeout";
\r
819 if (!read(addr, &word))
\r
822 //printf("erase_sector: addr:%08"PRIx32", %08"PRIx32"\n", addr, word);
\r
823 Sleep(ERASE_DELAY/1000);
\r
824 } while (word != 0xffffffff);
\r
827 } // Flash::erase_sector
\r
829 ////////////////////////////////////////////////////////////////////////
\r
830 bool Flash::write(uint32_t addr, uint32_t data)
\r
834 _err = "Not opened";
\r
839 _err = "Address should be 4-bytes aligned.";
\r
844 uint32_t sector = addr & SECT_MASK;
\r
845 uint32_t word_in_sector = (addr & ~SECT_MASK)/sizeof(uint32_t);
\r
847 if (!read(addr, &word))
\r
850 return true; // already there
\r
852 uint32_t buff[SECT_SIZE/sizeof(uint32_t)];
\r
853 if (!read(sector, buff, SECT_SIZE))
\r
855 buff[word_in_sector] = data;
\r
856 return write(sector, buff, SECT_SIZE);
\r
859 ////////////////////////////////////////////////////////////////////////
\r
860 bool Flash::write(uint32_t addr, void *data, uint32_t cnt,
\r
861 bool noerase, bool noverify)
\r
865 _err = "Not opened";
\r
870 _err = "Address should be 4-bytes aligned.";
\r
877 char *p = (char *)data;
\r
879 for (uint32_t i=0; i<cnt; i++,addr++)
\r
885 uint32_t bank = addr & BANK_MASK;
\r
886 if (bank != m_curr_bank)
\r
888 m_curr_bank = bank;
\r
889 if (!set_bank(bank))
\r
895 uint32_t sector = addr & SECT_MASK;
\r
896 if (sector != curr_sector)
\r
898 curr_sector = sector;
\r
899 if (!erase_sector(curr_sector))
\r
904 #ifdef FUJITSU_BYTE_MODE
\r
905 if (!write_internal(0xaaa, 0xaa))
\r
907 if (!write_internal(0x555, 0x55))
\r
909 if (!write_internal(0xaaa, 0xa0))
\r
911 #else /* FUJITSU_WORD_MODE */
\r
912 if (!write_internal(0x555, 0xaa))
\r
914 if (!write_internal(0x2aa, 0x55))
\r
916 if (!write_internal(0x555, 0xa0))
\r
920 if (!write_internal(addr, *p++))
\r
925 if ( !read (addr &~3, &word) )
\r
927 #if __BYTE_ORDER == __LITTLE_ENDIAN
\r
928 act = (word >> ((addr & 3) * 8)) & 0xff;
\r
929 #elif __BYTE_ORDER == __BIG_ENDIAN
\r
930 act = (word >> ((3 - (addr & 3)) * 8)) & 0xff;
\r
932 exp = *(p-1) & 0xff;
\r
935 M_DEBUG("Flash write error - read value %#x doesn't written value %#x", act, exp);
\r
943 void Flash::hca_close (void)
\r
947 ib_close_ca( m_mf.h_ca, NULL );
\r
949 ib_close_al( m_mf.h_al);
\r
951 bool Flash::hca_open(void)
\r
953 ib_api_status_t ib_status = IB_SUCCESS;
\r
956 ib_status = ib_open_al( m_mf.ph_al );
\r
957 if ( ib_status != IB_SUCCESS )
\r
959 M_DEBUG("Failed ot open AL status %#x\n", ib_status);
\r
963 ib_status = ib_get_ca_guids ( *m_mf.ph_al, NULL, &m_mf.ca_guids_count );
\r
964 if (m_mf.ca_guids_count == 0)
\r
966 M_DEBUG("FOUND NO GUIDS\n");
\r
970 m_mf.ca_guid =(ib_net64_t *)cl_zalloc(m_mf.ca_guids_count*sizeof(ib_net64_t));
\r
971 if(m_mf.ca_guid == NULL)
\r
973 M_DEBUG("Failed to allocate memory for CA GUID table\n");
\r
977 ib_status = ib_get_ca_guids (*m_mf.ph_al, m_mf.ca_guid, &m_mf.ca_guids_count );
\r
978 if (ib_status != IB_SUCCESS)
\r
980 M_DEBUG("Failed to get CA GUIDs\n");
\r
984 ib_status = ib_open_ca( *m_mf.ph_al, m_mf.ca_guid[0], NULL, &m_mf, m_mf.ph_ca );
\r
985 if (ib_status != IB_SUCCESS)
\r
987 M_DEBUG("Failed to open CA\n");
\r
994 #define STR_LEN 128
\r
995 void printPercent(const uint32_t percent, const uint32_t reset)
\r
997 #define PRECISION 2
\r
998 #define NO_OF_PARTS (100 / (PRECISION))
\r
999 /*"12345678901234567890123456789012345678901234567890"*/
\r
1000 char markerBar[NO_OF_PARTS+1] = " ";
\r
1001 static uint32_t prevNoOfXs = 0;
\r
1002 uint32_t noOfXs = 0;
\r
1004 char str[STR_LEN];
\r
1005 cl_memset(str,0,STR_LEN);
\r
1007 markerBar[NO_OF_PARTS+1] = '\0';
\r
1011 sprintf(str,"|%s| %3d%%", markerBar, percent);
\r
1016 noOfXs = percent / PRECISION;
\r
1017 for (x = 0; x < NO_OF_PARTS; x++)
\r
1020 markerBar[x] = '*';
\r
1022 if (noOfXs>prevNoOfXs)
\r
1024 sprintf(str,"|%s| %3d%%", markerBar, percent);
\r
1025 //printf("|%s| %3d%%", markerBar, percent);
\r
1026 prevNoOfXs = noOfXs;
\r
1029 printf("\r%s",str);
\r
1033 void printStatus(const uint32_t status)
\r
1035 printf("[%s]\n",((status == 0)?"SUCCESS":"FAILED"));
\r
1038 ////////////////////////////////////////////////////////////////////////
\r
1039 bool Flash::write_image(uint32_t addr, void *data, uint32_t cnt, bool eraseInvariant, bool report)
\r
1041 uint8_t *p = (uint8_t *)data;
\r
1042 uint32_t curr_addr = addr;
\r
1043 uint32_t towrite = cnt;
\r
1044 uint32_t perc = 0xffffffff;
\r
1045 bool noerase = false;
\r
1047 curr_sector = 0xffffffff; // Erase sector first time
\r
1050 printf("writing: ");
\r
1051 printPercent(0,1);
\r
1058 uint32_t trans = (towrite > (uint32_t)TRANS) ? (uint32_t)TRANS : towrite;
\r
1060 if (eraseInvariant)
\r
1065 if (curr_addr < SECT_SIZE)
\r
1076 if (!write(curr_addr, p, trans, noerase, true))
\r
1083 curr_addr += trans;
\r
1089 uint32_t new_perc = ((cnt - towrite) * 100) / cnt;
\r
1090 if (new_perc != perc)
\r
1092 printPercent(new_perc,0);
\r
1101 printPercent(100,0);
\r
1107 } // Flash::write_image
\r
1112 for read - data return in native Endian mode,
\r
1113 for write - data should be written in BigEndian mode
\r
1114 check where data is actually converted !!!!
\r
1116 ib_api_status_t Flash::access(hca_dev_t *dev, u_int32_t offset, void *p_data, uint32_t length, uint32_t operation )
\r
1120 ib_api_status_t ib_status;
\r
1125 ci_op.buf_size = length;
\r
1126 ci_op.p_buf = p_data;
\r
1127 ci_op.buf_info = offset;
\r
1128 ci_op.num_bytes_ret = sizeof (ib_ci_op_t);
\r
1129 ci_op.command = operation;
\r
1131 ib_status = ib_ci_call (m_mf.h_ca, NULL, 0, &ci_op);
\r
1133 if ( ib_status != IB_SUCCESS )
\r
1135 FW_TRACE (FW_DBG_ERROR,("Failed ib_ci_call return status %#x\n", ib_status ));
\r
1138 return IB_SUCCESS;
\r
1141 bool getGUIDsFromFlash(FBase &device, uint64_t guids[GUIDS])
\r
1143 uint32_t NODE_GUIDH, NODE_GUIDL;
\r
1144 uint32_t PORT1_GUIDH, PORT1_GUIDL;
\r
1145 uint32_t PORT2_GUIDH, PORT2_GUIDL;
\r
1146 uint32_t prim_ptr;
\r
1147 uint32_t signature;
\r
1149 bool isFailSafe = false;
\r
1151 READ4(device, 0x24, &signature, "Signature");
\r
1152 TOCPU1(signature);
\r
1154 if (signature == SIGNATURE)
\r
1156 // Fail Safe image
\r
1158 // Assume flash has been verified, and both images have the same guids, therefore,
\r
1159 // we only need to read the primary image's guids
\r
1160 device.read(SECT_SIZE, &ps, sizeof(ps));
\r
1161 TOCPUBY(ps,sizeof(ps));
\r
1162 READ4(device, ps.fi_addr+0x24, &prim_ptr, "Primary Section");
\r
1163 M_DEBUG("Firmware Address : 0x%"PRIx32"\n", ps.fi_addr);
\r
1164 M_DEBUG("Node GUID Offset : 0x%"PRIx32"\n", prim_ptr);
\r
1165 prim_ptr = BE2CPU32(prim_ptr)+ps.fi_addr;
\r
1166 isFailSafe = true;
\r
1171 prim_ptr = signature;
\r
1174 printf("Found valid GUID pointer : %08"PRIx32"\n", prim_ptr);
\r
1175 if (prim_ptr < MST_MAX_FLASH || isFailSafe)
\r
1177 READ4(device, prim_ptr, &NODE_GUIDH, "Node GUID High");
\r
1178 READ4(device, prim_ptr+4, &NODE_GUIDL, "Node GUID Low");
\r
1179 guids[0] = BE2CPU32(NODE_GUIDH);
\r
1180 guids[0] = (guids[0]<<32) | BE2CPU32(NODE_GUIDL);
\r
1181 READ4(device, prim_ptr+8, &PORT1_GUIDH, "Port 1 GUID High");
\r
1182 READ4(device, prim_ptr+12, &PORT1_GUIDL, "Port 1 GUID Low");
\r
1183 guids[1] = BE2CPU32(PORT1_GUIDH);
\r
1184 guids[1] = (guids[1]<<32) | BE2CPU32(PORT1_GUIDL);
\r
1185 READ4(device, prim_ptr+16, &PORT2_GUIDH, "Port 2 GUID High");
\r
1186 READ4(device, prim_ptr+20, &PORT2_GUIDL, "Port 2 GUID Low");
\r
1187 guids[2] = BE2CPU32(PORT2_GUIDH);
\r
1188 guids[2] = (guids[2]<<32) | BE2CPU32(PORT2_GUIDL);
\r
1190 guids[3] = guids[0];
\r
1191 printf("Found device's existing GUIDs:\n");
\r
1192 printf("Node GUID : 0x%016"PRIx64"\n", guids[0]);
\r
1193 printf("Port1 GUID : 0x%016"PRIx64"\n", guids[1]);
\r
1194 printf("Port2 GUID : 0x%016"PRIx64"\n", guids[2]);
\r
1197 printf("Found an invalid GUID pointer!\n");
\r
1204 bool getGUIDs(char *guidString, uint64_t guids[GUIDS])
\r
1206 uint32_t PORT1_GUIDH, PORT1_GUIDL;
\r
1207 uint32_t PORT2_GUIDH, PORT2_GUIDL;
\r
1208 uint64_t GUID; //strtoull(guidString, (char **)NULL, 0);
\r
1209 uint32_t NODE_GUIDH;
\r
1210 uint32_t NODE_GUIDL;
\r
1212 if (!getGUID(guidString, &GUID))
\r
1217 NODE_GUIDH = (uint32_t)(GUID >> 32);
\r
1218 NODE_GUIDL = (uint32_t)GUID;
\r
1220 if ((NODE_GUIDH & 0xffffffff) == 0x00066a00
\r
1221 && ((NODE_GUIDL & 0xf8000000) == 0x98000000
\r
1222 || (NODE_GUIDL & 0xf8000000) == 0xb0000000))
\r
1224 // Always make it a InfiniCon NODE GUID
\r
1225 NODE_GUIDL = (NODE_GUIDL & 0x0FFFFFFF) | 0x98000000;
\r
1227 // Convert to the InfiniCon Node Guid Convention.
\r
1228 PORT1_GUIDH = NODE_GUIDH;
\r
1229 PORT1_GUIDL = (NODE_GUIDL & 0x07ffffff) | 0xa0000000;
\r
1230 PORT2_GUIDH = NODE_GUIDH | 1;
\r
1231 PORT2_GUIDL = (NODE_GUIDL & 0x07ffffff) | 0xa0000000;
\r
1233 // Treat everything else as a Mellanox Node Guid Convention.
\r
1234 PORT1_GUIDH=NODE_GUIDH;
\r
1235 PORT1_GUIDL=NODE_GUIDL+1;
\r
1236 if ( PORT1_GUIDL==0 ) {
\r
1239 PORT2_GUIDH=PORT1_GUIDH;
\r
1240 PORT2_GUIDL=PORT1_GUIDL+1;
\r
1241 if ( PORT2_GUIDL==0 ) {
\r
1246 guids[0] = NODE_GUIDH;
\r
1247 guids[0] = (guids[0]<<32) | NODE_GUIDL;
\r
1249 guids[1] = PORT1_GUIDH;
\r
1250 guids[1] = (guids[1]<<32) | PORT1_GUIDL;
\r
1252 guids[2] = PORT2_GUIDH;
\r
1253 guids[2] = (guids[2]<<32) | PORT2_GUIDL;
\r
1255 guids[3] = guids[0];
\r
1257 printf("Using user specified GUIDs :\n");
\r
1258 printf("Node GUID : 0x%016"PRIx64"\n", guids[0]);
\r
1259 printf("Port 1 GUID : 0x%016"PRIx64"\n", guids[1]);
\r
1260 printf("Port 2 GUID : 0x%016"PRIx64"\n", guids[2]);
\r
1264 bool _silent = false;
\r
1265 #define report printf
\r
1267 ////////////////////////////////////////////////////////////////////////
\r
1268 bool isInvariantSectionEqual(FBase& f1, FBase& f2)
\r
1272 uint32_t beg = 0x0;
\r
1273 uint32_t offs = 0x28;
\r
1274 const char* pr = "isInvariantSectionEqual";
\r
1277 bool status = true;
\r
1280 READ4(f1, offs+beg+4, &size1, pr);
\r
1281 READ4(f2, offs+beg+4, &size2, pr);
\r
1285 // M_DEBUG("Invariant sector size1: %"PRId32"\n", size1);
\r
1286 // M_DEBUG("Invariant sector size2: %"PRId32"\n", size2);
\r
1288 if (size1 != size2)
\r
1290 M_DEBUG("Invariant sector sizes do not match.\n");
\r
1294 buf1 = (uint32_t *)cl_zalloc((size1+4)*4);
\r
1297 cl_dbg_out("Failed to allocate memory size =%d", size1+4 );
\r
1300 buf2 = (uint32_t *)cl_zalloc( (size2+4)*4);
\r
1304 cl_dbg_out("Failed to allocate memory size =%d", size2+4 );
\r
1308 READBUF(f1, offs+beg, buf1, (size1+4)*4, pr);
\r
1309 READBUF(f2, offs+beg, buf2, (size2+4)*4, pr);
\r
1311 if ( cl_memcmp(buf1, buf2, (size1+4)*4) )
\r
1313 // M_DEBUG("Invariant sections are not equal.\n");
\r
1319 } // isInvariantSectionEqual
\r
1321 ////////////////////////////////////////////////////////////////////////
\r
1322 bool checkBoot2(FBase& f, uint32_t beg, uint32_t offs, uint32_t& next, const char *pref)
\r
1327 uint32_t *safe_buf;
\r
1328 //sprintf(pr, "%s /0x%08"PRIx32"/ (BOOT2)", pref, offs+beg);
\r
1331 READ4(f, offs+beg+4, &size, pr);
\r
1334 if (size > 1048576 || size < 4)
\r
1336 report("%s /0x%08"PRIx32"/ - unexpected size (0x%x)\n", pr, offs+beg+4, size);
\r
1340 //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
1344 buff = (uint32_t*)cl_zalloc((size+4)*4);
\r
1347 READBUF(f, offs+beg, buff, (size+4)*4, pr);
\r
1348 TOCPU(buff, (size+4)*4 );
\r
1349 CRC1(crc, buff, (size+4)*4 );
\r
1351 uint32_t crc_act = *(buff+size+3);
\r
1352 if (crc.get() != crc_act)
\r
1354 report("%s /0x%08"PRIx32"/ - wrong CRC (exp:0x%x, act:0x%x)\n",
\r
1355 pr, offs+beg, crc.get(), crc_act);
\r
1356 cl_free(safe_buf);
\r
1360 //report("%s - OK\n", pr);
\r
1361 next = offs + (size+4)*4;
\r
1362 cl_free(safe_buf);
\r
1366 static uint32_t part_cnt;
\r
1368 ////////////////////////////////////////////////////////////////////////
\r
1369 bool checkGen(FBase& f, uint32_t beg,
\r
1370 uint32_t offs, uint32_t& next, const char *pref)
\r
1375 cl_memset(pr,0,1024);
\r
1377 sprintf(pr, "%s /0x%08"PRIx32"/ (GeneralHeader)", pref, offs+beg);
\r
1378 READBUF(f, offs+beg, &gph, sizeof(GPH), pr);
\r
1379 TOCPUBY(gph, sizeof(GPH));
\r
1386 if (gph.type < H_FIRST || gph.type > H_LAST)
\r
1390 report("%s /0x%"PRIx32"/ - Invalid partition type (%"PRIx32")\n",
\r
1391 pref, offs+beg, gph.type);
\r
1395 return checkBoot2(f, beg, offs, next, pref);
\r
1398 // All partitions here
\r
1403 size = gph.size * sizeof(uint32_t);
\r
1404 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (DDR)",
\r
1405 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1408 size = gph.size * sizeof(uint32_t);
\r
1409 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (Configuration)",
\r
1410 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1413 size = gph.size * sizeof(uint32_t);
\r
1414 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (Jump addresses)",
\r
1415 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1419 size = (size + 3) / 4 * 4;
\r
1420 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (EMT Service)",
\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")/ (ROM)",
\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")/ (GUID)",
\r
1431 pref, offs, offs+size+(unsigned)sizeof(gph)+3, size+(unsigned)sizeof(gph)+4);
\r
1434 size = gph.size * sizeof(uint32_t);
\r
1435 sprintf(pr, "%s /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ (Board ID)",
\r
1436 pref, offs, offs+size+(unsigned)sizeof(gph)+3,size+(u_int32_t)sizeof(gph)+4);
\r
1439 report("%s /0x%08"PRIx32"/ - Invalid partition type (%"PRIx32")\n", pref,offs,gph.type);
\r
1446 buff = (uint32_t*)cl_zalloc(size);
\r
1447 READBUF(f, offs+sizeof(gph), buff, size, pr);
\r
1449 CRCBY(crc, gph, sizeof(GPH));
\r
1450 CRC(crc, buff,size);
\r
1453 READ4(f, offs+sizeof(gph)+size, &crc_act, pr);
\r
1455 if (crc.get() != crc_act)
\r
1457 report("%s /0x%08"PRIx32"/ - wrong CRC (exp:0x%x, act:0x%x)\n",
\r
1458 pr, offs, crc.get(), crc_act);
\r
1463 report("%s - OK\n", pr);
\r
1469 ////////////////////////////////////////////////////////////////////////
\r
1470 bool checkPS(FBase& f, uint32_t offs, uint32_t& next, const char *pref)
\r
1474 f.read(offs, &ps, sizeof(ps));
\r
1475 TOCPUBY(ps, sizeof(ps));
\r
1478 if (ps.signature != SIGNATURE)
\r
1480 report("%s Pointer Sector /0x%08"PRIx32"/ - wrong signature (%08"PRIx32")\n",
\r
1481 pref, offs, ps.signature);
\r
1486 CRC1BY(crc, ps, sizeof(PS));
\r
1488 if (crc.get() != ps.crc016)
\r
1490 report("%s Pointer Sector /0x%08"PRIx32"/ - wrong CRC (exp:0x%"PRIx32", act:0x%x)\n",
\r
1491 pref, offs, ps.crc016, crc.get());
\r
1495 next = ps.fi_addr;
\r
1496 report("%s Image /0x%08"PRIx32"-0x%08"PRIx32" (0x%06"PRIx32")/ - OK\n", pref, offs,
\r
1497 offs+(unsigned)sizeof(ps)-1, (unsigned)sizeof(ps));
\r
1501 ////////////////////////////////////////////////////////////////////////
\r
1502 bool checkList(FBase& f, uint32_t offs, const char *pref)
\r
1504 uint32_t next_ptr;
\r
1506 CHECKB2(f, offs, 0x28, next_ptr, pref);
\r
1508 while (next_ptr && next_ptr != 0xff000000)
\r
1509 CHECKGN(f, offs, next_ptr, next_ptr, pref);
\r
1513 ////////////////////////////////////////////////////////////////////////
\r
1514 bool FBase::verify()
\r
1516 uint32_t prim_ptr, scnd_ptr;
\r
1517 uint32_t signature;
\r
1519 READ4((*this), 0x24, &signature, "Signature");
\r
1520 TOCPU1(signature);
\r
1521 if (signature == SIGNATURE)
\r
1524 report("\nFailsafe image:\n\n");
\r
1525 CHECKB2((*this), 0, 0x28, prim_ptr, "Invariant ");
\r
1527 if (checkPS((*this), SECT_SIZE, prim_ptr, "Primary "))
\r
1528 CHECKLS((*this), prim_ptr, " ");
\r
1530 if (checkPS((*this), SECT_SIZE * 2, scnd_ptr, "Secondary"))
\r
1531 CHECKLS((*this), scnd_ptr, " ");
\r
1536 report("\nShort image:\n");
\r
1537 CHECKLS((*this), 0, " ");
\r
1544 ////////////////////////////////////////////////////////////////////////
\r
1546 // ****************************************************************** //
\r
1547 // GUIDs TREATMENT //
\r
1548 // ****************************************************************** //
\r
1550 ////////////////////////////////////////////////////////////////////////
\r
1551 #define GETGUID(s, g) do { if (!getGUID(s,g)) return 1; } while (0)
\r
1552 #define GETBSN(s, g) do { if (!getBSN(s,g)) return 1; } while (0)
\r
1554 #define BSN_RET do { \
\r
1555 printf("Invalid BSN. Should be MTxxxxxRddmmyy-nnn[-cc]\n"); \
\r
1558 #define BSN_RET1(s) do { \
\r
1559 printf("Valid BSN format is: MTxxxxxRddmmyy-nnn[-cc]\n%s.\n",s); \
\r
1562 uint32_t BSN_subfield(const char *s, uint32_t beg, uint32_t len)
\r
1565 strncpy(buf, &s[beg], len);
\r
1567 return strtoul(&buf[0], 0, 10);
\r
1569 bool getBSN(char *s, uint64_t *guid)
\r
1571 const uint64_t COMPANY_ID = 0x0002c9;
\r
1572 const uint64_t TYPE = 1;
\r
1573 bool cc_present = false;
\r
1577 // Convert to lowercase
\r
1578 for (p = s; *p; p++)
\r
1579 *p = (char)tolower(*p);
\r
1583 if (strncmp(p, "mt", 2)) // MT
\r
1586 for (i=0; i<5; i++)
\r
1587 if (!isdigit(*p++)) // xxxxx
\r
1589 if (*p < 'a' || *p > 'z') // R
\r
1592 for (i=0; i<6; i++) // ddmmyy
\r
1593 if (!isdigit(*p++))
\r
1595 if (*p++ != '-') // -
\r
1597 for (i=0; i<3; i++) // nnn
\r
1598 if (!isdigit(*p++))
\r
1602 cc_present = true;
\r
1603 if (*p++ != '-') // -
\r
1605 for (i=0; i<2; i++) // cc
\r
1606 if (!isdigit(*p++))
\r
1610 uint32_t dd = BSN_subfield(s, 8, 2);
\r
1612 BSN_RET1("Day (dd) should not exceed 31");
\r
1614 BSN_RET1("Day (dd) can't be zero");
\r
1615 uint32_t mm = BSN_subfield(s, 10, 2);
\r
1617 BSN_RET1("Months (mm) should not exceed 12");
\r
1619 BSN_RET1("Months (mm) can't be zero");
\r
1620 uint32_t yy = BSN_subfield(s, 12, 2);
\r
1622 BSN_RET1("Year (yy) should not exceed 99");
\r
1624 BSN_RET1("Year (yy) can't be zero");
\r
1625 uint32_t num = BSN_subfield(s, 15, 3);
\r
1627 BSN_RET1("Number (num) should not exceed 999");
\r
1629 BSN_RET1("Number (num) can't be zero");
\r
1633 cc = BSN_subfield(s, 19, 2);
\r
1635 BSN_RET1("Chip number (cc) should not exceed 14");
\r
1637 BSN_RET1("Chip number (cc) can't be zero");
\r
1639 uint64_t id = ((((yy*12+mm-1)*31+ dd-1) * 1000) + num-1) * 112;
\r
1641 *guid = (COMPANY_ID << 40) | (TYPE << 32) | id;
\r
1645 bool getGUID(const char *s, uint64_t *guid)
\r
1647 char str[17], *endp;
\r
1650 memset(str, '0', 15);
\r
1653 for (i=(int)strlen(s)-1,j=15;i >= 0 && j >= 0 ; i-- )
\r
1655 if (isxdigit(s[i]))
\r
1658 l = strtoul(&str[8], &endp, 16);
\r
1661 printf("Invalid GUID syntax (%s)\n", &str[8]);
\r
1665 h = strtoul(&str[0], &endp, 16);
\r
1668 printf("Invalid GUID syntax (%s)\n", str);
\r
1671 *guid = ((uint64_t)h << 32) | l;
\r
1675 ////////////////////////////////////////////////////////////////////////
\r
1676 bool extractGUIDptr(uint32_t sign, uint32_t *buf, uint32_t buf_len,
\r
1677 char *pref, uint32_t *ind, uint32_t *nguids)
\r
1679 uint32_t offs = 0;
\r
1681 // Check signature
\r
1684 uint32_t signature = buf[(sign + 8)/4];
\r
1685 TOCPU1(signature);
\r
1686 if (signature != SIGNATURE)
\r
1688 printf("%s pointer section not valid\n", pref);
\r
1691 offs = buf[sign/4];
\r
1696 *ind = buf[(offs+0x24)/4];
\r
1699 if (*ind >= (uint32_t)buf_len)
\r
1701 printf("%s image - insane GUID pointer (%08"PRIx32")\n", pref, *ind);
\r
1704 *nguids = buf[*ind/4 - 3];
\r
1708 // More sanity check
\r
1709 if (*nguids > GUIDS)
\r
1711 printf("%s image - insane number of GUIDs (%d)\n", pref, *nguids);
\r
1716 } // extractGUIDptr
\r
1718 ////////////////////////////////////////////////////////////////////////
\r
1719 void patchGUIDsSection(
\r
1722 uint64_t guids[GUIDS],
\r
1726 uint32_t new_buf[GUIDS*2];
\r
1729 // Form new GUID section
\r
1730 for (i=0; i<(uint32_t)nguids; i++)
\r
1732 new_buf[i*2] = (uint32_t)(guids[i] >> 32);
\r
1733 new_buf[i*2+1] = (uint32_t)(guids[i] & 0xffffffff);
\r
1736 // Calculate new CRC16
\r
1737 for (i=ind/4 - 4; i<ind/4; i++)
\r
1743 for (i=0; i<(uint32_t)nguids*2; i++)
\r
1744 crc << new_buf[i];
\r
1747 TOCPU(new_buf,GUIDS*2*4);
\r
1748 memcpy(&buf[ind/4], &new_buf[0], nguids * 2 * sizeof(uint32_t));
\r
1754 buf[ind/4 + nguids*2] = word;
\r
1755 } // patchGUIDsSection
\r
1757 ////////////////////////////////////////////////////////////////////////
\r
1758 bool patchGUIDs(FImage& f, uint64_t guids[GUIDS],
\r
1761 uint64_t old_guids[GUIDS];
\r
1762 uint32_t *buf = f.getBuf();
\r
1763 uint32_t buf_len = f.getBufLength();
\r
1764 uint32_t signature = buf[0x24/4];
\r
1765 uint32_t ind1=0,ind2=0;
\r
1766 uint32_t nguid1, nguid2;
\r
1768 TOCPU1(signature);
\r
1769 if (signature == SIGNATURE)
\r
1772 M_DEBUG("Extracting GUIDs from PPS : ");
\r
1773 if (!extractGUIDptr(SECT_SIZE, buf, buf_len, "Primary", &ind1, &nguid1))
\r
1775 M_DEBUG("Failed\n");
\r
1779 M_DEBUG("[SUCCESS]\n");
\r
1781 M_DEBUG("Extracting GUIDs from SPS : ");
\r
1782 if (!extractGUIDptr(SECT_SIZE*2, buf, buf_len, "Secondary", &ind2,
\r
1785 M_DEBUG("Failed\n");
\r
1788 M_DEBUG("[SUCCESS]\n");
\r
1793 M_DEBUG("Extracting GUIDs from PS : ");
\r
1794 if (!extractGUIDptr(0, buf, buf_len, "Primary", &ind1, &nguid1))
\r
1796 M_DEBUG("Failed\n");
\r
1800 M_DEBUG("[SUCCESS]\n");
\r
1803 // Print old GUIDs and get confirmation
\r
1806 bool old_guids_fmt = nguid1 < GUIDS;
\r
1807 for (uint32_t i=0; i<GUIDS; i++)
\r
1809 uint32_t h = buf[ind1/4 + i*2];
\r
1811 uint32_t l = buf[ind1/4 + i*2 + 1];
\r
1813 old_guids[i] = ((uint64_t)h << 32) | l;
\r
1815 if ( !(old_guids[0] == guids[0]) || !(old_guids[1] == guids[1]) || !(old_guids[2] == guids[2]))
\r
1817 if (old_guids_fmt)
\r
1818 printf(" Old image!!!! Only %d GUIDs may be set.\n", nguid1);
\r
1819 printf(" Old GUIDs (inside image) are:\n");
\r
1820 printf(" Node: %016"PRIx64"\n", old_guids[0]);
\r
1821 printf(" Port1: %016"PRIx64"\n", old_guids[1]);
\r
1822 printf(" Port2: %016"PRIx64"\n", old_guids[2]);
\r
1823 if (!old_guids_fmt)
\r
1824 printf(" Sys.Image: %016"PRIx64"\n", old_guids[3]);
\r
1825 printf("\n You are about to change them to the following GUIDs:\n");
\r
1826 printf(" Node: %016"PRIx64"\n", guids[0]);
\r
1827 printf(" Port1: %016"PRIx64"\n", guids[1]);
\r
1828 printf(" Port2: %016"PRIx64"\n", guids[2]);
\r
1829 if (!old_guids_fmt)
\r
1830 printf(" Sys.Image: %016"PRIx64"\n", guids[3]);
\r
1831 printf("\n Is it OK ? (y/n) [n] : ");
\r
1833 char c = (char)getchar();
\r
1835 while (getchar() != '\n');
\r
1841 // Path GUIDs section
\r
1842 patchGUIDsSection(buf, ind1, guids, nguid1);
\r
1844 M_DEBUG("Inserting GUIDs into PPS : [SUCCESS]\n");
\r
1848 M_DEBUG("Inserting GUIDs into SPS : [SUCCESS]\n");
\r
1849 patchGUIDsSection(buf, ind2, guids, nguid2);
\r
1855 void patchVSDSection(
\r
1856 uint32_t *buffer,
\r
1857 uint32_t pointerSectorOffset,
\r
1858 uint32_t companyid,
\r
1862 uint32_t i, x, word, offset=0;
\r
1863 uint32_t newbuffer[sizeof(PS)];
\r
1867 memcpy(newbuffer, (buffer+pointerSectorOffset/sizeof(uint32_t)), sizeof(PS));
\r
1869 memcpy(&ps, newbuffer, sizeof(PS));
\r
1870 ps.vsd[0] = __cpu_to_be32(companyid);
\r
1871 // Currently time_t is 32 bits, but this will only last until the
\r
1872 // year 2037. Therefore, I am leaving 64bits for when the time_t
\r
1873 // size is increased which will probably provide an Epoch time far larger
\r
1874 // than man will exist. Note: Although, I have provided the space for a
\r
1875 // larger time_t this code will need to be modified to handle the 64bit
\r
1876 // Epoch time before 2037.
\r
1878 *((uint64_t*)&ps.vsd[1]) = cl_ntoh64(timestamp);
\r
1880 ps.vsd[1] = (uint32_t)0;
\r
1881 ps.vsd[2] = __cpu_to_be32(timestamp);
\r
1884 if (NULL != revision)
\r
1888 memcpy(&ps.vsd[x], revision+offset, sizeof(uint32_t));
\r
1889 ps.vsd[x] = __cpu_to_be32(ps.vsd[x]);
\r
1890 offset = offset + 4;
\r
1893 memcpy(newbuffer, &ps, sizeof(PS));
\r
1895 // Calculate new CRC16
\r
1896 for (i=0; i<((sizeof(PS)/sizeof(uint32_t))-1); i++)
\r
1898 word = newbuffer[i];
\r
1908 memcpy(newbuffer, &ps, sizeof(PS));
\r
1909 // patch VSD in buffer
\r
1910 memcpy(buffer+pointerSectorOffset/sizeof(uint32_t), newbuffer, sizeof(PS));
\r
1912 } // patchGUIDsSection
\r
1914 bool patchVSDs(FImage &image, char *revision)
\r
1916 uint32_t signature;
\r
1917 uint32_t companyid = 0x0000066A; // InfiniCon
\r
1919 READ4(image, 0x24, &signature, "Signature");
\r
1920 TOCPU1(signature);
\r
1922 if (signature == SIGNATURE)
\r
1926 etime = time(NULL);
\r
1928 (device.getClassType()==Flash::FlashDeviceType?"Burn Date : ":"Creation : "),
\r
1929 asctime(localtime(&etime)));
\r
1930 patchVSDSection(image.getBuf(), SECT_SIZE , companyid, etime, revision);
\r
1931 patchVSDSection(image.getBuf(), SECT_SIZE*2, companyid, etime, revision);
\r
1936 //printf("Can not inject VSD into a Short Image.\n");
\r
1941 bool burnImageToFlash(FlashCommandLine cl)
\r
1944 uint64_t guids[GUIDS];
\r
1945 bool insertGUIDs = false;
\r
1946 uint32_t Fhardwareversion=0;
\r
1947 uint32_t Ihardwareversion=0;
\r
1948 uint32_t Fsignature=0;
\r
1949 uint32_t Isignature=0;
\r
1951 if (!device.open(cl.getDeviceName()))
\r
1953 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
1957 // We are always able to get the revision from the pci bus.
\r
1958 device.read(0x10, &Fhardwareversion, sizeof(Fhardwareversion));
\r
1959 TOCPU1(Fhardwareversion);
\r
1960 Fhardwareversion >>=24;
\r
1962 if (Fhardwareversion > 0xA0)
\r
1964 device.read(0x24, &Fsignature, sizeof(Fsignature));
\r
1965 TOCPU1(Fsignature);
\r
1968 if (!cl.isOption(FlashCommandLine::force))
\r
1970 if (Fhardwareversion != 0xA1 && Fhardwareversion != 0xA0)
\r
1972 printf("!!!WARNING!!!\n"
\r
1973 "Unable to determine the device\'s %s firmware revision (unknown rev %x)!\n"
\r
1974 "It could be a corrupted firmware or an unsupported board revision.\n"
\r
1976 "Aborting operation.\n",
\r
1977 cl.getDeviceName(),
\r
1979 techSupportMessage);
\r
1984 printf("!!!WARNING!!! Skipping flash device hardware revision integrity check.\n");
\r
1987 M_DEBUG("Open raw file.\n");
\r
1989 if (!image.open(cl.getRawFileName()))
\r
1991 printf("Error: %s %s\n", image._err, cl.getRawFileName());
\r
1995 M_DEBUG("Verify raw file.\n");
\r
1998 if (!image.verify())
\r
2000 printf("%s is not a valid image\n", cl.getRawFileName());
\r
2004 image.read(0x24, &Isignature);
\r
2005 TOCPU1(Isignature);
\r
2007 image.read(0x10, &Ihardwareversion, sizeof(Ihardwareversion));
\r
2008 TOCPU1(Ihardwareversion);
\r
2009 Ihardwareversion >>=24;
\r
2011 M_DEBUG("Verify hardware and signature information.\n");
\r
2013 if (!cl.isOption(FlashCommandLine::force))
\r
2015 if (Ihardwareversion != 0xA1 && Ihardwareversion != 0xA0)
\r
2017 printf("!!!WARNING!!!\n"
\r
2018 "Unable to determine the image\'s %s firmware revision (unknown rev %x)!\n"
\r
2019 "It could be a corrupted image or an unsupported board revision.\n"
\r
2021 "Aborting operation.\n",
\r
2022 cl.getDeviceName(),
\r
2024 techSupportMessage);
\r
2027 else if (Fhardwareversion != Ihardwareversion)
\r
2029 printf("!!!WARNING!!! "
\r
2030 "An HCA Rev %X firmware can not be used with HCA Rev %X device!!!\n"
\r
2031 "Aborting operation.\n",
\r
2033 Fhardwareversion);
\r
2037 if (Fhardwareversion == 0xA0)
\r
2039 if (Isignature == SIGNATURE)
\r
2041 printf("!!!WARNING!!! "
\r
2042 "Rev A0 HCA's will not work with a fail safe image!!!\n"
\r
2044 "Aborting operation.\n", techSupportMessage);
\r
2051 printf("!!!DANGER!!!! Skipping image file hardware revision integrity check.\n");
\r
2054 printf("HCA Rev : %"PRIX32"\n", Fhardwareversion);
\r
2055 printf("Image Rev : %"PRIX32"\n", Ihardwareversion);
\r
2057 if (!cl.useFlashNodeGUID())
\r
2058 { // the user specified the guid at the command line
\r
2059 if (!getGUIDs(cl.getNodeGUID(),guids))
\r
2061 printf("Aborting burn operation.\n");
\r
2065 insertGUIDs = true;
\r
2068 // should we query the flash device for the guids
\r
2069 // If we don't query the flash for the guids, and
\r
2070 // we don't specify the guids at the command line
\r
2071 // then we will use the guids supplied in the raw
\r
2073 M_DEBUG("Query the flash device\n");
\r
2074 if (!cl.isOption(FlashCommandLine::noquery))
\r
2076 // obtain the guids from the flash
\r
2077 if (!getGUIDsFromFlash(device, guids))
\r
2079 printf("The image on the flash device appears corrupted!\n"
\r
2080 "Unable to determine the GUIDs from the flash device %s.\n"
\r
2081 "Try the -n <0xGUID> option. If this fails, then contact\n"
\r
2082 "SilverStorm Technologies technical support.\n",
\r
2083 cl.getDeviceName());
\r
2087 insertGUIDs = true;
\r
2093 if (cl.isOption(FlashCommandLine::no_prompts))
\r
2095 interactive=false;
\r
2099 interactive = (_isatty(_fileno( stdin )) > 0 ? true: false);
\r
2102 bool eraseInvariant = false;
\r
2104 if (cl.isOption(FlashCommandLine::burn_invariant_section))
\r
2106 M_DEBUG("Always burn invariant section.\n");
\r
2107 eraseInvariant = true;
\r
2108 } else // only burn the invariant section if it differs
\r
2110 if (isInvariantSectionEqual(device, image))
\r
2112 M_DEBUG("The invariant sections are equal.\n");
\r
2113 eraseInvariant = false;
\r
2116 M_DEBUG("The invariant sections differ.\n");
\r
2117 eraseInvariant = true;
\r
2121 M_DEBUG("Patch GUIDs.\n");
\r
2124 if (insertGUIDs && !patchGUIDs(image, guids, interactive))
\r
2126 printf("Aborting burn operation at user request.\n");
\r
2130 M_DEBUG("Patch VSDs.\n");
\r
2133 if (!patchVSDs(image, NULL))
\r
2135 // if this fails it means it's a short image, and we should just continue on
\r
2138 M_DEBUG("Write firmware.\n");
\r
2141 if (!device.write_image(0, image.getBuf(), image.getBufLength(), eraseInvariant, (_isatty(_fileno( stdin )) > 0? true: false)) )
\r
2143 printf("Error: %s\n", device._err);
\r
2153 bool patchVSDToRawImage(FlashCommandLine cl)
\r
2155 printf("Attempting to insert VSD section into the %s file: \n", cl.getRawFileName());
\r
2157 if (!image.open(cl.getRawFileName()))
\r
2159 printf("Error: %s\n", image._err);
\r
2160 printf("Aborting operation.\n");
\r
2164 if (!patchVSDs(image, cl.getRevisionString()))
\r
2166 printf("Failed.\n"
\r
2168 "Unable to inject the VSD into a Short Image.\n"
\r
2169 "Short images do not support the VSD section.\n"
\r
2170 "Only Fail Safe images support the VSD section.\n"
\r
2171 "Aborting operation.\n");
\r
2176 void *write_buffer;
\r
2177 uint32_t buflen = image.getBufLength();
\r
2179 // it is necessary to close the file prior to re-opening for write privileges
\r
2180 // this allows us to write to the same file without using a temporary file
\r
2181 write_buffer = malloc(buflen);
\r
2182 memcpy(write_buffer, image.getBuf(), buflen);
\r
2185 // only open the file, if any things fails, then the image verify
\r
2186 // will indicate issues
\r
2187 if ((fd = fopen(cl.getRawFileName(),"w")) != NULL)
\r
2189 fwrite(write_buffer, buflen, 1, fd);
\r
2193 printf("Failed.\n"
\r
2194 "Unable to write to raw image file %s.\n", cl.getRawFileName());
\r
2196 if (!image.verify()) // verify file integrity
\r
2198 printf("!!!WARNING!!! "
\r
2199 "The file appears to have been corrupted!!!\n");
\r
2203 printf("File appears to be valid, but the VSD injection failed.\n");
\r
2210 // ok to free the buffer now
\r
2211 free(write_buffer);
\r
2213 if (!image.open(cl.getRawFileName()))
\r
2215 printf("Error: %s\n", image._err);
\r
2216 printf("Aborting operation.\n");
\r
2220 if (!image.verify()) // verify file integrity
\r
2222 printf("Failed Verification.\n"
\r
2223 "The file %s appears to have been corrupted\n", cl.getRawFileName());
\r
2228 printf("Insertion : [SUCCESS]\n");
\r
2229 printf("Done.\n");
\r
2233 bool showInfo(FBase &device, FlashCommandLine cl)
\r
2235 uint32_t NODE_GUIDH, NODE_GUIDL;
\r
2236 uint32_t PORT1_GUIDH, PORT1_GUIDL;
\r
2237 uint32_t PORT2_GUIDH, PORT2_GUIDL;
\r
2238 uint32_t hardwareversion;
\r
2240 uint32_t signature;
\r
2244 bool isFailSafe = false;
\r
2245 uint64_t guids[GUIDS];
\r
2246 char revision[FlashCommandLine::revisionStringLength];
\r
2248 READ4(device, 0x24, &signature, "Signature");
\r
2249 TOCPU1(signature);
\r
2259 if (signature == SIGNATURE)
\r
2261 uint8_t offset =0, x=0;
\r
2262 // Fail Safe image
\r
2264 // verify the image invariant section
\r
2265 if (!checkBoot2(device, 0, 0x28, psptr, "Invariant\t"))
\r
2267 printf("Invariant section is not valid!");
\r
2272 if (!checkPS(device, SECT_SIZE, psptr, "Primary\t"))
\r
2274 M_DEBUG("Primary section is not valid\n");
\r
2275 // If the primary is invalid then try secondary section
\r
2276 if (!checkPS(device, SECT_SIZE*2, psptr, "Secondary\t"))
\r
2278 printf("Firmware is corrupted. Unable to display information.\n");
\r
2282 section=2; // secondary is valid, use it
\r
2285 device.read(0x10, &hardwareversion, sizeof(hardwareversion));
\r
2286 TOCPU1(hardwareversion);
\r
2287 hardwareversion >>=24;
\r
2288 device.read(SECT_SIZE*section, &ps, sizeof(ps));
\r
2289 TOCPUBY(ps,sizeof(ps));
\r
2290 printf("Image Type : Fail Safe\n");
\r
2291 if (hardwareversion != 0xA0 && hardwareversion != 0xA1)
\r
2293 printf("Hardware Version : 0xInvalid\n");
\r
2297 printf("Hardware Version : 0x%"PRIX32"\n", hardwareversion);
\r
2299 printf("Company : %s\n", ps.vsd[0]==0x00066A?"SilverStorm Technologies":"Mellanox, Inc");
\r
2301 myTime = ps.vsd[2];
\r
2302 printf("%s Date : %s", (device.getClassType()==Flash::FlashDeviceType?"Burn ":"Creation"), asctime(localtime(&myTime)));
\r
2306 memcpy(revision+offset, &ps.vsd[x], sizeof(uint32_t));
\r
2307 offset = offset + 4;
\r
2309 revision[FlashCommandLine::revisionStringLength-1]='\0';
\r
2310 printf("Firmware Revision : %s\n", revision);
\r
2311 READ4(device, ps.fi_addr+0x24, &psptr, "pointer section");
\r
2312 printf("Firmware Address : 0x%"PRIx32"\n", ps.fi_addr);
\r
2313 printf("Node GUID Offset : 0x%"PRIx32"\n", psptr);
\r
2314 psptr = BE2CPU32(psptr)+ps.fi_addr;
\r
2315 isFailSafe = true;
\r
2319 if (!checkList(device, 0,""))
\r
2321 printf("Firmware is not valid. Can not display information.\n");
\r
2326 // Assume flash has been verified, and both images have the same guids, therefore,
\r
2327 // we only need to read the primary image's guids
\r
2328 device.read(0x10, &hardwareversion, sizeof(hardwareversion));
\r
2329 TOCPU1(hardwareversion);
\r
2330 hardwareversion >>=24;
\r
2331 printf("Image Type : Short\n");
\r
2332 if (hardwareversion != 0xA0 && hardwareversion != 0xA1)
\r
2334 printf("Hardware Version : 0xInvalid\n");
\r
2338 printf("Hardware Version : 0x%X\n", hardwareversion);
\r
2340 printf("Company : Unknown\n");
\r
2341 printf("%s Date : Unknown\n", (device.getClassType()==Flash::FlashDeviceType?"Burn ":"Creation"));
\r
2342 printf("Firmware Revision : Unknown\n");
\r
2343 printf("Firmware Address : 0xUnknown\n");
\r
2344 psptr = signature;
\r
2345 if (psptr < MST_MAX_FLASH )
\r
2347 printf("Node GUID Offset : 0x%"PRIx32"\n", psptr);
\r
2350 printf("Node GUID Offset : 0x%"PRIx32" !!! Error: Invalid !!!\n", psptr);
\r
2355 if (psptr < MST_MAX_FLASH || isFailSafe)
\r
2357 READ4(device, psptr, &NODE_GUIDH, "Node GUID High");
\r
2358 READ4(device, psptr+4, &NODE_GUIDL, "Node GUID Low");
\r
2359 guids[0] = BE2CPU32(NODE_GUIDH);
\r
2360 guids[0] = (guids[0]<<32) | BE2CPU32(NODE_GUIDL);
\r
2361 READ4(device, psptr+8, &PORT1_GUIDH, "Port 1 GUID High");
\r
2362 READ4(device, psptr+12, &PORT1_GUIDL, "Port 1 GUID Low");
\r
2363 guids[1] = BE2CPU32(PORT1_GUIDH);
\r
2364 guids[1] = (guids[1]<<32) | BE2CPU32(PORT1_GUIDL);
\r
2365 READ4(device, psptr+16, &PORT2_GUIDH, "Port 2 GUID High");
\r
2366 READ4(device, psptr+20, &PORT2_GUIDL, "Port 2 GUID Low");
\r
2367 guids[2] = BE2CPU32(PORT2_GUIDH);
\r
2368 guids[2] = (guids[2]<<32) | BE2CPU32(PORT2_GUIDL);
\r
2370 guids[3] = guids[0];
\r
2371 printf("Node GUID : 0x%016"PRIx64"\n", guids[0]);
\r
2372 printf("Port1 GUID : 0x%016"PRIx64"\n", guids[1]);
\r
2373 printf("Port2 GUID : 0x%016"PRIx64"\n", guids[2]);
\r
2376 printf("Node GUID : 0xInvalid\n");
\r
2377 printf("Port1 GUID : 0xInvalid\n");
\r
2378 printf("Port2 GUID : 0xInvalid\n");
\r
2379 printf("!!! WARNING: The flash %s is corrupted.\n"
\r
2380 "You must use the -n <0xGUID> and --force option to update this device.\n",
\r
2381 cl.getDeviceName());
\r
2389 ////////////////////////////////////////////////////////////////////////
\r
2391 // ****************************************************************** //
\r
2393 // ****************************************************************** //
\r
2395 ////////////////////////////////////////////////////////////////////////
\r
2397 main(uint32_t ac, char *av[])
\r
2399 FlashCommandLine cl;
\r
2401 //try to get lock on box
\r
2402 if (FwUpdateLock() != 0 )
\r
2405 // register unlock func in exit
\r
2406 _onexit((_onexit_t)FwUpdateUnlock);
\r
2410 if (cl.isOption(FlashCommandLine::debug))
\r
2416 if (cl.isOption(FlashCommandLine::disable_bestdevice))
\r
2418 DisableBestDevice = true;
\r
2422 if (cl.isOption(FlashCommandLine::flash_format))
\r
2424 if (!device.open(cl.getDeviceName()))
\r
2426 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2434 if (cl.isOption(FlashCommandLine::show_image_info))
\r
2436 if (!image.open(cl.getRawFileName()))
\r
2438 printf("Error: %s\n", image._err);
\r
2442 showInfo(image, cl);
\r
2446 if (cl.isOption(FlashCommandLine::show_flash_info))
\r
2448 if (!device.open(cl.getDeviceName()))
\r
2450 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2454 showInfo(device, cl);
\r
2458 if (cl.isOption(FlashCommandLine::dump_image))
\r
2460 if (!image.open(cl.getRawFileName()))
\r
2462 printf("Error: %s\n", image._err);
\r
2470 if (cl.isOption(FlashCommandLine::dump_flash))
\r
2472 if (!device.open(cl.getDeviceName()))
\r
2474 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2481 if (cl.isOption(FlashCommandLine::verify_image))
\r
2483 if (!image.open(cl.getRawFileName()))
\r
2485 printf("Error: %s\n", image._err);
\r
2492 if (cl.isOption(FlashCommandLine::verify_flash))
\r
2494 if (!device.open(cl.getDeviceName()))
\r
2496 printf("Error: %s %s\n", device._err, cl.getDeviceName());
\r
2503 if (cl.isOption(FlashCommandLine::write_file))
\r
2505 if (!patchVSDToRawImage(cl))
\r
2511 if (cl.isOption(FlashCommandLine::burn))
\r
2513 if (!burnImageToFlash(cl))
\r
2518 // For A0 HCAs we need to write to both banks of the flash.
\r
2519 if ((devType == TAVOR_TYPE) && (devRevision == 0xA0))
\r
2521 device.setGPIOState(Flash::High);
\r
2523 if (!burnImageToFlash(cl))
\r
2533 bool probePciBusForHcaDevice(const char *device)
\r
2536 char output[MAXPATHLEN];
\r
2537 char tmpRevision[5];
\r
2540 devId = HcaDevnameToDevId(device);
\r
2541 devType = HcaDevnameToDevType(device);
\r
2543 sprintf(output,"lspci -m -n | grep 15b3 | grep %x",devType);
\r
2544 stream = _popen(output, "r");
\r
2546 if (NULL == stream)
\r
2548 printf("Error probing the PCI bus for HCA devcies.\n");
\r
2551 M_DEBUG("Probing PCI bus for HCA devices.\n");
\r
2553 while (fgets(output, MAXPATHLEN, stream))
\r
2555 if (mellanox_mode)
\r
2557 if (i++ != devId) continue;
\r
2560 if (++i != devId) continue;
\r
2563 if (strlen(output)>1)
\r
2564 output[strlen(output)-1]='\0';
\r
2566 tmpRevision[0] = '0';
\r
2567 tmpRevision[1] = 'x';
\r
2568 tmpRevision[2] = output[37];
\r
2569 tmpRevision[3] = output[38];
\r
2570 tmpRevision[4] = '\0';
\r
2572 // probably should check errno in case of an invalid revision
\r
2573 devRevision = strtol(tmpRevision, (char**)NULL, 0);
\r
2575 sprintf(bestDev, "/dev/mst/mt%d_pci_cr%d", devType, devId);
\r
2577 M_DEBUG("Trying device %s.\n", bestDev);
\r
2579 if (NULL != fopen(bestDev, "r"))
\r
2581 M_DEBUG("HCA %d (Rev. %"PRIx32") using device name %s.\n", devId, devRevision, bestDev);
\r
2584 sprintf(bestDev, "/dev/mst/mt%d_pciconf%d", devType, devId);
\r
2585 M_DEBUG("Trying device %s.\n", bestDev);
\r
2587 if (NULL != fopen(bestDev, "r"))
\r
2589 M_DEBUG("HCA %d (Rev. %"PRIx32") using device name %s.\n", devId, devRevision, bestDev);
\r
2592 printf("We found HCA %d on the PCI bus, but it does not appear to be operating properly.\n", devId);
\r
2593 printf("Please verify the mst device driver is running without errors. If the problem persist,\n"
\r
2594 "then contact technical support.\n");
\r
2603 printf("Specified device %d not found.\n", devId);
\r
2604 printf("Found %d device%s of type mt%d\n",i,(i==1)?"":"s",devType);
\r
2609 uint32_t HcaDevnameToDevId(const char *devname)
\r
2611 if (strlen(devname) >= 1)
\r
2613 if (isdigit(devname[strlen(devname)-1]))
\r
2615 return ((uint8_t)devname[strlen(devname)-1])-48;
\r
2618 M_DEBUG("Device name should end with a numeric value between 1 and 9.\n");
\r
2623 M_DEBUG("Device name is too short.\n");
\r
2626 M_DEBUG("Invalid device name using default device 1.\n");
\r
2630 uint32_t HcaDevnameToDevType(const char *devname)
\r
2632 uint32_t type = 0;
\r
2635 str = strstr(devname, "mt");
\r
2639 type = strtol(str, NULL, 10);
\r
2641 if ((type != TAVOR_TYPE) && (type != ARBEL_TYPE))
\r
2643 M_DEBUG("Device name should contain device type, using mt23108.\n");
\r
2644 type = TAVOR_TYPE;
\r
2649 bool isMstLoaded(void)
\r
2652 char output[MAXPATHLEN];
\r
2654 /* Check for infinicon-compiled mst driver. */
\r
2655 stream = _popen("/sbin/lsmod | grep mst |cut -d\" \" -f1", "r");
\r
2657 if (NULL == stream)
\r
2660 fgets(output, MAXPATHLEN, stream);
\r
2662 if (strlen(output)>1)
\r
2663 output[strlen(output)-1]='\0';
\r
2667 if ((NULL != output) && (strncmp("mst", output, MAXPATHLEN) == 0))
\r
2670 /* That failed - check for mellanox-compiled mst driver. */
\r
2671 stream = _popen("/sbin/lsmod | grep mst_pci |cut -d\" \" -f1", "r");
\r
2673 if (NULL == stream)
\r
2676 fgets(output, MAXPATHLEN, stream);
\r
2678 if (strlen(output)>1)
\r
2679 output[strlen(output)-1]='\0';
\r
2683 if ((NULL != output) && (strncmp("mst_pci", output, MAXPATHLEN) == 0))
\r
2685 mellanox_mode = 1;
\r
2692 void __cdecl catch_signal( int sig )
\r
2694 //fprintf( stdout, "\nProgram Interrupted. Closing devices.\n" );
\r
2701 FwUpdateLock(void)
\r
2704 if ((file_lock = _open( LOCK_FILE_NAME, _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE )) == -1 )
\r
2706 printf("One instance is running already\n");
\r
2712 FwUpdateUnlock(void)
\r
2714 if ((_close(file_lock)) != -1 )
\r
2716 if ((_unlink(LOCK_FILE_NAME)) != -1 )
\r
2721 printf("Unlock can not release lock\n");
\r