drm/nouveau/secboot: abstract LS firmware loading functions
authorAlexandre Courbot <acourbot@nvidia.com>
Wed, 14 Dec 2016 08:02:45 +0000 (17:02 +0900)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 17 Feb 2017 05:14:32 +0000 (15:14 +1000)
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>
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h

index c193fa905174e1ad621992744ea25ebd9861f8b0..741f3fc8856513aac034e1b53cccd2a5b316deb2 100644 (file)
@@ -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,
index 9323ed0ae04077a417370045ac63849d5db046b4..f335dced1e61a8405924b44a8e049b247275265c 100644 (file)
 #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
index 097e641d3a11a561d42caf520d31ce1fd58a1e83..4b9a688965e5c765279ebccc3a125cd0610f8324 100644 (file)
@@ -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,
index ad739c6215263ffbf02b46d7ac819bebd79b8831..27c9dfffb9a6e5080c0a99fab9f59a73ba99a7ff 100644 (file)
@@ -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;
 }
index be9eac5d44ab963512dc04d62a29e6e8a0d097df..00886cee57ebcc5f6c6aaf4e86a238c0267c6cef 100644 (file)
 #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;
 };
 
 /**
index 197ec1be47bf81309d34365feace2a2a737da7fd..40a6df77bb8a7ab8c43e9fe05cab030051f5584f 100644 (file)
@@ -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");
 }
index 430b88ec74cf68ab575e4cc058e60796ad43bb24..936a65f5658c682929fd68feb9494aea7b859515 100644 (file)
@@ -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 *);