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
memcpy32_helper(uintptr_t src,uintptr_t dst,uint32_t entries,int inc_src_addr)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
ape_host_view_addr_get(uint32_t bnxt_view_addr,uint32_t size)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
ape_hdr_crc_calc(const struct ape_bin_hdr_s * hdr)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
ape_bin_hdr_valid(const struct ape_bin_hdr_s * hdr)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
get_char(uint8_t * inbuf,size_t * inbuf_idx,size_t inbuf_size)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
put_char(uint8_t * outbuf,size_t * outbuf_idx,size_t outbuf_size,uint8_t ch)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
ape_section_uncompress(uint8_t * inbuf,size_t inbuf_size,uint8_t * outbuf,size_t outbuf_size)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
ape_section_copy(struct ape_bin_hdr_s * bin_hdr,struct ape_section_hdr_s * section)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
ape_section_zero(struct ape_section_hdr_s * section)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
bnxt_load(vaddr_t img_buffer)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
bnxt_crash_config(uintptr_t info_dst,uint32_t crash_area_start,uint32_t crash_len)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
bnxt_load_fw(int chip_type)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
bnxt_copy_crash_dump(uint8_t * d,uint32_t offset,uint32_t len)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