diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2016-12-14 17:02:45 +0900 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2017-02-17 15:14:32 +1000 |
commit | 9d896f3e41a6093a843ce668c97159367c1e4573 (patch) | |
tree | 23b18096f1ce3fd46f451722076a6806f6540a84 /drivers | |
parent | 9839307cfeedca72d4f2c27d60ada4a1ec5c9489 (diff) | |
download | linux-9d896f3e41a6093a843ce668c97159367c1e4573.tar.bz2 |
drm/nouveau/secboot: abstract LS firmware loading functions
The WPR and LSB headers, used to generate the LS blob, may have a
different layout and sizes depending on the driver version they come
from. Abstract them and confine their use to driver-specific code.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
7 files changed, 215 insertions, 167 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c index c193fa905174..741f3fc88565 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c @@ -21,7 +21,6 @@ */ #include "acr_r352.h" -#include "ls_ucode.h" #include <core/gpuobj.h> #include <core/firmware.h> @@ -94,11 +93,12 @@ struct acr_r352_flcn_bl_desc { */ static void acr_r352_generate_flcn_bl_desc(const struct nvkm_acr *acr, - const struct ls_ucode_img *img, u64 wpr_addr, + const struct ls_ucode_img *_img, u64 wpr_addr, void *_desc) { + struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); struct acr_r352_flcn_bl_desc *desc = _desc; - const struct ls_ucode_img_desc *pdesc = &img->ucode_desc; + const struct ls_ucode_img_desc *pdesc = &_img->ucode_desc; u64 base, addr_code, addr_data; base = wpr_addr + img->lsb_header.ucode_off + pdesc->app_start_offset; @@ -163,29 +163,46 @@ struct hsflcn_acr_desc { * Low-secure blob creation */ -typedef int (*lsf_load_func)(const struct nvkm_subdev *, struct ls_ucode_img *); - /** * ls_ucode_img_load() - create a lsf_ucode_img and load it */ -static struct ls_ucode_img * -ls_ucode_img_load(const struct nvkm_subdev *subdev, lsf_load_func load_func) +struct ls_ucode_img * +acr_r352_ls_ucode_img_load(const struct acr_r352 *acr, + enum nvkm_secboot_falcon falcon_id) { - struct ls_ucode_img *img; + const struct nvkm_subdev *subdev = acr->base.subdev; + struct ls_ucode_img_r352 *img; int ret; img = kzalloc(sizeof(*img), GFP_KERNEL); if (!img) return ERR_PTR(-ENOMEM); - ret = load_func(subdev, img); + img->base.falcon_id = falcon_id; + + ret = acr->func->ls_func[falcon_id]->load(subdev, &img->base); if (ret) { + kfree(img->base.ucode_data); + kfree(img->base.sig); kfree(img); return ERR_PTR(ret); } - return img; + /* Check that the signature size matches our expectations... */ + if (img->base.sig_size != sizeof(img->lsb_header.signature)) { + nvkm_error(subdev, "invalid signature size for %s falcon!\n", + nvkm_secboot_falcon_name[falcon_id]); + return ERR_PTR(-EINVAL); + } + + /* Copy signature to the right place */ + memcpy(&img->lsb_header.signature, img->base.sig, img->base.sig_size); + + /* not needed? the signature should already have the right value */ + img->lsb_header.signature.falcon_id = falcon_id; + + return &img->base; } #define LSF_LSB_HEADER_ALIGN 256 @@ -195,7 +212,7 @@ ls_ucode_img_load(const struct nvkm_subdev *subdev, lsf_load_func load_func) #define LSF_UCODE_DATA_ALIGN 4096 /** - * ls_ucode_img_fill_headers - fill the WPR and LSB headers of an image + * acr_r352_ls_img_fill_headers - fill the WPR and LSB headers of an image * @acr: ACR to use * @img: image to generate for * @offset: offset in the WPR region where this image starts @@ -206,24 +223,25 @@ ls_ucode_img_load(const struct nvkm_subdev *subdev, lsf_load_func load_func) * Return: offset at the end of this image. */ static u32 -ls_ucode_img_fill_headers(struct acr_r352 *acr, struct ls_ucode_img *img, - u32 offset) +acr_r352_ls_img_fill_headers(struct acr_r352 *acr, + struct ls_ucode_img_r352 *img, u32 offset) { - struct lsf_wpr_header *whdr = &img->wpr_header; - struct lsf_lsb_header *lhdr = &img->lsb_header; - struct ls_ucode_img_desc *desc = &img->ucode_desc; + struct ls_ucode_img *_img = &img->base; + struct acr_r352_lsf_wpr_header *whdr = &img->wpr_header; + struct acr_r352_lsf_lsb_header *lhdr = &img->lsb_header; + struct ls_ucode_img_desc *desc = &_img->ucode_desc; const struct acr_r352_ls_func *func = - acr->func->ls_func[img->falcon_id]; + acr->func->ls_func[_img->falcon_id]; /* Fill WPR header */ - whdr->falcon_id = img->falcon_id; + whdr->falcon_id = _img->falcon_id; whdr->bootstrap_owner = acr->base.boot_falcon; whdr->status = LSF_IMAGE_STATUS_COPY; /* Align, save off, and include an LSB header size */ offset = ALIGN(offset, LSF_LSB_HEADER_ALIGN); whdr->lsb_offset = offset; - offset += sizeof(struct lsf_lsb_header); + offset += sizeof(*lhdr); /* * Align, save off, and include the original (static) ucode @@ -231,7 +249,7 @@ ls_ucode_img_fill_headers(struct acr_r352 *acr, struct ls_ucode_img *img, */ offset = ALIGN(offset, LSF_UCODE_DATA_ALIGN); lhdr->ucode_off = offset; - offset += img->ucode_size; + offset += _img->ucode_size; /* * For falcons that use a boot loader (BL), we append a loader @@ -261,7 +279,7 @@ ls_ucode_img_fill_headers(struct acr_r352 *acr, struct ls_ucode_img *img, lhdr->app_data_size = desc->app_resident_data_size; lhdr->flags = func->lhdr_flags; - if (img->falcon_id == acr->base.boot_falcon) + if (_img->falcon_id == acr->base.boot_falcon) lhdr->flags |= LSF_FLAG_DMACTL_REQ_CTX; /* Align and save off BL descriptor size */ @@ -280,10 +298,10 @@ ls_ucode_img_fill_headers(struct acr_r352 *acr, struct ls_ucode_img *img, /** * acr_r352_ls_fill_headers - fill WPR and LSB headers of all managed images */ -static int +int acr_r352_ls_fill_headers(struct acr_r352 *acr, struct list_head *imgs) { - struct ls_ucode_img *img; + struct ls_ucode_img_r352 *img; struct list_head *l; u32 count = 0; u32 offset; @@ -298,34 +316,35 @@ acr_r352_ls_fill_headers(struct acr_r352 *acr, struct list_head *imgs) * read of this array and cache it internally so it's ok to pack these. * Also, we add 1 to the falcon count to indicate the end of the array. */ - offset = sizeof(struct lsf_wpr_header) * (count + 1); + offset = sizeof(img->wpr_header) * (count + 1); /* * Walk the managed falcons, accounting for the LSB structs * as well as the ucode images. */ - list_for_each_entry(img, imgs, node) { - offset = ls_ucode_img_fill_headers(acr, img, offset); + list_for_each_entry(img, imgs, base.node) { + offset = acr_r352_ls_img_fill_headers(acr, img, offset); } return offset; } /** - * ls_ucode_mgr_write_wpr - write the WPR blob contents + * acr_r352_ls_write_wpr - write the WPR blob contents */ -static int -ls_ucode_mgr_write_wpr(struct acr_r352 *acr, struct list_head *imgs, - struct nvkm_gpuobj *wpr_blob, u32 wpr_addr) +int +acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, + struct nvkm_gpuobj *wpr_blob, u32 wpr_addr) { - struct ls_ucode_img *img; + struct ls_ucode_img *_img; u32 pos = 0; nvkm_kmap(wpr_blob); - list_for_each_entry(img, imgs, node) { + list_for_each_entry(_img, imgs, node) { + struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); const struct acr_r352_ls_func *ls_func = - acr->func->ls_func[img->falcon_id]; + acr->func->ls_func[_img->falcon_id]; u8 gdesc[ls_func->bl_desc_size]; nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, @@ -335,14 +354,14 @@ ls_ucode_mgr_write_wpr(struct acr_r352 *acr, struct list_head *imgs, &img->lsb_header, sizeof(img->lsb_header)); /* Generate and write BL descriptor */ - ls_func->generate_bl_desc(&acr->base, img, wpr_addr, gdesc); + ls_func->generate_bl_desc(&acr->base, _img, wpr_addr, gdesc); nvkm_gpuobj_memcpy_to(wpr_blob, img->lsb_header.bl_data_off, gdesc, ls_func->bl_desc_size); /* Copy ucode */ nvkm_gpuobj_memcpy_to(wpr_blob, img->lsb_header.ucode_off, - img->ucode_data, img->ucode_size); + _img->ucode_data, _img->ucode_size); pos += sizeof(img->wpr_header); } @@ -382,13 +401,12 @@ acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size) for_each_set_bit(falcon_id, &managed_falcons, NVKM_SECBOOT_FALCON_END) { struct ls_ucode_img *img; - img = ls_ucode_img_load(subdev, - acr->func->ls_func[falcon_id]->load); - + img = acr->func->ls_ucode_img_load(acr, falcon_id); if (IS_ERR(img)) { ret = PTR_ERR(img); goto cleanup; } + list_add_tail(&img->node, &imgs); managed_count++; } @@ -397,7 +415,7 @@ acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size) * Fill the WPR and LSF headers with the right offsets and compute * required WPR size */ - image_wpr_size = acr_r352_ls_fill_headers(acr, &imgs); + image_wpr_size = acr->func->ls_fill_headers(acr, &imgs); image_wpr_size = ALIGN(image_wpr_size, WPR_ALIGNMENT); /* Allocate GPU object that will contain the WPR region */ @@ -426,13 +444,14 @@ acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size) } /* Write LS blob */ - ret = ls_ucode_mgr_write_wpr(acr, &imgs, acr->ls_blob, wpr_addr); + ret = acr->func->ls_write_wpr(acr, &imgs, acr->ls_blob, wpr_addr); if (ret) nvkm_gpuobj_del(&acr->ls_blob); cleanup: list_for_each_entry_safe(img, t, &imgs, node) { kfree(img->ucode_data); + kfree(img->sig); kfree(img); } @@ -859,6 +878,9 @@ const struct acr_r352_func acr_r352_func = { .generate_hs_bl_desc = acr_r352_generate_hs_bl_desc, .hs_bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc), + .ls_ucode_img_load = acr_r352_ls_ucode_img_load, + .ls_fill_headers = acr_r352_ls_fill_headers, + .ls_write_wpr = acr_r352_ls_write_wpr, .ls_func = { [NVKM_SECBOOT_FALCON_FECS] = &acr_r352_ls_fecs_func, [NVKM_SECBOOT_FALCON_GPCCS] = &acr_r352_ls_gpccs_func, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h index 9323ed0ae040..f335dced1e61 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h @@ -23,11 +23,116 @@ #define __NVKM_SECBOOT_ACR_R352_H__ #include "acr.h" +#include "ls_ucode.h" struct ls_ucode_img; #define ACR_R352_MAX_APPS 8 +/* + * + * LS blob structures + * + */ + +/** + * struct acr_r352_lsf_lsb_header - LS firmware header + * @signature: signature to verify the firmware against + * @ucode_off: offset of the ucode blob in the WPR region. The ucode + * blob contains the bootloader, code and data of the + * LS falcon + * @ucode_size: size of the ucode blob, including bootloader + * @data_size: size of the ucode blob data + * @bl_code_size: size of the bootloader code + * @bl_imem_off: offset in imem of the bootloader + * @bl_data_off: offset of the bootloader data in WPR region + * @bl_data_size: size of the bootloader data + * @app_code_off: offset of the app code relative to ucode_off + * @app_code_size: size of the app code + * @app_data_off: offset of the app data relative to ucode_off + * @app_data_size: size of the app data + * @flags: flags for the secure bootloader + * + * This structure is written into the WPR region for each managed falcon. Each + * instance is referenced by the lsb_offset member of the corresponding + * lsf_wpr_header. + */ +struct acr_r352_lsf_lsb_header { + /** + * LS falcon signatures + * @prd_keys: signature to use in production mode + * @dgb_keys: signature to use in debug mode + * @b_prd_present: whether the production key is present + * @b_dgb_present: whether the debug key is present + * @falcon_id: ID of the falcon the ucode applies to + */ + struct { + u8 prd_keys[2][16]; + u8 dbg_keys[2][16]; + u32 b_prd_present; + u32 b_dbg_present; + u32 falcon_id; + } signature; + u32 ucode_off; + u32 ucode_size; + u32 data_size; + u32 bl_code_size; + u32 bl_imem_off; + u32 bl_data_off; + u32 bl_data_size; + u32 app_code_off; + u32 app_code_size; + u32 app_data_off; + u32 app_data_size; + u32 flags; +#define LSF_FLAG_LOAD_CODE_AT_0 1 +#define LSF_FLAG_DMACTL_REQ_CTX 4 +#define LSF_FLAG_FORCE_PRIV_LOAD 8 +}; + +/** + * struct acr_r352_lsf_wpr_header - LS blob WPR Header + * @falcon_id: LS falcon ID + * @lsb_offset: offset of the lsb_lsf_header in the WPR region + * @bootstrap_owner: secure falcon reponsible for bootstrapping the LS falcon + * @lazy_bootstrap: skip bootstrapping by ACR + * @status: bootstrapping status + * + * An array of these is written at the beginning of the WPR region, one for + * each managed falcon. The array is terminated by an instance which falcon_id + * is LSF_FALCON_ID_INVALID. + */ +struct acr_r352_lsf_wpr_header { + u32 falcon_id; + u32 lsb_offset; + u32 bootstrap_owner; + u32 lazy_bootstrap; + u32 status; +#define LSF_IMAGE_STATUS_NONE 0 +#define LSF_IMAGE_STATUS_COPY 1 +#define LSF_IMAGE_STATUS_VALIDATION_CODE_FAILED 2 +#define LSF_IMAGE_STATUS_VALIDATION_DATA_FAILED 3 +#define LSF_IMAGE_STATUS_VALIDATION_DONE 4 +#define LSF_IMAGE_STATUS_VALIDATION_SKIPPED 5 +#define LSF_IMAGE_STATUS_BOOTSTRAP_READY 6 +}; + +/** + * struct ls_ucode_img_r352 - ucode image augmented with r352 headers + */ +struct ls_ucode_img_r352 { + struct ls_ucode_img base; + + struct acr_r352_lsf_wpr_header wpr_header; + struct acr_r352_lsf_lsb_header lsb_header; +}; +#define ls_ucode_img_r352(i) container_of(i, struct ls_ucode_img_r352, base) + + +/* + * HS blob structures + */ + struct hsf_load_header_app { u32 sec_code_off; u32 sec_code_size; @@ -62,6 +167,8 @@ struct acr_r352_ls_func { u32 lhdr_flags; }; +struct acr_r352; + /** * struct acr_r352_func - manages nuances between ACR versions * @@ -74,6 +181,12 @@ struct acr_r352_func { u64); u32 hs_bl_desc_size; + struct ls_ucode_img *(*ls_ucode_img_load)(const struct acr_r352 *, + enum nvkm_secboot_falcon); + int (*ls_fill_headers)(struct acr_r352 *, struct list_head *); + int (*ls_write_wpr)(struct acr_r352 *, struct list_head *, + struct nvkm_gpuobj *, u32); + const struct acr_r352_ls_func *ls_func[NVKM_SECBOOT_FALCON_END]; }; @@ -125,4 +238,10 @@ struct acr_r352 { struct nvkm_acr *acr_r352_new_(const struct acr_r352_func *, enum nvkm_secboot_falcon, unsigned long); +struct ls_ucode_img *acr_r352_ls_ucode_img_load(const struct acr_r352 *, + enum nvkm_secboot_falcon); +int acr_r352_ls_fill_headers(struct acr_r352 *, struct list_head *); +int acr_r352_ls_write_wpr(struct acr_r352 *, struct list_head *, + struct nvkm_gpuobj *, u32); + #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.c index 097e641d3a11..4b9a688965e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.c @@ -21,7 +21,6 @@ */ #include "acr_r352.h" -#include "ls_ucode.h" #include <engine/falcon.h> @@ -64,11 +63,12 @@ struct acr_r361_flcn_bl_desc { static void acr_r361_generate_flcn_bl_desc(const struct nvkm_acr *acr, - const struct ls_ucode_img *img, u64 wpr_addr, + const struct ls_ucode_img *_img, u64 wpr_addr, void *_desc) { + struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); struct acr_r361_flcn_bl_desc *desc = _desc; - const struct ls_ucode_img_desc *pdesc = &img->ucode_desc; + const struct ls_ucode_img_desc *pdesc = &img->base.ucode_desc; u64 base, addr_code, addr_data; base = wpr_addr + img->lsb_header.ucode_off + pdesc->app_start_offset; @@ -123,6 +123,9 @@ const struct acr_r352_func acr_r361_func = { .generate_hs_bl_desc = acr_r361_generate_hs_bl_desc, .hs_bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc), + .ls_ucode_img_load = acr_r352_ls_ucode_img_load, + .ls_fill_headers = acr_r352_ls_fill_headers, + .ls_write_wpr = acr_r352_ls_write_wpr, .ls_func = { [NVKM_SECBOOT_FALCON_FECS] = &acr_r361_ls_fecs_func, [NVKM_SECBOOT_FALCON_GPCCS] = &acr_r361_ls_gpccs_func, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c index ad739c621526..27c9dfffb9a6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c @@ -88,8 +88,8 @@ #include <subdev/timer.h> #include <subdev/pmu.h> -static const char * -managed_falcons_names[] = { +const char * +nvkm_secboot_falcon_name[] = { [NVKM_SECBOOT_FALCON_PMU] = "PMU", [NVKM_SECBOOT_FALCON_RESERVED] = "<reserved>", [NVKM_SECBOOT_FALCON_FECS] = "FECS", @@ -135,7 +135,7 @@ nvkm_secboot_oneinit(struct nvkm_subdev *subdev) break; default: nvkm_error(subdev, "Unmanaged boot falcon %s!\n", - managed_falcons_names[sb->acr->boot_falcon]); + nvkm_secboot_falcon_name[sb->acr->boot_falcon]); return -EINVAL; } @@ -197,7 +197,8 @@ nvkm_secboot_ctor(const struct nvkm_secboot_func *func, struct nvkm_acr *acr, nvkm_debug(&sb->subdev, "securely managed falcons:\n"); for_each_set_bit(fid, &sb->acr->managed_falcons, NVKM_SECBOOT_FALCON_END) - nvkm_debug(&sb->subdev, "- %s\n", managed_falcons_names[fid]); + nvkm_debug(&sb->subdev, "- %s\n", + nvkm_secboot_falcon_name[fid]); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h index be9eac5d44ab..00886cee57eb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h @@ -27,98 +27,6 @@ #include <core/subdev.h> #include <subdev/secboot.h> -/* - * - * LS blob structures - * - */ - -/** - * struct lsf_ucode_desc - LS falcon signatures - * @prd_keys: signature to use when the GPU is in production mode - * @dgb_keys: signature to use when the GPU is in debug mode - * @b_prd_present: whether the production key is present - * @b_dgb_present: whether the debug key is present - * @falcon_id: ID of the falcon the ucode applies to - * - * Directly loaded from a signature file. - */ -struct lsf_ucode_desc { - u8 prd_keys[2][16]; - u8 dbg_keys[2][16]; - u32 b_prd_present; - u32 b_dbg_present; - u32 falcon_id; -}; - -/** - * struct lsf_lsb_header - LS firmware header - * @signature: signature to verify the firmware against - * @ucode_off: offset of the ucode blob in the WPR region. The ucode - * blob contains the bootloader, code and data of the - * LS falcon - * @ucode_size: size of the ucode blob, including bootloader - * @data_size: size of the ucode blob data - * @bl_code_size: size of the bootloader code - * @bl_imem_off: offset in imem of the bootloader - * @bl_data_off: offset of the bootloader data in WPR region - * @bl_data_size: size of the bootloader data - * @app_code_off: offset of the app code relative to ucode_off - * @app_code_size: size of the app code - * @app_data_off: offset of the app data relative to ucode_off - * @app_data_size: size of the app data - * @flags: flags for the secure bootloader - * - * This structure is written into the WPR region for each managed falcon. Each - * instance is referenced by the lsb_offset member of the corresponding - * lsf_wpr_header. - */ -struct lsf_lsb_header { - struct lsf_ucode_desc signature; - u32 ucode_off; - u32 ucode_size; - u32 data_size; - u32 bl_code_size; - u32 bl_imem_off; - u32 bl_data_off; - u32 bl_data_size; - u32 app_code_off; - u32 app_code_size; - u32 app_data_off; - u32 app_data_size; - u32 flags; -#define LSF_FLAG_LOAD_CODE_AT_0 1 -#define LSF_FLAG_DMACTL_REQ_CTX 4 -#define LSF_FLAG_FORCE_PRIV_LOAD 8 -}; - -/** - * struct lsf_wpr_header - LS blob WPR Header - * @falcon_id: LS falcon ID - * @lsb_offset: offset of the lsb_lsf_header in the WPR region - * @bootstrap_owner: secure falcon reponsible for bootstrapping the LS falcon - * @lazy_bootstrap: skip bootstrapping by ACR - * @status: bootstrapping status - * - * An array of these is written at the beginning of the WPR region, one for - * each managed falcon. The array is terminated by an instance which falcon_id - * is LSF_FALCON_ID_INVALID. - */ -struct lsf_wpr_header { - u32 falcon_id; - u32 lsb_offset; - u32 bootstrap_owner; - u32 lazy_bootstrap; - u32 status; -#define LSF_IMAGE_STATUS_NONE 0 -#define LSF_IMAGE_STATUS_COPY 1 -#define LSF_IMAGE_STATUS_VALIDATION_CODE_FAILED 2 -#define LSF_IMAGE_STATUS_VALIDATION_DATA_FAILED 3 -#define LSF_IMAGE_STATUS_VALIDATION_DONE 4 -#define LSF_IMAGE_STATUS_VALIDATION_SKIPPED 5 -#define LSF_IMAGE_STATUS_BOOTSTRAP_READY 6 -}; - /** * struct ls_ucode_img_desc - descriptor of firmware image @@ -175,8 +83,8 @@ struct ls_ucode_img_desc { * @ucode_desc: loaded or generated map of ucode_data * @ucode_data: firmware payload (code and data) * @ucode_size: size in bytes of data in ucode_data - * @wpr_header: WPR header to be written to the LS blob - * @lsb_header: LSB header to be written to the LS blob + * @sig: signature for this firmware + * @sig:size: size of the signature in bytes * * Preparing the WPR LS blob requires information about all the LS firmwares * (size, etc) to be known. This structure contains all the data of one LS @@ -190,8 +98,8 @@ struct ls_ucode_img { u8 *ucode_data; u32 ucode_size; - struct lsf_wpr_header wpr_header; - struct lsf_lsb_header lsb_header; + u8 *sig; + u32 sig_size; }; /** diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c index 197ec1be47bf..40a6df77bb8a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c @@ -91,10 +91,9 @@ ls_ucode_img_build(const struct firmware *bl, const struct firmware *code, */ static int ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img, - const char *falcon_name, const u32 falcon_id) + const char *falcon_name) { - const struct firmware *bl, *code, *data; - struct lsf_ucode_desc *lsf_desc; + const struct firmware *bl, *code, *data, *sig; char f[64]; int ret; @@ -113,6 +112,17 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img, if (ret) goto free_inst; + snprintf(f, sizeof(f), "gr/%s_sig", falcon_name); + ret = nvkm_firmware_get(subdev->device, f, &sig); + if (ret) + goto free_data; + img->sig = kmemdup(sig->data, sig->size, GFP_KERNEL); + if (!img->sig) { + ret = -ENOMEM; + goto free_sig; + } + img->sig_size = sig->size; + img->ucode_data = ls_ucode_img_build(bl, code, data, &img->ucode_desc); if (IS_ERR(img->ucode_data)) { @@ -121,23 +131,8 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img, } img->ucode_size = img->ucode_desc.image_size; - snprintf(f, sizeof(f), "gr/%s_sig", falcon_name); - lsf_desc = nvkm_acr_load_firmware(subdev, f, sizeof(*lsf_desc)); - if (IS_ERR(lsf_desc)) { - ret = PTR_ERR(lsf_desc); - goto free_image; - } - /* not needed? the signature should already have the right value */ - lsf_desc->falcon_id = falcon_id; - memcpy(&img->lsb_header.signature, lsf_desc, sizeof(*lsf_desc)); - img->falcon_id = lsf_desc->falcon_id; - kfree(lsf_desc); - - /* success path - only free requested firmware files */ - goto free_data; - -free_image: - kfree(img->ucode_data); +free_sig: + nvkm_firmware_put(sig); free_data: nvkm_firmware_put(data); free_inst: @@ -152,14 +147,12 @@ int acr_ls_ucode_load_fecs(const struct nvkm_subdev *subdev, struct ls_ucode_img *img) { - return ls_ucode_img_load_gr(subdev, img, "fecs", - NVKM_SECBOOT_FALCON_FECS); + return ls_ucode_img_load_gr(subdev, img, "fecs"); } int acr_ls_ucode_load_gpccs(const struct nvkm_subdev *subdev, struct ls_ucode_img *img) { - return ls_ucode_img_load_gr(subdev, img, "gpccs", - NVKM_SECBOOT_FALCON_GPCCS); + return ls_ucode_img_load_gr(subdev, img, "gpccs"); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h index 430b88ec74cf..936a65f5658c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h @@ -33,6 +33,8 @@ struct nvkm_secboot_func { int (*run_blob)(struct nvkm_secboot *, struct nvkm_gpuobj *); }; +extern const char *nvkm_secboot_falcon_name[]; + int nvkm_secboot_ctor(const struct nvkm_secboot_func *, struct nvkm_acr *, struct nvkm_device *, int, struct nvkm_secboot *); int nvkm_secboot_falcon_reset(struct nvkm_secboot *); |