drm/nouveau/secboot: support standard NVIDIA HS binaries
I had the brilliant idea to "improve" the binary format by removing a useless indirection in the HS binary files. In the end it just makes things more complicated than they ought to be as NVIDIA-provided files need to be adapted. Since the format used can be identified by the header, support both. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
b58b417163
commit
c5e1fef487
@ -599,19 +599,35 @@ cleanup:
|
||||
|
||||
|
||||
/**
|
||||
* acr_r352_hsf_patch_signature() - patch HS blob with correct signature
|
||||
* acr_r352_hsf_patch_signature() - patch HS blob with correct signature for
|
||||
* specified falcon.
|
||||
*/
|
||||
static void
|
||||
acr_r352_hsf_patch_signature(struct nvkm_secboot *sb, void *acr_image)
|
||||
acr_r352_hsf_patch_signature(const struct nvkm_falcon *falcon, void *acr_image,
|
||||
bool new_format)
|
||||
{
|
||||
struct fw_bin_header *hsbin_hdr = acr_image;
|
||||
struct hsf_fw_header *fw_hdr = acr_image + hsbin_hdr->header_offset;
|
||||
void *hs_data = acr_image + hsbin_hdr->data_offset;
|
||||
void *sig;
|
||||
u32 sig_size;
|
||||
u32 patch_loc, patch_sig;
|
||||
|
||||
/*
|
||||
* I had the brilliant idea to "improve" the binary format by
|
||||
* removing this useless indirection. However to make NVIDIA files
|
||||
* directly compatible, let's support both format.
|
||||
*/
|
||||
if (new_format) {
|
||||
patch_loc = fw_hdr->patch_loc;
|
||||
patch_sig = fw_hdr->patch_sig;
|
||||
} else {
|
||||
patch_loc = *(u32 *)(acr_image + fw_hdr->patch_loc);
|
||||
patch_sig = *(u32 *)(acr_image + fw_hdr->patch_sig);
|
||||
}
|
||||
|
||||
/* Falcon in debug or production mode? */
|
||||
if (sb->boot_falcon->debug) {
|
||||
if (falcon->debug) {
|
||||
sig = acr_image + fw_hdr->sig_dbg_offset;
|
||||
sig_size = fw_hdr->sig_dbg_size;
|
||||
} else {
|
||||
@ -620,7 +636,7 @@ acr_r352_hsf_patch_signature(struct nvkm_secboot *sb, void *acr_image)
|
||||
}
|
||||
|
||||
/* Patch signature */
|
||||
memcpy(hs_data + fw_hdr->patch_loc, sig + fw_hdr->patch_sig, sig_size);
|
||||
memcpy(hs_data + patch_loc, sig + patch_sig, sig_size);
|
||||
}
|
||||
|
||||
void
|
||||
@ -670,6 +686,37 @@ acr_r352_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc,
|
||||
bl_desc->data_size = hdr->data_size;
|
||||
}
|
||||
|
||||
void *
|
||||
acr_r352_load_hs_blob(struct nvkm_secboot *sb, const struct nvkm_falcon *falcon,
|
||||
const char *fw)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &sb->subdev;
|
||||
void *acr_image;
|
||||
bool new_format;
|
||||
|
||||
acr_image = nvkm_acr_load_firmware(subdev, fw, 0);
|
||||
if (IS_ERR(acr_image))
|
||||
return acr_image;
|
||||
|
||||
/* detect the format to define how signature should be patched */
|
||||
switch (((u32 *)acr_image)[0]) {
|
||||
case 0x3b1d14f0:
|
||||
new_format = true;
|
||||
break;
|
||||
case 0x000010de:
|
||||
new_format = false;
|
||||
break;
|
||||
default:
|
||||
nvkm_error(subdev, "unknown header for HS blob %s\n", fw);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/* Patch signature */
|
||||
acr_r352_hsf_patch_signature(falcon, acr_image, new_format);
|
||||
|
||||
return acr_image;
|
||||
}
|
||||
|
||||
/**
|
||||
* acr_r352_prepare_hs_blob - load and prepare a HS blob and BL descriptor
|
||||
*
|
||||
@ -692,7 +739,7 @@ acr_r352_prepare_hs_blob(struct acr_r352 *acr, struct nvkm_secboot *sb,
|
||||
void *acr_data;
|
||||
int ret;
|
||||
|
||||
acr_image = nvkm_acr_load_firmware(subdev, fw, 0);
|
||||
acr_image = acr_r352_load_hs_blob(sb, sb->boot_falcon, fw);
|
||||
if (IS_ERR(acr_image))
|
||||
return PTR_ERR(acr_image);
|
||||
|
||||
@ -701,9 +748,6 @@ acr_r352_prepare_hs_blob(struct acr_r352 *acr, struct nvkm_secboot *sb,
|
||||
load_hdr = acr_image + fw_hdr->hdr_offset;
|
||||
acr_data = acr_image + hsbin_hdr->data_offset;
|
||||
|
||||
/* Patch signature */
|
||||
acr_r352_hsf_patch_signature(sb, acr_image);
|
||||
|
||||
/* Patch descriptor with WPR information? */
|
||||
if (patch) {
|
||||
struct hsflcn_acr_desc *desc;
|
||||
|
Loading…
Reference in New Issue
Block a user