summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2016-05-23 06:42:11 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-05-26 19:04:25 -0400
commite9d5e7dfca6ac2fa7af380ceea0a0ca4ac3827c6 (patch)
tree1b46893ce4b27ef947937162eb3f3782ca3f39a2 /drivers/gpu/nvgpu/gm20b/acr_gm20b.c
parentad24c028dba639cebefc3326f925e62c3724a59e (diff)
gpu: nvgpu: secure boot HAL update
Updated/added secure boot HAL with methods required to support multiple GPU chips. JIRA DNVGPU-10 Change-Id: I343b289f2236fd6a6b0ecf9115367ce19990e7d5 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1151784 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/acr_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c153
1 files changed, 119 insertions, 34 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index 3ac2cec8..ea4500eb 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -36,6 +36,14 @@ typedef int (*get_ucode_details)(struct gk20a *g, struct flcn_ucode_img *udata);
36/*Externs*/ 36/*Externs*/
37 37
38/*Forwards*/ 38/*Forwards*/
39static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img);
40static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img);
41static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img);
42static int gm20b_bootstrap_hs_flcn(struct gk20a *g);
43static int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout);
44static int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout);
45static int gm20b_init_pmu_setup_hw1(struct gk20a *g,
46 struct flcn_bl_dmem_desc *desc, u32 bl_sz);
39static int lsfm_discover_ucode_images(struct gk20a *g, 47static int lsfm_discover_ucode_images(struct gk20a *g,
40 struct ls_flcn_mgr *plsfm); 48 struct ls_flcn_mgr *plsfm);
41static int lsfm_add_ucode_img(struct gk20a *g, struct ls_flcn_mgr *plsfm, 49static int lsfm_add_ucode_img(struct gk20a *g, struct ls_flcn_mgr *plsfm,
@@ -45,13 +53,18 @@ static void lsfm_free_nonpmu_ucode_img_res(struct flcn_ucode_img *p_img);
45static int lsf_gen_wpr_requirements(struct gk20a *g, struct ls_flcn_mgr *plsfm); 53static int lsf_gen_wpr_requirements(struct gk20a *g, struct ls_flcn_mgr *plsfm);
46static void lsfm_init_wpr_contents(struct gk20a *g, struct ls_flcn_mgr *plsfm, 54static void lsfm_init_wpr_contents(struct gk20a *g, struct ls_flcn_mgr *plsfm,
47 struct mem_desc *nonwpr); 55 struct mem_desc *nonwpr);
48static int acr_ucode_patch_sig(struct gk20a *g,
49 unsigned int *p_img,
50 unsigned int *p_prod_sig,
51 unsigned int *p_dbg_sig,
52 unsigned int *p_patch_loc,
53 unsigned int *p_patch_ind);
54static void free_acr_resources(struct gk20a *g, struct ls_flcn_mgr *plsfm); 56static void free_acr_resources(struct gk20a *g, struct ls_flcn_mgr *plsfm);
57static int gm20b_pmu_populate_loader_cfg(struct gk20a *g,
58 struct lsfm_managed_ucode_img *lsfm,
59 union flcn_bl_generic_desc *p_bl_gen_desc, u32 *p_bl_gen_desc_size);
60static int gm20b_flcn_populate_bl_dmem_desc(struct gk20a *g,
61 struct lsfm_managed_ucode_img *lsfm,
62 union flcn_bl_generic_desc *p_bl_gen_desc, u32 *p_bl_gen_desc_size,
63 u32 falconid);
64static int gm20b_alloc_blob_space(struct gk20a *g,
65 size_t size, struct mem_desc *mem);
66static bool gm20b_is_priv_load(u32 falcon_id);
67static bool gm20b_is_lazy_bootstrap(u32 falcon_id);
55 68
56/*Globals*/ 69/*Globals*/
57static get_ucode_details pmu_acr_supp_ucode_list[] = { 70static get_ucode_details pmu_acr_supp_ucode_list[] = {
@@ -72,14 +85,33 @@ static void start_gm20b_pmu(struct gk20a *g)
72 pwr_falcon_cpuctl_startcpu_f(1)); 85 pwr_falcon_cpuctl_startcpu_f(1));
73} 86}
74 87
88void gm20b_wpr_info(struct gk20a *g, u64 *base, u64 *size)
89{
90 struct mc_carveout_info inf;
91
92 mc_get_carveout_info(&inf, NULL, MC_SECURITY_CARVEOUT2);
93 *base = inf.base;
94 *size = inf.size;
95}
96
75void gm20b_init_secure_pmu(struct gpu_ops *gops) 97void gm20b_init_secure_pmu(struct gpu_ops *gops)
76{ 98{
77 gops->pmu.prepare_ucode = prepare_ucode_blob; 99 gops->pmu.prepare_ucode = prepare_ucode_blob;
78 gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_bootstrap_hs_flcn; 100 gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_bootstrap_hs_flcn;
101 gops->pmu.is_lazy_bootstrap = gm20b_is_lazy_bootstrap;
102 gops->pmu.is_priv_load = gm20b_is_priv_load;
103 gops->pmu.get_wpr = gm20b_wpr_info;
104 gops->pmu.alloc_blob_space = gm20b_alloc_blob_space;
105 gops->pmu.pmu_populate_loader_cfg = gm20b_pmu_populate_loader_cfg;
106 gops->pmu.flcn_populate_bl_dmem_desc = gm20b_flcn_populate_bl_dmem_desc;
107 gops->pmu.falcon_wait_for_halt = pmu_wait_for_halt;
108 gops->pmu.falcon_clear_halt_interrupt_status =
109 clear_halt_interrupt_status;
110 gops->pmu.init_falcon_setup_hw = gm20b_init_pmu_setup_hw1;
79} 111}
80/* TODO - check if any free blob res needed*/ 112/* TODO - check if any free blob res needed*/
81 113
82int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 114static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
83{ 115{
84 const struct firmware *pmu_fw, *pmu_desc, *pmu_sig; 116 const struct firmware *pmu_fw, *pmu_desc, *pmu_sig;
85 struct pmu_gk20a *pmu = &g->pmu; 117 struct pmu_gk20a *pmu = &g->pmu;
@@ -143,7 +175,7 @@ release_img_fw:
143 return err; 175 return err;
144} 176}
145 177
146int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 178static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
147{ 179{
148 struct lsf_ucode_desc *lsf_desc; 180 struct lsf_ucode_desc *lsf_desc;
149 const struct firmware *fecs_sig; 181 const struct firmware *fecs_sig;
@@ -210,7 +242,7 @@ rel_sig:
210 release_firmware(fecs_sig); 242 release_firmware(fecs_sig);
211 return err; 243 return err;
212} 244}
213int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 245static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
214{ 246{
215 struct lsf_ucode_desc *lsf_desc; 247 struct lsf_ucode_desc *lsf_desc;
216 const struct firmware *gpccs_sig; 248 const struct firmware *gpccs_sig;
@@ -282,6 +314,52 @@ rel_sig:
282 return err; 314 return err;
283} 315}
284 316
317static bool gm20b_is_lazy_bootstrap(u32 falcon_id)
318{
319 bool enable_status = false;
320
321 switch (falcon_id) {
322 case LSF_FALCON_ID_FECS:
323 enable_status = false;
324 break;
325 case LSF_FALCON_ID_GPCCS:
326 enable_status = false;
327 break;
328 default:
329 break;
330 }
331
332 return enable_status;
333}
334
335static bool gm20b_is_priv_load(u32 falcon_id)
336{
337 bool enable_status = false;
338
339 switch (falcon_id) {
340 case LSF_FALCON_ID_FECS:
341 enable_status = false;
342 break;
343 case LSF_FALCON_ID_GPCCS:
344 enable_status = false;
345 break;
346 default:
347 break;
348 }
349
350 return enable_status;
351}
352
353static int gm20b_alloc_blob_space(struct gk20a *g,
354 size_t size, struct mem_desc *mem)
355{
356 int err;
357
358 err = gk20a_gmmu_alloc(g, size, mem);
359
360 return err;
361}
362
285int prepare_ucode_blob(struct gk20a *g) 363int prepare_ucode_blob(struct gk20a *g)
286{ 364{
287 365
@@ -312,11 +390,12 @@ int prepare_ucode_blob(struct gk20a *g)
312 gm20b_mm_mmu_vpr_info_fetch(g); 390 gm20b_mm_mmu_vpr_info_fetch(g);
313 gr_gk20a_init_ctxsw_ucode(g); 391 gr_gk20a_init_ctxsw_ucode(g);
314 392
315 mc_get_carveout_info(&inf, NULL, MC_SECURITY_CARVEOUT2); 393 g->ops.pmu.get_wpr(g, &inf.base, &inf.size);
316 gm20b_dbg_pmu("wpr carveout base:%llx\n", inf.base);
317 wpr_addr = (phys_addr_t)inf.base; 394 wpr_addr = (phys_addr_t)inf.base;
318 gm20b_dbg_pmu("wpr carveout size :%llx\n", inf.size);
319 wprsize = (u32)inf.size; 395 wprsize = (u32)inf.size;
396 gm20b_dbg_pmu("wpr carveout base:%llx\n", inf.base);
397 gm20b_dbg_pmu("wpr carveout size :%x\n", wprsize);
398
320 sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); 399 sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
321 if (!sgt) { 400 if (!sgt) {
322 gk20a_err(dev_from_gk20a(g), "failed to allocate memory\n"); 401 gk20a_err(dev_from_gk20a(g), "failed to allocate memory\n");
@@ -349,7 +428,8 @@ int prepare_ucode_blob(struct gk20a *g)
349 goto free_sgt; 428 goto free_sgt;
350 429
351 /*Alloc memory to hold ucode blob contents*/ 430 /*Alloc memory to hold ucode blob contents*/
352 err = gk20a_gmmu_alloc(g, plsfm->wpr_size, &g->acr.ucode_blob); 431 err = g->ops.pmu.alloc_blob_space(g, plsfm->wpr_size
432 , &g->acr.ucode_blob);
353 if (err) 433 if (err)
354 goto free_sgt; 434 goto free_sgt;
355 435
@@ -458,7 +538,7 @@ static int lsfm_discover_ucode_images(struct gk20a *g,
458} 538}
459 539
460 540
461static int pmu_populate_loader_cfg(struct gk20a *g, 541static int gm20b_pmu_populate_loader_cfg(struct gk20a *g,
462 struct lsfm_managed_ucode_img *lsfm, 542 struct lsfm_managed_ucode_img *lsfm,
463 union flcn_bl_generic_desc *p_bl_gen_desc, u32 *p_bl_gen_desc_size) 543 union flcn_bl_generic_desc *p_bl_gen_desc, u32 *p_bl_gen_desc_size)
464{ 544{
@@ -485,7 +565,7 @@ static int pmu_populate_loader_cfg(struct gk20a *g,
485 physical addresses of each respective segment. 565 physical addresses of each respective segment.
486 */ 566 */
487 addr_base = lsfm->lsb_header.ucode_off; 567 addr_base = lsfm->lsb_header.ucode_off;
488 mc_get_carveout_info(&inf, NULL, MC_SECURITY_CARVEOUT2); 568 g->ops.pmu.get_wpr(g, &inf.base, &inf.size);
489 addr_base += inf.base; 569 addr_base += inf.base;
490 gm20b_dbg_pmu("pmu loader cfg u32 addrbase %x\n", (u32)addr_base); 570 gm20b_dbg_pmu("pmu loader cfg u32 addrbase %x\n", (u32)addr_base);
491 /*From linux*/ 571 /*From linux*/
@@ -530,7 +610,7 @@ static int pmu_populate_loader_cfg(struct gk20a *g,
530 return 0; 610 return 0;
531} 611}
532 612
533static int flcn_populate_bl_dmem_desc(struct gk20a *g, 613static int gm20b_flcn_populate_bl_dmem_desc(struct gk20a *g,
534 struct lsfm_managed_ucode_img *lsfm, 614 struct lsfm_managed_ucode_img *lsfm,
535 union flcn_bl_generic_desc *p_bl_gen_desc, u32 *p_bl_gen_desc_size, 615 union flcn_bl_generic_desc *p_bl_gen_desc, u32 *p_bl_gen_desc_size,
536 u32 falconid) 616 u32 falconid)
@@ -557,13 +637,13 @@ static int flcn_populate_bl_dmem_desc(struct gk20a *g,
557 physical addresses of each respective segment. 637 physical addresses of each respective segment.
558 */ 638 */
559 addr_base = lsfm->lsb_header.ucode_off; 639 addr_base = lsfm->lsb_header.ucode_off;
560 mc_get_carveout_info(&inf, NULL, MC_SECURITY_CARVEOUT2); 640 g->ops.pmu.get_wpr(g, &inf.base, &inf.size);
561 if (falconid == LSF_FALCON_ID_GPCCS) 641 if (falconid == LSF_FALCON_ID_GPCCS)
562 addr_base += g->pmu.wpr_buf.gpu_va; 642 addr_base += g->pmu.wpr_buf.gpu_va;
563 else 643 else
564 addr_base += inf.base; 644 addr_base += inf.base;
565 gm20b_dbg_pmu("gen loader cfg %x u32 addrbase %x ID\n", (u32)addr_base, 645 gm20b_dbg_pmu("gen loader cfg %x u32 addrbase %x ID\n", (u32)addr_base,
566 lsfm->wpr_header.falcon_id); 646 lsfm->wpr_header.falcon_id);
567 addr_code = u64_lo32((addr_base + 647 addr_code = u64_lo32((addr_base +
568 desc->app_start_offset + 648 desc->app_start_offset +
569 desc->app_resident_code_offset) >> 8); 649 desc->app_resident_code_offset) >> 8);
@@ -595,16 +675,17 @@ static int lsfm_fill_flcn_bl_gen_desc(struct gk20a *g,
595 struct pmu_gk20a *pmu = &g->pmu; 675 struct pmu_gk20a *pmu = &g->pmu;
596 if (pnode->wpr_header.falcon_id != pmu->falcon_id) { 676 if (pnode->wpr_header.falcon_id != pmu->falcon_id) {
597 gm20b_dbg_pmu("non pmu. write flcn bl gen desc\n"); 677 gm20b_dbg_pmu("non pmu. write flcn bl gen desc\n");
598 flcn_populate_bl_dmem_desc(g, pnode, &pnode->bl_gen_desc, 678 g->ops.pmu.flcn_populate_bl_dmem_desc(g,
599 &pnode->bl_gen_desc_size, 679 pnode, &pnode->bl_gen_desc,
600 pnode->wpr_header.falcon_id); 680 &pnode->bl_gen_desc_size,
681 pnode->wpr_header.falcon_id);
601 return 0; 682 return 0;
602 } 683 }
603 684
604 if (pmu->pmu_mode & PMU_LSFM_MANAGED) { 685 if (pmu->pmu_mode & PMU_LSFM_MANAGED) {
605 gm20b_dbg_pmu("pmu write flcn bl gen desc\n"); 686 gm20b_dbg_pmu("pmu write flcn bl gen desc\n");
606 if (pnode->wpr_header.falcon_id == pmu->falcon_id) 687 if (pnode->wpr_header.falcon_id == pmu->falcon_id)
607 return pmu_populate_loader_cfg(g, pnode, 688 return g->ops.pmu.pmu_populate_loader_cfg(g, pnode,
608 &pnode->bl_gen_desc, &pnode->bl_gen_desc_size); 689 &pnode->bl_gen_desc, &pnode->bl_gen_desc_size);
609 } 690 }
610 691
@@ -808,7 +889,8 @@ static void lsfm_fill_static_lsb_hdr_info(struct gk20a *g,
808 data = NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE; 889 data = NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE;
809 pnode->lsb_header.flags = data; 890 pnode->lsb_header.flags = data;
810 } 891 }
811 if (falcon_id == LSF_FALCON_ID_GPCCS) { 892
893 if (g->ops.pmu.is_priv_load(falcon_id)) {
812 pnode->lsb_header.flags |= 894 pnode->lsb_header.flags |=
813 NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE; 895 NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE;
814 } 896 }
@@ -833,8 +915,8 @@ static int lsfm_add_ucode_img(struct gk20a *g, struct ls_flcn_mgr *plsfm,
833 pnode->wpr_header.bootstrap_owner = LSF_BOOTSTRAP_OWNER_DEFAULT; 915 pnode->wpr_header.bootstrap_owner = LSF_BOOTSTRAP_OWNER_DEFAULT;
834 pnode->wpr_header.status = LSF_IMAGE_STATUS_COPY; 916 pnode->wpr_header.status = LSF_IMAGE_STATUS_COPY;
835 917
836 if (falcon_id == LSF_FALCON_ID_GPCCS) 918 pnode->wpr_header.lazy_bootstrap =
837 pnode->wpr_header.lazy_bootstrap = 1; 919 g->ops.pmu.is_lazy_bootstrap(falcon_id);
838 920
839 /*TODO to check if PDB_PROP_FLCN_LAZY_BOOTSTRAP is to be supported by 921 /*TODO to check if PDB_PROP_FLCN_LAZY_BOOTSTRAP is to be supported by
840 Android */ 922 Android */
@@ -1090,8 +1172,7 @@ static u8 pmu_is_debug_mode_en(struct gk20a *g)
1090/* 1172/*
1091 * @brief Patch signatures into ucode image 1173 * @brief Patch signatures into ucode image
1092 */ 1174 */
1093static int 1175int acr_ucode_patch_sig(struct gk20a *g,
1094acr_ucode_patch_sig(struct gk20a *g,
1095 unsigned int *p_img, 1176 unsigned int *p_img,
1096 unsigned int *p_prod_sig, 1177 unsigned int *p_prod_sig,
1097 unsigned int *p_dbg_sig, 1178 unsigned int *p_dbg_sig,
@@ -1231,7 +1312,7 @@ static int gm20b_init_pmu_setup_hw1(struct gk20a *g,
1231 gk20a_dbg_fn(""); 1312 gk20a_dbg_fn("");
1232 1313
1233 mutex_lock(&pmu->isr_mutex); 1314 mutex_lock(&pmu->isr_mutex);
1234 pmu_reset(pmu); 1315 g->ops.pmu.reset(g);
1235 pmu->isr_enabled = true; 1316 pmu->isr_enabled = true;
1236 mutex_unlock(&pmu->isr_mutex); 1317 mutex_unlock(&pmu->isr_mutex);
1237 1318
@@ -1346,20 +1427,24 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1346 * to PMU halt 1427 * to PMU halt
1347 */ 1428 */
1348 1429
1349 if (clear_halt_interrupt_status(g, gk20a_get_gr_idle_timeout(g))) 1430 if (g->ops.pmu.falcon_clear_halt_interrupt_status(g,
1431 gk20a_get_gr_idle_timeout(g)))
1350 goto err_unmap_bl; 1432 goto err_unmap_bl;
1351 1433
1352 gm20b_dbg_pmu("phys sec reg %x\n", gk20a_readl(g, 1434 gm20b_dbg_pmu("phys sec reg %x\n", gk20a_readl(g,
1353 pwr_falcon_mmu_phys_sec_r())); 1435 pwr_falcon_mmu_phys_sec_r()));
1354 gm20b_dbg_pmu("sctl reg %x\n", gk20a_readl(g, pwr_falcon_sctl_r())); 1436 gm20b_dbg_pmu("sctl reg %x\n", gk20a_readl(g, pwr_falcon_sctl_r()));
1355 1437
1356 gm20b_init_pmu_setup_hw1(g, desc, acr->hsbl_ucode.size); 1438 g->ops.pmu.init_falcon_setup_hw(g, desc, acr->hsbl_ucode.size);
1439
1357 /* Poll for HALT */ 1440 /* Poll for HALT */
1358 if (b_wait_for_halt) { 1441 if (b_wait_for_halt) {
1359 err = pmu_wait_for_halt(g, ACR_COMPLETION_TIMEOUT_MS); 1442 err = g->ops.pmu.falcon_wait_for_halt(g,
1443 ACR_COMPLETION_TIMEOUT_MS);
1360 if (err == 0) { 1444 if (err == 0) {
1361 /* Clear the HALT interrupt */ 1445 /* Clear the HALT interrupt */
1362 if (clear_halt_interrupt_status(g, gk20a_get_gr_idle_timeout(g))) 1446 if (g->ops.pmu.falcon_clear_halt_interrupt_status(g,
1447 gk20a_get_gr_idle_timeout(g)))
1363 goto err_unmap_bl; 1448 goto err_unmap_bl;
1364 } 1449 }
1365 else 1450 else
@@ -1387,7 +1472,7 @@ err_done:
1387* @param[in] timeout Timeout in msec for PMU to halt 1472* @param[in] timeout Timeout in msec for PMU to halt
1388* @return '0' if PMU halts 1473* @return '0' if PMU halts
1389*/ 1474*/
1390int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout) 1475static int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout)
1391{ 1476{
1392 u32 data = 0; 1477 u32 data = 0;
1393 int completion = -EBUSY; 1478 int completion = -EBUSY;
@@ -1424,7 +1509,7 @@ int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout)
1424* @param[in] timeout_us Timeout in msec for halt to clear 1509* @param[in] timeout_us Timeout in msec for halt to clear
1425* @return '0' if PMU halt irq status is clear 1510* @return '0' if PMU halt irq status is clear
1426*/ 1511*/
1427int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout) 1512static int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout)
1428{ 1513{
1429 u32 data = 0; 1514 u32 data = 0;
1430 unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); 1515 unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);