Commit 2963a06a authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ben Skeggs

drm/nouveau/secboot: pass instance to LS firmware loaders

Having access to the secboot instance loading a LS firmware can be
useful to LS firmware handlers. At least more useful than just having an
out-of-context subdev pointer.

GP10B's firmware will also need to know the WPR address, which can be
obtained from the secboot instance.
Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 598a8148
...@@ -22,17 +22,14 @@ ...@@ -22,17 +22,14 @@
#ifndef __NVKM_CORE_MSGQUEUE_H #ifndef __NVKM_CORE_MSGQUEUE_H
#define __NVKM_CORE_MSGQUEUE_H #define __NVKM_CORE_MSGQUEUE_H
#include <subdev/secboot.h>
#include <core/os.h>
struct nvkm_falcon;
struct nvkm_msgqueue; struct nvkm_msgqueue;
enum nvkm_secboot_falcon;
/* Hopefully we will never have firmware arguments larger than that... */ /* Hopefully we will never have firmware arguments larger than that... */
#define NVKM_MSGQUEUE_CMDLINE_SIZE 0x100 #define NVKM_MSGQUEUE_CMDLINE_SIZE 0x100
int nvkm_msgqueue_new(u32, struct nvkm_falcon *, struct nvkm_msgqueue **); int nvkm_msgqueue_new(u32, struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
void nvkm_msgqueue_del(struct nvkm_msgqueue **); void nvkm_msgqueue_del(struct nvkm_msgqueue **);
void nvkm_msgqueue_recv(struct nvkm_msgqueue *); void nvkm_msgqueue_recv(struct nvkm_msgqueue *);
int nvkm_msgqueue_reinit(struct nvkm_msgqueue *); int nvkm_msgqueue_reinit(struct nvkm_msgqueue *);
......
...@@ -491,17 +491,18 @@ nvkm_msgqueue_acr_boot_falcons(struct nvkm_msgqueue *queue, ...@@ -491,17 +491,18 @@ nvkm_msgqueue_acr_boot_falcons(struct nvkm_msgqueue *queue,
} }
int int
nvkm_msgqueue_new(u32 version, struct nvkm_falcon *falcon, struct nvkm_msgqueue **queue) nvkm_msgqueue_new(u32 version, struct nvkm_falcon *falcon,
const struct nvkm_secboot *sb, struct nvkm_msgqueue **queue)
{ {
const struct nvkm_subdev *subdev = falcon->owner; const struct nvkm_subdev *subdev = falcon->owner;
int ret = -EINVAL; int ret = -EINVAL;
switch (version) { switch (version) {
case 0x0137c63d: case 0x0137c63d:
ret = msgqueue_0137c63d_new(falcon, queue); ret = msgqueue_0137c63d_new(falcon, sb, queue);
break; break;
case 0x0148cdec: case 0x0148cdec:
ret = msgqueue_0148cdec_new(falcon, queue); ret = msgqueue_0148cdec_new(falcon, sb, queue);
break; break;
default: default:
nvkm_error(subdev, "unhandled firmware version 0x%08x\n", nvkm_error(subdev, "unhandled firmware version 0x%08x\n",
......
...@@ -203,7 +203,9 @@ int nvkm_msgqueue_post(struct nvkm_msgqueue *, enum msgqueue_msg_priority, ...@@ -203,7 +203,9 @@ int nvkm_msgqueue_post(struct nvkm_msgqueue *, enum msgqueue_msg_priority,
void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *, void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *,
struct nvkm_msgqueue_queue *); struct nvkm_msgqueue_queue *);
int msgqueue_0137c63d_new(struct nvkm_falcon *, struct nvkm_msgqueue **); int msgqueue_0137c63d_new(struct nvkm_falcon *, const struct nvkm_secboot *,
int msgqueue_0148cdec_new(struct nvkm_falcon *, struct nvkm_msgqueue **); struct nvkm_msgqueue **);
int msgqueue_0148cdec_new(struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
#endif #endif
...@@ -307,7 +307,8 @@ msgqueue_0137c63d_func = { ...@@ -307,7 +307,8 @@ msgqueue_0137c63d_func = {
}; };
int int
msgqueue_0137c63d_new(struct nvkm_falcon *falcon, struct nvkm_msgqueue **queue) msgqueue_0137c63d_new(struct nvkm_falcon *falcon, const struct nvkm_secboot *sb,
struct nvkm_msgqueue **queue)
{ {
struct msgqueue_0137c63d *ret; struct msgqueue_0137c63d *ret;
......
...@@ -247,7 +247,8 @@ msgqueue_0148cdec_func = { ...@@ -247,7 +247,8 @@ msgqueue_0148cdec_func = {
}; };
int int
msgqueue_0148cdec_new(struct nvkm_falcon *falcon, struct nvkm_msgqueue **queue) msgqueue_0148cdec_new(struct nvkm_falcon *falcon, const struct nvkm_secboot *sb,
struct nvkm_msgqueue **queue)
{ {
struct msgqueue_0148cdec *ret; struct msgqueue_0148cdec *ret;
......
...@@ -241,6 +241,7 @@ struct ls_ucode_img_r352 { ...@@ -241,6 +241,7 @@ struct ls_ucode_img_r352 {
*/ */
struct ls_ucode_img * struct ls_ucode_img *
acr_r352_ls_ucode_img_load(const struct acr_r352 *acr, acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
const struct nvkm_secboot *sb,
enum nvkm_secboot_falcon falcon_id) enum nvkm_secboot_falcon falcon_id)
{ {
const struct nvkm_subdev *subdev = acr->base.subdev; const struct nvkm_subdev *subdev = acr->base.subdev;
...@@ -253,7 +254,7 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr, ...@@ -253,7 +254,7 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
img->base.falcon_id = falcon_id; img->base.falcon_id = falcon_id;
ret = acr->func->ls_func[falcon_id]->load(subdev, &img->base); ret = acr->func->ls_func[falcon_id]->load(sb, &img->base);
if (ret) { if (ret) {
kfree(img->base.ucode_data); kfree(img->base.ucode_data);
...@@ -462,12 +463,14 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, ...@@ -462,12 +463,14 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs,
* will be copied into the WPR region by the HS firmware. * will be copied into the WPR region by the HS firmware.
*/ */
static int static int
acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size) acr_r352_prepare_ls_blob(struct acr_r352 *acr, struct nvkm_secboot *sb)
{ {
const struct nvkm_subdev *subdev = acr->base.subdev; const struct nvkm_subdev *subdev = acr->base.subdev;
struct list_head imgs; struct list_head imgs;
struct ls_ucode_img *img, *t; struct ls_ucode_img *img, *t;
unsigned long managed_falcons = acr->base.managed_falcons; unsigned long managed_falcons = acr->base.managed_falcons;
u64 wpr_addr = sb->wpr_addr;
u32 wpr_size = sb->wpr_size;
int managed_count = 0; int managed_count = 0;
u32 image_wpr_size, ls_blob_size; u32 image_wpr_size, ls_blob_size;
int falcon_id; int falcon_id;
...@@ -479,7 +482,7 @@ acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size) ...@@ -479,7 +482,7 @@ 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) { for_each_set_bit(falcon_id, &managed_falcons, NVKM_SECBOOT_FALCON_END) {
struct ls_ucode_img *img; struct ls_ucode_img *img;
img = acr->func->ls_ucode_img_load(acr, falcon_id); img = acr->func->ls_ucode_img_load(acr, sb, falcon_id);
if (IS_ERR(img)) { if (IS_ERR(img)) {
if (acr->base.optional_falcons & BIT(falcon_id)) { if (acr->base.optional_falcons & BIT(falcon_id)) {
managed_falcons &= ~BIT(falcon_id); managed_falcons &= ~BIT(falcon_id);
...@@ -704,7 +707,7 @@ acr_r352_load_blobs(struct acr_r352 *acr, struct nvkm_secboot *sb) ...@@ -704,7 +707,7 @@ acr_r352_load_blobs(struct acr_r352 *acr, struct nvkm_secboot *sb)
return 0; return 0;
/* Load and prepare the managed falcon's firmwares */ /* Load and prepare the managed falcon's firmwares */
ret = acr_r352_prepare_ls_blob(acr, sb->wpr_addr, sb->wpr_size); ret = acr_r352_prepare_ls_blob(acr, sb);
if (ret) if (ret)
return ret; return ret;
......
...@@ -57,7 +57,7 @@ hsf_load_header_app_size(const struct hsf_load_header *hdr, u32 app) ...@@ -57,7 +57,7 @@ hsf_load_header_app_size(const struct hsf_load_header *hdr, u32 app)
* @lhdr_flags: LS flags * @lhdr_flags: LS flags
*/ */
struct acr_r352_ls_func { struct acr_r352_ls_func {
int (*load)(const struct nvkm_subdev *, struct ls_ucode_img *); int (*load)(const struct nvkm_secboot *, 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;
...@@ -82,6 +82,7 @@ struct acr_r352_func { ...@@ -82,6 +82,7 @@ struct acr_r352_func {
bool shadow_blob; bool shadow_blob;
struct ls_ucode_img *(*ls_ucode_img_load)(const struct acr_r352 *, struct ls_ucode_img *(*ls_ucode_img_load)(const struct acr_r352 *,
const struct nvkm_secboot *,
enum nvkm_secboot_falcon); enum nvkm_secboot_falcon);
int (*ls_fill_headers)(struct acr_r352 *, struct list_head *); int (*ls_fill_headers)(struct acr_r352 *, struct list_head *);
int (*ls_write_wpr)(struct acr_r352 *, struct list_head *, int (*ls_write_wpr)(struct acr_r352 *, struct list_head *,
...@@ -145,6 +146,7 @@ struct nvkm_acr *acr_r352_new_(const struct acr_r352_func *, ...@@ -145,6 +146,7 @@ struct nvkm_acr *acr_r352_new_(const struct acr_r352_func *,
enum nvkm_secboot_falcon, unsigned long); enum nvkm_secboot_falcon, unsigned long);
struct ls_ucode_img *acr_r352_ls_ucode_img_load(const struct acr_r352 *, struct ls_ucode_img *acr_r352_ls_ucode_img_load(const struct acr_r352 *,
const struct nvkm_secboot *,
enum nvkm_secboot_falcon); enum nvkm_secboot_falcon);
int acr_r352_ls_fill_headers(struct acr_r352 *, struct list_head *); int acr_r352_ls_fill_headers(struct acr_r352 *, struct list_head *);
int acr_r352_ls_write_wpr(struct acr_r352 *, struct list_head *, int acr_r352_ls_write_wpr(struct acr_r352 *, struct list_head *,
......
...@@ -107,6 +107,7 @@ struct ls_ucode_img_r367 { ...@@ -107,6 +107,7 @@ struct ls_ucode_img_r367 {
struct ls_ucode_img * struct ls_ucode_img *
acr_r367_ls_ucode_img_load(const struct acr_r352 *acr, acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
const struct nvkm_secboot *sb,
enum nvkm_secboot_falcon falcon_id) enum nvkm_secboot_falcon falcon_id)
{ {
const struct nvkm_subdev *subdev = acr->base.subdev; const struct nvkm_subdev *subdev = acr->base.subdev;
...@@ -119,7 +120,7 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr, ...@@ -119,7 +120,7 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
img->base.falcon_id = falcon_id; img->base.falcon_id = falcon_id;
ret = acr->func->ls_func[falcon_id]->load(subdev, &img->base); ret = acr->func->ls_func[falcon_id]->load(sb, &img->base);
if (ret) { if (ret) {
kfree(img->base.ucode_data); kfree(img->base.ucode_data);
kfree(img->base.sig); kfree(img->base.sig);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
void acr_r367_fixup_hs_desc(struct acr_r352 *, struct nvkm_secboot *, void *); void acr_r367_fixup_hs_desc(struct acr_r352 *, struct nvkm_secboot *, void *);
struct ls_ucode_img *acr_r367_ls_ucode_img_load(const struct acr_r352 *, struct ls_ucode_img *acr_r367_ls_ucode_img_load(const struct acr_r352 *,
const struct nvkm_secboot *,
enum nvkm_secboot_falcon); enum nvkm_secboot_falcon);
int acr_r367_ls_fill_headers(struct acr_r352 *, struct list_head *); int acr_r367_ls_fill_headers(struct acr_r352 *, struct list_head *);
int acr_r367_ls_write_wpr(struct acr_r352 *, struct list_head *, int acr_r367_ls_write_wpr(struct acr_r352 *, struct list_head *,
......
...@@ -147,11 +147,11 @@ struct fw_bl_desc { ...@@ -147,11 +147,11 @@ struct fw_bl_desc {
u32 data_size; u32 data_size;
}; };
int acr_ls_ucode_load_fecs(const struct nvkm_subdev *, struct ls_ucode_img *); int acr_ls_ucode_load_fecs(const struct nvkm_secboot *, struct ls_ucode_img *);
int acr_ls_ucode_load_gpccs(const struct nvkm_subdev *, struct ls_ucode_img *); int acr_ls_ucode_load_gpccs(const struct nvkm_secboot *, struct ls_ucode_img *);
int acr_ls_ucode_load_pmu(const struct nvkm_subdev *, struct ls_ucode_img *); int acr_ls_ucode_load_pmu(const struct nvkm_secboot *, struct ls_ucode_img *);
void acr_ls_pmu_post_run(const struct nvkm_acr *, const struct nvkm_secboot *); void acr_ls_pmu_post_run(const struct nvkm_acr *, const struct nvkm_secboot *);
int acr_ls_ucode_load_sec2(const struct nvkm_subdev *, struct ls_ucode_img *); int acr_ls_ucode_load_sec2(const struct nvkm_secboot *, struct ls_ucode_img *);
void acr_ls_sec2_post_run(const struct nvkm_acr *, const struct nvkm_secboot *); void acr_ls_sec2_post_run(const struct nvkm_acr *, const struct nvkm_secboot *);
#endif #endif
...@@ -144,15 +144,13 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img, ...@@ -144,15 +144,13 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img,
} }
int int
acr_ls_ucode_load_fecs(const struct nvkm_subdev *subdev, acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
struct ls_ucode_img *img)
{ {
return ls_ucode_img_load_gr(subdev, img, "fecs"); return ls_ucode_img_load_gr(&sb->subdev, img, "fecs");
} }
int int
acr_ls_ucode_load_gpccs(const struct nvkm_subdev *subdev, acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
struct ls_ucode_img *img)
{ {
return ls_ucode_img_load_gr(subdev, img, "gpccs"); return ls_ucode_img_load_gr(&sb->subdev, img, "gpccs");
} }
...@@ -88,19 +88,18 @@ acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue, ...@@ -88,19 +88,18 @@ acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue,
} }
int int
acr_ls_ucode_load_pmu(const struct nvkm_subdev *subdev, acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
struct ls_ucode_img *img)
{ {
struct nvkm_pmu *pmu = subdev->device->pmu; struct nvkm_pmu *pmu = sb->subdev.device->pmu;
int ret; int ret;
ret = acr_ls_ucode_load_msgqueue(subdev, "pmu", img); ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", img);
if (ret) if (ret)
return ret; return ret;
/* Allocate the PMU queue corresponding to the FW version */ /* Allocate the PMU queue corresponding to the FW version */
ret = nvkm_msgqueue_new(img->ucode_desc.app_version, pmu->falcon, ret = nvkm_msgqueue_new(img->ucode_desc.app_version, pmu->falcon,
&pmu->queue); sb, &pmu->queue);
if (ret) if (ret)
return ret; return ret;
...@@ -118,19 +117,18 @@ acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb) ...@@ -118,19 +117,18 @@ acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb)
} }
int int
acr_ls_ucode_load_sec2(const struct nvkm_subdev *subdev, acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
struct ls_ucode_img *img)
{ {
struct nvkm_sec2 *sec = subdev->device->sec2; struct nvkm_sec2 *sec = sb->subdev.device->sec2;
int ret; int ret;
ret = acr_ls_ucode_load_msgqueue(subdev, "sec2", img); ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", img);
if (ret) if (ret)
return ret; return ret;
/* Allocate the PMU queue corresponding to the FW version */ /* Allocate the PMU queue corresponding to the FW version */
ret = nvkm_msgqueue_new(img->ucode_desc.app_version, sec->falcon, ret = nvkm_msgqueue_new(img->ucode_desc.app_version, sec->falcon,
&sec->queue); sb, &sec->queue);
if (ret) if (ret)
return ret; return ret;
......
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