summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdeel Raza <araza@nvidia.com>2018-05-07 19:48:04 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-05-16 17:33:53 -0400
commit464e9dd474cb88a58dffc136de54466e12c5a6ef (patch)
tree1dd3239b2e4ea53767ae014c2d03394127124852
parente5000d299f84432f63b30c0bd43841046c704f04 (diff)
gpu: nvgpu: gv100: use new MINION ucode format
Migrate to the new NVLINK MINION ucode format. The new format strips out an unnecessary ACR header from the ucode image. Moving to the new format will allow MINION ucode generation scripts to be unified. Bug 2113404 Change-Id: I9a72d6c3fa5edd50a4ec5eb835d157672931f994 Signed-off-by: Adeel Raza <araza@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1709986 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gv100/nvlink_gv100.c242
1 files changed, 164 insertions, 78 deletions
diff --git a/drivers/gpu/nvgpu/gv100/nvlink_gv100.c b/drivers/gpu/nvgpu/gv100/nvlink_gv100.c
index 9d99242f..10e7b149 100644
--- a/drivers/gpu/nvgpu/gv100/nvlink_gv100.c
+++ b/drivers/gpu/nvgpu/gv100/nvlink_gv100.c
@@ -95,19 +95,6 @@
95 minion_falcon_irqdest_target_swgen0_host_normal_f() | \ 95 minion_falcon_irqdest_target_swgen0_host_normal_f() | \
96 minion_falcon_irqdest_target_swgen1_host_normal_f()) 96 minion_falcon_irqdest_target_swgen1_host_normal_f())
97 97
98/* Minion FW header format */
99union gv100_minion_hdr {
100 struct {
101 u32 os_code_offset;
102 u32 os_code_size;
103 u32 os_data_offset;
104 u32 os_data_size;
105 u32 num_apps;
106 u32 app_0_code_start;
107 };
108 u8 raw_data[256];
109};
110
111struct __nvlink_reginit { 98struct __nvlink_reginit {
112 u32 addr; 99 u32 addr;
113 u32 value; 100 u32 value;
@@ -443,20 +430,35 @@ static bool gv100_nvlink_minion_isr(struct gk20a *g) {
443 return (intr == 0); 430 return (intr == 0);
444} 431}
445 432
433/* Extract a WORD from the MINION ucode */
434static inline u32 minion_extract_word(struct nvgpu_firmware *fw, u32 idx)
435{
436 u32 out_data = 0;
437 u8 byte = 0;
438 u32 i = 0;
439
440 for (i = 0; i < 4; i++) {
441 byte = fw->data[idx + i];
442 out_data |= ((u32)byte) << (8 * i);
443 }
444
445 return out_data;
446}
447
446/* 448/*
447 * Load minion FW and set up bootstrap 449 * Load minion FW and set up bootstrap
448 */ 450 */
449static u32 gv100_nvlink_minion_load(struct gk20a *g) 451static u32 gv100_nvlink_minion_load(struct gk20a *g)
450{ 452{
451 struct bin_hdr *hdr = NULL;
452 struct nvgpu_firmware *minion_fw = NULL;
453 union gv100_minion_hdr *minion_hdr;
454 u32 *minion_ucode = NULL;
455 u32 err = 0; 453 u32 err = 0;
454 struct nvlink_device *ndev = (struct nvlink_device *) g->nvlink.priv;
455 struct nvgpu_firmware *nvgpu_minion_fw = NULL;
456 struct minion_hdr *minion_hdr = &ndev->minion_hdr;
457 u32 data_idx = 0;
458 u32 app = 0;
456 struct nvgpu_timeout timeout; 459 struct nvgpu_timeout timeout;
457 u32 delay = GR_IDLE_CHECK_DEFAULT; 460 u32 delay = GR_IDLE_CHECK_DEFAULT;
458 u32 reg; 461 u32 reg;
459 u32 app;
460 462
461 nvgpu_log_fn(g, " "); 463 nvgpu_log_fn(g, " ");
462 464
@@ -464,8 +466,8 @@ static u32 gv100_nvlink_minion_load(struct gk20a *g)
464 return 0; 466 return 0;
465 467
466 /* get mem unlock ucode binary */ 468 /* get mem unlock ucode binary */
467 minion_fw = nvgpu_request_firmware(g, "minion.bin", 0); 469 nvgpu_minion_fw = nvgpu_request_firmware(g, "minion.bin", 0);
468 if (!minion_fw) { 470 if (!nvgpu_minion_fw) {
469 nvgpu_err(g, "minion ucode get fail"); 471 nvgpu_err(g, "minion ucode get fail");
470 err = -ENOENT; 472 err = -ENOENT;
471 goto exit; 473 goto exit;
@@ -474,24 +476,125 @@ static u32 gv100_nvlink_minion_load(struct gk20a *g)
474 /* nvdec falcon reset */ 476 /* nvdec falcon reset */
475 nvgpu_flcn_reset(&g->minion_flcn); 477 nvgpu_flcn_reset(&g->minion_flcn);
476 478
477 hdr = (struct bin_hdr *) minion_fw->data; 479 /* Read ucode header */
478 480 minion_hdr->os_code_offset = minion_extract_word(nvgpu_minion_fw,
479 minion_hdr = (union gv100_minion_hdr *) (minion_fw->data + 481 data_idx);
480 hdr->header_offset); 482 data_idx += 4;
481 minion_ucode = (u32 *) (minion_fw->data + hdr->data_offset); 483 minion_hdr->os_code_size = minion_extract_word(nvgpu_minion_fw,
484 data_idx);
485 data_idx += 4;
486 minion_hdr->os_data_offset = minion_extract_word(nvgpu_minion_fw,
487 data_idx);
488 data_idx += 4;
489 minion_hdr->os_data_size = minion_extract_word(nvgpu_minion_fw,
490 data_idx);
491 data_idx += 4;
492 minion_hdr->num_apps = minion_extract_word(nvgpu_minion_fw,
493 data_idx);
494 data_idx += 4;
482 495
483 nvgpu_log(g, gpu_dbg_nvlink, 496 nvgpu_log(g, gpu_dbg_nvlink,
484 "os_code_offset: 0x%x", minion_hdr->os_code_offset); 497 "MINION Ucode Header Info:");
498 nvgpu_log(g, gpu_dbg_nvlink,
499 "-------------------------");
485 nvgpu_log(g, gpu_dbg_nvlink, 500 nvgpu_log(g, gpu_dbg_nvlink,
486 "os_code_size: 0x%x", minion_hdr->os_code_size); 501 " - OS Code Offset = %u", minion_hdr->os_code_offset);
487 nvgpu_log(g, gpu_dbg_nvlink, 502 nvgpu_log(g, gpu_dbg_nvlink,
488 "os_data_offset: 0x%x", minion_hdr->os_data_offset); 503 " - OS Code Size = %u", minion_hdr->os_code_size);
504 nvgpu_log(g, gpu_dbg_nvlink,
505 " - OS Data Offset = %u", minion_hdr->os_data_offset);
506 nvgpu_log(g, gpu_dbg_nvlink,
507 " - OS Data Size = %u", minion_hdr->os_data_size);
508 nvgpu_log(g, gpu_dbg_nvlink,
509 " - Num Apps = %u", minion_hdr->num_apps);
510
511 /* Allocate offset/size arrays for all the ucode apps */
512 minion_hdr->app_code_offsets = nvgpu_kcalloc(g,
513 minion_hdr->num_apps,
514 sizeof(u32));
515 if (!minion_hdr->app_code_offsets) {
516 nvgpu_err(g, "Couldn't allocate MINION app_code_offsets array");
517 err = -ENOMEM;
518 goto exit;
519 }
520
521 minion_hdr->app_code_sizes = nvgpu_kcalloc(g,
522 minion_hdr->num_apps,
523 sizeof(u32));
524 if (!minion_hdr->app_code_sizes) {
525 nvgpu_err(g, "Couldn't allocate MINION app_code_sizes array");
526 err = -ENOMEM;
527 goto exit;
528 }
529
530 minion_hdr->app_data_offsets = nvgpu_kcalloc(g,
531 minion_hdr->num_apps,
532 sizeof(u32));
533 if (!minion_hdr->app_data_offsets) {
534 nvgpu_err(g, "Couldn't allocate MINION app_data_offsets array");
535 err = -ENOMEM;
536 goto exit;
537 }
538
539 minion_hdr->app_data_sizes = nvgpu_kcalloc(g,
540 minion_hdr->num_apps,
541 sizeof(u32));
542 if (!minion_hdr->app_data_sizes) {
543 nvgpu_err(g, "Couldn't allocate MINION app_data_sizes array");
544 err = -ENOMEM;
545 goto exit;
546 }
547
548 /* Get app code offsets and sizes */
549 for (app = 0; app < minion_hdr->num_apps; app++) {
550 minion_hdr->app_code_offsets[app] =
551 minion_extract_word(nvgpu_minion_fw, data_idx);
552 data_idx += 4;
553 minion_hdr->app_code_sizes[app] =
554 minion_extract_word(nvgpu_minion_fw, data_idx);
555 data_idx += 4;
556
557 nvgpu_log(g, gpu_dbg_nvlink,
558 " - App Code:");
559 nvgpu_log(g, gpu_dbg_nvlink,
560 " - App #%d: Code Offset = %u, Code Size = %u",
561 app,
562 minion_hdr->app_code_offsets[app],
563 minion_hdr->app_code_sizes[app]);
564 }
565
566 /* Get app data offsets and sizes */
567 for (app = 0; app < minion_hdr->num_apps; app++) {
568 minion_hdr->app_data_offsets[app] =
569 minion_extract_word(nvgpu_minion_fw, data_idx);
570 data_idx += 4;
571 minion_hdr->app_data_sizes[app] =
572 minion_extract_word(nvgpu_minion_fw, data_idx);
573 data_idx += 4;
574
575 nvgpu_log(g, gpu_dbg_nvlink,
576 " - App Data:");
577 nvgpu_log(g, gpu_dbg_nvlink,
578 " - App #%d: Data Offset = %u, Data Size = %u",
579 app,
580 minion_hdr->app_data_offsets[app],
581 minion_hdr->app_data_sizes[app]);
582 }
583
584 minion_hdr->ovl_offset = minion_extract_word(nvgpu_minion_fw, data_idx);
585 data_idx += 4;
586 minion_hdr->ovl_size = minion_extract_word(nvgpu_minion_fw, data_idx);
587 data_idx += 4;
588
589 ndev->minion_img = &(nvgpu_minion_fw->data[data_idx]);
590 minion_hdr->ucode_data_size = nvgpu_minion_fw->size - data_idx;
591
489 nvgpu_log(g, gpu_dbg_nvlink, 592 nvgpu_log(g, gpu_dbg_nvlink,
490 "os_data_size: 0x%x", minion_hdr->os_data_size); 593 " - Overlay Offset = %u", minion_hdr->ovl_offset);
491 nvgpu_log(g, gpu_dbg_nvlink, 594 nvgpu_log(g, gpu_dbg_nvlink,
492 "num_apps: 0x%x", minion_hdr->num_apps); 595 " - Overlay Size = %u", minion_hdr->ovl_size);
493 nvgpu_log(g, gpu_dbg_nvlink, 596 nvgpu_log(g, gpu_dbg_nvlink,
494 "app_0_code_start: 0x%x", minion_hdr->app_0_code_start); 597 " - Ucode Data Size = %u", minion_hdr->ucode_data_size);
495 598
496 /* Clear interrupts */ 599 /* Clear interrupts */
497 nvgpu_flcn_set_irq(&g->minion_flcn, true, MINION_FALCON_INTR_MASK, 600 nvgpu_flcn_set_irq(&g->minion_flcn, true, MINION_FALCON_INTR_MASK,
@@ -499,58 +602,34 @@ static u32 gv100_nvlink_minion_load(struct gk20a *g)
499 602
500 /* Copy Non Secure IMEM code */ 603 /* Copy Non Secure IMEM code */
501 nvgpu_flcn_copy_to_imem(&g->minion_flcn, 0, 604 nvgpu_flcn_copy_to_imem(&g->minion_flcn, 0,
502 (u8 *)&minion_ucode[minion_hdr->os_code_offset >> 2], 605 (u8 *)&ndev->minion_img[minion_hdr->os_code_offset],
503 minion_hdr->os_code_size, 0, false, 606 minion_hdr->os_code_size, 0, false,
504 GET_IMEM_TAG(minion_hdr->os_code_offset)); 607 GET_IMEM_TAG(minion_hdr->os_code_offset));
505 608
506 /* Copy Non Secure DMEM code */ 609 /* Copy Non Secure DMEM code */
507 nvgpu_flcn_copy_to_dmem(&g->minion_flcn, 0, 610 nvgpu_flcn_copy_to_dmem(&g->minion_flcn, 0,
508 (u8 *)&minion_ucode[minion_hdr->os_data_offset >> 2], 611 (u8 *)&ndev->minion_img[minion_hdr->os_data_offset],
509 minion_hdr->os_data_size, 0); 612 minion_hdr->os_data_size, 0);
510 613
511 /* If apps are there load them securely */ 614 /* Load the apps securely */
512 if (minion_hdr->num_apps) { 615 for (app = 0; app < minion_hdr->num_apps; app++) {
513 for (app = 0; app < minion_hdr->num_apps; app++) { 616 u32 app_code_start = minion_hdr->app_code_offsets[app];
514 u32 app_code_start, app_code_size; 617 u32 app_code_size = minion_hdr->app_code_sizes[app];
515 u32 app_data_start, app_data_size; 618 u32 app_data_start = minion_hdr->app_data_offsets[app];
516 619 u32 app_data_size = minion_hdr->app_data_sizes[app];
517 app_code_start = 620
518 *((u32 *) &minion_hdr->app_0_code_start + 621 if (app_code_size)
519 2*app); 622 nvgpu_flcn_copy_to_imem(&g->minion_flcn,
520 app_code_size = 623 app_code_start,
521 *((u32 *) &minion_hdr->app_0_code_start + 624 (u8 *)&ndev->minion_img[app_code_start],
522 2*app + 1); 625 app_code_size, 0, true,
523 app_data_start = 626 GET_IMEM_TAG(app_code_start));
524 *((u32 *) &minion_hdr->app_0_code_start + 627
525 2*minion_hdr->num_apps + 2*app); 628 if (app_data_size)
526 app_data_size = 629 nvgpu_flcn_copy_to_dmem(&g->minion_flcn,
527 *((u32 *) &minion_hdr->app_0_code_start + 630 app_data_start,
528 2*minion_hdr->num_apps + 2*app + 1); 631 (u8 *)&ndev->minion_img[app_data_start],
529 632 app_data_size, 0);
530 nvgpu_log(g, gpu_dbg_nvlink,
531 " app %d code_offset 0x%x", app, app_code_start);
532 nvgpu_log(g, gpu_dbg_nvlink,
533 " app %d code_size 0x%x", app, app_code_size);
534 nvgpu_log(g, gpu_dbg_nvlink,
535 " app %d data_offset 0x%x", app, app_data_start);
536 nvgpu_log(g, gpu_dbg_nvlink,
537 " app %d data_size 0x%x", app, app_data_size);
538
539 if (app_code_size)
540 nvgpu_flcn_copy_to_imem(&g->minion_flcn,
541 app_code_start,
542 (u8 *)&minion_ucode[
543 app_code_start >> 2],
544 app_code_size, 0, true,
545 GET_IMEM_TAG(app_code_start));
546
547 if (app_data_size)
548 nvgpu_flcn_copy_to_dmem(&g->minion_flcn,
549 app_data_start,
550 (u8 *)&minion_ucode[
551 app_data_start >> 2],
552 app_data_size, 0);
553 }
554 } 633 }
555 634
556 /* set BOOTVEC to start of non-secure code */ 635 /* set BOOTVEC to start of non-secure code */
@@ -595,8 +674,15 @@ static u32 gv100_nvlink_minion_load(struct gk20a *g)
595 gv100_nvlink_initialize_minion(g); 674 gv100_nvlink_initialize_minion(g);
596 675
597exit: 676exit:
598 if (minion_fw) 677 nvgpu_kfree(g, minion_hdr->app_code_offsets);
599 nvgpu_release_firmware(g, minion_fw); 678 nvgpu_kfree(g, minion_hdr->app_code_sizes);
679 nvgpu_kfree(g, minion_hdr->app_data_offsets);
680 nvgpu_kfree(g, minion_hdr->app_data_sizes);
681
682 if (nvgpu_minion_fw) {
683 nvgpu_release_firmware(g, nvgpu_minion_fw);
684 ndev->minion_img = NULL;
685 }
600 686
601 return err; 687 return err;
602} 688}