Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7defd1da authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ben Skeggs
Browse files

drm/nouveau/secboot: support for different load and unload falcons



On some secure boot instances (e.g. gp10x) the load and unload blobs do
not run on the same falcon. Support this case by introducing a new
member to the ACR structure and making related functions take the falcon
to use as an argument instead of assuming the boot falcon is to be used.

The rule is that the load blob can be run on either the SEC or PMU
falcons, but the unload blob must be always run on PMU.

Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent a13edd0b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ struct nvkm_secboot {
	struct nvkm_acr *acr;
	struct nvkm_subdev subdev;
	struct nvkm_falcon *boot_falcon;
	struct nvkm_falcon *halt_falcon;

	u64 wpr_addr;
	u32 wpr_size;
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ struct nvkm_acr_func {
	void (*dtor)(struct nvkm_acr *);
	int (*oneinit)(struct nvkm_acr *, struct nvkm_secboot *);
	int (*fini)(struct nvkm_acr *, struct nvkm_secboot *, bool);
	int (*load)(struct nvkm_acr *, struct nvkm_secboot *,
	int (*load)(struct nvkm_acr *, struct nvkm_falcon *,
		    struct nvkm_gpuobj *, u64);
	int (*reset)(struct nvkm_acr *, struct nvkm_secboot *,
		     enum nvkm_secboot_falcon);
+6 −6
Original line number Diff line number Diff line
@@ -816,11 +816,10 @@ acr_r352_load_blobs(struct acr_r352 *acr, struct nvkm_secboot *sb)
 * Returns the start address to use, or a negative error value.
 */
static int
acr_r352_load(struct nvkm_acr *_acr, struct nvkm_secboot *sb,
acr_r352_load(struct nvkm_acr *_acr, struct nvkm_falcon *falcon,
	      struct nvkm_gpuobj *blob, u64 offset)
{
	struct acr_r352 *acr = acr_r352(_acr);
	struct nvkm_falcon *falcon = sb->boot_falcon;
	struct fw_bin_header *hdr = acr->hsbl_blob;
	struct fw_bl_desc *hsbl_desc = acr->hsbl_blob + hdr->header_offset;
	void *blob_data = acr->hsbl_blob + hdr->data_offset;
@@ -873,7 +872,7 @@ acr_r352_shutdown(struct acr_r352 *acr, struct nvkm_secboot *sb)
		int ret;

		nvkm_debug(&sb->subdev, "running HS unload blob\n");
		ret = sb->func->run_blob(sb, acr->unload_blob);
		ret = sb->func->run_blob(sb, acr->unload_blob, sb->halt_falcon);
		if (ret)
			return ret;
		nvkm_debug(&sb->subdev, "HS unload blob completed\n");
@@ -935,7 +934,7 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb)
		return ret;

	nvkm_debug(subdev, "running HS load blob\n");
	ret = sb->func->run_blob(sb, acr->load_blob);
	ret = sb->func->run_blob(sb, acr->load_blob, sb->boot_falcon);
	/* clear halt interrupt */
	nvkm_falcon_clear_interrupt(sb->boot_falcon, 0x10);
	sb->wpr_set = acr_r352_wpr_is_set(acr, sb);
@@ -967,9 +966,10 @@ acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb)
	nvkm_falcon_wr32(sb->boot_falcon, 0x10, 0xff);
	nvkm_mc_intr_mask(subdev->device, sb->boot_falcon->owner->index, true);

	/* Start PMU */
	/* Start LS firmware on boot falcon */
	nvkm_falcon_start(sb->boot_falcon);
	nvkm_debug(subdev, "PMU started\n");
	nvkm_debug(subdev, "%s started\n",
		   nvkm_secboot_falcon_name[acr->base.boot_falcon]);

	return 0;
}
+2 −1
Original line number Diff line number Diff line
@@ -133,12 +133,13 @@ nvkm_secboot_oneinit(struct nvkm_subdev *subdev)

	switch (sb->acr->boot_falcon) {
	case NVKM_SECBOOT_FALCON_PMU:
		sb->boot_falcon = subdev->device->pmu->falcon;
		sb->halt_falcon = sb->boot_falcon = subdev->device->pmu->falcon;
		break;
	case NVKM_SECBOOT_FALCON_SEC2:
		/* we must keep SEC2 alive forever since ACR will run on it */
		nvkm_engine_ref(&subdev->device->sec2->engine);
		sb->boot_falcon = subdev->device->sec2->falcon;
		sb->halt_falcon = subdev->device->pmu->falcon;
		break;
	default:
		nvkm_error(subdev, "Unmanaged boot falcon %s!\n",
+4 −4
Original line number Diff line number Diff line
@@ -34,11 +34,11 @@
 *
 */
int
gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob)
gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob,
		       struct nvkm_falcon *falcon)
{
	struct gm200_secboot *gsb = gm200_secboot(sb);
	struct nvkm_subdev *subdev = &gsb->base.subdev;
	struct nvkm_falcon *falcon = gsb->base.boot_falcon;
	struct nvkm_vma vma;
	u32 start_address;
	int ret;
@@ -61,7 +61,7 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob)
	nvkm_falcon_bind_context(falcon, gsb->inst);

	/* Load the HS bootloader into the falcon's IMEM/DMEM */
	ret = sb->acr->func->load(sb->acr, &gsb->base, blob, vma.offset);
	ret = sb->acr->func->load(sb->acr, falcon, blob, vma.offset);
	if (ret < 0)
		goto end;

@@ -83,7 +83,7 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob)
	/* If mailbox register contains an error code, then ACR has failed */
	ret = nvkm_falcon_rd32(falcon, 0x040);
	if (ret) {
		nvkm_error(subdev, "ACR boot failed, ret 0x%08x", ret);
		nvkm_error(subdev, "HS blob failed, ret 0x%08x", ret);
		ret = -EINVAL;
		goto end;
	}
Loading