diff --git a/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c b/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c index 472ad2444..f7fcb4da1 100644 --- a/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c +++ b/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c @@ -187,16 +187,8 @@ int nvgpu_acr_self_hs_load_bootstrap(struct gk20a *g, struct nvgpu_falcon *flcn, struct acr_fw_header *fw_hdr = NULL; u32 *ucode_header = NULL; u32 *ucode = NULL; - u32 sec_imem_dest = 0U; int err = 0; - /* falcon reset */ - err = nvgpu_falcon_reset(flcn); - if (err != 0) { - nvgpu_err(g, "nvgpu_falcon_reset() failed err=%d", err); - return err; - } - hs_bin_hdr = (struct bin_hdr *)(void *)hs_fw->data; fw_hdr = (struct acr_fw_header *)(void *)(hs_fw->data + hs_bin_hdr->header_offset); @@ -215,54 +207,9 @@ int nvgpu_acr_self_hs_load_bootstrap(struct gk20a *g, struct nvgpu_falcon *flcn, goto exit; } - /* setup falcon apertures, boot-config */ - err = nvgpu_falcon_setup_bootstrap_config(flcn); + err = nvgpu_falcon_hs_ucode_load_bootstrap(flcn, ucode, ucode_header); if (err != 0) { - goto exit; - } - - /* Copy Non Secure IMEM code */ - err = nvgpu_falcon_copy_to_imem(flcn, 0U, - (u8 *)&ucode[ucode_header[OS_CODE_OFFSET] >> 2U], - ucode_header[OS_CODE_SIZE], 0U, false, - GET_IMEM_TAG(ucode_header[OS_CODE_OFFSET])); - if (err != 0) { - nvgpu_err(g, "HS ucode non-secure code to IMEM failed"); - goto exit; - } - - /* Put secure code after non-secure block */ - sec_imem_dest = GET_NEXT_BLOCK(ucode_header[OS_CODE_SIZE]); - - err = nvgpu_falcon_copy_to_imem(flcn, sec_imem_dest, - (u8 *)&ucode[ucode_header[APP_0_CODE_OFFSET] >> 2U], - ucode_header[APP_0_CODE_SIZE], 0U, true, - GET_IMEM_TAG(ucode_header[APP_0_CODE_OFFSET])); - if (err != 0) { - nvgpu_err(g, "HS ucode secure code to IMEM failed"); - goto exit; - } - - /* load DMEM: ensure that signatures are patched */ - err = nvgpu_falcon_copy_to_dmem(flcn, 0U, (u8 *)&ucode[ - ucode_header[OS_DATA_OFFSET] >> 2U], - ucode_header[OS_DATA_SIZE], 0U); - if (err != 0) { - nvgpu_err(g, "HS ucode data copy to DMEM failed"); - goto exit; - } - - /* - * Write non-zero value to mailbox register which is updated by - * HS bin to denote its return status. - */ - nvgpu_falcon_mailbox_write(flcn, FALCON_MAILBOX_0, 0xdeadbeefU); - - /* set BOOTVEC to start of non-secure code */ - err = nvgpu_falcon_bootstrap(flcn, 0U); - if (err != 0) { - nvgpu_err(g, "HS ucode bootstrap failed err-%d on falcon-%d", err, - nvgpu_falcon_get_id(flcn)); + nvgpu_err(g, "HS ucode load & bootstrap failed"); goto exit; } diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index 4adb0d839..97fa355f9 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -390,6 +390,81 @@ exit: return err; } +int nvgpu_falcon_hs_ucode_load_bootstrap(struct nvgpu_falcon *flcn, u32 *ucode, + u32 *ucode_header) +{ + struct gk20a *g; + u32 sec_imem_dest = 0U; + int err = 0; + + if (!is_falcon_valid(flcn)) { + return -EINVAL; + } + + g = flcn->g; + + /* falcon reset */ + err = nvgpu_falcon_reset(flcn); + if (err != 0) { + nvgpu_err(g, "nvgpu_falcon_reset() failed err=%d", err); + return err; + } + + /* setup falcon apertures, boot-config */ + err = nvgpu_falcon_setup_bootstrap_config(flcn); + if (err != 0) { + goto exit; + } + + /* Copy Non Secure IMEM code */ + err = nvgpu_falcon_copy_to_imem(flcn, 0U, + (u8 *)&ucode[ucode_header[OS_CODE_OFFSET] >> 2U], + ucode_header[OS_CODE_SIZE], 0U, false, + GET_IMEM_TAG(ucode_header[OS_CODE_OFFSET])); + if (err != 0) { + nvgpu_err(g, "HS ucode non-secure code to IMEM failed"); + goto exit; + } + + /* Put secure code after non-secure block */ + sec_imem_dest = GET_NEXT_BLOCK(ucode_header[OS_CODE_SIZE]); + + err = nvgpu_falcon_copy_to_imem(flcn, sec_imem_dest, + (u8 *)&ucode[ucode_header[APP_0_CODE_OFFSET] >> 2U], + ucode_header[APP_0_CODE_SIZE], 0U, true, + GET_IMEM_TAG(ucode_header[APP_0_CODE_OFFSET])); + if (err != 0) { + nvgpu_err(g, "HS ucode secure code to IMEM failed"); + goto exit; + } + + /* load DMEM: ensure that signatures are patched */ + err = nvgpu_falcon_copy_to_dmem(flcn, 0U, (u8 *)&ucode[ + ucode_header[OS_DATA_OFFSET] >> 2U], + ucode_header[OS_DATA_SIZE], 0U); + if (err != 0) { + nvgpu_err(g, "HS ucode data copy to DMEM failed"); + goto exit; + } + + /* + * Write non-zero value to mailbox register which is updated by + * HS bin to denote its return status. + */ + nvgpu_falcon_mailbox_write(flcn, FALCON_MAILBOX_0, 0xdeadbeefU); + + /* set BOOTVEC to start of non-secure code */ + err = nvgpu_falcon_bootstrap(flcn, 0U); + if (err != 0) { + nvgpu_err(g, "HS ucode bootstrap failed err-%d on falcon-%d", err, + nvgpu_falcon_get_id(flcn)); + goto exit; + } + +exit: + return err; +} + int nvgpu_falcon_get_mem_size(struct nvgpu_falcon *flcn, enum falcon_mem_type type, u32 *size) { diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h index 9ef052d6d..89faf0e90 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h +++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h @@ -409,6 +409,21 @@ void nvgpu_falcon_mailbox_write(struct nvgpu_falcon *flcn, u32 mailbox_index, int nvgpu_falcon_bl_bootstrap(struct nvgpu_falcon *flcn, struct nvgpu_falcon_bl_info *bl_info); +/** + * @brief Bootstrap the falcon with HS ucode. + * + * @param flcn [in] The falcon + * @param ucode [in] ucode to be copied + * @param ucode_header [in] ucode header + * + * Copies HS ucode source and descriptor to IMEM and DMEM and then + * bootstraps the falcon. + * + * @return 0 in case of success, < 0 in case of failure. + */ +int nvgpu_falcon_hs_ucode_load_bootstrap(struct nvgpu_falcon *flcn, u32 *ucode, + u32 *ucode_header); + /** * @brief Get the size of falcon's memory. *