Commit 5f0f8b57 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/secboot: split out FW version-specific LS function pointers

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent c26f3061
...@@ -229,6 +229,8 @@ struct acr_r352_lsf_wpr_header { ...@@ -229,6 +229,8 @@ struct acr_r352_lsf_wpr_header {
struct ls_ucode_img_r352 { struct ls_ucode_img_r352 {
struct ls_ucode_img base; struct ls_ucode_img base;
const struct acr_r352_lsf_func *func;
struct acr_r352_lsf_wpr_header wpr_header; struct acr_r352_lsf_wpr_header wpr_header;
struct acr_r352_lsf_lsb_header lsb_header; struct acr_r352_lsf_lsb_header lsb_header;
}; };
...@@ -261,6 +263,8 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr, ...@@ -261,6 +263,8 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
return ERR_PTR(ret); return ERR_PTR(ret);
} }
img->func = func->version[ret];
/* Check that the signature size matches our expectations... */ /* Check that the signature size matches our expectations... */
if (img->base.sig_size != sizeof(img->lsb_header.signature)) { if (img->base.sig_size != sizeof(img->lsb_header.signature)) {
nvkm_error(subdev, "invalid signature size for %s falcon!\n", nvkm_error(subdev, "invalid signature size for %s falcon!\n",
...@@ -302,8 +306,7 @@ acr_r352_ls_img_fill_headers(struct acr_r352 *acr, ...@@ -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_wpr_header *whdr = &img->wpr_header;
struct acr_r352_lsf_lsb_header *lhdr = &img->lsb_header; struct acr_r352_lsf_lsb_header *lhdr = &img->lsb_header;
struct ls_ucode_img_desc *desc = &_img->ucode_desc; struct ls_ucode_img_desc *desc = &_img->ucode_desc;
const struct acr_r352_ls_func *func = const struct acr_r352_lsf_func *func = img->func;
acr->func->ls_func[_img->falcon_id];
/* Fill WPR header */ /* Fill WPR header */
whdr->falcon_id = _img->falcon_id; whdr->falcon_id = _img->falcon_id;
...@@ -419,8 +422,8 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, ...@@ -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. */ /* Figure out how large we need gdesc to be. */
list_for_each_entry(_img, imgs, node) { list_for_each_entry(_img, imgs, node) {
const struct acr_r352_ls_func *ls_func = struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img);
acr->func->ls_func[_img->falcon_id]; const struct acr_r352_lsf_func *ls_func = img->func;
max_desc_size = max(max_desc_size, ls_func->bl_desc_size); 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, ...@@ -433,8 +436,7 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
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); struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img);
const struct acr_r352_ls_func *ls_func = const struct acr_r352_lsf_func *ls_func = img->func;
acr->func->ls_func[_img->falcon_id];
nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header,
sizeof(img->wpr_header)); sizeof(img->wpr_header));
...@@ -1063,20 +1065,36 @@ acr_r352_dtor(struct nvkm_acr *_acr) ...@@ -1063,20 +1065,36 @@ acr_r352_dtor(struct nvkm_acr *_acr)
kfree(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 const struct acr_r352_ls_func
acr_r352_ls_fecs_func = { acr_r352_ls_fecs_func = {
.load = acr_ls_ucode_load_fecs, .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, .generate_bl_desc = acr_r352_generate_flcn_bl_desc,
.bl_desc_size = sizeof(struct acr_r352_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 const struct acr_r352_ls_func
acr_r352_ls_gpccs_func = { acr_r352_ls_gpccs_func = {
.load = acr_ls_ucode_load_gpccs, .load = acr_ls_ucode_load_gpccs,
.generate_bl_desc = acr_r352_generate_flcn_bl_desc, .version_max = 0,
.bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc), .version = {
/* GPCCS will be loaded using PRI */ &acr_r352_ls_gpccs_func_0,
.lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, }
}; };
...@@ -1150,12 +1168,20 @@ acr_r352_generate_pmu_bl_desc(const struct nvkm_acr *acr, ...@@ -1150,12 +1168,20 @@ acr_r352_generate_pmu_bl_desc(const struct nvkm_acr *acr,
desc->argv = addr_args; 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 static const struct acr_r352_ls_func
acr_r352_ls_pmu_func = { acr_r352_ls_pmu_func = {
.load = acr_ls_ucode_load_pmu, .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, .post_run = acr_ls_pmu_post_run,
.version_max = 0,
.version = {
&acr_r352_ls_pmu_func_0,
}
}; };
const struct acr_r352_func const struct acr_r352_func
......
...@@ -47,24 +47,32 @@ hsf_load_header_app_size(const struct hsf_load_header *hdr, u32 app) ...@@ -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 * @generate_bl_desc: function called on a block of bl_desc_size to generate the
* proper bootloader descriptor for this LS firmware * proper bootloader descriptor for this LS firmware
* @bl_desc_size: size of the bootloader descriptor * @bl_desc_size: size of the bootloader descriptor
* @post_run: hook called right after the ACR is executed
* @lhdr_flags: LS flags * @lhdr_flags: LS flags
*/ */
struct acr_r352_ls_func { struct acr_r352_lsf_func {
int (*load)(const struct nvkm_secboot *, int maxver,
struct ls_ucode_img *);
void (*generate_bl_desc)(const struct nvkm_acr *, void (*generate_bl_desc)(const struct nvkm_acr *,
const struct ls_ucode_img *, u64, void *); const struct ls_ucode_img *, u64, void *);
u32 bl_desc_size; u32 bl_desc_size;
int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *);
u32 lhdr_flags; 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; int version_max;
const struct acr_r352_lsf_func *version[];
}; };
struct acr_r352; struct acr_r352;
......
...@@ -66,20 +66,36 @@ acr_r361_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc, ...@@ -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; 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 const struct acr_r352_ls_func
acr_r361_ls_fecs_func = { acr_r361_ls_fecs_func = {
.load = acr_ls_ucode_load_fecs, .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, .generate_bl_desc = acr_r361_generate_flcn_bl_desc,
.bl_desc_size = sizeof(struct acr_r361_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 const struct acr_r352_ls_func
acr_r361_ls_gpccs_func = { acr_r361_ls_gpccs_func = {
.load = acr_ls_ucode_load_gpccs, .load = acr_ls_ucode_load_gpccs,
.generate_bl_desc = acr_r361_generate_flcn_bl_desc, .version_max = 0,
.bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc), .version = {
/* GPCCS will be loaded using PRI */ &acr_r361_ls_gpccs_func_0,
.lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, }
}; };
struct acr_r361_pmu_bl_desc { struct acr_r361_pmu_bl_desc {
...@@ -125,12 +141,20 @@ acr_r361_generate_pmu_bl_desc(const struct nvkm_acr *acr, ...@@ -125,12 +141,20 @@ acr_r361_generate_pmu_bl_desc(const struct nvkm_acr *acr,
desc->argv = addr_args; 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 const struct acr_r352_ls_func
acr_r361_ls_pmu_func = { acr_r361_ls_pmu_func = {
.load = acr_ls_ucode_load_pmu, .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, .post_run = acr_ls_pmu_post_run,
.version_max = 0,
.version = {
&acr_r361_ls_pmu_func_0,
}
}; };
static void static void
...@@ -164,12 +188,20 @@ acr_r361_generate_sec2_bl_desc(const struct nvkm_acr *acr, ...@@ -164,12 +188,20 @@ acr_r361_generate_sec2_bl_desc(const struct nvkm_acr *acr,
desc->argv = 0x01000000; 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 const struct acr_r352_ls_func
acr_r361_ls_sec2_func = { acr_r361_ls_sec2_func = {
.load = acr_ls_ucode_load_sec2, .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, .post_run = acr_ls_sec2_post_run,
.version_max = 0,
.version = {
&acr_r361_ls_sec2_func_0,
}
}; };
......
...@@ -100,6 +100,8 @@ struct acr_r367_lsf_wpr_header { ...@@ -100,6 +100,8 @@ struct acr_r367_lsf_wpr_header {
struct ls_ucode_img_r367 { struct ls_ucode_img_r367 {
struct ls_ucode_img base; struct ls_ucode_img base;
const struct acr_r352_lsf_func *func;
struct acr_r367_lsf_wpr_header wpr_header; struct acr_r367_lsf_wpr_header wpr_header;
struct acr_r367_lsf_lsb_header lsb_header; struct acr_r367_lsf_lsb_header lsb_header;
}; };
...@@ -129,6 +131,8 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr, ...@@ -129,6 +131,8 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
return ERR_PTR(ret); return ERR_PTR(ret);
} }
img->func = func->version[ret];
/* Check that the signature size matches our expectations... */ /* Check that the signature size matches our expectations... */
if (img->base.sig_size != sizeof(img->lsb_header.signature)) { if (img->base.sig_size != sizeof(img->lsb_header.signature)) {
nvkm_error(subdev, "invalid signature size for %s falcon!\n", nvkm_error(subdev, "invalid signature size for %s falcon!\n",
...@@ -159,8 +163,7 @@ acr_r367_ls_img_fill_headers(struct acr_r352 *acr, ...@@ -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_wpr_header *whdr = &img->wpr_header;
struct acr_r367_lsf_lsb_header *lhdr = &img->lsb_header; struct acr_r367_lsf_lsb_header *lhdr = &img->lsb_header;
struct ls_ucode_img_desc *desc = &_img->ucode_desc; struct ls_ucode_img_desc *desc = &_img->ucode_desc;
const struct acr_r352_ls_func *func = const struct acr_r352_lsf_func *func = img->func;
acr->func->ls_func[_img->falcon_id];
/* Fill WPR header */ /* Fill WPR header */
whdr->falcon_id = _img->falcon_id; whdr->falcon_id = _img->falcon_id;
...@@ -270,8 +273,8 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, ...@@ -270,8 +273,8 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
u8 *gdesc; u8 *gdesc;
list_for_each_entry(_img, imgs, node) { list_for_each_entry(_img, imgs, node) {
const struct acr_r352_ls_func *ls_func = struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img);
acr->func->ls_func[_img->falcon_id]; const struct acr_r352_lsf_func *ls_func = img->func;
max_desc_size = max(max_desc_size, ls_func->bl_desc_size); 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, ...@@ -284,8 +287,7 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
list_for_each_entry(_img, imgs, node) { list_for_each_entry(_img, imgs, node) {
struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img); struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img);
const struct acr_r352_ls_func *ls_func = const struct acr_r352_lsf_func *ls_func = img->func;
acr->func->ls_func[_img->falcon_id];
nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header,
sizeof(img->wpr_header)); sizeof(img->wpr_header));
......
...@@ -49,20 +49,36 @@ acr_r370_generate_flcn_bl_desc(const struct nvkm_acr *acr, ...@@ -49,20 +49,36 @@ acr_r370_generate_flcn_bl_desc(const struct nvkm_acr *acr,
desc->data_size = pdesc->app_resident_data_size; 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 const struct acr_r352_ls_func
acr_r370_ls_fecs_func = { acr_r370_ls_fecs_func = {
.load = acr_ls_ucode_load_fecs, .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, .generate_bl_desc = acr_r370_generate_flcn_bl_desc,
.bl_desc_size = sizeof(struct acr_r370_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 const struct acr_r352_ls_func
acr_r370_ls_gpccs_func = { acr_r370_ls_gpccs_func = {
.load = acr_ls_ucode_load_gpccs, .load = acr_ls_ucode_load_gpccs,
.generate_bl_desc = acr_r370_generate_flcn_bl_desc, .version_max = 0,
.bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), .version = {
/* GPCCS will be loaded using PRI */ &acr_r370_ls_gpccs_func_0,
.lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, }
}; };
static void static void
...@@ -95,12 +111,20 @@ acr_r370_generate_sec2_bl_desc(const struct nvkm_acr *acr, ...@@ -95,12 +111,20 @@ acr_r370_generate_sec2_bl_desc(const struct nvkm_acr *acr,
desc->argv = 0x01000000; 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 const struct acr_r352_ls_func
acr_r370_ls_sec2_func = { acr_r370_ls_sec2_func = {
.load = acr_ls_ucode_load_sec2, .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, .post_run = acr_ls_sec2_post_run,
.version_max = 0,
.version = {
&acr_r370_ls_sec2_func_0,
}
}; };
void void
......
...@@ -54,12 +54,20 @@ acr_r375_generate_pmu_bl_desc(const struct nvkm_acr *acr, ...@@ -54,12 +54,20 @@ acr_r375_generate_pmu_bl_desc(const struct nvkm_acr *acr,
desc->argv = addr_args; 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 const struct acr_r352_ls_func
acr_r375_ls_pmu_func = { acr_r375_ls_pmu_func = {
.load = acr_ls_ucode_load_pmu, .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, .post_run = acr_ls_pmu_post_run,
.version_max = 0,
.version = {
&acr_r375_ls_pmu_func_0,
}
}; };
const struct acr_r352_func const struct acr_r352_func
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment