drm/nouveau/secboot: split out FW version-specific LS function pointers
authorBen Skeggs <bskeggs@redhat.com>
Thu, 6 Jun 2019 05:57:14 +0000 (15:57 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 7 Jun 2019 05:13:58 +0000 (15:13 +1000)
It's not enough to have per-falcon structures anymore, we have multiple
versions of some firmware now that have interface differences.

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/acr_r367.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c

index df666fb03f5f9f6ad3357fc277920e603becc838..4fd4cfe459b8ac5541eaf0eb8d1f70c3a2ab71e1 100644 (file)
@@ -229,6 +229,8 @@ struct acr_r352_lsf_wpr_header {
 struct ls_ucode_img_r352 {
        struct ls_ucode_img base;
 
+       const struct acr_r352_lsf_func *func;
+
        struct acr_r352_lsf_wpr_header wpr_header;
        struct acr_r352_lsf_lsb_header lsb_header;
 };
@@ -261,6 +263,8 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
                return ERR_PTR(ret);
        }
 
+       img->func = func->version[ret];
+
        /* 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",
@@ -302,8 +306,7 @@ acr_r352_ls_img_fill_headers(struct acr_r352 *acr,
        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];
+       const struct acr_r352_lsf_func *func = img->func;
 
        /* Fill WPR header */
        whdr->falcon_id = _img->falcon_id;
@@ -419,8 +422,8 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
 
        /* Figure out how large we need gdesc to be. */
        list_for_each_entry(_img, imgs, node) {
-               const struct acr_r352_ls_func *ls_func =
-                                           acr->func->ls_func[_img->falcon_id];
+               struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img);
+               const struct acr_r352_lsf_func *ls_func = img->func;
 
                max_desc_size = max(max_desc_size, ls_func->bl_desc_size);
        }
@@ -433,8 +436,7 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
 
        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];
+               const struct acr_r352_lsf_func *ls_func = img->func;
 
                nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header,
                                      sizeof(img->wpr_header));
@@ -1063,20 +1065,36 @@ acr_r352_dtor(struct nvkm_acr *_acr)
        kfree(acr);
 }
 
+static const struct acr_r352_lsf_func
+acr_r352_ls_fecs_func_0 = {
+       .generate_bl_desc = acr_r352_generate_flcn_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc),
+};
+
 const struct acr_r352_ls_func
 acr_r352_ls_fecs_func = {
        .load = acr_ls_ucode_load_fecs,
+       .version_max = 0,
+       .version = {
+               &acr_r352_ls_fecs_func_0,
+       }
+};
+
+static const struct acr_r352_lsf_func
+acr_r352_ls_gpccs_func_0 = {
        .generate_bl_desc = acr_r352_generate_flcn_bl_desc,
        .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc),
+       /* GPCCS will be loaded using PRI */
+       .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
 };
 
 const struct acr_r352_ls_func
 acr_r352_ls_gpccs_func = {
        .load = acr_ls_ucode_load_gpccs,
-       .generate_bl_desc = acr_r352_generate_flcn_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc),
-       /* GPCCS will be loaded using PRI */
-       .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
+       .version_max = 0,
+       .version = {
+               &acr_r352_ls_gpccs_func_0,
+       }
 };
 
 
@@ -1150,12 +1168,20 @@ acr_r352_generate_pmu_bl_desc(const struct nvkm_acr *acr,
        desc->argv = addr_args;
 }
 
+static const struct acr_r352_lsf_func
+acr_r352_ls_pmu_func_0 = {
+       .generate_bl_desc = acr_r352_generate_pmu_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r352_pmu_bl_desc),
+};
+
 static const struct acr_r352_ls_func
 acr_r352_ls_pmu_func = {
        .load = acr_ls_ucode_load_pmu,
-       .generate_bl_desc = acr_r352_generate_pmu_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r352_pmu_bl_desc),
        .post_run = acr_ls_pmu_post_run,
+       .version_max = 0,
+       .version = {
+               &acr_r352_ls_pmu_func_0,
+       }
 };
 
 const struct acr_r352_func
index f29c2268c026a83d3c19d1c18bd70707fc4ed3d1..e516cab849dd1915926d2117839d31c3ac9b7d57 100644 (file)
@@ -47,24 +47,32 @@ hsf_load_header_app_size(const struct hsf_load_header *hdr, u32 app)
 }
 
 /**
- * struct acr_r352_ls_func - manages a single LS firmware
+ * struct acr_r352_lsf_func - manages a specific LS firmware version
  *
- * @load: load the external firmware into a ls_ucode_img
  * @generate_bl_desc: function called on a block of bl_desc_size to generate the
  *                   proper bootloader descriptor for this LS firmware
  * @bl_desc_size: size of the bootloader descriptor
- * @post_run: hook called right after the ACR is executed
  * @lhdr_flags: LS flags
  */
