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