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,
/* 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 */
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
*
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 */
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,
};
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
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
* @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 {
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 *);
};