-struct acr_r352_ls_func {
-       int (*load)(const struct nvkm_secboot *, int maxver,
-                   struct ls_ucode_img *);
+struct acr_r352_lsf_func {
        void (*generate_bl_desc)(const struct nvkm_acr *,
                                 const struct ls_ucode_img *, u64, void *);
        u32 bl_desc_size;
-       int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *);
        u32 lhdr_flags;
+};
+
+/**
+ * struct acr_r352_ls_func - manages a single LS falcon
+ *
+ * @load: load the external firmware into a ls_ucode_img
+ * @post_run: hook called right after the ACR is executed
+ */
+struct acr_r352_ls_func {
+       int (*load)(const struct nvkm_secboot *, int maxver,
+                   struct ls_ucode_img *);
+       int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *);
        int version_max;
+       const struct acr_r352_lsf_func *version[];
 };
 
 struct acr_r352;
index 14b36ef93628ea60a172f1079e3ec140ae81f72a..71f85b16ef34c30a4d59eb41d33758dd45a247dd 100644 (file)
@@ -66,20 +66,36 @@ acr_r361_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc,
        bl_desc->data_size = hdr->data_size;
 }
 
+static const struct acr_r352_lsf_func
+acr_r361_ls_fecs_func_0 = {
+       .generate_bl_desc = acr_r361_generate_flcn_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc),
+};
+
 const struct acr_r352_ls_func
 acr_r361_ls_fecs_func = {
        .load = acr_ls_ucode_load_fecs,
+       .version_max = 0,
+       .version = {
+               &acr_r361_ls_fecs_func_0,
+       }
+};
+
+static const struct acr_r352_lsf_func
+acr_r361_ls_gpccs_func_0 = {
        .generate_bl_desc = acr_r361_generate_flcn_bl_desc,
        .bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc),
+       /* GPCCS will be loaded using PRI */
+       .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
 };
 
 const struct acr_r352_ls_func
 acr_r361_ls_gpccs_func = {
        .load = acr_ls_ucode_load_gpccs,
-       .generate_bl_desc = acr_r361_generate_flcn_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc),
-       /* GPCCS will be loaded using PRI */
-       .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
+       .version_max = 0,
+       .version = {
+               &acr_r361_ls_gpccs_func_0,
+       }
 };
 
 struct acr_r361_pmu_bl_desc {
@@ -125,12 +141,20 @@ acr_r361_generate_pmu_bl_desc(const struct nvkm_acr *acr,
        desc->argv = addr_args;
 }
 
+static const struct acr_r352_lsf_func
+acr_r361_ls_pmu_func_0 = {
+       .generate_bl_desc = acr_r361_generate_pmu_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc),
+};
+
 const struct acr_r352_ls_func
 acr_r361_ls_pmu_func = {
        .load = acr_ls_ucode_load_pmu,
-       .generate_bl_desc = acr_r361_generate_pmu_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc),
        .post_run = acr_ls_pmu_post_run,
+       .version_max = 0,
+       .version = {
+               &acr_r361_ls_pmu_func_0,
+       }
 };
 
 static void
@@ -164,12 +188,20 @@ acr_r361_generate_sec2_bl_desc(const struct nvkm_acr *acr,
        desc->argv = 0x01000000;
 }
 
+static const struct acr_r352_lsf_func
+acr_r361_ls_sec2_func_0 = {
+       .generate_bl_desc = acr_r361_generate_sec2_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc),
+};
+
 const struct acr_r352_ls_func
 acr_r361_ls_sec2_func = {
        .load = acr_ls_ucode_load_sec2,
-       .generate_bl_desc = acr_r361_generate_sec2_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc),
        .post_run = acr_ls_sec2_post_run,
+       .version_max = 0,
+       .version = {
+               &acr_r361_ls_sec2_func_0,
+       }
 };
 
 
index 7c2424d730838be95ad0bac47f57c3b8fe8b6b3f..fe20a0977ba6514dc61fc783f8b611e477ba7fd3 100644 (file)
@@ -100,6 +100,8 @@ struct acr_r367_lsf_wpr_header {
 struct ls_ucode_img_r367 {
        struct ls_ucode_img base;
 
+       const struct acr_r352_lsf_func *func;
+
        struct acr_r367_lsf_wpr_header wpr_header;
        struct acr_r367_lsf_lsb_header lsb_header;
 };
@@ -129,6 +131,8 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
                return ERR_PTR(ret);
        }
 
