mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: pkc signature verification support
This change adds lsf_ucode_desc_wrapper to hold the pkc signature header and corresponding lsf_lsb_header_v2. During blob preparation based on the flag is_sig_pkc, the new header defines will be packed into ls blob and passed to acr. The flag NVGPU_PKC_LS_SIG_ENABLED is also added, which will be set based on the acr core selection. JIRA NVGPU-6365 Change-Id: I74e25d7c0f69d4007893e46006f97f2a607fd11f Signed-off-by: smadhavan <smadhavan@nvidia.com> Signed-off-by: deepak goyal <dgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2506136 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
f80dccb543
commit
d9add2db52
@@ -104,7 +104,8 @@ exit:
|
|||||||
#if defined(CONFIG_NVGPU_NON_FUSA)
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
s32 nvgpu_acr_lsf_pmu_ncore_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
s32 nvgpu_acr_lsf_pmu_ncore_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
||||||
{
|
{
|
||||||
struct lsf_ucode_desc *lsf_desc;
|
struct lsf_ucode_desc *lsf_desc = NULL;
|
||||||
|
struct lsf_ucode_desc_wrapper *lsf_desc_wrapper = NULL;
|
||||||
struct nvgpu_firmware *fw_sig;
|
struct nvgpu_firmware *fw_sig;
|
||||||
struct nvgpu_firmware *fw_desc;
|
struct nvgpu_firmware *fw_desc;
|
||||||
struct nvgpu_firmware *fw_image;
|
struct nvgpu_firmware *fw_image;
|
||||||
@@ -112,26 +113,45 @@ s32 nvgpu_acr_lsf_pmu_ncore_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
(struct flcn_ucode_img *)lsf_ucode_img;
|
(struct flcn_ucode_img *)lsf_ucode_img;
|
||||||
s32 err = 0;
|
s32 err = 0;
|
||||||
|
|
||||||
lsf_desc = nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc));
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
if (lsf_desc == NULL) {
|
lsf_desc = nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc));
|
||||||
err = -ENOMEM;
|
if (lsf_desc == NULL) {
|
||||||
goto exit;
|
err = -ENOMEM;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lsf_desc_wrapper =
|
||||||
|
nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc_wrapper));
|
||||||
|
if (lsf_desc_wrapper == NULL) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fw_sig = nvgpu_pmu_fw_sig_desc(g, g->pmu);
|
fw_sig = nvgpu_pmu_fw_sig_desc(g, g->pmu);
|
||||||
fw_desc = nvgpu_pmu_fw_desc_desc(g, g->pmu);
|
fw_desc = nvgpu_pmu_fw_desc_desc(g, g->pmu);
|
||||||
fw_image = nvgpu_pmu_fw_image_desc(g, g->pmu);
|
fw_image = nvgpu_pmu_fw_image_desc(g, g->pmu);
|
||||||
|
|
||||||
nvgpu_memcpy((u8 *)lsf_desc, (u8 *)fw_sig->data,
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
min_t(size_t, sizeof(*lsf_desc), fw_sig->size));
|
nvgpu_memcpy((u8 *)lsf_desc, (u8 *)fw_sig->data,
|
||||||
|
min_t(size_t, sizeof(*lsf_desc), fw_sig->size));
|
||||||
lsf_desc->falcon_id = FALCON_ID_PMU_NEXT_CORE;
|
lsf_desc->falcon_id = FALCON_ID_PMU_NEXT_CORE;
|
||||||
|
} else {
|
||||||
|
nvgpu_memcpy((u8 *)lsf_desc_wrapper, (u8 *)fw_sig->data,
|
||||||
|
min_t(size_t, sizeof(*lsf_desc_wrapper), fw_sig->size));
|
||||||
|
lsf_desc_wrapper->lsf_ucode_desc_v2.falcon_id = FALCON_ID_PMU_NEXT_CORE;
|
||||||
|
}
|
||||||
|
|
||||||
p_img->ndesc = (struct falcon_next_core_ucode_desc *)(void *)fw_desc->data;
|
p_img->ndesc = (struct falcon_next_core_ucode_desc *)(void *)fw_desc->data;
|
||||||
|
|
||||||
p_img->data = (u32 *)(void *)fw_image->data;
|
p_img->data = (u32 *)(void *)fw_image->data;
|
||||||
p_img->data_size = U32(fw_image->size);
|
p_img->data_size = U32(fw_image->size);
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
||||||
|
} else {
|
||||||
|
p_img->lsf_desc_wrapper =
|
||||||
|
(struct lsf_ucode_desc_wrapper *)lsf_desc_wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
p_img->is_next_core_img = true;
|
p_img->is_next_core_img = true;
|
||||||
|
|
||||||
@@ -146,7 +166,10 @@ int nvgpu_acr_lsf_fecs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
u32 tmp_size;
|
u32 tmp_size;
|
||||||
u32 ver = nvgpu_safe_add_u32(g->params.gpu_arch,
|
u32 ver = nvgpu_safe_add_u32(g->params.gpu_arch,
|
||||||
g->params.gpu_impl);
|
g->params.gpu_impl);
|
||||||
struct lsf_ucode_desc *lsf_desc;
|
struct lsf_ucode_desc *lsf_desc = NULL;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
struct lsf_ucode_desc_wrapper *lsf_desc_wrapper = NULL;
|
||||||
|
#endif
|
||||||
struct nvgpu_firmware *fecs_sig = NULL;
|
struct nvgpu_firmware *fecs_sig = NULL;
|
||||||
struct flcn_ucode_img *p_img =
|
struct flcn_ucode_img *p_img =
|
||||||
(struct flcn_ucode_img *)lsf_ucode_img;
|
(struct flcn_ucode_img *)lsf_ucode_img;
|
||||||
@@ -157,12 +180,22 @@ int nvgpu_acr_lsf_fecs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
|
|
||||||
switch (ver) {
|
switch (ver) {
|
||||||
case NVGPU_GPUID_GV11B:
|
case NVGPU_GPUID_GV11B:
|
||||||
#if defined(CONFIG_NVGPU_NON_FUSA)
|
|
||||||
case NVGPU_GPUID_GA10B:
|
|
||||||
#endif
|
|
||||||
fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG,
|
fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG,
|
||||||
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
||||||
break;
|
break;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
case NVGPU_GPUID_GA10B:
|
||||||
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
fecs_sig = nvgpu_request_firmware(g,
|
||||||
|
GM20B_FECS_UCODE_SIG,
|
||||||
|
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
||||||
|
} else {
|
||||||
|
fecs_sig = nvgpu_request_firmware(g,
|
||||||
|
GA10B_FECS_UCODE_PKC_SIG,
|
||||||
|
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_NVGPU_DGPU
|
#ifdef CONFIG_NVGPU_DGPU
|
||||||
case NVGPU_GPUID_TU104:
|
case NVGPU_GPUID_TU104:
|
||||||
fecs_sig = nvgpu_request_firmware(g, TU104_FECS_UCODE_SIG,
|
fecs_sig = nvgpu_request_firmware(g, TU104_FECS_UCODE_SIG,
|
||||||
@@ -185,15 +218,30 @@ int nvgpu_acr_lsf_fecs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
nvgpu_err(g, "failed to load fecs sig");
|
nvgpu_err(g, "failed to load fecs sig");
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
lsf_desc = nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc));
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
if (lsf_desc == NULL) {
|
lsf_desc = nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc));
|
||||||
err = -ENOMEM;
|
if (lsf_desc == NULL) {
|
||||||
goto rel_sig;
|
err = -ENOMEM;
|
||||||
}
|
goto rel_sig;
|
||||||
nvgpu_memcpy((u8 *)lsf_desc, (u8 *)fecs_sig->data,
|
}
|
||||||
min_t(size_t, sizeof(*lsf_desc), fecs_sig->size));
|
nvgpu_memcpy((u8 *)lsf_desc, (u8 *)fecs_sig->data,
|
||||||
|
min_t(size_t, sizeof(*lsf_desc), fecs_sig->size));
|
||||||
|
|
||||||
lsf_desc->falcon_id = FALCON_ID_FECS;
|
lsf_desc->falcon_id = FALCON_ID_FECS;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
lsf_desc_wrapper =
|
||||||
|
nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc_wrapper));
|
||||||
|
if (lsf_desc_wrapper == NULL) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto rel_sig;
|
||||||
|
}
|
||||||
|
nvgpu_memcpy((u8 *)lsf_desc_wrapper, (u8 *)fecs_sig->data,
|
||||||
|
min_t(size_t, sizeof(*lsf_desc_wrapper), fecs_sig->size));
|
||||||
|
|
||||||
|
lsf_desc_wrapper->lsf_ucode_desc_v2.falcon_id = FALCON_ID_FECS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
p_img->desc = nvgpu_kzalloc(g, sizeof(struct ls_falcon_ucode_desc));
|
p_img->desc = nvgpu_kzalloc(g, sizeof(struct ls_falcon_ucode_desc));
|
||||||
if (p_img->desc == NULL) {
|
if (p_img->desc == NULL) {
|
||||||
@@ -230,7 +278,14 @@ int nvgpu_acr_lsf_fecs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
p_img->data = nvgpu_gr_falcon_get_surface_desc_cpu_va(gr_falcon);
|
p_img->data = nvgpu_gr_falcon_get_surface_desc_cpu_va(gr_falcon);
|
||||||
p_img->data_size = p_img->desc->image_size;
|
p_img->data_size = p_img->desc->image_size;
|
||||||
|
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
p_img->lsf_desc_wrapper =
|
||||||
|
(struct lsf_ucode_desc_wrapper *)lsf_desc_wrapper;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
nvgpu_acr_dbg(g, "fecs fw loaded\n");
|
nvgpu_acr_dbg(g, "fecs fw loaded\n");
|
||||||
|
|
||||||
@@ -238,7 +293,13 @@ int nvgpu_acr_lsf_fecs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
free_lsf_desc:
|
free_lsf_desc:
|
||||||
nvgpu_kfree(g, lsf_desc);
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
nvgpu_kfree(g, lsf_desc);
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
nvgpu_kfree(g, lsf_desc_wrapper);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
rel_sig:
|
rel_sig:
|
||||||
nvgpu_release_firmware(g, fecs_sig);
|
nvgpu_release_firmware(g, fecs_sig);
|
||||||
return err;
|
return err;
|
||||||
@@ -248,7 +309,10 @@ int nvgpu_acr_lsf_gpccs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
{
|
{
|
||||||
u32 tmp_size;
|
u32 tmp_size;
|
||||||
u32 ver = nvgpu_safe_add_u32(g->params.gpu_arch, g->params.gpu_impl);
|
u32 ver = nvgpu_safe_add_u32(g->params.gpu_arch, g->params.gpu_impl);
|
||||||
struct lsf_ucode_desc *lsf_desc;
|
struct lsf_ucode_desc *lsf_desc = NULL;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
struct lsf_ucode_desc_wrapper *lsf_desc_wrapper = NULL;
|
||||||
|
#endif
|
||||||
struct nvgpu_firmware *gpccs_sig = NULL;
|
struct nvgpu_firmware *gpccs_sig = NULL;
|
||||||
struct flcn_ucode_img *p_img =
|
struct flcn_ucode_img *p_img =
|
||||||
(struct flcn_ucode_img *)lsf_ucode_img;
|
(struct flcn_ucode_img *)lsf_ucode_img;
|
||||||
@@ -267,12 +331,22 @@ int nvgpu_acr_lsf_gpccs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
|
|
||||||
switch (ver) {
|
switch (ver) {
|
||||||
case NVGPU_GPUID_GV11B:
|
case NVGPU_GPUID_GV11B:
|
||||||
#if defined(CONFIG_NVGPU_NON_FUSA)
|
|
||||||
case NVGPU_GPUID_GA10B:
|
|
||||||
#endif
|
|
||||||
gpccs_sig = nvgpu_request_firmware(g, T18x_GPCCS_UCODE_SIG,
|
gpccs_sig = nvgpu_request_firmware(g, T18x_GPCCS_UCODE_SIG,
|
||||||
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
||||||
break;
|
break;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
case NVGPU_GPUID_GA10B:
|
||||||
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
gpccs_sig = nvgpu_request_firmware(g,
|
||||||
|
T18x_GPCCS_UCODE_SIG,
|
||||||
|
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
||||||
|
} else {
|
||||||
|
gpccs_sig = nvgpu_request_firmware(g,
|
||||||
|
GA10B_GPCCS_UCODE_PKC_SIG,
|
||||||
|
NVGPU_REQUEST_FIRMWARE_NO_WARN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_NVGPU_DGPU
|
#ifdef CONFIG_NVGPU_DGPU
|
||||||
case NVGPU_GPUID_TU104:
|
case NVGPU_GPUID_TU104:
|
||||||
gpccs_sig = nvgpu_request_firmware(g, TU104_GPCCS_UCODE_SIG,
|
gpccs_sig = nvgpu_request_firmware(g, TU104_GPCCS_UCODE_SIG,
|
||||||
@@ -291,19 +365,35 @@ int nvgpu_acr_lsf_gpccs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_acr_dbg(g, "gpccs fw fetched from FS\n");
|
||||||
if (gpccs_sig == NULL) {
|
if (gpccs_sig == NULL) {
|
||||||
nvgpu_err(g, "failed to load gpccs sig");
|
nvgpu_err(g, "failed to load gpccs sig");
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
lsf_desc = nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc));
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
if (lsf_desc == NULL) {
|
lsf_desc = nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc));
|
||||||
err = -ENOMEM;
|
if (lsf_desc == NULL) {
|
||||||
goto rel_sig;
|
err = -ENOMEM;
|
||||||
}
|
goto rel_sig;
|
||||||
nvgpu_memcpy((u8 *)lsf_desc, gpccs_sig->data,
|
}
|
||||||
|
nvgpu_memcpy((u8 *)lsf_desc, gpccs_sig->data,
|
||||||
min_t(size_t, sizeof(*lsf_desc), gpccs_sig->size));
|
min_t(size_t, sizeof(*lsf_desc), gpccs_sig->size));
|
||||||
lsf_desc->falcon_id = FALCON_ID_GPCCS;
|
lsf_desc->falcon_id = FALCON_ID_GPCCS;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
lsf_desc_wrapper =
|
||||||
|
nvgpu_kzalloc(g, sizeof(struct lsf_ucode_desc_wrapper));
|
||||||
|
if (lsf_desc_wrapper == NULL) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto rel_sig;
|
||||||
|
}
|
||||||
|
nvgpu_memcpy((u8 *)lsf_desc_wrapper, gpccs_sig->data,
|
||||||
|
min_t(size_t, sizeof(*lsf_desc_wrapper), gpccs_sig->size));
|
||||||
|
lsf_desc_wrapper->lsf_ucode_desc_v2.falcon_id = FALCON_ID_GPCCS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
nvgpu_acr_dbg(g, "gpccs fw copied to desc buffer\n");
|
||||||
p_img->desc = nvgpu_kzalloc(g, sizeof(struct ls_falcon_ucode_desc));
|
p_img->desc = nvgpu_kzalloc(g, sizeof(struct ls_falcon_ucode_desc));
|
||||||
if (p_img->desc == NULL) {
|
if (p_img->desc == NULL) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
@@ -348,7 +438,15 @@ int nvgpu_acr_lsf_gpccs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
+ gpccs->boot.offset);
|
+ gpccs->boot.offset);
|
||||||
p_img->data_size = NVGPU_ALIGN(p_img->desc->image_size,
|
p_img->data_size = NVGPU_ALIGN(p_img->desc->image_size,
|
||||||
LSF_DATA_SIZE_ALIGNMENT);
|
LSF_DATA_SIZE_ALIGNMENT);
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
|
||||||
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
p_img->lsf_desc_wrapper =
|
||||||
|
(struct lsf_ucode_desc_wrapper *)lsf_desc_wrapper;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
nvgpu_acr_dbg(g, "gpccs fw loaded\n");
|
nvgpu_acr_dbg(g, "gpccs fw loaded\n");
|
||||||
|
|
||||||
@@ -356,7 +454,13 @@ int nvgpu_acr_lsf_gpccs_ucode_details(struct gk20a *g, void *lsf_ucode_img)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
free_lsf_desc:
|
free_lsf_desc:
|
||||||
nvgpu_kfree(g, lsf_desc);
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
nvgpu_kfree(g, lsf_desc);
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
nvgpu_kfree(g, lsf_desc_wrapper);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
rel_sig:
|
rel_sig:
|
||||||
nvgpu_release_firmware(g, gpccs_sig);
|
nvgpu_release_firmware(g, gpccs_sig);
|
||||||
return err;
|
return err;
|
||||||
@@ -455,8 +559,7 @@ release_img_fw:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Populate static LSB header information using the provided ucode image */
|
static void lsfm_fill_static_lsb_hdr_info_aes(struct gk20a *g,
|
||||||
static void lsfm_fill_static_lsb_hdr_info(struct gk20a *g,
|
|
||||||
u32 falcon_id, struct lsfm_managed_ucode_img *pnode)
|
u32 falcon_id, struct lsfm_managed_ucode_img *pnode)
|
||||||
{
|
{
|
||||||
u32 full_app_size = 0;
|
u32 full_app_size = 0;
|
||||||
@@ -468,59 +571,140 @@ static void lsfm_fill_static_lsb_hdr_info(struct gk20a *g,
|
|||||||
sizeof(struct lsf_ucode_desc));
|
sizeof(struct lsf_ucode_desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pnode->ucode_img.is_next_core_img) {
|
pnode->lsb_header.ucode_size = pnode->ucode_img.data_size;
|
||||||
pnode->lsb_header.ucode_size = pnode->ucode_img.data_size;
|
|
||||||
|
|
||||||
/* Uses a loader. that is has a desc */
|
/* Uses a loader. that is has a desc */
|
||||||
pnode->lsb_header.data_size = LSB_HDR_DATA_SIZE;
|
pnode->lsb_header.data_size = LSB_HDR_DATA_SIZE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The loader code size is already aligned (padded) such that
|
* The loader code size is already aligned (padded) such that
|
||||||
* the code following it is aligned, but the size in the image
|
* the code following it is aligned, but the size in the image
|
||||||
* desc is not, bloat it up to be on a 256 byte alignment.
|
* desc is not, bloat it up to be on a 256 byte alignment.
|
||||||
*/
|
*/
|
||||||
pnode->lsb_header.bl_code_size = NVGPU_ALIGN(
|
pnode->lsb_header.bl_code_size = NVGPU_ALIGN(
|
||||||
pnode->ucode_img.desc->bootloader_size,
|
pnode->ucode_img.desc->bootloader_size,
|
||||||
LSF_BL_CODE_SIZE_ALIGNMENT);
|
LSF_BL_CODE_SIZE_ALIGNMENT);
|
||||||
full_app_size = nvgpu_safe_add_u32(
|
full_app_size = nvgpu_safe_add_u32(
|
||||||
NVGPU_ALIGN(pnode->ucode_img.desc->app_size,
|
NVGPU_ALIGN(pnode->ucode_img.desc->app_size,
|
||||||
LSF_BL_CODE_SIZE_ALIGNMENT),
|
|
||||||
pnode->lsb_header.bl_code_size);
|
|
||||||
|
|
||||||
pnode->lsb_header.ucode_size = nvgpu_safe_add_u32(NVGPU_ALIGN(
|
|
||||||
pnode->ucode_img.desc->app_resident_data_offset,
|
|
||||||
LSF_BL_CODE_SIZE_ALIGNMENT),
|
LSF_BL_CODE_SIZE_ALIGNMENT),
|
||||||
pnode->lsb_header.bl_code_size);
|
pnode->lsb_header.bl_code_size);
|
||||||
|
|
||||||
pnode->lsb_header.data_size = nvgpu_safe_sub_u32(full_app_size,
|
pnode->lsb_header.ucode_size = nvgpu_safe_add_u32(NVGPU_ALIGN(
|
||||||
pnode->lsb_header.ucode_size);
|
pnode->ucode_img.desc->app_resident_data_offset,
|
||||||
/*
|
LSF_BL_CODE_SIZE_ALIGNMENT),
|
||||||
* Though the BL is located at 0th offset of the image, the VA
|
pnode->lsb_header.bl_code_size);
|
||||||
* is different to make sure that it doesn't collide the actual OS
|
|
||||||
* VA range
|
|
||||||
*/
|
|
||||||
pnode->lsb_header.bl_imem_off =
|
|
||||||
pnode->ucode_img.desc->bootloader_imem_offset;
|
|
||||||
|
|
||||||
pnode->lsb_header.flags = NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_FALSE;
|
pnode->lsb_header.data_size = nvgpu_safe_sub_u32(full_app_size,
|
||||||
|
pnode->lsb_header.ucode_size);
|
||||||
|
/*
|
||||||
|
* Though the BL is located at 0th offset of the image, the VA
|
||||||
|
* is different to make sure that it doesn't collide the actual OS
|
||||||
|
* VA range
|
||||||
|
*/
|
||||||
|
pnode->lsb_header.bl_imem_off =
|
||||||
|
pnode->ucode_img.desc->bootloader_imem_offset;
|
||||||
|
|
||||||
if (falcon_id == FALCON_ID_PMU) {
|
pnode->lsb_header.flags = NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_FALSE;
|
||||||
data = NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE;
|
|
||||||
pnode->lsb_header.flags = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g->acr->lsf[falcon_id].is_priv_load) {
|
if (falcon_id == FALCON_ID_PMU) {
|
||||||
pnode->lsb_header.flags |=
|
data = NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE;
|
||||||
NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE;
|
pnode->lsb_header.flags = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
if (g->acr->lsf[falcon_id].is_priv_load) {
|
||||||
|
pnode->lsb_header.flags |=
|
||||||
|
NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
static void lsfm_fill_static_lsb_hdr_info_pkc(struct gk20a *g,
|
||||||
|
u32 falcon_id, struct lsfm_managed_ucode_img *pnode)
|
||||||
|
{
|
||||||
|
u32 full_app_size = 0;
|
||||||
|
|
||||||
|
if (pnode->ucode_img.lsf_desc_wrapper != NULL) {
|
||||||
|
nvgpu_memcpy((u8 *)&pnode->lsb_header_v2.signature,
|
||||||
|
(u8 *)pnode->ucode_img.lsf_desc_wrapper,
|
||||||
|
sizeof(struct lsf_ucode_desc_wrapper));
|
||||||
|
}
|
||||||
|
pnode->lsb_header_v2.ucode_size = pnode->ucode_img.data_size;
|
||||||
|
pnode->lsb_header_v2.data_size = LSB_HDR_DATA_SIZE;
|
||||||
|
|
||||||
|
pnode->lsb_header_v2.bl_code_size = NVGPU_ALIGN(
|
||||||
|
pnode->ucode_img.desc->bootloader_size,
|
||||||
|
LSF_BL_CODE_SIZE_ALIGNMENT);
|
||||||
|
full_app_size = nvgpu_safe_add_u32(
|
||||||
|
NVGPU_ALIGN(pnode->ucode_img.desc->app_size,
|
||||||
|
LSF_BL_CODE_SIZE_ALIGNMENT),
|
||||||
|
pnode->lsb_header_v2.bl_code_size);
|
||||||
|
|
||||||
|
pnode->lsb_header_v2.ucode_size = nvgpu_safe_add_u32(NVGPU_ALIGN(
|
||||||
|
pnode->ucode_img.desc->app_resident_data_offset,
|
||||||
|
LSF_BL_CODE_SIZE_ALIGNMENT),
|
||||||
|
pnode->lsb_header_v2.bl_code_size);
|
||||||
|
|
||||||
|
pnode->lsb_header_v2.data_size = nvgpu_safe_sub_u32(full_app_size,
|
||||||
|
pnode->lsb_header_v2.ucode_size);
|
||||||
|
|
||||||
|
pnode->lsb_header_v2.bl_imem_off =
|
||||||
|
pnode->ucode_img.desc->bootloader_imem_offset;
|
||||||
|
|
||||||
|
pnode->lsb_header_v2.flags = NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_FALSE;
|
||||||
|
|
||||||
|
if (g->acr->lsf[falcon_id].is_priv_load) {
|
||||||
|
pnode->lsb_header_v2.flags |=
|
||||||
|
NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Populate static LSB header information using the provided ucode image */
|
||||||
|
static void lsfm_fill_static_lsb_hdr_info(struct gk20a *g,
|
||||||
|
u32 falcon_id, struct lsfm_managed_ucode_img *pnode)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
u32 base_size = 0;
|
||||||
|
u32 image_padding_size = 0;
|
||||||
|
struct falcon_next_core_ucode_desc *ndesc = pnode->ucode_img.ndesc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)
|
||||||
|
&& (!pnode->ucode_img.is_next_core_img)) {
|
||||||
|
lsfm_fill_static_lsb_hdr_info_aes(g, falcon_id, pnode);
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else if (nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)
|
||||||
|
&& (!pnode->ucode_img.is_next_core_img)) {
|
||||||
|
lsfm_fill_static_lsb_hdr_info_pkc(g, falcon_id, pnode);
|
||||||
|
} else if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)
|
||||||
|
&& (pnode->ucode_img.is_next_core_img)) {
|
||||||
pnode->lsb_header.ucode_size = 0;
|
pnode->lsb_header.ucode_size = 0;
|
||||||
pnode->lsb_header.data_size = 0;
|
pnode->lsb_header.data_size = 0;
|
||||||
pnode->lsb_header.bl_code_size = 0;
|
pnode->lsb_header.bl_code_size = 0;
|
||||||
pnode->lsb_header.bl_imem_off = 0;
|
pnode->lsb_header.bl_imem_off = 0;
|
||||||
pnode->lsb_header.bl_data_size = 0;
|
pnode->lsb_header.bl_data_size = 0;
|
||||||
pnode->lsb_header.bl_data_off = 0;
|
pnode->lsb_header.bl_data_off = 0;
|
||||||
|
} else {
|
||||||
|
if (pnode->ucode_img.lsf_desc_wrapper != NULL) {
|
||||||
|
nvgpu_memcpy((u8 *)&pnode->lsb_header_v2.signature,
|
||||||
|
(u8 *)pnode->ucode_img.lsf_desc_wrapper,
|
||||||
|
sizeof(struct lsf_ucode_desc_wrapper));
|
||||||
|
}
|
||||||
|
pnode->lsb_header_v2.ucode_size = ndesc->bootloader_offset +
|
||||||
|
ndesc->bootloader_size +
|
||||||
|
ndesc->bootloader_param_size;
|
||||||
|
base_size = pnode->lsb_header_v2.ucode_size +
|
||||||
|
ndesc->next_core_elf_size;
|
||||||
|
image_padding_size = PAGE_ALIGN(base_size) - base_size;
|
||||||
|
pnode->lsb_header_v2.data_size = ndesc->next_core_elf_size +
|
||||||
|
image_padding_size;
|
||||||
|
pnode->lsb_header_v2.bl_code_size = 0;
|
||||||
|
pnode->lsb_header_v2.bl_imem_off = 0;
|
||||||
|
pnode->lsb_header_v2.bl_data_size = 0;
|
||||||
|
pnode->lsb_header_v2.bl_data_off = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +734,15 @@ static int lsfm_add_ucode_img(struct gk20a *g, struct ls_flcn_mgr *plsfm,
|
|||||||
|
|
||||||
/* Fill in static LSB header info elsewhere */
|
/* Fill in static LSB header info elsewhere */
|
||||||
lsfm_fill_static_lsb_hdr_info(g, falcon_id, pnode);
|
lsfm_fill_static_lsb_hdr_info(g, falcon_id, pnode);
|
||||||
pnode->wpr_header.bin_version = pnode->lsb_header.signature.version;
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
pnode->wpr_header.bin_version =
|
||||||
|
pnode->lsb_header.signature.version;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
pnode->wpr_header.bin_version =
|
||||||
|
pnode->lsb_header_v2.signature.lsf_ucode_desc_v2.ls_ucode_version;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
pnode->next = plsfm->ucode_img_list;
|
pnode->next = plsfm->ucode_img_list;
|
||||||
plsfm->ucode_img_list = pnode;
|
plsfm->ucode_img_list = pnode;
|
||||||
|
|
||||||
@@ -562,7 +754,7 @@ static int lsfm_check_and_add_ucode_image(struct gk20a *g,
|
|||||||
{
|
{
|
||||||
struct flcn_ucode_img ucode_img;
|
struct flcn_ucode_img ucode_img;
|
||||||
struct nvgpu_acr *acr = g->acr;
|
struct nvgpu_acr *acr = g->acr;
|
||||||
u32 falcon_id;
|
u32 falcon_id = 0U;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!nvgpu_test_bit(lsf_index, (void *)&acr->lsf_enable_mask)) {
|
if (!nvgpu_test_bit(lsf_index, (void *)&acr->lsf_enable_mask)) {
|
||||||
@@ -584,7 +776,14 @@ static int lsfm_check_and_add_ucode_image(struct gk20a *g,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
falcon_id = ucode_img.lsf_desc->falcon_id;
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
falcon_id = ucode_img.lsf_desc->falcon_id;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
falcon_id = ucode_img.lsf_desc_wrapper->lsf_ucode_desc_v2.falcon_id;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
err = lsfm_add_ucode_img(g, plsfm, &ucode_img, falcon_id);
|
err = lsfm_add_ucode_img(g, plsfm, &ucode_img, falcon_id);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
nvgpu_err(g, " Failed to add falcon-%d to LSFM ", falcon_id);
|
nvgpu_err(g, " Failed to add falcon-%d to LSFM ", falcon_id);
|
||||||
@@ -672,6 +871,116 @@ static int lsfm_discover_and_add_sub_wprs(struct gk20a *g,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void lsf_calc_wpr_size_aes(struct lsfm_managed_ucode_img *pnode,
|
||||||
|
u32 *wpr_off)
|
||||||
|
{
|
||||||
|
u32 wpr_offset = *wpr_off;
|
||||||
|
|
||||||
|
/* Align, save off and include an LSB header size */
|
||||||
|
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_LSB_HEADER_ALIGNMENT);
|
||||||
|
pnode->wpr_header.lsb_offset = wpr_offset;
|
||||||
|
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
||||||
|
(u32)sizeof(struct lsf_lsb_header));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Align, save off and include the original (static)ucode
|
||||||
|
* image size
|
||||||
|
*/
|
||||||
|
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_UCODE_DATA_ALIGNMENT);
|
||||||
|
pnode->lsb_header.ucode_off = wpr_offset;
|
||||||
|
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
||||||
|
pnode->ucode_img.data_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For falcons that use a boot loader (BL), we append a loader
|
||||||
|
* desc structure on the end of the ucode image and consider this
|
||||||
|
* the boot loader data. The host will then copy the loader desc
|
||||||
|
* args to this space within the WPR region (before locking down)
|
||||||
|
* and the HS bin will then copy them to DMEM 0 for the loader.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Track the size for LSB details filled in later
|
||||||
|
* Note that at this point we don't know what kind of
|
||||||
|
* boot loader desc, so we just take the size of the
|
||||||
|
* generic one, which is the largest it will ever be.
|
||||||
|
*/
|
||||||
|
/* Align (size bloat) and save off generic descriptor size*/
|
||||||
|
pnode->lsb_header.bl_data_size = NVGPU_ALIGN(
|
||||||
|
nvgpu_safe_cast_u64_to_u32(
|
||||||
|
sizeof(pnode->bl_gen_desc)),
|
||||||
|
LSF_BL_DATA_SIZE_ALIGNMENT);
|
||||||
|
|
||||||
|
/*Align, save off, and include the additional BL data*/
|
||||||
|
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_BL_DATA_ALIGNMENT);
|
||||||
|
pnode->lsb_header.bl_data_off = wpr_offset;
|
||||||
|
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
||||||
|
pnode->lsb_header.bl_data_size);
|
||||||
|
|
||||||
|
/* Finally, update ucode surface size to include updates */
|
||||||
|
pnode->full_ucode_size = wpr_offset -
|
||||||
|
pnode->lsb_header.ucode_off;
|
||||||
|
if (pnode->wpr_header.falcon_id != FALCON_ID_PMU &&
|
||||||
|
pnode->wpr_header.falcon_id != FALCON_ID_PMU_NEXT_CORE) {
|
||||||
|
pnode->lsb_header.app_code_off =
|
||||||
|
pnode->lsb_header.bl_code_size;
|
||||||
|
pnode->lsb_header.app_code_size =
|
||||||
|
pnode->lsb_header.ucode_size -
|
||||||
|
pnode->lsb_header.bl_code_size;
|
||||||
|
pnode->lsb_header.app_data_off =
|
||||||
|
pnode->lsb_header.ucode_size;
|
||||||
|
pnode->lsb_header.app_data_size =
|
||||||
|
pnode->lsb_header.data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
*wpr_off = wpr_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
static void lsf_calc_wpr_size_pkc(struct lsfm_managed_ucode_img *pnode,
|
||||||
|
u32 *wpr_off)
|
||||||
|
{
|
||||||
|
u32 wpr_offset = *wpr_off;
|
||||||
|
|
||||||
|
/* Align, save off, and include an LSB header size */
|
||||||
|
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_LSB_HEADER_ALIGNMENT);
|
||||||
|
pnode->wpr_header.lsb_offset = wpr_offset;
|
||||||
|
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
||||||
|
(u32)sizeof(struct lsf_lsb_header_v2));
|
||||||
|
|
||||||
|
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_UCODE_DATA_ALIGNMENT);
|
||||||
|
pnode->lsb_header_v2.ucode_off = wpr_offset;
|
||||||
|
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
||||||
|
pnode->ucode_img.data_size);
|
||||||
|
|
||||||
|
pnode->lsb_header_v2.bl_data_size = NVGPU_ALIGN(
|
||||||
|
nvgpu_safe_cast_u64_to_u32(
|
||||||
|
sizeof(pnode->bl_gen_desc)),
|
||||||
|
LSF_BL_DATA_SIZE_ALIGNMENT);
|
||||||
|
|
||||||
|
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_BL_DATA_ALIGNMENT);
|
||||||
|
pnode->lsb_header_v2.bl_data_off = wpr_offset;
|
||||||
|
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
||||||
|
pnode->lsb_header_v2.bl_data_size);
|
||||||
|
|
||||||
|
pnode->full_ucode_size = wpr_offset -
|
||||||
|
pnode->lsb_header_v2.ucode_off;
|
||||||
|
if (pnode->wpr_header.falcon_id != FALCON_ID_PMU &&
|
||||||
|
pnode->wpr_header.falcon_id != FALCON_ID_PMU_NEXT_CORE) {
|
||||||
|
pnode->lsb_header_v2.app_code_off =
|
||||||
|
pnode->lsb_header_v2.bl_code_size;
|
||||||
|
pnode->lsb_header_v2.app_code_size =
|
||||||
|
pnode->lsb_header_v2.ucode_size -
|
||||||
|
pnode->lsb_header_v2.bl_code_size;
|
||||||
|
pnode->lsb_header_v2.app_data_off =
|
||||||
|
pnode->lsb_header_v2.ucode_size;
|
||||||
|
pnode->lsb_header_v2.app_data_size =
|
||||||
|
pnode->lsb_header_v2.data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
*wpr_off = wpr_offset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Generate WPR requirements for ACR allocation request */
|
/* Generate WPR requirements for ACR allocation request */
|
||||||
static int lsf_gen_wpr_requirements(struct gk20a *g,
|
static int lsf_gen_wpr_requirements(struct gk20a *g,
|
||||||
struct ls_flcn_mgr *plsfm)
|
struct ls_flcn_mgr *plsfm)
|
||||||
@@ -715,60 +1024,12 @@ static int lsf_gen_wpr_requirements(struct gk20a *g,
|
|||||||
* as well as the ucode images.
|
* as well as the ucode images.
|
||||||
*/
|
*/
|
||||||
while (pnode != NULL) {
|
while (pnode != NULL) {
|
||||||
/* Align, save off, and include an LSB header size */
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_LSB_HEADER_ALIGNMENT);
|
lsf_calc_wpr_size_aes(pnode, &wpr_offset);
|
||||||
pnode->wpr_header.lsb_offset = wpr_offset;
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
} else {
|
||||||
(u32)sizeof(struct lsf_lsb_header));
|
lsf_calc_wpr_size_pkc(pnode, &wpr_offset);
|
||||||
|
#endif
|
||||||
/*
|
|
||||||
* Align, save off, and include the original (static)ucode
|
|
||||||
* image size
|
|
||||||
*/
|
|
||||||
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_UCODE_DATA_ALIGNMENT);
|
|
||||||
pnode->lsb_header.ucode_off = wpr_offset;
|
|
||||||
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
|
||||||
pnode->ucode_img.data_size);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For falcons that use a boot loader (BL), we append a loader
|
|
||||||
* desc structure on the end of the ucode image and consider this
|
|
||||||
* the boot loader data. The host will then copy the loader desc
|
|
||||||
* args to this space within the WPR region (before locking down)
|
|
||||||
* and the HS bin will then copy them to DMEM 0 for the loader.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Track the size for LSB details filled in later
|
|
||||||
* Note that at this point we don't know what kind of
|
|
||||||
* boot loader desc, so we just take the size of the
|
|
||||||
* generic one, which is the largest it will will ever be.
|
|
||||||
*/
|
|
||||||
/* Align (size bloat) and save off generic descriptor size*/
|
|
||||||
pnode->lsb_header.bl_data_size = NVGPU_ALIGN(
|
|
||||||
nvgpu_safe_cast_u64_to_u32(
|
|
||||||
sizeof(pnode->bl_gen_desc)),
|
|
||||||
LSF_BL_DATA_SIZE_ALIGNMENT);
|
|
||||||
|
|
||||||
/*Align, save off, and include the additional BL data*/
|
|
||||||
wpr_offset = NVGPU_ALIGN(wpr_offset, LSF_BL_DATA_ALIGNMENT);
|
|
||||||
pnode->lsb_header.bl_data_off = wpr_offset;
|
|
||||||
wpr_offset = nvgpu_safe_add_u32(wpr_offset,
|
|
||||||
pnode->lsb_header.bl_data_size);
|
|
||||||
|
|
||||||
/* Finally, update ucode surface size to include updates */
|
|
||||||
pnode->full_ucode_size = wpr_offset -
|
|
||||||
pnode->lsb_header.ucode_off;
|
|
||||||
if (pnode->wpr_header.falcon_id != FALCON_ID_PMU &&
|
|
||||||
pnode->wpr_header.falcon_id != FALCON_ID_PMU_NEXT_CORE) {
|
|
||||||
pnode->lsb_header.app_code_off =
|
|
||||||
pnode->lsb_header.bl_code_size;
|
|
||||||
pnode->lsb_header.app_code_size =
|
|
||||||
pnode->lsb_header.ucode_size -
|
|
||||||
pnode->lsb_header.bl_code_size;
|
|
||||||
pnode->lsb_header.app_data_off =
|
|
||||||
pnode->lsb_header.ucode_size;
|
|
||||||
pnode->lsb_header.app_data_size =
|
|
||||||
pnode->lsb_header.data_size;
|
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_NVGPU_NON_FUSA)
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
/* Falcon image is cleanly partitioned between a code and
|
/* Falcon image is cleanly partitioned between a code and
|
||||||
@@ -817,7 +1078,7 @@ static int lsfm_populate_flcn_bl_dmem_desc(struct gk20a *g,
|
|||||||
struct flcn_ucode_img *p_img = &(p_lsfm->ucode_img);
|
struct flcn_ucode_img *p_img = &(p_lsfm->ucode_img);
|
||||||
struct flcn_bl_dmem_desc *ldr_cfg =
|
struct flcn_bl_dmem_desc *ldr_cfg =
|
||||||
&(p_lsfm->bl_gen_desc);
|
&(p_lsfm->bl_gen_desc);
|
||||||
u64 addr_base;
|
u64 addr_base = 0;
|
||||||
struct ls_falcon_ucode_desc *desc;
|
struct ls_falcon_ucode_desc *desc;
|
||||||
u64 addr_code, addr_data;
|
u64 addr_code, addr_data;
|
||||||
|
|
||||||
@@ -838,7 +1099,13 @@ static int lsfm_populate_flcn_bl_dmem_desc(struct gk20a *g,
|
|||||||
* The 32-bit addresses will be the upper 32-bits of the virtual or
|
* The 32-bit addresses will be the upper 32-bits of the virtual or
|
||||||
* physical addresses of each respective segment.
|
* physical addresses of each respective segment.
|
||||||
*/
|
*/
|
||||||
addr_base = p_lsfm->lsb_header.ucode_off;
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
addr_base = p_lsfm->lsb_header.ucode_off;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
addr_base = p_lsfm->lsb_header_v2.ucode_off;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
g->acr->get_wpr_info(g, &wpr_inf);
|
g->acr->get_wpr_info(g, &wpr_inf);
|
||||||
addr_base = nvgpu_safe_add_u64(addr_base, wpr_inf.wpr_base);
|
addr_base = nvgpu_safe_add_u64(addr_base, wpr_inf.wpr_base);
|
||||||
|
|
||||||
@@ -970,36 +1237,74 @@ static int lsfm_init_wpr_contents(struct gk20a *g,
|
|||||||
pnode->wpr_header.status);
|
pnode->wpr_header.status);
|
||||||
|
|
||||||
/*Flush LSB header to memory*/
|
/*Flush LSB header to memory*/
|
||||||
nvgpu_mem_wr_n(g, ucode, pnode->wpr_header.lsb_offset,
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
nvgpu_mem_wr_n(g, ucode, pnode->wpr_header.lsb_offset,
|
||||||
&pnode->lsb_header,
|
&pnode->lsb_header,
|
||||||
nvgpu_safe_cast_u64_to_u32(
|
nvgpu_safe_cast_u64_to_u32(
|
||||||
sizeof(pnode->lsb_header)));
|
sizeof(pnode->lsb_header)));
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
nvgpu_mem_wr_n(g, ucode, pnode->wpr_header.lsb_offset,
|
||||||
|
&pnode->lsb_header_v2,
|
||||||
|
nvgpu_safe_cast_u64_to_u32(
|
||||||
|
sizeof(pnode->lsb_header_v2)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
nvgpu_acr_dbg(g, "lsb header");
|
nvgpu_acr_dbg(g, "lsb header");
|
||||||
nvgpu_acr_dbg(g, "ucode_off :%x",
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
pnode->lsb_header.ucode_off);
|
nvgpu_acr_dbg(g, "ucode_off :%x",
|
||||||
nvgpu_acr_dbg(g, "ucode_size :%x",
|
pnode->lsb_header.ucode_off);
|
||||||
pnode->lsb_header.ucode_size);
|
nvgpu_acr_dbg(g, "ucode_size :%x",
|
||||||
nvgpu_acr_dbg(g, "data_size :%x",
|
pnode->lsb_header.ucode_size);
|
||||||
pnode->lsb_header.data_size);
|
nvgpu_acr_dbg(g, "data_size :%x",
|
||||||
nvgpu_acr_dbg(g, "bl_code_size :%x",
|
pnode->lsb_header.data_size);
|
||||||
pnode->lsb_header.bl_code_size);
|
nvgpu_acr_dbg(g, "bl_code_size :%x",
|
||||||
nvgpu_acr_dbg(g, "bl_imem_off :%x",
|
pnode->lsb_header.bl_code_size);
|
||||||
pnode->lsb_header.bl_imem_off);
|
nvgpu_acr_dbg(g, "bl_imem_off :%x",
|
||||||
nvgpu_acr_dbg(g, "bl_data_off :%x",
|
pnode->lsb_header.bl_imem_off);
|
||||||
pnode->lsb_header.bl_data_off);
|
nvgpu_acr_dbg(g, "bl_data_off :%x",
|
||||||
nvgpu_acr_dbg(g, "bl_data_size :%x",
|
pnode->lsb_header.bl_data_off);
|
||||||
pnode->lsb_header.bl_data_size);
|
nvgpu_acr_dbg(g, "bl_data_size :%x",
|
||||||
nvgpu_acr_dbg(g, "app_code_off :%x",
|
pnode->lsb_header.bl_data_size);
|
||||||
pnode->lsb_header.app_code_off);
|
nvgpu_acr_dbg(g, "app_code_off :%x",
|
||||||
nvgpu_acr_dbg(g, "app_code_size :%x",
|
pnode->lsb_header.app_code_off);
|
||||||
pnode->lsb_header.app_code_size);
|
nvgpu_acr_dbg(g, "app_code_size :%x",
|
||||||
nvgpu_acr_dbg(g, "app_data_off :%x",
|
pnode->lsb_header.app_code_size);
|
||||||
pnode->lsb_header.app_data_off);
|
nvgpu_acr_dbg(g, "app_data_off :%x",
|
||||||
nvgpu_acr_dbg(g, "app_data_size :%x",
|
pnode->lsb_header.app_data_off);
|
||||||
pnode->lsb_header.app_data_size);
|
nvgpu_acr_dbg(g, "app_data_size :%x",
|
||||||
nvgpu_acr_dbg(g, "flags :%x",
|
pnode->lsb_header.app_data_size);
|
||||||
pnode->lsb_header.flags);
|
nvgpu_acr_dbg(g, "flags :%x",
|
||||||
|
pnode->lsb_header.flags);
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
nvgpu_acr_dbg(g, "ucode_off :%x",
|
||||||
|
pnode->lsb_header_v2.ucode_off);
|
||||||
|
nvgpu_acr_dbg(g, "ucode_size :%x",
|
||||||
|
pnode->lsb_header_v2.ucode_size);
|
||||||
|
nvgpu_acr_dbg(g, "data_size :%x",
|
||||||
|
pnode->lsb_header_v2.data_size);
|
||||||
|
nvgpu_acr_dbg(g, "bl_code_size :%x",
|
||||||
|
pnode->lsb_header_v2.bl_code_size);
|
||||||
|
nvgpu_acr_dbg(g, "bl_imem_off :%x",
|
||||||
|
pnode->lsb_header_v2.bl_imem_off);
|
||||||
|
nvgpu_acr_dbg(g, "bl_data_off :%x",
|
||||||
|
pnode->lsb_header_v2.bl_data_off);
|
||||||
|
nvgpu_acr_dbg(g, "bl_data_size :%x",
|
||||||
|
pnode->lsb_header_v2.bl_data_size);
|
||||||
|
nvgpu_acr_dbg(g, "app_code_off :%x",
|
||||||
|
pnode->lsb_header_v2.app_code_off);
|
||||||
|
nvgpu_acr_dbg(g, "app_code_size :%x",
|
||||||
|
pnode->lsb_header_v2.app_code_size);
|
||||||
|
nvgpu_acr_dbg(g, "app_data_off :%x",
|
||||||
|
pnode->lsb_header_v2.app_data_off);
|
||||||
|
nvgpu_acr_dbg(g, "app_data_size :%x",
|
||||||
|
pnode->lsb_header_v2.app_data_size);
|
||||||
|
nvgpu_acr_dbg(g, "flags :%x",
|
||||||
|
pnode->lsb_header_v2.flags);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (!pnode->ucode_img.is_next_core_img) {
|
if (!pnode->ucode_img.is_next_core_img) {
|
||||||
/*
|
/*
|
||||||
@@ -1012,13 +1317,33 @@ static int lsfm_init_wpr_contents(struct gk20a *g,
|
|||||||
nvgpu_err(g, "bl_gen_desc failed err=%d", err);
|
nvgpu_err(g, "bl_gen_desc failed err=%d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
nvgpu_mem_wr_n(g, ucode, pnode->lsb_header.bl_data_off,
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
&pnode->bl_gen_desc, pnode->bl_gen_desc_size);
|
nvgpu_mem_wr_n(g, ucode,
|
||||||
|
pnode->lsb_header.bl_data_off,
|
||||||
|
&pnode->bl_gen_desc,
|
||||||
|
pnode->bl_gen_desc_size);
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
nvgpu_mem_wr_n(g, ucode,
|
||||||
|
pnode->lsb_header_v2.bl_data_off,
|
||||||
|
&pnode->bl_gen_desc,
|
||||||
|
pnode->bl_gen_desc_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copying of ucode */
|
/* Copying of ucode */
|
||||||
nvgpu_mem_wr_n(g, ucode, pnode->lsb_header.ucode_off,
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
pnode->ucode_img.data, pnode->ucode_img.data_size);
|
nvgpu_mem_wr_n(g, ucode, pnode->lsb_header.ucode_off,
|
||||||
|
pnode->ucode_img.data,
|
||||||
|
pnode->ucode_img.data_size);
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
} else {
|
||||||
|
nvgpu_mem_wr_n(g, ucode, pnode->lsb_header_v2.ucode_off,
|
||||||
|
pnode->ucode_img.data,
|
||||||
|
pnode->ucode_img.data_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
pnode = pnode->next;
|
pnode = pnode->next;
|
||||||
i = nvgpu_safe_add_u32(i, 1U);
|
i = nvgpu_safe_add_u32(i, 1U);
|
||||||
@@ -1043,6 +1368,12 @@ static void lsfm_free_ucode_img_res(struct gk20a *g,
|
|||||||
nvgpu_kfree(g, p_img->lsf_desc);
|
nvgpu_kfree(g, p_img->lsf_desc);
|
||||||
p_img->lsf_desc = NULL;
|
p_img->lsf_desc = NULL;
|
||||||
}
|
}
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
if (p_img->lsf_desc_wrapper != NULL) {
|
||||||
|
nvgpu_kfree(g, p_img->lsf_desc_wrapper);
|
||||||
|
p_img->lsf_desc_wrapper = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lsfm_free_nonpmu_ucode_img_res(struct gk20a *g,
|
static void lsfm_free_nonpmu_ucode_img_res(struct gk20a *g,
|
||||||
@@ -1052,6 +1383,12 @@ static void lsfm_free_nonpmu_ucode_img_res(struct gk20a *g,
|
|||||||
nvgpu_kfree(g, p_img->lsf_desc);
|
nvgpu_kfree(g, p_img->lsf_desc);
|
||||||
p_img->lsf_desc = NULL;
|
p_img->lsf_desc = NULL;
|
||||||
}
|
}
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
if (p_img->lsf_desc_wrapper != NULL) {
|
||||||
|
nvgpu_kfree(g, p_img->lsf_desc_wrapper);
|
||||||
|
p_img->lsf_desc_wrapper = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (p_img->desc != NULL) {
|
if (p_img->desc != NULL) {
|
||||||
nvgpu_kfree(g, p_img->desc);
|
nvgpu_kfree(g, p_img->desc);
|
||||||
p_img->desc = NULL;
|
p_img->desc = NULL;
|
||||||
@@ -1065,8 +1402,8 @@ static void free_acr_resources(struct gk20a *g, struct ls_flcn_mgr *plsfm)
|
|||||||
|
|
||||||
while (cnt != 0U) {
|
while (cnt != 0U) {
|
||||||
mg_ucode_img = plsfm->ucode_img_list;
|
mg_ucode_img = plsfm->ucode_img_list;
|
||||||
if (mg_ucode_img->ucode_img.lsf_desc->falcon_id ==
|
if (mg_ucode_img->ucode_img.lsf_desc != NULL &&
|
||||||
FALCON_ID_PMU) {
|
mg_ucode_img->ucode_img.lsf_desc->falcon_id == FALCON_ID_PMU) {
|
||||||
lsfm_free_ucode_img_res(g, &mg_ucode_img->ucode_img);
|
lsfm_free_ucode_img_res(g, &mg_ucode_img->ucode_img);
|
||||||
} else {
|
} else {
|
||||||
lsfm_free_nonpmu_ucode_img_res(g,
|
lsfm_free_nonpmu_ucode_img_res(g,
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ struct flcn_ucode_img {
|
|||||||
struct lsf_ucode_desc *lsf_desc;
|
struct lsf_ucode_desc *lsf_desc;
|
||||||
bool is_next_core_img;
|
bool is_next_core_img;
|
||||||
#if defined(CONFIG_NVGPU_NON_FUSA)
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
struct lsf_ucode_desc_wrapper *lsf_desc_wrapper;
|
||||||
struct falcon_next_core_ucode_desc *ndesc;
|
struct falcon_next_core_ucode_desc *ndesc;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -96,6 +97,9 @@ struct lsfm_managed_ucode_img {
|
|||||||
struct lsfm_managed_ucode_img *next;
|
struct lsfm_managed_ucode_img *next;
|
||||||
struct lsf_wpr_header wpr_header;
|
struct lsf_wpr_header wpr_header;
|
||||||
struct lsf_lsb_header lsb_header;
|
struct lsf_lsb_header lsb_header;
|
||||||
|
#if defined(CONFIG_NVGPU_NON_FUSA)
|
||||||
|
struct lsf_lsb_header_v2 lsb_header_v2;
|
||||||
|
#endif
|
||||||
struct flcn_bl_dmem_desc bl_gen_desc;
|
struct flcn_bl_dmem_desc bl_gen_desc;
|
||||||
u32 bl_gen_desc_size;
|
u32 bl_gen_desc_size;
|
||||||
u32 full_ucode_size;
|
u32 full_ucode_size;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -89,6 +89,9 @@ struct wpr_carveout_info;
|
|||||||
#define GM20B_FECS_UCODE_SIG "fecs_sig.bin"
|
#define GM20B_FECS_UCODE_SIG "fecs_sig.bin"
|
||||||
#define T18x_GPCCS_UCODE_SIG "gpccs_sig.bin"
|
#define T18x_GPCCS_UCODE_SIG "gpccs_sig.bin"
|
||||||
|
|
||||||
|
#define GA10B_FECS_UCODE_PKC_SIG "fecs_pkc_sig.bin"
|
||||||
|
#define GA10B_GPCCS_UCODE_PKC_SIG "gpccs_pkc_sig.bin"
|
||||||
|
|
||||||
#define TU104_FECS_UCODE_SIG "tu104/fecs_sig.bin"
|
#define TU104_FECS_UCODE_SIG "tu104/fecs_sig.bin"
|
||||||
#define TU104_GPCCS_UCODE_SIG "tu104/gpccs_sig.bin"
|
#define TU104_GPCCS_UCODE_SIG "tu104/gpccs_sig.bin"
|
||||||
|
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ void nvgpu_ga10b_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr)
|
|||||||
#ifdef CONFIG_NVGPU_NON_FUSA
|
#ifdef CONFIG_NVGPU_NON_FUSA
|
||||||
if (nvgpu_falcon_is_falcon2_enabled(&g->gsp_flcn)) {
|
if (nvgpu_falcon_is_falcon2_enabled(&g->gsp_flcn)) {
|
||||||
nvgpu_set_enabled(g, NVGPU_ACR_NEXT_CORE_ENABLED, true);
|
nvgpu_set_enabled(g, NVGPU_ACR_NEXT_CORE_ENABLED, true);
|
||||||
|
nvgpu_set_enabled(g, NVGPU_PKC_LS_SIG_ENABLED, false);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (nvgpu_falcon_is_falcon2_enabled(&g->pmu_flcn)) {
|
if (nvgpu_falcon_is_falcon2_enabled(&g->pmu_flcn)) {
|
||||||
@@ -329,6 +330,7 @@ void nvgpu_ga10b_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr)
|
|||||||
* in ACR unit
|
* in ACR unit
|
||||||
*/
|
*/
|
||||||
nvgpu_set_enabled(g, NVGPU_ACR_NEXT_CORE_ENABLED, true);
|
nvgpu_set_enabled(g, NVGPU_ACR_NEXT_CORE_ENABLED, true);
|
||||||
|
nvgpu_set_enabled(g, NVGPU_PKC_LS_SIG_ENABLED, false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -249,6 +249,92 @@ struct lsf_ucode_desc {
|
|||||||
u8 kdf[16];
|
u8 kdf[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* PKC */
|
||||||
|
/*
|
||||||
|
* Currently 2 components in ucode image have signature.
|
||||||
|
* One is code section and another is data section.
|
||||||
|
*/
|
||||||
|
#define LSF_UCODE_COMPONENT_INDEX_CODE (0)
|
||||||
|
#define LSF_UCODE_COMPONENT_INDEX_DATA (1)
|
||||||
|
#define LSF_UCODE_COMPONENT_INDEX_MAX (2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For PKC operation, SE engine needs each input component size to be 512 bytes
|
||||||
|
* length. So even though PKC signature is 384 bytes, it needs to be padded with
|
||||||
|
* zeros until size is 512.
|
||||||
|
* Currently, for version 2, MAX LS signature size is set to be 512 as well.
|
||||||
|
*/
|
||||||
|
#define PKC_SIGNATURE_SIZE_BYTE (384)
|
||||||
|
#define PKC_SIGNATURE_PADDING_SIZE_BYTE (128)
|
||||||
|
#define PKC_SIGNATURE_PADDED_SIZE_BYTE \
|
||||||
|
(PKC_SIGNATURE_SIZE_BYTE + PKC_SIGNATURE_PADDING_SIZE_BYTE)
|
||||||
|
|
||||||
|
/* Size in bytes for RSA 3K (RSA_3K struct from bootrom_pkc_parameters.h */
|
||||||
|
#define PKC_PK_SIZE_BYTE (2048)
|
||||||
|
|
||||||
|
#define LSF_SIGNATURE_SIZE_PKC_BYTE \
|
||||||
|
(PKC_SIGNATURE_SIZE_BYTE + PKC_SIGNATURE_PADDING_SIZE_BYTE)
|
||||||
|
#define LSF_SIGNATURE_SIZE_MAX_BYTE LSF_SIGNATURE_SIZE_PKC_BYTE
|
||||||
|
#define LSF_PK_SIZE_MAX PKC_PK_SIZE_BYTE
|
||||||
|
|
||||||
|
/* LS Encryption Defines */
|
||||||
|
#define LS_ENCRYPTION_AES_CBC_IV_SIZE_BYTE (16)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* WPR generic struct header
|
||||||
|
* identifier - To identify type of WPR struct i.e. WPR vs SUBWPR vs LSB vs LSF_UCODE_DESC
|
||||||
|
* version - To specify version of struct, for backward compatibility
|
||||||
|
* size - Size of struct, include header and body
|
||||||
|
*/
|
||||||
|
struct wpr_generic_header {
|
||||||
|
u16 identifier;
|
||||||
|
u16 version;
|
||||||
|
u32 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Light Secure Falcon Ucode Version 2 Description Defines
|
||||||
|
* This stucture is prelim and may change as the ucode signing flow evolves.
|
||||||
|
*/
|
||||||
|
struct lsf_ucode_desc_v2 {
|
||||||
|
u32 falcon_id; // lsenginedid
|
||||||
|
u8 b_prd_present;
|
||||||
|
u8 b_dbg_present;
|
||||||
|
u16 reserved;
|
||||||
|
u32 sig_size;
|
||||||
|
u8 prod_sig[LSF_UCODE_COMPONENT_INDEX_MAX][LSF_SIGNATURE_SIZE_PKC_BYTE];
|
||||||
|
u8 debug_sig[LSF_UCODE_COMPONENT_INDEX_MAX][LSF_SIGNATURE_SIZE_PKC_BYTE];
|
||||||
|
u16 sig_algo_ver;
|
||||||
|
u16 sig_algo;
|
||||||
|
u16 hash_algo_ver;
|
||||||
|
u16 hash_algo;
|
||||||
|
u32 sig_algo_padding_type;
|
||||||
|
u8 dep_map[LSF_FALCON_DEPMAP_SIZE * 8];
|
||||||
|
u32 dep_map_count;
|
||||||
|
u8 b_supports_versioning;
|
||||||
|
u8 pad[3];
|
||||||
|
u32 ls_ucode_version; // lsucodeversion
|
||||||
|
u32 ls_ucode_id; // lsucodeid
|
||||||
|
u32 b_ucode_ls_encrypted;
|
||||||
|
u32 ls_encalgo_type;
|
||||||
|
u32 ls_enc_algo_ver;
|
||||||
|
u8 ls_enc_iv[LS_ENCRYPTION_AES_CBC_IV_SIZE_BYTE];
|
||||||
|
u8 rsvd[36]; // reserved for any future usage
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The wrapper for LSF_UCODE_DESC, start support from version 2.
|
||||||
|
*/
|
||||||
|
struct lsf_ucode_desc_wrapper {
|
||||||
|
struct wpr_generic_header generic_hdr;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct lsf_ucode_desc_v2 lsf_ucode_desc_v2;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PKC end*/
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -355,7 +441,94 @@ struct lsf_lsb_header {
|
|||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct lsf_lsb_header_v2 {
|
||||||
|
/** Code/data signature details of each LS falcon */
|
||||||
|
struct lsf_ucode_desc_wrapper signature;
|
||||||
|
/**
|
||||||
|
* Offset from non-WPR base where UCODE is located,
|
||||||
|
* Offset = Non-WPR base + #LSF_LSB_HEADER_ALIGNMENT +
|
||||||
|
* #LSF_UCODE_DATA_ALIGNMENT + ( #LSF_BL_DATA_ALIGNMENT *
|
||||||
|
* LS Falcon index)
|
||||||
|
*/
|
||||||
|
u32 ucode_off;
|
||||||
|
/**
|
||||||
|
* Size of LS Falcon ucode, required to perform signature verification
|
||||||
|
* of LS Falcon ucode by ACR HS.
|
||||||
|
*/
|
||||||
|
u32 ucode_size;
|
||||||
|
/**
|
||||||
|
* Size of LS Falcon ucode data, required to perform signature
|
||||||
|
* verification of LS Falcon ucode data by ACR HS.
|
||||||
|
*/
|
||||||
|
u32 data_size;
|
||||||
|
/**
|
||||||
|
* Size of bootloader that needs to be loaded by bootstrap owner.
|
||||||
|
*
|
||||||
|
* On GV11B, respective LS Falcon BL code size should not exceed
|
||||||
|
* below mentioned size.
|
||||||
|
* FALCON_ID_FECS IMEM size - 32k
|
||||||
|
* FALCON_ID_GPCCS IMEM size - 16k
|
||||||
|
*/
|
||||||
|
u32 bl_code_size;
|
||||||
|
/** BL starting virtual address. Need for tagging */
|
||||||
|
u32 bl_imem_off;
|
||||||
|
/**
|
||||||
|
* Offset from non-WPR base holding the BL data
|
||||||
|
* Offset = (Non-WPR base + #LSF_LSB_HEADER_ALIGNMENT +
|
||||||
|
* #LSF_UCODE_DATA_ALIGNMENT + #LSF_BL_DATA_ALIGNMENT) *
|
||||||
|
* #LS Falcon index
|
||||||
|
*/
|
||||||
|
u32 bl_data_off;
|
||||||
|
/**
|
||||||
|
* Size of BL data, BL data will be copied to LS Falcon DMEM of
|
||||||
|
* bl data size
|
||||||
|
*
|
||||||
|
* On GV11B, respective LS Falcon BL data size should not exceed
|
||||||
|
* below mentioned size.
|
||||||
|
* FALCON_ID_FECS DMEM size - 8k
|
||||||
|
* FALCON_ID_GPCCS DMEM size - 5k
|
||||||
|
*/
|
||||||
|
u32 bl_data_size;
|
||||||
|
/**
|
||||||
|
* Offset from non-WPR base address where UCODE Application code is
|
||||||
|
* located.
|
||||||
|
*/
|
||||||
|
u32 app_code_off;
|
||||||
|
/**
|
||||||
|
* Size of UCODE Application code.
|
||||||
|
*
|
||||||
|
* On GV11B, FECS/GPCCS LS Falcon app code size should not exceed
|
||||||
|
* below mentioned size.
|
||||||
|
* FALCON_ID_FECS IMEM size - 32k
|
||||||
|
* FALCON_ID_GPCCS IMEM size - 16k
|
||||||
|
*/
|
||||||
|
u32 app_code_size;
|
||||||
|
/**
|
||||||
|
* Offset from non-WPR base address where UCODE Application data
|
||||||
|
* is located
|
||||||
|
*/
|
||||||
|
u32 app_data_off;
|
||||||
|
/**
|
||||||
|
* Size of UCODE Application data.
|
||||||
|
*
|
||||||
|
* On GV11B, respective LS Falcon app data size should not exceed
|
||||||
|
* below mentioned size.
|
||||||
|
* FALCON_ID_FECS DMEM size - 8k
|
||||||
|
* FALCON_ID_GPCCS DMEM size - 5k
|
||||||
|
*/
|
||||||
|
u32 app_data_size;
|
||||||
|
/**
|
||||||
|
* NV_FLCN_ACR_LSF_FLAG_LOAD_CODE_AT_0 - Load BL at 0th IMEM offset
|
||||||
|
* NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX - This falcon requires a ctx
|
||||||
|
* before issuing DMAs.
|
||||||
|
* NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD - Use priv loading method
|
||||||
|
* instead of bootloader/DMAs
|
||||||
|
*/
|
||||||
|
u32 flags;
|
||||||
|
};
|
||||||
|
|
||||||
#define FLCN_SIG_SIZE (4U)
|
#define FLCN_SIG_SIZE (4U)
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#define NVGPU_PMU_UCODE_SIG "pmu_sig.bin"
|
#define NVGPU_PMU_UCODE_SIG "pmu_sig.bin"
|
||||||
#define NVGPU_PMU_UCODE_NEXT_IMAGE "gpmu_ucode_next_image.bin"
|
#define NVGPU_PMU_UCODE_NEXT_IMAGE "gpmu_ucode_next_image.bin"
|
||||||
#define NVGPU_PMU_UCODE_NEXT_DESC "gpmu_ucode_next_desc.bin"
|
#define NVGPU_PMU_UCODE_NEXT_DESC "gpmu_ucode_next_desc.bin"
|
||||||
|
#define NVGPU_PMU_UCODE_NEXT_SIG "pmu_pkc_sig.bin"
|
||||||
|
|
||||||
void nvgpu_pmu_fw_get_cmd_line_args_offset(struct gk20a *g,
|
void nvgpu_pmu_fw_get_cmd_line_args_offset(struct gk20a *g,
|
||||||
u32 *args_offset)
|
u32 *args_offset)
|
||||||
@@ -303,8 +304,14 @@ int nvgpu_pmu_init_pmu_fw(struct gk20a *g, struct nvgpu_pmu *pmu,
|
|||||||
*rtos_fw_p = rtos_fw;
|
*rtos_fw_p = rtos_fw;
|
||||||
|
|
||||||
if (nvgpu_is_enabled(g, NVGPU_PMU_NEXT_CORE_ENABLED)) {
|
if (nvgpu_is_enabled(g, NVGPU_PMU_NEXT_CORE_ENABLED)) {
|
||||||
err = pmu_fw_read(g, NVGPU_PMU_UCODE_NEXT_IMAGE,
|
if (!nvgpu_is_enabled(g, NVGPU_PKC_LS_SIG_ENABLED)) {
|
||||||
|
err = pmu_fw_read(g, NVGPU_PMU_UCODE_NEXT_IMAGE,
|
||||||
NVGPU_PMU_UCODE_NEXT_DESC, NVGPU_PMU_UCODE_SIG);
|
NVGPU_PMU_UCODE_NEXT_DESC, NVGPU_PMU_UCODE_SIG);
|
||||||
|
} else {
|
||||||
|
err = pmu_fw_read(g, NVGPU_PMU_UCODE_NEXT_IMAGE,
|
||||||
|
NVGPU_PMU_UCODE_NEXT_DESC,
|
||||||
|
NVGPU_PMU_UCODE_NEXT_SIG);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
err = pmu_fw_read(g, NVGPU_PMU_UCODE_IMAGE,
|
err = pmu_fw_read(g, NVGPU_PMU_UCODE_IMAGE,
|
||||||
|
|||||||
@@ -207,6 +207,8 @@ struct gk20a;
|
|||||||
DEFINE_FLAG(NVGPU_PMU_NEXT_CORE_ENABLED, "PMU NEXT CORE enabled"), \
|
DEFINE_FLAG(NVGPU_PMU_NEXT_CORE_ENABLED, "PMU NEXT CORE enabled"), \
|
||||||
DEFINE_FLAG(NVGPU_ACR_NEXT_CORE_ENABLED, \
|
DEFINE_FLAG(NVGPU_ACR_NEXT_CORE_ENABLED, \
|
||||||
"NEXT CORE availability for acr"), \
|
"NEXT CORE availability for acr"), \
|
||||||
|
DEFINE_FLAG(NVGPU_PKC_LS_SIG_ENABLED, \
|
||||||
|
"PKC signature support"), \
|
||||||
DEFINE_FLAG(NVGPU_ELPG_MS_ENABLED, "ELPG_MS support"), \
|
DEFINE_FLAG(NVGPU_ELPG_MS_ENABLED, "ELPG_MS support"), \
|
||||||
DEFINE_FLAG(NVGPU_L2_MAX_WAYS_EVICT_LAST_ENABLED, \
|
DEFINE_FLAG(NVGPU_L2_MAX_WAYS_EVICT_LAST_ENABLED, \
|
||||||
"Set L2 Max Ways Evict Last support"), \
|
"Set L2 Max Ways Evict Last support"), \
|
||||||
|
|||||||
Reference in New Issue
Block a user