drm/nouveau/secboot: get start address of blob from ACR
authorAlexandre Courbot <acourbot@nvidia.com>
Thu, 26 Jan 2017 07:04:14 +0000 (16:04 +0900)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 7 Mar 2017 07:05:13 +0000 (17:05 +1000)
The start address used for secure blobs is not unique to the ACR, but
rather blob-dependent. Remove the unique member stored in the ACR
structure and make the load function return the start address for the
current blob instead.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c

index 580036d623b21fc3c95e72a4636db6252a02ee69..9738340d33a16ed9570e835453d485b8ae5230a9 100644 (file)
@@ -49,7 +49,6 @@ struct nvkm_acr_func {
  * @boot_falcon: ID of the falcon that will perform secure boot
  * @managed_falcons: bitfield of falcons managed by this ACR
  * @optional_falcons: bitfield of falcons we can live without
- * @start_address: virtual start address of the HS bootloader
  */
 struct nvkm_acr {
        const struct nvkm_acr_func *func;
@@ -58,7 +57,6 @@ struct nvkm_acr {
        enum nvkm_secboot_falcon boot_falcon;
        unsigned long managed_falcons;
        unsigned long optional_falcons;
-       u32 start_address;
 };
 
 void *nvkm_acr_load_firmware(const struct nvkm_subdev *, const char *, size_t);
index 814f9f2a17ef89c30004cd3b19d84cf1a8ba6d64..83395147e8556ca713619fe50630703e5a3976f0 100644 (file)
@@ -754,9 +754,6 @@ acr_r352_prepare_hsbl_blob(struct acr_r352 *acr)
        hdr = acr->hsbl_blob;
        hsbl_desc = acr->hsbl_blob + hdr->header_offset;
 
-       /* virtual start address for boot vector */
-       acr->base.start_address = hsbl_desc->start_tag << 8;
-
        return 0;
 }
 
@@ -813,8 +810,9 @@ acr_r352_load_blobs(struct acr_r352 *acr, struct nvkm_secboot *sb)
 }
 
 /**
- * acr_r352_load() - prepare HS falcon to run the specified blob, mapped
- * at GPU address offset.
+ * acr_r352_load() - prepare HS falcon to run the specified blob, mapped.
+ *
+ * Returns the start address to use, or a negative error value.
  */
 static int
 acr_r352_load(struct nvkm_acr *_acr, struct nvkm_secboot *sb,
@@ -861,7 +859,7 @@ acr_r352_load(struct nvkm_acr *_acr, struct nvkm_secboot *sb,
        nvkm_falcon_load_dmem(falcon, bl_desc, hsbl_desc->dmem_load_off,
                              bl_desc_size, 0);
 
-       return 0;
+       return hsbl_desc->start_tag << 8;
 }
 
 static int
index 813c4eb0b25f5fc865db58c16809416ffc0c2f06..b21e91778f86077545829c6394ed2798c353acff 100644 (file)
@@ -40,6 +40,7 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob)
        struct nvkm_subdev *subdev = &gsb->base.subdev;
        struct nvkm_falcon *falcon = gsb->base.boot_falcon;
        struct nvkm_vma vma;
+       u32 start_address;
        int ret;
 
        ret = nvkm_falcon_get(falcon, subdev);
@@ -61,9 +62,11 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob)
 
        /* Load the HS bootloader into the falcon's IMEM/DMEM */
        ret = sb->acr->func->load(sb->acr, &gsb->base, blob, vma.offset);
-       if (ret)
+       if (ret < 0)
                goto end;
 
+       start_address = ret;
+
        /* Disable interrupts as we will poll for the HALT bit */
        nvkm_mc_intr_mask(sb->subdev.device, falcon->owner->index, false);
 
@@ -71,7 +74,7 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob)
        nvkm_falcon_wr32(falcon, 0x040, 0xdeada5a5);
 
        /* Start the HS bootloader */
-       nvkm_falcon_set_start_addr(falcon, sb->acr->start_address);
+       nvkm_falcon_set_start_addr(falcon, start_address);
        nvkm_falcon_start(falcon);
        ret = nvkm_falcon_wait_for_halt(falcon, 100);
        if (ret)