diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c index 98d18eccbb6f3332916683c01f36827e263b46c3..27479891a973971426fade443d2a48b8a1caa34c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c @@ -772,7 +772,7 @@ ls_ucode_mgr_write_wpr(struct gm200_secboot *gsb, struct ls_ucode_mgr *mgr, u8 desc[gsb->func->bl_desc_size]; struct gm200_flcn_bl_desc gdesc; - ls_ucode_img_populate_bl_desc(img, gsb->wpr_addr, + ls_ucode_img_populate_bl_desc(img, gsb->acr_wpr_addr, &gdesc); gsb->func->fixup_bl_desc(&gdesc, &desc); nvkm_gpuobj_memcpy_to(wpr_blob, @@ -847,8 +847,11 @@ gm200_secboot_prepare_ls_blob(struct gm200_secboot *gsb) /* If WPR address and size are not fixed, set them to fit the LS blob */ if (!gsb->wpr_size) { - gsb->wpr_addr = gsb->ls_blob->addr; - gsb->wpr_size = gsb->ls_blob->size; + gsb->acr_wpr_addr = gsb->ls_blob->addr; + gsb->acr_wpr_size = gsb->ls_blob->size; + } else { + gsb->acr_wpr_addr = gsb->wpr_addr; + gsb->acr_wpr_size = gsb->wpr_size; } /* Write LS blob */ @@ -925,6 +928,69 @@ gm200_secboot_populate_hsf_bl_desc(void *acr_image, bl_desc->data_size = load_hdr->data_size; } +/** + * struct hsflcn_acr_desc - data section of the HS firmware + * + * This header is to be copied at the beginning of DMEM by the HS bootloader. + * + * @signature: signature of ACR ucode + * @wpr_region_id: region ID holding the WPR header and its details + * @wpr_offset: offset from the WPR region holding the wpr header + * @regions: region descriptors + * @nonwpr_ucode_blob_size: size of LS blob + * @nonwpr_ucode_blob_start: FB location of LS blob is + */ +struct hsflcn_acr_desc { + union { + u8 reserved_dmem[0x200]; + u32 signatures[4]; + } ucode_reserved_space; + u32 wpr_region_id; + u32 wpr_offset; + u32 mmu_mem_range; +#define FLCN_ACR_MAX_REGIONS 2 + struct { + u32 no_regions; + struct { + u32 start_addr; + u32 end_addr; + u32 region_id; + u32 read_mask; + u32 write_mask; + u32 client_mask; + } region_props[FLCN_ACR_MAX_REGIONS]; + } regions; + u32 ucode_blob_size; + u64 ucode_blob_base __aligned(8); + struct { + u32 vpr_enabled; + u32 vpr_start; + u32 vpr_end; + u32 hdcp_policies; + } vpr_desc; +}; + +static void +gm200_secboot_fixup_hs_desc(struct gm200_secboot *gsb, + struct hsflcn_acr_desc *desc) +{ + desc->ucode_blob_base = gsb->ls_blob->addr; + desc->ucode_blob_size = gsb->ls_blob->size; + + desc->wpr_offset = 0; + + /* WPR region information if WPR is not fixed */ + if (gsb->wpr_size == 0) { + desc->wpr_region_id = 1; + desc->regions.no_regions = 1; + desc->regions.region_props[0].region_id = 1; + desc->regions.region_props[0].start_addr = + gsb->acr_wpr_addr >> 8; + desc->regions.region_props[0].end_addr = + (gsb->acr_wpr_addr + gsb->acr_wpr_size) >> 8; + } +} + /** * gm200_secboot_prepare_hs_blob - load and prepare a HS blob and BL descriptor * @@ -958,12 +1024,12 @@ gm200_secboot_prepare_hs_blob(struct gm200_secboot *gsb, const char *fw, acr_data = acr_image + hsbin_hdr->data_offset; - /* Patch descriptor? */ + /* Patch descriptor with WPR information? */ if (patch) { fw_hdr = acr_image + hsbin_hdr->header_offset; load_hdr = acr_image + fw_hdr->hdr_offset; desc = acr_data + load_hdr->data_dma_base; - gsb->func->fixup_hs_desc(gsb, desc); + gm200_secboot_fixup_hs_desc(gsb, desc); } /* Generate HS BL descriptor */ @@ -1351,29 +1417,10 @@ gm200_secboot_fixup_bl_desc(const struct gm200_flcn_bl_desc *desc, void *ret) memcpy(ret, desc, sizeof(*desc)); } -static void -gm200_secboot_fixup_hs_desc(struct gm200_secboot *gsb, - struct hsflcn_acr_desc *desc) -{ - desc->ucode_blob_base = gsb->ls_blob->addr; - desc->ucode_blob_size = gsb->ls_blob->size; - - desc->wpr_offset = 0; - - /* WPR region information for the HS binary to set up */ - desc->wpr_region_id = 1; - desc->regions.no_regions = 1; - desc->regions.region_props[0].region_id = 1; - desc->regions.region_props[0].start_addr = gsb->wpr_addr >> 8; - desc->regions.region_props[0].end_addr = - (gsb->wpr_addr + gsb->wpr_size) >> 8; -} - static const struct gm200_secboot_func gm200_secboot_func = { .bl_desc_size = sizeof(struct gm200_flcn_bl_desc), .fixup_bl_desc = gm200_secboot_fixup_bl_desc, - .fixup_hs_desc = gm200_secboot_fixup_hs_desc, .prepare_blobs = gm200_secboot_prepare_blobs, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c index c08eb775d3a6a2dff8aa8489ce1dd8b53ecefc19..5f38187be85750e08b2c9e229630e715cb473b3a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c @@ -99,21 +99,10 @@ gm20b_secboot_fixup_bl_desc(const struct gm200_flcn_bl_desc *desc, void *ret) gdesc->data_size = desc->data_size; } -static void -gm20b_secboot_fixup_hs_desc(struct gm200_secboot *gsb, - struct hsflcn_acr_desc *desc) -{ - desc->ucode_blob_base = gsb->ls_blob->addr; - desc->ucode_blob_size = gsb->ls_blob->size; - - desc->wpr_offset = 0; -} - static const struct gm200_secboot_func gm20b_secboot_func = { .bl_desc_size = sizeof(struct gm20b_flcn_bl_desc), .fixup_bl_desc = gm20b_secboot_fixup_bl_desc, - .fixup_hs_desc = gm20b_secboot_fixup_hs_desc, .prepare_blobs = gm20b_secboot_prepare_blobs, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h index 393b945f3d8df9641189299e1a76b414a20ff7e2..e1caa6faeed28b4431692d2a1dd55751d1c01b05 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h @@ -87,48 +87,6 @@ struct gm200_flcn_bl_desc { u32 data_size; }; -/** - * struct hsflcn_acr_desc - data section of the HS firmware - * - * This header is to be copied at the beginning of DMEM by the HS bootloader. - * - * @signature: signature of ACR ucode - * @wpr_region_id: region ID holding the WPR header and its details - * @wpr_offset: offset from the WPR region holding the wpr header - * @regions: region descriptors - * @nonwpr_ucode_blob_size: size of LS blob - * @nonwpr_ucode_blob_start: FB location of LS blob is - */ -struct hsflcn_acr_desc { - union { - u8 reserved_dmem[0x200]; - u32 signatures[4]; - } ucode_reserved_space; - u32 wpr_region_id; - u32 wpr_offset; - u32 mmu_mem_range; -#define FLCN_ACR_MAX_REGIONS 2 - struct { - u32 no_regions; - struct { - u32 start_addr; - u32 end_addr; - u32 region_id; - u32 read_mask; - u32 write_mask; - u32 client_mask; - } region_props[FLCN_ACR_MAX_REGIONS]; - } regions; - u32 ucode_blob_size; - u64 ucode_blob_base __aligned(8); - struct { - u32 vpr_enabled; - u32 vpr_start; - u32 vpr_end; - u32 hdcp_policies; - } vpr_desc; -}; - /** * Contains the whole secure boot state, allowing it to be performed as needed * @wpr_addr: physical address of the WPR region @@ -151,13 +109,18 @@ struct gm200_secboot { const struct gm200_secboot_func *func; /* - * Address and size of the WPR region. On dGPU this will be the - * address of the LS blob. On Tegra this is a fixed region set by the - * bootloader + * Address and size of the fixed WPR region, if any. On Tegra this + * region is set by the bootloader */ u64 wpr_addr; u32 wpr_size; + /* + * Address and size of the actual WPR region. + */ + u64 acr_wpr_addr; + u32 acr_wpr_size; + /* * HS FW - lock WPR region (dGPU only) and load LS FWs * on Tegra the HS FW copies the LS blob into the fixed WPR instead @@ -200,7 +163,6 @@ struct gm200_secboot { * @fixup_bl_desc: hook that generates the proper BL descriptor format from * the generic GM200 format into a data array of size * bl_desc_size - * @fixup_hs_desc: hook that twiddles the HS descriptor before it is used * @prepare_blobs: prepares the various blobs needed for secure booting */ struct gm200_secboot_func { @@ -212,12 +174,6 @@ struct gm200_secboot_func { u32 bl_desc_size; void (*fixup_bl_desc)(const struct gm200_flcn_bl_desc *, void *); - /* - * Chip-specific modifications of the HS descriptor can be done here. - * On dGPU this is used to fill the information about the WPR region - * we want the HS FW to set up. - */ - void (*fixup_hs_desc)(struct gm200_secboot *, struct hsflcn_acr_desc *); int (*prepare_blobs)(struct gm200_secboot *); };