fixes #443: -udev stdout should replace 70-uuu.rules rather than be appended to it
[mfgtools.git] / libuuu / sdp.cpp
blobda008368779794f7e0178401f001d22010e36ab0
1 /*
2 * Copyright 2018 NXP.
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
14 * Neither the name of the NXP Semiconductor nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
32 #include <string>
33 #include "config.h"
34 #include "sdps.h"
35 #include "hidreport.h"
36 #include "liberror.h"
37 #include "libcomm.h"
38 #include "buffer.h"
39 #include "sdp.h"
40 #include "rominfo.h"
41 #include "libusb.h"
42 #include "trans.h"
44 #include <cstring>
46 int SDPCmdBase::check_ack(HIDReport *report, uint32_t ack)
48 if (get_hab_type(report) == HabUnknown)
49 return -1;
51 uint32_t status;
52 if (get_status(report, status, 4))
53 return -1;
55 if (ack != status)
57 set_last_err_string("Status Miss matched");
58 return -1;
60 return 0;
63 SDPCmdBase::HAB_t SDPCmdBase::get_hab_type(HIDReport *report)
65 uint32_t status;
66 if (get_status(report, status, 3))
67 return HabUnknown;
69 if (status == HabEnabled)
70 return HabEnabled;
72 if (status == HabDisabled)
73 return HabDisabled;
75 set_last_err_string("unknown hab type");
76 return HabUnknown;
79 int SDPCmdBase::get_status(HIDReport *p, uint32_t &status, uint8_t report_id)
81 m_input.resize(1025);
82 m_input[0] = report_id;
83 int ret = p->read(m_input);
84 if (ret < 0)
85 return -1;
87 if (m_input.size() < (1 + sizeof(uint32_t)))
89 set_last_err_string("HID report size is too small");
90 return -1;
93 status = *(uint32_t*)(m_input.data() + 1);
94 return 0;
97 int SDPCmdBase::init_cmd()
99 memset(&m_spdcmd, 0, sizeof(m_spdcmd));
100 insert_param_info("-scanlimited", &m_scan_limited, Param::Type::e_uint64);
101 return 0;
104 IvtHeader *SDPCmdBase::search_ivt_header(shared_ptr<DataBuffer> data, size_t &off, size_t limit)
106 if (limit >= data->size())
107 limit = data->size();
109 for (; off < limit; off += 0x4)
111 IvtHeader *p = (IvtHeader*)(data->data() + off);
112 if (p->IvtBarker == IVT_BARKER_HEADER)
113 return p;
114 if (p->IvtBarker == IVT_BARKER2_HEADER)
116 BootData *pDB = (BootData *) &(data->at(off + p->BootData - p->SelfAddr));
118 /*Skip HDMI firmware for i.MX8MQ*/
119 if (pDB->PluginFlag & 0xFFFFFFFE)
120 continue;
121 return p;
124 off = -1;
125 return nullptr;
128 int SDPCmdBase::send_cmd(HIDReport *p)
130 return p->write(&m_spdcmd, sizeof(m_spdcmd), 1);
133 SDPDcdCmd::SDPDcdCmd(char *p) : SDPCmdBase(p)
135 insert_param_info("dcd", nullptr, Param::Type::e_null);
136 insert_param_info("-f", &m_filename, Param::Type::e_string_filename);
137 insert_param_info("-dcdaddr", &m_dcd_addr, Param::Type::e_uint32);
138 m_dcd_addr = 0;
141 int SDPDcdCmd::run(CmdCtx*ctx)
143 const ROM_INFO * rom = search_rom_info(ctx->m_config_item);
144 if (rom == nullptr)
146 string_ex err;
147 err.format("%s:%d can't get rom info", __FUNCTION__, __LINE__);
148 set_last_err_string(err);
149 return -1;
151 init_cmd();
153 shared_ptr<FileBuffer> p = get_file_buffer(m_filename, true);
155 if (!p)
156 return -1;
158 shared_ptr<DataBuffer> buff;
159 buff = p->request_data(0, m_scan_limited);
160 if (!buff) return -1;
162 size_t off = 0;
163 IvtHeader *pIVT = search_ivt_header(buff, off);
164 if (pIVT == nullptr)
166 return 0;
169 if (pIVT->DCDAddress == 0)
170 return 0;
172 uint8_t * pdcd = &(buff->at(off + pIVT->DCDAddress - pIVT->SelfAddr));
174 if (pdcd[0] != HAB_TAG_DCD)
176 string_ex err;
177 err.format("%s:%d DCD TAG miss matched", __FUNCTION__, __LINE__);
178 set_last_err_string(err);
179 return -1;
182 uint32_t size = (pdcd[1] << 8) | pdcd[2];
184 if (size >= m_scan_limited)
186 set_last_err_string("dcd bigger than 8M");
187 return -1;
190 // point maybe change after new requisition buffer.
191 pdcd = &(buff->at(off + pIVT->DCDAddress - pIVT->SelfAddr));
193 m_spdcmd.m_cmd = ROM_KERNEL_CMD_DCD_WRITE;
194 m_spdcmd.m_addr = EndianSwap(m_dcd_addr ? m_dcd_addr : rom->free_addr);
195 m_spdcmd.m_count = EndianSwap(size);
197 HIDTrans dev(m_timeout);
198 if (dev.open(ctx->m_dev))
199 return -1;
201 HIDReport report(&dev);
202 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
203 return -1;
205 if (report.write(pdcd, size, 2))
206 return -1;
208 if (check_ack(&report, ROM_WRITE_ACK))
209 return -1;
211 return 0;
214 SDPSkipDCDCmd::SDPSkipDCDCmd(char *p) : SDPCmdBase(p)
216 m_spdcmd.m_cmd = ROM_KERNEL_CMD_SKIP_DCD_HEADER;
219 int SDPSkipDCDCmd::run(CmdCtx*ctx)
221 HIDTrans dev(m_timeout);
222 if (dev.open(ctx->m_dev))
223 return -1;
225 HIDReport report(&dev);
226 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
227 return -1;
229 if (check_ack(&report, ROM_OK_ACK))
230 return -1;
232 return 0;
235 SDPBootCmd::SDPBootCmd(char *p) : SDPCmdBase(p)
237 insert_param_info("boot", nullptr, Param::Type::e_null);
238 insert_param_info("-f", &m_filename, Param::Type::e_string_filename);
239 insert_param_info("-nojump", &m_nojump, Param::Type::e_bool);
240 insert_param_info("-cleardcd", &m_clear_dcd, Param::Type::e_bool);
241 insert_param_info("-dcdaddr", &m_dcd_addr, Param::Type::e_uint32);
242 insert_param_info("-scanlimited", &m_scan_limited, Param::Type::e_uint64);
243 insert_param_info("-barebox", &m_barebox, Param::Type::e_bool);
246 # define BAREBOX_MAGIC_OFFSET 0x20
248 bool SDPBootCmd::is_barebox_img(void)
250 shared_ptr<FileBuffer> fbuf= get_file_buffer(m_filename, true);
251 if (fbuf == nullptr)
252 return false;
254 string barebox_magic ("barebox");
256 shared_ptr<DataBuffer> dbuf = fbuf->request_data(0, BAREBOX_MAGIC_OFFSET + barebox_magic.length());
257 if (dbuf == nullptr)
258 return false;
260 string img ((const char *)&dbuf->at(BAREBOX_MAGIC_OFFSET), barebox_magic.length());
262 return img.compare(barebox_magic) == 0 ? true : false;
265 int SDPBootCmd::load_barebox(CmdCtx *ctx)
267 const ROM_INFO *rom = search_rom_info(ctx->m_config_item);
269 if (!rom)
270 return 0;
272 // The barebox USB loading mechanism differs between SoCs due to SRAM
273 // size limitations.
275 // E.g. all i.MX8M SoCs require a two stage loading, first the
276 // pre-bootloader (PBL) is loaded to the internal SRAM and started. The
277 // PBL intialize the DDR and uses the BootROM initialized USB
278 // controller to load the remaining "full barebox image" to the DDR.
280 // On i.MX6 devices this is not the case since the DDR setup is done
281 // via the DCD and we can load the image directly to the DDR.
283 // The ROM_INFO_NEED_BAREBOX_FULL_IMAGE flag indicates if the two-stage
284 // load mechanism is required for a specific SoC. So the user can
285 // always specify '-barebox' no matter if it's required or not:
287 // SDP: boot -barebox -f <barebox.img>
288 if (!(rom->flags & ROM_INFO_NEED_BAREBOX_FULL_IMAGE))
289 return 0;
291 string str;
292 str = "SDP: write -f ";
293 str += m_filename;
294 str += " -ivt 0";
295 str += " -barebox-bl33";
297 SDPWriteCmd wr((char *)str.c_str());
298 if (wr.parser()) return -1;
300 return wr.run(ctx);
303 int SDPBootCmd::run(CmdCtx *ctx)
305 string str;
306 str = "SDP: dcd -f ";
307 str += m_filename;
308 if (m_dcd_addr) {
309 str += " -dcdaddr ";
310 str += std::to_string(m_dcd_addr);
313 if (m_scan_limited != UINT64_MAX)
315 str += " -scanlimited ";
316 str += std::to_string(m_scan_limited);
319 SDPDcdCmd dcd((char *)str.c_str());
321 if (m_scan_limited != UINT64_MAX)
323 str += " -scanlimited ";
324 str += std::to_string(m_scan_limited);
327 if (dcd.parser()) return -1;
328 if (dcd.run(ctx)) return -1;
330 str = "SDP: write -f ";
331 str += m_filename;
332 str += " -ivt 0";
334 if (m_scan_limited != UINT64_MAX)
336 str += " -scanlimited ";
337 str += std::to_string(m_scan_limited);
340 SDPWriteCmd wr((char *)str.c_str());
341 if (wr.parser()) return -1;
342 if (wr.run(ctx)) return -1;
344 str = "SDP: jump -f ";
345 str += m_filename;
346 str += " -ivt 0";
347 if (m_clear_dcd)
348 str += " -cleardcd";
350 if (m_scan_limited != UINT64_MAX)
352 str += " -scanlimited ";
353 str += std::to_string(m_scan_limited);
356 SDPJumpCmd jmp((char *)str.c_str());
357 if (!m_nojump)
359 if (jmp.parser()) return -1;
360 if (jmp.run(ctx)) return -1;
363 if (m_barebox || is_barebox_img())
365 if (load_barebox(ctx)) return -1;
368 SDPBootlogCmd log(nullptr);
369 log.run(ctx);
371 return 0;
374 SDPStatusCmd::SDPStatusCmd(char *p) : SDPCmdBase(p)
376 m_spdcmd.m_cmd = ROM_KERNEL_CMD_ERROR_STATUS;
377 insert_param_info("status", nullptr, Param::Type::e_null);
380 int SDPStatusCmd::run(CmdCtx *ctx)
382 HIDTrans dev(m_timeout);
383 if (dev.open(ctx->m_dev))
384 return -1;
386 HIDReport report(&dev);
387 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
388 return -1;
390 if (get_hab_type(&report) == HabUnknown)
391 return -1;
393 uint32_t status;
394 if (get_status(&report, status, 4))
395 return -1;
397 return 0;
400 SDPWriteCmd::SDPWriteCmd(char *p) : SDPCmdBase(p)
402 m_spdcmd.m_cmd = ROM_KERNEL_CMD_WR_FILE;
403 m_PlugIn = -1;
404 m_Ivt = -1;
405 m_max_download_pre_cmd = 0x200000;
406 m_offset = 0;
407 m_bIvtReserve = false;
408 m_download_addr = 0;
409 m_bskipspl = false;
410 m_bscanterm = false;
411 m_barebox_bl33 = false;
413 insert_param_info("write", nullptr, Param::Type::e_null);
414 insert_param_info("-f", &m_filename, Param::Type::e_string_filename);
415 insert_param_info("-ivt", &m_Ivt, Param::Type::e_uint32);
416 insert_param_info("-addr", &m_download_addr, Param::Type::e_uint32);
417 insert_param_info("-barebox-bl33", &m_barebox_bl33, Param::Type::e_bool);
418 insert_param_info("-offset", &m_offset, Param::Type::e_uint32);
419 insert_param_info("-skipspl", &m_bskipspl, Param::Type::e_bool);
420 insert_param_info("-skipfhdr", &m_bskipfhdr, Param::Type::e_bool);
421 insert_param_info("-scanterm", &m_bscanterm, Param::Type::e_bool);
424 int SDPWriteCmd::run(CmdCtx*ctx)
426 size_t size;
427 uint8_t *pbuff;
428 ssize_t offset = 0;
429 bool validate_run = true;
431 shared_ptr<FileBuffer> p1= get_file_buffer(m_filename, true);
433 if (p1 == nullptr)
434 return -1;
436 shared_ptr<DataBuffer> fbuff;
438 fbuff = p1->request_data(0, m_scan_limited);
439 if (!fbuff) return -1;
441 if (m_Ivt < 0)
443 pbuff = fbuff->data();
444 size = fbuff->size();
446 offset = m_offset;
448 if (m_bskipfhdr)
449 offset += GetFlashHeaderSize(fbuff, offset);
451 size_t pos = 0, length;
452 if (m_bscanterm)
454 if (IsMBR(fbuff))
456 length = ScanTerm(fbuff, pos);
457 if (length == 0)
459 set_last_err_string("This wic have NOT terminate tag after bootloader, please use new yocto");
460 return -1;
463 offset = pos - length;
464 if (offset < 0)
466 set_last_err_string("This wic boot length is wrong");
467 return -1;
469 size = pos;
473 if (m_bskipspl) {
474 const ROM_INFO * rom = search_rom_info(ctx->m_config_item);
475 if(! (rom->flags & ROM_INFO_AUTO_SCAN_UBOOT_POS))
477 set_last_err_string("SPL doesn't support auto scan uboot position");
478 return -1;
481 size_t off = offset;
482 IvtHeader *pIvt = search_ivt_header(fbuff, off, 0x100000);
483 if (pIvt)
485 if (pIvt->BootData)
487 BootData *pDB = (BootData *) &(fbuff->at(off + pIvt->BootData - pIvt->SelfAddr));
488 offset = off + pDB->ImageSize - (pIvt->SelfAddr - pDB->ImageStartAddr);
491 else
493 offset += GetContainerActualSize(fbuff, offset, rom->flags & ROM_INFO_HID_ROMAPI, m_bskipspl);
496 if (size_t(offset) >= fbuff->size())
498 set_last_err_string("Unknown Image type, can't use skipspl format");
499 return -1;
503 size -= offset;
505 else
507 size_t off = 0;
508 IvtHeader *pIvt = search_ivt_header(fbuff, off);
509 for (int i = 0; i < m_Ivt; i++)
511 off += sizeof(IvtHeader);
512 pIvt = search_ivt_header(fbuff, off, m_scan_limited);
514 if (pIvt == nullptr)
516 set_last_err_string("Cannot find valid IVT header");
517 return -1;
520 BootData *pDB = (BootData *) &(fbuff->at(off + pIvt->BootData - pIvt->SelfAddr));
522 m_download_addr = pIvt->SelfAddr;
523 //size = fbuff->size() - off;
524 size = pDB->ImageSize - (pIvt->SelfAddr - pDB->ImageStartAddr);
526 if (size >= m_scan_limited)
528 set_last_err_string("TODO: image is too big");
529 return -1;
532 //ImageSize may be bigger than Imagesize because ImageSize include IVT offset
533 //Difference boot storage have difference IVT offset.
534 if (size > fbuff->size() - off)
535 size = fbuff->size() - off;
537 if (m_barebox_bl33) {
538 if (pIvt->IvtBarker != IVT_BARKER_HEADER) {
539 set_last_err_string("Barebox BL33 loading is only support for IVT Header V2");
540 return -1;
542 offset = pIvt->ImageStartAddr - pIvt->SelfAddr;
543 size = fbuff->size() - off - offset;
544 m_download_addr = 0;
546 // Barebox does start as soon as the bl33 was loaded
547 // and the check_ack() fails
548 validate_run = false;
551 pbuff = (uint8_t*)pIvt;
553 return run(ctx, pbuff + offset, size, m_download_addr, validate_run);
556 int SDPWriteCmd::run(CmdCtx *ctx, void *pbuff, size_t size, uint32_t addr, bool validate)
558 HIDTrans dev(m_timeout);
559 if (dev.open(ctx->m_dev))
560 return -1;
562 HIDReport report(&dev);
564 report.set_notify_total(size);
566 const ROM_INFO * rom = search_rom_info(ctx->m_config_item);
568 size_t max = m_max_download_pre_cmd;
570 /* SPL needn't split transfer */
571 if (rom && (rom ->flags & ROM_INFO_HID_SDP_NO_MAX_PER_TRANS))
572 max = size;
574 for (size_t i=0; i < size; i += max)
576 size_t sz;
577 sz = size - i;
578 if (sz > max)
579 sz = max;
581 m_spdcmd.m_addr = EndianSwap((uint32_t)(addr + i)); // force use 32bit endian swap function;
582 m_spdcmd.m_count = EndianSwap((uint32_t)sz); //force use 32bit endian swap function;
584 report.set_position_base(i);
585 report.set_skip_notify(true);
587 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
588 return -1;
590 report.set_skip_notify(false);
592 if (report.write(((uint8_t*)pbuff)+i, sz, 2))
593 return -1;
595 if (validate && check_ack(&report, ROM_STATUS_ACK))
596 return -1;
599 return 0;
602 SDPReadMemCmd::SDPReadMemCmd(char *p) : SDPCmdBase(p)
604 m_spdcmd.m_cmd = ROM_KERNEL_CMD_RD_MEM;
606 insert_param_info("rdmem", nullptr, Param::Type::e_null);
607 insert_param_info("-addr", &m_mem_addr, Param::Type::e_uint32);
608 insert_param_info("-format", &m_mem_format, Param::Type::e_uint32);
611 int SDPReadMemCmd::run(CmdCtx *ctx)
613 HIDTrans dev(m_timeout);
614 if (dev.open(ctx->m_dev))
615 return -1;
617 HIDReport report(&dev);
619 printf("\nReading address 0x%08X ...\n", m_mem_addr);
620 m_spdcmd.m_addr = EndianSwap(m_mem_addr);
621 m_spdcmd.m_format = m_mem_format;
622 switch (m_mem_format) {
623 case 0x8:
624 m_spdcmd.m_count = EndianSwap((uint32_t)0x1);
625 break;
626 case 0x10:
627 m_spdcmd.m_count = EndianSwap((uint32_t)0x2);
628 break;
629 case 0x20:
630 m_spdcmd.m_count = EndianSwap((uint32_t)0x4);
631 break;
632 default:
633 set_last_err_string("Invalid format, use <8|16|32>");
634 return -1;
635 break;
638 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
639 return -1;
641 if (get_hab_type(&report) == HabUnknown)
642 return -1;
644 uint32_t mem_value;
645 if (get_status(&report, mem_value, 4) == 0)
647 printf("\nValue of address 0x%08X: ", m_mem_addr);
648 switch (m_mem_format) {
649 case 0x8:
650 printf("0x%02X\n", mem_value & 0xff);
651 break;
652 case 0x10:
653 printf("0x%04X\n", mem_value & 0xffff);
654 break;
655 case 0x20:
656 printf("0x%08X\n", mem_value);
657 break;
658 default:
659 set_last_err_string("Invalid format, use <8|16|32>");
660 return -1;
664 return 0;
667 SDPWriteMemCmd::SDPWriteMemCmd(char *p) : SDPCmdBase(p)
669 m_spdcmd.m_cmd = ROM_KERNEL_CMD_WR_MEM;
671 insert_param_info("wrmem", nullptr, Param::Type::e_null);
672 insert_param_info("-addr", &m_mem_addr, Param::Type::e_uint32);
673 insert_param_info("-format", &m_mem_format, Param::Type::e_uint32);
674 insert_param_info("-value", &m_mem_value, Param::Type::e_uint32);
677 int SDPWriteMemCmd::run(CmdCtx *ctx)
679 HIDTrans dev(m_timeout);
680 if (dev.open(ctx->m_dev))
681 return -1;
683 HIDReport report(&dev);
685 printf("\nWriting 0x%08X to address 0x%08X ...\n", m_mem_value, m_mem_addr);
686 m_spdcmd.m_addr = EndianSwap(m_mem_addr);
687 m_spdcmd.m_format = m_mem_format;
688 switch (m_mem_format) {
689 case 0x8:
690 m_spdcmd.m_count = EndianSwap((uint32_t)0x1);
691 break;
692 case 0x10:
693 m_spdcmd.m_count = EndianSwap((uint32_t)0x2);
694 break;
695 case 0x20:
696 m_spdcmd.m_count = EndianSwap((uint32_t)0x4);
697 break;
698 default:
699 set_last_err_string("Invalid format, use <8|16|32>");
700 return -1;
701 break;
703 m_spdcmd.m_data = EndianSwap(m_mem_value);
705 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
706 return -1;
708 if (get_hab_type(&report) == HabUnknown)
709 return -1;
711 uint32_t status;
713 if (get_status(&report, status, 4) < 0 || status != ROM_WRITE_ACK) {
715 string_ex err;
716 err.format("%s:%d Failed to write to address 0x%X",
717 __FUNCTION__, __LINE__, m_mem_addr);
718 set_last_err_string(err);
721 return 0;
724 SDPJumpCmd::SDPJumpCmd(char *p) : SDPCmdBase(p)
726 m_spdcmd.m_cmd = ROM_KERNEL_CMD_JUMP_ADDR;
727 insert_param_info("jump", nullptr, Param::Type::e_null);
728 insert_param_info("-f", &m_filename, Param::Type::e_string_filename);
729 insert_param_info("-ivt", &m_Ivt, Param::Type::e_uint32);
730 insert_param_info("-plugin", &m_PlugIn, Param::Type::e_bool);
731 insert_param_info("-addr", &m_jump_addr, Param::Type::e_uint32);
732 insert_param_info("-cleardcd", &m_clear_dcd, Param::Type::e_bool);
735 int SDPJumpCmd::run(CmdCtx *ctx)
737 const ROM_INFO * rom = search_rom_info(ctx->m_config_item);
739 HIDTrans dev(m_timeout);
740 if (dev.open(ctx->m_dev))
741 return -1;
743 HIDReport report(&dev);
745 if (rom == nullptr)
747 string_ex err;
748 err.format("%s:%d can't get rom info", __FUNCTION__, __LINE__);
749 set_last_err_string(err);
750 return -1;
753 if (rom->flags & ROM_INFO_SPL_JUMP)
755 m_spdcmd.m_addr = EndianSwap(m_jump_addr);
756 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
757 return -1;
759 //Omit last return value.
760 check_ack(&report, ROM_OK_ACK);
761 return 0;
764 shared_ptr<FileBuffer> p1 = get_file_buffer(m_filename, true);
765 if (!p1)
766 return -1;
768 shared_ptr<DataBuffer> buff;
769 buff = p1->request_data(0, m_scan_limited);
770 if (!buff) return -1;
772 size_t off = 0;
773 IvtHeader *pIVT = search_ivt_header(buff, off, m_scan_limited);
775 for (int i = 0; i < m_Ivt; i++)
777 off += sizeof(IvtHeader);
778 pIVT = search_ivt_header(buff, off);
781 if (pIVT == nullptr)
783 set_last_err_string("Cannot find valid IVT header");
784 return -1;
787 m_spdcmd.m_addr = EndianSwap(pIVT->SelfAddr);
790 if (rom->flags & ROM_INFO_HID_SKIP_DCD && !m_clear_dcd)
792 SDPSkipDCDCmd skipcmd(nullptr);
793 if (skipcmd.run(ctx))
794 return -1;
796 else
797 { /*Clear DCD*/
798 vector<uint8_t> ivt;
799 /* Need send out whole report size buffer avoid overwrite other data
800 * Some platform require receive whole package for report id = 2
802 ivt.resize(report.get_out_package_size());
804 size_t sz = buff->size();
805 sz -= (uint8_t*)pIVT - (uint8_t*)buff->data();
807 if (sz > ivt.size())
808 sz = ivt.size();
810 memcpy(ivt.data(), pIVT, sz);
812 IvtHeader *header = (IvtHeader *)ivt.data();
813 header->DCDAddress = 0;
815 SDPWriteCmd writecmd(nullptr);
816 if(writecmd.run(ctx, header, ivt.size(), pIVT->SelfAddr))
817 return -1;
820 if (report.write(&m_spdcmd, sizeof(m_spdcmd), 1))
821 return -1;
823 //Omit last return value.
824 check_ack(&report, ROM_OK_ACK);
826 return 0;
829 SDPBootlogCmd::SDPBootlogCmd(char *p) : SDPCmdBase(p)
831 insert_param_info("blog", nullptr, Param::Type::e_null);
834 int SDPBootlogCmd::run(CmdCtx *ctx)
836 HIDTrans dev{2000};
838 if (dev.open(ctx->m_dev))
839 return -1;
841 HIDReport report(&dev);
843 vector<uint8_t> v(65);
844 v[0] = 'I';
846 uuu_notify nt;
847 nt.type = uuu_notify::NOTIFY_CMD_INFO;
849 int ret;
850 while (1)
852 ret = report.read(v);
853 if (ret)
854 return 0;
855 else
857 nt.str = (char*)(v.data() + 4);
858 v[5] = 0;
859 call_notify(nt);
860 continue;
863 return 0;