diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index fe36ab871..aa55fb6a0 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -304,6 +304,19 @@ int nvgpu_init_pmu_support(struct gk20a *g) } if (nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { + + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { + /* Reset PMU engine */ + err = nvgpu_flcn_reset(&g->pmu_flcn); + + /* Bootstrap PMU from SEC2 RTOS*/ + err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, + LSF_FALCON_ID_PMU); + if (err != 0) { + goto exit; + } + } + /* * clear halt interrupt to avoid PMU-RTOS ucode * hitting breakpoint due to PMU halt diff --git a/drivers/gpu/nvgpu/common/sec2/sec2.c b/drivers/gpu/nvgpu/common/sec2/sec2.c index 46b6e0fa6..965fde4f4 100644 --- a/drivers/gpu/nvgpu/common/sec2/sec2.c +++ b/drivers/gpu/nvgpu/common/sec2/sec2.c @@ -161,7 +161,8 @@ int nvgpu_init_sec2_support(struct gk20a *g) sec2->isr_enabled = true; nvgpu_mutex_release(&sec2->isr_mutex); - /* TBD - call SEC2 in secure mode to boot RTOS */ + /* execute SEC2 in secure mode to boot RTOS */ + g->ops.sec2.secured_sec2_start(g); exit: return err; @@ -186,3 +187,87 @@ int nvgpu_sec2_destroy(struct gk20a *g) return 0; } + +/* Add code below to handle SEC2 RTOS commands */ +/* LSF's bootstrap command */ +static void sec2_handle_lsfm_boot_acr_msg(struct gk20a *g, + struct nv_flcn_msg_sec2 *msg, + void *param, u32 handle, u32 status) +{ + bool *command_ack = param; + + nvgpu_log_fn(g, " "); + + nvgpu_sec2_dbg(g, "reply NV_SEC2_ACR_CMD_ID_BOOTSTRAP_FALCON"); + + nvgpu_sec2_dbg(g, "flcn %d: error code = %x", + msg->msg.acr.msg_flcn.falcon_id, + msg->msg.acr.msg_flcn.error_code); + + *command_ack = true; +} + +static void sec2_load_ls_falcons(struct gk20a *g, struct nvgpu_sec2 *sec2, + u32 falcon_id, u32 flags) +{ + struct nv_flcn_cmd_sec2 cmd; + bool command_ack; + u32 seq = 0; + int err = 0; + + nvgpu_log_fn(g, " "); + + /* send message to load falcon */ + memset(&cmd, 0, sizeof(struct nv_flcn_cmd_sec2)); + cmd.hdr.unit_id = NV_SEC2_UNIT_ACR; + cmd.hdr.size = PMU_CMD_HDR_SIZE + + sizeof(struct nv_sec2_acr_cmd_bootstrap_falcon); + + cmd.cmd.acr.bootstrap_falcon.cmd_type = + NV_SEC2_ACR_CMD_ID_BOOTSTRAP_FALCON; + cmd.cmd.acr.bootstrap_falcon.flags = flags; + cmd.cmd.acr.bootstrap_falcon.falcon_id = falcon_id; + + nvgpu_sec2_dbg(g, "NV_SEC2_ACR_CMD_ID_BOOTSTRAP_FALCON : %x", + falcon_id); + + command_ack = false; + err = nvgpu_sec2_cmd_post(g, &cmd, NULL, PMU_COMMAND_QUEUE_HPQ, + sec2_handle_lsfm_boot_acr_msg, &command_ack, &seq, ~0); + if (err != 0) { + nvgpu_err(g, "command post failed"); + } + + err = nvgpu_sec2_wait_message_cond(sec2, gk20a_get_gr_idle_timeout(g), + &command_ack, true); + if (err != 0) { + nvgpu_err(g, "command ack receive failed"); + } + + return; +} + +int nvgpu_sec2_bootstrap_ls_falcons(struct gk20a *g, struct nvgpu_sec2 *sec2, + u32 falcon_id) +{ + int err = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_sec2_dbg(g, "Check SEC2 RTOS is ready else wait"); + err = nvgpu_sec2_wait_message_cond(&g->sec2, gk20a_get_gr_idle_timeout(g), + &g->sec2.sec2_ready, true); + if (err != 0){ + nvgpu_err(g, "SEC2 RTOS not ready yet, failed to bootstrap flcn %d", + falcon_id); + goto exit; + } + + nvgpu_sec2_dbg(g, "LS flcn %d bootstrap, blocked call", falcon_id); + sec2_load_ls_falcons(g, sec2, falcon_id, + NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES); + +exit: + nvgpu_sec2_dbg(g, "Done, err-%x", err); + return err; +} diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index c67f78707..d091d6eef 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c @@ -805,9 +805,16 @@ int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) } else { /* bind WPR VA inst block */ gr_gk20a_load_falcon_bind_instblk(g); - err = g->ops.pmu.load_lsfalcon_ucode(g, - (1 << LSF_FALCON_ID_FECS) | - (1 << LSF_FALCON_ID_GPCCS)); + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { + err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, + LSF_FALCON_ID_FECS); + err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, + LSF_FALCON_ID_GPCCS); + } else { + err = g->ops.pmu.load_lsfalcon_ucode(g, + (1 << LSF_FALCON_ID_FECS) | + (1 << LSF_FALCON_ID_GPCCS)); + } } if (err) { nvgpu_err(g, "Unable to recover GR falcon"); @@ -829,7 +836,14 @@ int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) falcon_id_mask |= (1 << LSF_FALCON_ID_GPCCS); } - err = g->ops.pmu.load_lsfalcon_ucode(g, falcon_id_mask); + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { + err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, + LSF_FALCON_ID_FECS); + err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, + LSF_FALCON_ID_GPCCS); + } else { + err = g->ops.pmu.load_lsfalcon_ucode(g, falcon_id_mask); + } if (err) { nvgpu_err(g, "Unable to boot GPCCS"); diff --git a/drivers/gpu/nvgpu/gp106/acr_gp106.c b/drivers/gpu/nvgpu/gp106/acr_gp106.c index f5ae565a6..a74a3841b 100644 --- a/drivers/gpu/nvgpu/gp106/acr_gp106.c +++ b/drivers/gpu/nvgpu/gp106/acr_gp106.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "gm20b/mm_gm20b.h" #include "gm20b/acr_gm20b.h" @@ -594,7 +595,7 @@ int lsfm_discover_ucode_images(struct gk20a *g, /* The falon_id is formed by grabbing the static base * falon_id from the image and adding the * engine-designated falcon instance. - */ + */ pmu->pmu_mode |= PMU_SECURE_MODE; falcon_id = ucode_img.lsf_desc->falcon_id + ucode_img.flcn_inst; @@ -605,7 +606,6 @@ int lsfm_discover_ucode_images(struct gk20a *g, pmu->falcon_id) == 0) { pmu->pmu_mode |= PMU_LSFM_MANAGED; } - plsfm->managed_flcn_cnt++; } else { gp106_dbg_pmu(g, "id not managed %d\n", @@ -785,7 +785,15 @@ int gp106_flcn_populate_bl_dmem_desc(struct gk20a *g, /* Populate the LOADER_CONFIG state */ memset((void *) ldr_cfg, 0, sizeof(struct flcn_bl_dmem_desc_v1)); - ldr_cfg->ctx_dma = GK20A_PMU_DMAIDX_UCODE; + + if (falconid == LSF_FALCON_ID_SEC2) { + addr_code = addr_base + desc->app_start_offset; + ldr_cfg->ctx_dma = NV_SEC2_DMAIDX_UCODE; + ldr_cfg->non_sec_code_off = desc->app_resident_code_offset; + } else { + ldr_cfg->ctx_dma = GK20A_PMU_DMAIDX_UCODE; + } + flcn64_set_dma(&ldr_cfg->code_dma_base, addr_code); ldr_cfg->non_sec_code_size = desc->app_resident_code_size; flcn64_set_dma(&ldr_cfg->data_dma_base, addr_data); diff --git a/drivers/gpu/nvgpu/include/nvgpu/sec2.h b/drivers/gpu/nvgpu/include/nvgpu/sec2.h index 357f1a20f..ccd8e1232 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/sec2.h +++ b/drivers/gpu/nvgpu/include/nvgpu/sec2.h @@ -101,6 +101,10 @@ int nvgpu_sec2_process_message(struct nvgpu_sec2 *sec2); int nvgpu_sec2_wait_message_cond(struct nvgpu_sec2 *sec2, u32 timeout_ms, void *var, u8 val); +/* commands methods*/ +int nvgpu_sec2_bootstrap_ls_falcons(struct gk20a *g, struct nvgpu_sec2 *sec2, + u32 falcon_id); + /* sec2 init */ int nvgpu_init_sec2_support(struct gk20a *g); int nvgpu_sec2_destroy(struct gk20a *g);