1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2019 Broadcom. 4 */ 5 6 #include <crc32.h> 7 #include <drivers/bcm/bnxt.h> 8 #include <mm/core_mmu.h> 9 #include <stdint.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <util.h> 13 14 /* 15 * These macros are the offsets where images reside on sec mem 16 */ 17 #define BNXT_BUFFER_SEC_MEM 0x8ae00000 18 #define BNXT_FW_SEC_MEM_SRC BNXT_BUFFER_SEC_MEM 19 #define BNXT_FW_SEC_MEM_CFG (BNXT_BUFFER_SEC_MEM + 0x100000) 20 #define TEMP_MEM (BNXT_BUFFER_SEC_MEM + 0x180000) 21 22 #define BNXT_CRASH_SEC_MEM 0x8b000000 23 #define BNXT_CRASH_LEN 0x2000000 24 25 #define BNXT_CONFIG_NS3_DEST 0x03a00000 26 #define BNXT_BSPD_CFG_OFFSET 0x51b0 27 #define BNXT_CONFIG_NS3_BSPD_DEST (BNXT_CONFIG_NS3_DEST + \ 28 BNXT_BSPD_CFG_OFFSET) 29 #define BNXT_BSPD_CFG_SIZE 0x200 30 31 #define BNXT_CRASH_DUMP_INFO_NS3_BASE 0x3a5ff00 32 33 #define SZ_1K 0x400 34 35 #define BUFFER_PADDING SZ_1K 36 37 #define INC_SRC_ADDR 1 38 39 #define EOF -1 40 41 #define BCM_BNXT_FASTBOOT_MASK 0x3u 42 #define BCM_BNXT_FASTBOOT_TYPE_1 1 43 44 #define ADDR_IS_4BYTE_ALIGNED(addr) IS_ALIGNED(addr, 4) 45 46 #define SECTION_IS_LOADABLE(section_ptr) \ 47 ((section_ptr)->flags_src_offset & SECTION_FLAGS_IS_LOADABLE) 48 #define SECTION_IS_ZIPPED(section_ptr) \ 49 ((section_ptr)->flags_src_offset & SECTION_FLAGS_IS_ZIPPED) 50 #define SECTION_IS_TOBE_COPIED(section_ptr) \ 51 ((section_ptr)->flags_src_offset & \ 52 (SECTION_FLAGS_IS_EXEC_INSTR | SECTION_FLAGS_IS_DATA)) 53 #define SECTION_IS_TOBE_ZEROED(section_ptr) \ 54 ((section_ptr)->flags_src_offset & SECTION_FLAGS_IS_BSS) 55 #define SECTION_IS_4BYTE_ALIGNED(section_ptr) \ 56 ADDR_IS_4BYTE_ALIGNED((section_ptr)->dest_addr) 57 58 #define SECTION_SRC_OFFSET(section_ptr) \ 59 ((section_ptr)->flags_src_offset & SECTION_SRC_OFFFSET_MASK) 60 61 /* -------------------------------------------------------------------------- */ 62 63 /* Section header for each image block */ 64 struct ape_section_hdr_s { 65 /* Destination address that this section is to be copied to */ 66 uint32_t dest_addr; 67 68 /* 69 * bit[0:23] source offset address that this image copy from 70 * bit[24:31] flags 71 */ 72 uint32_t flags_src_offset; 73 #define SECTION_FLAGS_MASK 0xff000000 74 /* Session is compressed (zipped) */ 75 #define SECTION_FLAGS_IS_ZIPPED 0x01000000 76 /* Session contains CRC */ 77 #define SECTION_FLAGS_IS_CRC 0x02000000 78 /* Session contains executable code (e.g. .text) */ 79 #define SECTION_FLAGS_IS_EXEC_INSTR 0x04000000 80 /* Session contains initialized data (e.g. .data) */ 81 #define SECTION_FLAGS_IS_DATA 0x08000000 82 /* Session contains zero initialized data (e.g. .bss) */ 83 #define SECTION_FLAGS_IS_BSS 0x10000000 84 /* Loadable section mask */ 85 #define SECTION_FLAGS_IS_LOADABLE (SECTION_FLAGS_IS_EXEC_INSTR | \ 86 SECTION_FLAGS_IS_DATA | \ 87 SECTION_FLAGS_IS_BSS) 88 #define SECTION_SRC_OFFFSET_MASK 0x00ffffff 89 90 /* Original image length, dword (4byte) length */ 91 uint32_t org_data_len; 92 93 /* Compressed image length (if FlAGS_IS_ZIPPED is set) */ 94 uint32_t zip_data_len; 95 96 /* 97 * checksum value for this image block, if FLAGS_IS_CRC then 98 * this is CRC checksum; otherwise it is a simple summation 99 */ 100 uint32_t checksum; 101 }; 102 103 struct version_s { 104 uint8_t version[16]; /* Null-terminated file version string */ 105 }; 106 107 struct ver_ext_offset_s { 108 uint8_t version[12]; /* Null-terminated file version string */ 109 uint32_t ext_hdr_offset; 110 }; 111 112 union version_and_offset_u { 113 struct version_s version1; 114 struct ver_ext_offset_s version2; 115 }; 116 117 struct ape_bin_hdr_s { 118 /* APE binary header signature; expects APE_BIN_HDR_SIGNATURE */ 119 uint32_t signature; 120 #define APE_BIN_HDR_SIGNATURE 0x1a4d4342 /* "BCM"+0x1a */ 121 /* Reserved for ChiMP's use */ 122 uint8_t flags; 123 uint8_t code_type; 124 uint8_t device; 125 uint8_t media; 126 union version_and_offset_u ver; 127 uint8_t build; 128 uint8_t revision; 129 uint8_t minor_ver; 130 uint8_t major_ver; 131 uint32_t entry_address; 132 uint8_t reserved; 133 uint8_t header_dword_size; 134 uint8_t num_total_sections; 135 uint8_t num_loadable_sections; 136 uint32_t checksum; 137 } __packed __aligned(1); 138 139 #define APE_BIN_HDR_SIZE sizeof(struct ape_bin_hdr_s) 140 #define APE_SECTION_HDR_SIZE sizeof(struct ape_section_hdr_s) 141 142 /* MAX number of image sections that will be accepted */ 143 #define APE_IMG_MAX_SECTIONS 16 144 145 #define APE_IMG_LOAD_DEBUG 0 146 147 /* -------------------------------------------------------------------------- */ 148 149 struct ape_mem_region_s { 150 uint32_t c_base; /* ChiMP's view of address */ 151 uint32_t h_base; /* Host's view of address */ 152 uint32_t size; /* Size in bytes */ 153 }; 154 155 /* Memory map into various scratchpad memories */ 156 static struct ape_mem_region_s ape_mem_regions[] = { 157 /* CHIMP scratchpad */ 158 {0x00100000, 0x03100000, 1024 * SZ_1K}, 159 160 /* APE scratchpad */ 161 {0x61000000, 0x03300000, 1152 * SZ_1K}, 162 163 /* BONO scratchpad */ 164 {0x61600000, 0x03a00000, 512 * SZ_1K}, 165 166 /* KONG scratchpad */ 167 {0x61400000, 0x03800000, 512 * SZ_1K}, 168 169 /* Keep this last!! */ 170 {0, 0, 0} 171 }; 172 173 /* Nitro crash address configuration related macros */ 174 #define BNXT_CRASH_INFO_SIGNATURE 0x20524444 175 #define BNXT_CRASH_INFO_VALID 0x1 176 #define MAX_CRASH_ADDR_ITEM 8 177 178 struct nitro_crash_addr_item { 179 uint32_t info; 180 uint32_t size; 181 uint32_t addr_hi; 182 uint32_t addr_lo; 183 }; 184 185 struct nitro_crash_addr_info { 186 /* CRC of the struct content, starting at next field. */ 187 uint32_t crc; 188 uint32_t signature; 189 uint32_t version; 190 struct nitro_crash_addr_item table[MAX_CRASH_ADDR_ITEM]; 191 }; 192 193 static inline void memcpy32_helper(uintptr_t src, 194 uintptr_t dst, 195 uint32_t entries, 196 int inc_src_addr) 197 { 198 uint32_t copied_entries = 0; 199 200 while (entries) { 201 copied_entries = bnxt_write32_multiple(dst, src, entries, 202 inc_src_addr); 203 204 if (copied_entries < entries) { 205 dst += copied_entries * sizeof(uint32_t); 206 src += (inc_src_addr) ? 207 (copied_entries * sizeof(uint32_t)) : 0; 208 entries -= copied_entries; 209 } else { 210 entries = 0; 211 } 212 } 213 } 214 215 static uint32_t ape_host_view_addr_get(uint32_t bnxt_view_addr, uint32_t size) 216 { 217 struct ape_mem_region_s *region = ape_mem_regions; 218 uint32_t addr = 0; 219 220 for (; region->size != 0; region++) { 221 if (bnxt_view_addr < region->c_base) 222 continue; 223 224 if (bnxt_view_addr >= (region->c_base + region->size)) 225 continue; 226 227 if (size > (region->c_base + region->size - bnxt_view_addr)) { 228 EMSG("ERROR: 0x%x + 0x%x spans memory boundary", 229 bnxt_view_addr, size); 230 break; 231 } 232 233 addr = bnxt_view_addr - region->c_base; 234 addr += region->h_base; 235 break; 236 } 237 238 return addr; 239 } 240 241 static uint32_t ape_hdr_crc_calc(const struct ape_bin_hdr_s *hdr) 242 { 243 uint32_t crc = 0; 244 uint32_t dummy = 0; 245 246 /* Compute the CRC up to, but not including, the checksum field */ 247 crc = CRC32(CRC32_INIT_VAL, 248 (const char *)hdr, 249 (uintptr_t)(&hdr->checksum) - (uintptr_t)hdr); 250 251 /* Compute the CRC with the checksum field zeroed out */ 252 crc = CRC32(~crc, (const char *)&dummy, sizeof(uint32_t)); 253 254 /* 255 * Compute the remainder part of the image header, i.e., the 256 * section headers 257 */ 258 crc = CRC32(~crc, 259 (const char *)((uintptr_t)hdr + APE_BIN_HDR_SIZE), 260 hdr->num_total_sections * APE_SECTION_HDR_SIZE); 261 262 return crc; 263 } 264 265 static int ape_bin_hdr_valid(const struct ape_bin_hdr_s *hdr) 266 { 267 uint32_t checksum = 0; 268 269 if (!hdr) { 270 EMSG("ERROR: no APE image header"); 271 return BNXT_FAILURE; 272 } 273 274 if (hdr->signature != APE_BIN_HDR_SIGNATURE) { 275 EMSG("ERROR: bad APE image signature"); 276 return BNXT_FAILURE; 277 } 278 279 if (hdr->num_total_sections > APE_IMG_MAX_SECTIONS) { 280 EMSG("ERROR: too many sections in APE image"); 281 return BNXT_FAILURE; 282 } 283 284 checksum = ape_hdr_crc_calc(hdr); 285 if (hdr->checksum != checksum) { 286 EMSG("ERROR: bad APE header checksum (exp: %x, act: %x)", 287 hdr->checksum, checksum); 288 return BNXT_FAILURE; 289 } 290 291 return BNXT_SUCCESS; 292 } 293 294 static int get_char(uint8_t *inbuf, size_t *inbuf_idx, size_t inbuf_size) 295 { 296 int c = 0; 297 298 if (*inbuf_idx >= inbuf_size) 299 return EOF; 300 301 c = inbuf[*inbuf_idx]; 302 *inbuf_idx += 1; 303 304 return c; 305 } 306 307 static void put_char(uint8_t *outbuf, 308 size_t *outbuf_idx, 309 size_t outbuf_size, 310 uint8_t ch) 311 { 312 if (*outbuf_idx >= outbuf_size) 313 return; 314 315 outbuf[*outbuf_idx] = ch; 316 *outbuf_idx += 1; 317 } 318 319 static size_t ape_section_uncompress(uint8_t *inbuf, 320 size_t inbuf_size, 321 uint8_t *outbuf, 322 size_t outbuf_size) 323 { 324 int i = 0, j = 0, k = 0, r = 0, c = 0; 325 uint32_t flags = 0; 326 size_t exp_size = 0, codesize = 0; 327 size_t inbuf_idx = 0, outbuf_idx = 0; 328 #define CODE_8U_MASK 0xff00u /* 8 code units count mask (8 bits) */ 329 #define CODE_END_MASK 0x100u /* End of code units mask */ 330 #define CODE_IS_UNENCODED_MASK 1 /* Unencoded code unit mask */ 331 #define CODE_POS_MASK 0xe0u /* Encoded unit position mask and */ 332 #define CODE_POS_SHIFT 3 /* Bit shift */ 333 #define CODE_LEN_MASK 0x1fu /* Encoded unit length mask */ 334 #define NS 2048 /* Size of ring buffer */ 335 #define F 34 /* Upper limit for match_length */ 336 #define THRESHOLD 2 /* Encode string into position and 337 * length, if match_length is 338 * greater than this. 339 */ 340 /* 341 * Ring buffer of size NS, with an extra F-1 bytes to facilitate 342 * string comparisons. 343 */ 344 uint8_t text_buf[NS + F - 1]; 345 346 inbuf_idx = 0; 347 outbuf_idx = 0; 348 349 for (i = 0; i < NS - F; i++) 350 text_buf[i] = ' '; 351 352 r = NS - F; 353 354 for (;;) { 355 if (((flags >>= 1) & CODE_END_MASK) == 0) { 356 c = get_char(inbuf, &inbuf_idx, inbuf_size); 357 if (c == EOF) 358 break; 359 ++exp_size; 360 361 if (exp_size > inbuf_size) 362 break; 363 364 /* Use higher byte cleverly to count to eight */ 365 flags = c | CODE_8U_MASK; 366 } 367 368 if (flags & CODE_IS_UNENCODED_MASK) { 369 /* Not encoded; simply copy the unit */ 370 c = get_char(inbuf, &inbuf_idx, inbuf_size); 371 if (c == EOF) 372 break; 373 374 ++exp_size; 375 if (exp_size > inbuf_size) 376 break; 377 378 put_char(outbuf, &outbuf_idx, outbuf_size, c); 379 text_buf[r++] = c; 380 r &= (NS - 1); 381 ++codesize; 382 } else { 383 /* Encoded; get the position and length & duplicate */ 384 i = get_char(inbuf, &inbuf_idx, inbuf_size); 385 if (i == EOF) 386 break; 387 388 ++exp_size; 389 if (exp_size > inbuf_size) 390 break; 391 392 j = get_char(inbuf, &inbuf_idx, inbuf_size); 393 if (j == EOF) 394 break; 395 396 ++exp_size; 397 if (exp_size > inbuf_size) 398 break; 399 400 i |= ((j & CODE_POS_MASK) << CODE_POS_SHIFT); 401 j = ((j & CODE_LEN_MASK) + THRESHOLD); 402 403 for (k = 0; k <= j; k++) { 404 c = text_buf[((i + k) & (NS - 1))]; 405 put_char(outbuf, &outbuf_idx, outbuf_size, c); 406 text_buf[r++] = c; 407 r &= (NS - 1); 408 ++codesize; 409 } 410 } 411 } 412 413 return codesize; 414 } 415 416 static int ape_section_copy(struct ape_bin_hdr_s *bin_hdr, 417 struct ape_section_hdr_s *section) 418 { 419 uintptr_t src = 0; 420 uintptr_t dst = 0; 421 uint32_t checksum = 0; 422 uint32_t i = 0; 423 size_t size = 0; 424 uint8_t *section_data = NULL; 425 size_t work_buff_size = 0; 426 void *work_buff = NULL; 427 int rc = BNXT_FAILURE; 428 429 if (SECTION_IS_ZIPPED(section)) { 430 work_buff_size = section->org_data_len + BUFFER_PADDING; 431 work_buff = (void *)phys_to_virt(TEMP_MEM, MEM_AREA_RAM_SEC, 432 work_buff_size); 433 if (!work_buff) { 434 EMSG("ERROR: buffer allocation"); 435 return BNXT_FAILURE; 436 } 437 438 section_data = (uint8_t *)((uintptr_t)bin_hdr + 439 SECTION_SRC_OFFSET(section)); 440 size = ape_section_uncompress(section_data, 441 section->zip_data_len, 442 work_buff, 443 work_buff_size); 444 if (size >= work_buff_size) { 445 EMSG("ERROR: section uncompress"); 446 goto ape_section_copy_exit; 447 } 448 if (size < section->org_data_len) { 449 EMSG("ERROR: decompressed data size mismatch "); 450 EMSG("(exp: %d, act: %ld)", 451 section->org_data_len, size); 452 goto ape_section_copy_exit; 453 } 454 src = (uintptr_t)work_buff; 455 } else { 456 src = (uintptr_t)bin_hdr + SECTION_SRC_OFFSET(section); 457 } 458 459 size = section->org_data_len; 460 461 if (section->flags_src_offset & SECTION_FLAGS_IS_CRC) { 462 checksum = CRC32(CRC32_INIT_VAL, (const char *)src, size); 463 } else { 464 checksum = 0; 465 for (i = 0; i < size / sizeof(uint32_t); i++) 466 checksum += ((uint32_t *)src)[i]; 467 } 468 if (checksum != section->checksum) { 469 EMSG("ERROR: checksum mismatch (exp: %x, act: %x)", 470 section->checksum, checksum); 471 goto ape_section_copy_exit; 472 } 473 474 dst = ape_host_view_addr_get(section->dest_addr, size); 475 if (dst == 0) { 476 EMSG("ERROR: ChiMP-to-host address conversion of %x", 477 section->dest_addr); 478 goto ape_section_copy_exit; 479 } 480 481 /* Copy the section */ 482 size = size / sizeof(uint32_t); 483 memcpy32_helper(src, dst, size, INC_SRC_ADDR); 484 485 rc = BNXT_SUCCESS; 486 487 ape_section_copy_exit: 488 return rc; 489 } 490 491 static int ape_section_zero(struct ape_section_hdr_s *section) 492 { 493 uint32_t dst = 0; 494 uint32_t size = section->org_data_len; 495 uint32_t zero = 0; 496 497 if (section->org_data_len == 0) 498 return BNXT_SUCCESS; 499 500 /* Convert ChiMP's view of the address in the image to the host view */ 501 dst = ape_host_view_addr_get(section->dest_addr, size); 502 if (dst == 0) { 503 EMSG("ERROR: ChiMP-to-host address conversion of %x", 504 section->dest_addr); 505 return BNXT_FAILURE; 506 } 507 508 /* 509 * Zero the section; we simply copy zeros and do not increment the 510 * source buffer address. 511 */ 512 size = size / sizeof(uint32_t); 513 memcpy32_helper((uintptr_t)&zero, dst, size, !INC_SRC_ADDR); 514 515 return BNXT_SUCCESS; 516 } 517 518 static int bnxt_load(vaddr_t img_buffer) 519 { 520 struct ape_bin_hdr_s *bin_hdr = NULL; 521 struct ape_section_hdr_s *section = NULL; 522 int sidx = 0; 523 int rc = BNXT_SUCCESS; 524 525 bin_hdr = (struct ape_bin_hdr_s *)img_buffer; 526 section = (struct ape_section_hdr_s *)(img_buffer + 527 APE_BIN_HDR_SIZE); 528 529 if (ape_bin_hdr_valid(bin_hdr) != BNXT_SUCCESS) 530 return BNXT_FAILURE; 531 532 for (sidx = 0; sidx < bin_hdr->num_total_sections; sidx++, section++) { 533 if (!SECTION_IS_LOADABLE(section)) 534 continue; 535 536 if (!ADDR_IS_4BYTE_ALIGNED(section->dest_addr)) { 537 EMSG("ERROR: unaligned section dest address 0x%x", 538 section->dest_addr); 539 rc = BNXT_FAILURE; 540 break; 541 } 542 543 if (!ADDR_IS_4BYTE_ALIGNED(SECTION_SRC_OFFSET(section))) { 544 EMSG("ERROR: unaligned section src offset (0x%x)", 545 SECTION_SRC_OFFSET(section)); 546 rc = BNXT_FAILURE; 547 break; 548 } 549 550 if (section->org_data_len % sizeof(uint32_t)) { 551 EMSG("ERROR: section size (%d) not divisible by 4", 552 section->org_data_len); 553 rc = BNXT_FAILURE; 554 break; 555 } 556 557 if (SECTION_IS_TOBE_COPIED(section)) { 558 rc = ape_section_copy(bin_hdr, section); 559 if (rc != BNXT_SUCCESS) 560 break; 561 } else if (SECTION_IS_TOBE_ZEROED(section)) { 562 rc = ape_section_zero(section); 563 if (rc != BNXT_SUCCESS) 564 break; 565 } 566 } 567 568 /* Set up boot mode and take BNXT out of reset */ 569 if (rc == BNXT_SUCCESS) { 570 bnxt_fastboot((bin_hdr->entry_address & 571 ~BCM_BNXT_FASTBOOT_MASK) | 572 BCM_BNXT_FASTBOOT_TYPE_1); 573 } 574 575 return rc; 576 } 577 578 static TEE_Result bnxt_crash_config(uintptr_t info_dst, 579 uint32_t crash_area_start, 580 uint32_t crash_len) 581 { 582 struct nitro_crash_addr_item *item = NULL; 583 uintptr_t dst = 0; 584 struct nitro_crash_addr_info *info = NULL; 585 uintptr_t src = 0; 586 uint32_t crc = 0; 587 size_t size = 0; 588 589 /* 590 * First we write into local memory to calculate CRC before 591 * updating into Nitro memory 592 */ 593 info = malloc(sizeof(struct nitro_crash_addr_info)); 594 if (!info) { 595 EMSG("ERROR: buffer allocation"); 596 return TEE_ERROR_OUT_OF_MEMORY; 597 } 598 599 memset(info, 0, sizeof(struct nitro_crash_addr_info)); 600 601 info->signature = BNXT_CRASH_INFO_SIGNATURE; 602 info->version = 0x01000000 | MAX_CRASH_ADDR_ITEM; 603 604 /* As of now only one item is filled */ 605 item = &info->table[0]; 606 item->info = 0; 607 item->size = crash_len | BNXT_CRASH_INFO_VALID; 608 item->addr_hi = 0; 609 item->addr_lo = crash_area_start; 610 611 /* Checksum calculation */ 612 crc = CRC32(CRC32_INIT_VAL, 613 (const char *)info + sizeof(uint32_t), 614 sizeof(struct nitro_crash_addr_info) - sizeof(uint32_t)); 615 info->crc = crc; 616 617 /* First we write the contents and then set valid bit */ 618 item->size &= ~BNXT_CRASH_INFO_VALID; 619 620 size = sizeof(struct nitro_crash_addr_info) / sizeof(uint32_t); 621 dst = info_dst; 622 src = (uintptr_t)info; 623 memcpy32_helper(src, dst, size, INC_SRC_ADDR); 624 625 /* Set the valid bit */ 626 item->size |= BNXT_CRASH_INFO_VALID; 627 dst = info_dst + offsetof(struct nitro_crash_addr_info, table) + 628 offsetof(struct nitro_crash_addr_item, size); 629 bnxt_write32_multiple(dst, (uintptr_t)&item->size, 1, 1); 630 631 free(info); 632 633 return TEE_SUCCESS; 634 } 635 636 TEE_Result bnxt_load_fw(int chip_type) 637 { 638 uint32_t size = 0; 639 uintptr_t dst = 0; 640 uintptr_t src = 0; 641 struct bnxt_images_info bnxt_src_image_info; 642 vaddr_t sec_mem_dest = (vaddr_t)phys_to_virt(BNXT_BUFFER_SEC_MEM, 643 MEM_AREA_RAM_SEC, 1); 644 645 memset(&bnxt_src_image_info, 0, sizeof(struct bnxt_images_info)); 646 647 if (get_bnxt_images_info(&bnxt_src_image_info, 648 chip_type, sec_mem_dest) != BNXT_SUCCESS) 649 return TEE_ERROR_ITEM_NOT_FOUND; 650 651 bnxt_handshake_clear(); 652 bnxt_kong_halt(); 653 bnxt_chimp_halt(); 654 655 /* Copy the configs */ 656 src = (uintptr_t)bnxt_src_image_info.bnxt_cfg_vaddr; 657 dst = (uintptr_t)BNXT_CONFIG_NS3_DEST; 658 size = bnxt_src_image_info.bnxt_cfg_len; 659 size = size / sizeof(uint32_t); 660 memcpy32_helper(src, dst, size, INC_SRC_ADDR); 661 662 /* Copy bspd config */ 663 src = (uintptr_t)bnxt_src_image_info.bnxt_bspd_cfg_vaddr; 664 size = bnxt_src_image_info.bnxt_bspd_cfg_len; 665 dst = (uintptr_t)BNXT_CONFIG_NS3_BSPD_DEST; 666 667 size = size / sizeof(uint32_t); 668 memcpy32_helper(src, dst, size, INC_SRC_ADDR); 669 670 /* Fill the bnxt crash dump info */ 671 bnxt_crash_config((uintptr_t)BNXT_CRASH_DUMP_INFO_NS3_BASE, 672 BNXT_CRASH_SEC_MEM, 673 BNXT_CRASH_LEN); 674 675 /* Load bnxt firmware and fastboot */ 676 bnxt_load(bnxt_src_image_info.bnxt_fw_vaddr); 677 678 return TEE_SUCCESS; 679 } 680 681 TEE_Result bnxt_copy_crash_dump(uint8_t *d, uint32_t offset, uint32_t len) 682 { 683 size_t crash_len = 0; 684 void *s = NULL; 685 686 if (ADD_OVERFLOW(offset, len, &crash_len) || 687 crash_len > BNXT_CRASH_LEN) 688 return TEE_ERROR_BAD_PARAMETERS; 689 690 s = phys_to_virt(BNXT_CRASH_SEC_MEM + offset, MEM_AREA_RAM_SEC, len); 691 692 cache_op_inner(DCACHE_AREA_INVALIDATE, s, len); 693 694 memcpy(d, s, len); 695 696 return TEE_SUCCESS; 697 } 698