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

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

drm/nouveau/secboot: support for unload blob bootloader



If the load and unload falcons are different, then a different
bootloader must also be used. Support this case.

Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent c93cfe35
Loading
Loading
Loading
Loading
+34 −30
Original line number Diff line number Diff line
@@ -737,27 +737,6 @@ acr_r352_prepare_hs_blob(struct acr_r352 *acr, struct nvkm_secboot *sb,
	return ret;
}

static int
acr_r352_prepare_hsbl_blob(struct acr_r352 *acr)
{
	const struct nvkm_subdev *subdev = acr->base.subdev;
	struct fw_bin_header *hdr;
	struct fw_bl_desc *hsbl_desc;

	acr->hsbl_blob = nvkm_acr_load_firmware(subdev, "acr/bl", 0);
	if (IS_ERR(acr->hsbl_blob)) {
		int ret = PTR_ERR(acr->hsbl_blob);

		acr->hsbl_blob = NULL;
		return ret;
	}

	hdr = acr->hsbl_blob;
	hsbl_desc = acr->hsbl_blob + hdr->header_offset;

	return 0;
}

/**
 * acr_r352_load_blobs - load blobs common to all ACR V1 versions.
 *
@@ -768,6 +747,7 @@ acr_r352_prepare_hsbl_blob(struct acr_r352 *acr)
int
acr_r352_load_blobs(struct acr_r352 *acr, struct nvkm_secboot *sb)
{
	struct nvkm_subdev *subdev = &sb->subdev;
	int ret;

	/* Firmware already loaded? */
@@ -799,11 +779,26 @@ acr_r352_load_blobs(struct acr_r352 *acr, struct nvkm_secboot *sb)

	/* Load the HS firmware bootloader */
	if (!acr->hsbl_blob) {
		ret = acr_r352_prepare_hsbl_blob(acr);
		if (ret)
		acr->hsbl_blob = nvkm_acr_load_firmware(subdev, "acr/bl", 0);
		if (IS_ERR(acr->hsbl_blob)) {
			ret = PTR_ERR(acr->hsbl_blob);
			acr->hsbl_blob = NULL;
			return ret;
		}

		if (acr->base.boot_falcon != NVKM_SECBOOT_FALCON_PMU) {
			acr->hsbl_unload_blob = nvkm_acr_load_firmware(subdev,
							    "acr/unload_bl", 0);
			if (IS_ERR(acr->hsbl_unload_blob)) {
				ret = PTR_ERR(acr->hsbl_unload_blob);
				acr->hsbl_unload_blob = NULL;
				return ret;
			}
		} else {
			acr->hsbl_unload_blob = acr->hsbl_blob;
		}
	}

	acr->firmware_ok = true;
	nvkm_debug(&sb->subdev, "LS blob successfully created\n");

@@ -820,26 +815,33 @@ 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 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;
	void *hsbl_code = blob_data + hsbl_desc->code_off;
	void *hsbl_data = blob_data + hsbl_desc->data_off;
	u32 code_size = ALIGN(hsbl_desc->code_size, 256);
	const struct hsf_load_header *load_hdr;
	const u32 bl_desc_size = acr->func->hs_bl_desc_size;
	const struct hsf_load_header *load_hdr;
	struct fw_bin_header *bl_hdr;
	struct fw_bl_desc *hsbl_desc;
	void *bl, *blob_data, *hsbl_code, *hsbl_data;
	u32 code_size;
	u8 bl_desc[bl_desc_size];

	/* Find the bootloader descriptor for our blob and copy it */
	if (blob == acr->load_blob) {
		load_hdr = &acr->load_bl_header;
		bl = acr->hsbl_blob;
	} else if (blob == acr->unload_blob) {
		load_hdr = &acr->unload_bl_header;
		bl = acr->hsbl_unload_blob;
	} else {
		nvkm_error(_acr->subdev, "invalid secure boot blob!\n");
		return -EINVAL;
	}

	bl_hdr = bl;
	hsbl_desc = bl + bl_hdr->header_offset;
	blob_data = bl + bl_hdr->data_offset;
	hsbl_code = blob_data + hsbl_desc->code_off;
	hsbl_data = blob_data + hsbl_desc->data_off;
	code_size = ALIGN(hsbl_desc->code_size, 256);

	/*
	 * Copy HS bootloader data
	 */
@@ -1087,6 +1089,8 @@ acr_r352_dtor(struct nvkm_acr *_acr)

	nvkm_gpuobj_del(&acr->unload_blob);

	if (_acr->boot_falcon != NVKM_SECBOOT_FALCON_PMU)
		kfree(acr->hsbl_unload_blob);
	kfree(acr->hsbl_blob);
	nvkm_gpuobj_del(&acr->load_blob);
	nvkm_gpuobj_del(&acr->ls_blob);
+3 −0
Original line number Diff line number Diff line
@@ -142,6 +142,9 @@ struct acr_r352 {
	/* HS bootloader */
	void *hsbl_blob;

	/* HS bootloader for unload blob, if using a different falcon */
	void *hsbl_unload_blob;

	/* LS FWs, to be loaded by the HS ACR */
	struct nvkm_gpuobj *ls_blob;