+       img->func = func->version[ret];
+
        /* 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",
@@ -159,8 +163,7 @@ acr_r367_ls_img_fill_headers(struct acr_r352 *acr,
        struct acr_r367_lsf_wpr_header *whdr = &img->wpr_header;
        struct acr_r367_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];
+       const struct acr_r352_lsf_func *func = img->func;
 
        /* Fill WPR header */
        whdr->falcon_id = _img->falcon_id;
@@ -270,8 +273,8 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
        u8 *gdesc;
 
        list_for_each_entry(_img, imgs, node) {
-               const struct acr_r352_ls_func *ls_func =
-                                           acr->func->ls_func[_img->falcon_id];
+               struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img);
+               const struct acr_r352_lsf_func *ls_func = img->func;
 
                max_desc_size = max(max_desc_size, ls_func->bl_desc_size);
        }
@@ -284,8 +287,7 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
 
        list_for_each_entry(_img, imgs, node) {
                struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img);
-               const struct acr_r352_ls_func *ls_func =
-                                           acr->func->ls_func[_img->falcon_id];
+               const struct acr_r352_lsf_func *ls_func = img->func;
 
                nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header,
                                      sizeof(img->wpr_header));
index 2f890dfae7fc16cd7ad037013b42e48e2f3014dc..ff52d40823a950eb32f77013bbf2db7bbddc84d4 100644 (file)
@@ -49,20 +49,36 @@ acr_r370_generate_flcn_bl_desc(const struct nvkm_acr *acr,
        desc->data_size = pdesc->app_resident_data_size;
 }
 
+static const struct acr_r352_lsf_func
+acr_r370_ls_fecs_func_0 = {
+       .generate_bl_desc = acr_r370_generate_flcn_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+};
+
 const struct acr_r352_ls_func
 acr_r370_ls_fecs_func = {
        .load = acr_ls_ucode_load_fecs,
+       .version_max = 0,
+       .version = {
+               &acr_r370_ls_fecs_func_0,
+       }
+};
+
+static const struct acr_r352_lsf_func
+acr_r370_ls_gpccs_func_0 = {
        .generate_bl_desc = acr_r370_generate_flcn_bl_desc,
        .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+       /* GPCCS will be loaded using PRI */
+       .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
 };
 
 const struct acr_r352_ls_func
 acr_r370_ls_gpccs_func = {
        .load = acr_ls_ucode_load_gpccs,
-       .generate_bl_desc = acr_r370_generate_flcn_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
-       /* GPCCS will be loaded using PRI */
-       .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
+       .version_max = 0,
+       .version = {
+               &acr_r370_ls_gpccs_func_0,
+       }
 };
 
 static void
@@ -95,12 +111,20 @@ acr_r370_generate_sec2_bl_desc(const struct nvkm_acr *acr,
        desc->argv = 0x01000000;
 }
 
+static const struct acr_r352_lsf_func
+acr_r370_ls_sec2_func_0 = {
+       .generate_bl_desc = acr_r370_generate_sec2_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+};
+
 const struct acr_r352_ls_func
 acr_r370_ls_sec2_func = {
        .load = acr_ls_ucode_load_sec2,
-       .generate_bl_desc = acr_r370_generate_sec2_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
        .post_run = acr_ls_sec2_post_run,
+       .version_max = 0,
+       .version = {
+               &acr_r370_ls_sec2_func_0,
+       }
 };
 
 void
index 7bdef93cb7aeacef382476d78b1d46812a275838..8f0647766038604635d90def01909cc5be75e378 100644 (file)
@@ -54,12 +54,20 @@ acr_r375_generate_pmu_bl_desc(const struct nvkm_acr *acr,
        desc->argv = addr_args;
 }
 
+static const struct acr_r352_lsf_func
+acr_r375_ls_pmu_func_0 = {
+       .generate_bl_desc = acr_r375_generate_pmu_bl_desc,
+       .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+};
+
 const struct acr_r352_ls_func
 acr_r375_ls_pmu_func = {
        .load = acr_ls_ucode_load_pmu,
-       .generate_bl_desc = acr_r375_generate_pmu_bl_desc,
-       .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
        .post_run = acr_ls_pmu_post_run,
+       .version_max = 0,
+       .version = {
+               &acr_r375_ls_pmu_func_0,
+       }
 };
 
 const struct acr_r352_func