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 @@
#ifndef __NVKM_CORE_MSGQUEUE_H
#define __NVKM_CORE_MSGQUEUE_H
#include <core/os.h>
struct nvkm_falcon;
#include <subdev/secboot.h>
struct nvkm_msgqueue;
enum nvkm_secboot_falcon;
/* Hopefully we will never have firmware arguments larger than that... */
#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_recv(struct nvkm_msgqueue *);
int nvkm_msgqueue_reinit(struct nvkm_msgqueue *);
......
......@@ -491,17 +491,18 @@ nvkm_msgqueue_acr_boot_falcons(struct nvkm_msgqueue *queue,
}
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;
int ret = -EINVAL;
switch (version) {
case 0x0137c63d:
ret = msgqueue_0137c63d_new(falcon, queue);
ret = msgqueue_0137c63d_new(falcon, sb, queue);
break;
case 0x0148cdec:
ret = msgqueue_0148cdec_new(falcon, queue);
ret = msgqueue_0148cdec_new(falcon, sb, queue);
break;
default:
nvkm_error(subdev, "unhandled firmware version 0x%08x\n",
......
......@@ -203,7 +203,9 @@ int nvkm_msgqueue_post(struct nvkm_msgqueue *, enum msgqueue_msg_priority,
void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *,
struct nvkm_msgqueue_queue *);
int msgqueue_0137c63d_new(struct nvkm_falcon *, struct nvkm_msgqueue **);
int msgqueue_0148cdec_new(struct nvkm_falcon *, struct nvkm_msgqueue **);
int msgqueue_0137c63d_new(struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
int msgqueue_0148cdec_new(struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
#endif
......@@ -307,7 +307,8 @@ msgqueue_0137c63d_func = {
};
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;
......
......@@ -247,7 +247,8 @@ msgqueue_0148cdec_func = {
};
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;
......
......@@ -241,6 +241,7 @@ struct ls_ucode_img_r352 {
*/
struct ls_ucode_img *
acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
const struct nvkm_secboot *sb,
enum nvkm_secboot_falcon falcon_id)
{
const struct nvkm_subdev *subdev = acr->base.subdev;
......@@ -253,7 +254,7 @@ acr_r352_ls_ucode_img_load(const struct acr_r352 *acr,
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) {
kfree(img->base.ucode_data);
......@@ -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.
*/
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;
struct list_head imgs;
struct ls_ucode_img *img, *t;
unsigned long managed_falcons = acr->base.managed_falcons;
u64 wpr_addr = sb->wpr_addr;
u32 wpr_size = sb->wpr_size;
int managed_count = 0;
u32 image_wpr_size, ls_blob_size;
int falcon_id;
......@@ -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) {
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 (acr->base.optional_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)
return 0;
/* 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)
return ret;
......
......@@ -57,7 +57,7 @@ hsf_load_header_app_size(const struct hsf_load_header *hdr, u32 app)
* @lhdr_flags: LS flags
*/
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 *,
const struct ls_ucode_img *, u64, void *);
u32 bl_desc_size;
......@@ -82,6 +82,7 @@ struct acr_r352_func {
bool shadow_blob;
struct ls_ucode_img *(*ls_ucode_img_load)(const struct acr_r352 *,
const struct nvkm_secboot *,
enum nvkm_secboot_falcon);
int (*ls_fill_headers)(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 *,
enum nvkm_secboot_falcon, unsigned long);
struct ls_ucode_img *acr_r352_ls_ucode_img_load(const struct acr_r352 *,
const struct nvkm_secboot *,
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 *,
......
......@@ -107,6 +107,7 @@ struct ls_ucode_img_r367 {
struct ls_ucode_img *
acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
const struct nvkm_secboot *sb,
enum nvkm_secboot_falcon falcon_id)
{
const struct nvkm_subdev *subdev = acr->base.subdev;
......@@ -119,7 +120,7 @@ acr_r367_ls_ucode_img_load(const struct acr_r352 *acr,
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) {
kfree(img->base.ucode_data);
kfree(img->base.sig);
......
......@@ -28,6 +28,7 @@
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 *,
const struct nvkm_secboot *,
enum nvkm_secboot_falcon);
int acr_r367_ls_fill_headers(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 {
u32 data_size;
};
int acr_ls_ucode_load_fecs(const struct nvkm_subdev *, struct ls_ucode_img *);
int acr_ls_ucode_load_gpccs(const struct nvkm_subdev *, struct ls_ucode_img *);
int acr_ls_ucode_load_pmu(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_secboot *, 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 *);
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 *);
#endif
......@@ -144,15 +144,13 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img,
}
int
acr_ls_ucode_load_fecs(const struct nvkm_subdev *subdev,
struct ls_ucode_img *img)
acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, 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
acr_ls_ucode_load_gpccs(const struct nvkm_subdev *subdev,
struct ls_ucode_img *img)
acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, 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,
}
int
acr_ls_ucode_load_pmu(const struct nvkm_subdev *subdev,
struct ls_ucode_img *img)
acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
{
struct nvkm_pmu *pmu = subdev->device->pmu;
struct nvkm_pmu *pmu = sb->subdev.device->pmu;
int ret;
ret = acr_ls_ucode_load_msgqueue(subdev, "pmu", img);
ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", img);
if (ret)
return ret;
/* Allocate the PMU queue corresponding to the FW version */
ret = nvkm_msgqueue_new(img->ucode_desc.app_version, pmu->falcon,
&pmu->queue);
sb, &pmu->queue);
if (ret)
return ret;
......@@ -118,19 +117,18 @@ acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb)
}
int
acr_ls_ucode_load_sec2(const struct nvkm_subdev *subdev,
struct ls_ucode_img *img)
acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
{
struct nvkm_sec2 *sec = subdev->device->sec2;
struct nvkm_sec2 *sec = sb->subdev.device->sec2;
int ret;
ret = acr_ls_ucode_load_msgqueue(subdev, "sec2", img);
ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", img);
if (ret)
return ret;
/* Allocate the PMU queue corresponding to the FW version */
ret = nvkm_msgqueue_new(img->ucode_desc.app_version, sec->falcon,
&sec->queue);
sb, &sec->queue);
if (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