1 /* 2 * Copyright 2021 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 #include "priv.h" 23 #include <subdev/acr.h> 24 #include <subdev/gsp.h> 25 #include <subdev/vfn.h> 26 27 #include <nvfw/flcn.h> 28 #include <nvfw/sec2.h> 29 30 static int 31 ga102_sec2_initmsg(struct nvkm_sec2 *sec2) 32 { 33 struct nv_sec2_init_msg_v1 msg; 34 int ret, i; 35 36 ret = nvkm_falcon_msgq_recv_initmsg(sec2->msgq, &msg, sizeof(msg)); 37 if (ret) 38 return ret; 39 40 if (msg.hdr.unit_id != NV_SEC2_UNIT_INIT || 41 msg.msg_type != NV_SEC2_INIT_MSG_INIT) 42 return -EINVAL; 43 44 for (i = 0; i < ARRAY_SIZE(msg.queue_info); i++) { 45 if (msg.queue_info[i].id == NV_SEC2_INIT_MSG_QUEUE_ID_MSGQ) { 46 nvkm_falcon_msgq_init(sec2->msgq, msg.queue_info[i].index, 47 msg.queue_info[i].offset, 48 msg.queue_info[i].size); 49 } else { 50 nvkm_falcon_cmdq_init(sec2->cmdq, msg.queue_info[i].index, 51 msg.queue_info[i].offset, 52 msg.queue_info[i].size); 53 } 54 } 55 56 return 0; 57 } 58 59 static struct nvkm_intr * 60 ga102_sec2_intr_vector(struct nvkm_sec2 *sec2, enum nvkm_intr_type *pvector) 61 { 62 struct nvkm_device *device = sec2->engine.subdev.device; 63 struct nvkm_falcon *falcon = &sec2->falcon; 64 int ret; 65 66 ret = ga102_flcn_select(falcon); 67 if (ret) 68 return ERR_PTR(ret); 69 70 *pvector = nvkm_rd32(device, 0x8403e0) & 0x000000ff; 71 return &device->vfn->intr; 72 } 73 74 static int 75 ga102_sec2_acr_bootstrap_falcon_callback(void *priv, struct nvfw_falcon_msg *hdr) 76 { 77 struct nv_sec2_acr_bootstrap_falcon_msg_v1 *msg = 78 container_of(hdr, typeof(*msg), msg.hdr); 79 struct nvkm_subdev *subdev = priv; 80 const char *name = nvkm_acr_lsf_id(msg->falcon_id); 81 82 if (msg->error_code) { 83 nvkm_error(subdev, "ACR_BOOTSTRAP_FALCON failed for falcon %d [%s]: %08x %08x\n", 84 msg->falcon_id, name, msg->error_code, msg->unkn08); 85 return -EINVAL; 86 } 87 88 nvkm_debug(subdev, "%s booted\n", name); 89 return 0; 90 } 91 92 static int 93 ga102_sec2_acr_bootstrap_falcon(struct nvkm_falcon *falcon, enum nvkm_acr_lsf_id id) 94 { 95 struct nvkm_sec2 *sec2 = container_of(falcon, typeof(*sec2), falcon); 96 struct nv_sec2_acr_bootstrap_falcon_cmd_v1 cmd = { 97 .cmd.hdr.unit_id = sec2->func->unit_acr, 98 .cmd.hdr.size = sizeof(cmd), 99 .cmd.cmd_type = NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON, 100 .flags = NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_YES, 101 .falcon_id = id, 102 }; 103 104 return nvkm_falcon_cmdq_send(sec2->cmdq, &cmd.cmd.hdr, 105 ga102_sec2_acr_bootstrap_falcon_callback, 106 &sec2->engine.subdev, 107 msecs_to_jiffies(1000)); 108 } 109 110 static const struct nvkm_acr_lsf_func 111 ga102_sec2_acr_0 = { 112 .bld_size = sizeof(struct flcn_bl_dmem_desc_v2), 113 .bld_write = gp102_sec2_acr_bld_write_1, 114 .bld_patch = gp102_sec2_acr_bld_patch_1, 115 .bootstrap_falcons = BIT_ULL(NVKM_ACR_LSF_FECS) | 116 BIT_ULL(NVKM_ACR_LSF_GPCCS) | 117 BIT_ULL(NVKM_ACR_LSF_SEC2), 118 .bootstrap_falcon = ga102_sec2_acr_bootstrap_falcon, 119 }; 120 121 static const struct nvkm_falcon_func 122 ga102_sec2_flcn = { 123 .disable = gm200_flcn_disable, 124 .enable = gm200_flcn_enable, 125 .select = ga102_flcn_select, 126 .addr2 = 0x1000, 127 .reset_pmc = true, 128 .reset_eng = gp102_flcn_reset_eng, 129 .reset_prep = ga102_flcn_reset_prep, 130 .reset_wait_mem_scrubbing = ga102_flcn_reset_wait_mem_scrubbing, 131 .imem_dma = &ga102_flcn_dma, 132 .dmem_pio = &gm200_flcn_dmem_pio, 133 .dmem_dma = &ga102_flcn_dma, 134 .emem_addr = 0x01000000, 135 .emem_pio = &gp102_flcn_emem_pio, 136 .start = nvkm_falcon_v1_start, 137 .cmdq = { 0xc00, 0xc04, 8 }, 138 .msgq = { 0xc80, 0xc84, 8 }, 139 }; 140 141 static const struct nvkm_sec2_func 142 ga102_sec2 = { 143 .flcn = &ga102_sec2_flcn, 144 .intr_vector = ga102_sec2_intr_vector, 145 .intr = gp102_sec2_intr, 146 .initmsg = ga102_sec2_initmsg, 147 .unit_acr = NV_SEC2_UNIT_V2_ACR, 148 .unit_unload = NV_SEC2_UNIT_V2_UNLOAD, 149 }; 150 151 MODULE_FIRMWARE("nvidia/ga102/sec2/desc.bin"); 152 MODULE_FIRMWARE("nvidia/ga102/sec2/image.bin"); 153 MODULE_FIRMWARE("nvidia/ga102/sec2/sig.bin"); 154 MODULE_FIRMWARE("nvidia/ga102/sec2/hs_bl_sig.bin"); 155 156 MODULE_FIRMWARE("nvidia/ga103/sec2/desc.bin"); 157 MODULE_FIRMWARE("nvidia/ga103/sec2/image.bin"); 158 MODULE_FIRMWARE("nvidia/ga103/sec2/sig.bin"); 159 MODULE_FIRMWARE("nvidia/ga103/sec2/hs_bl_sig.bin"); 160 161 MODULE_FIRMWARE("nvidia/ga104/sec2/desc.bin"); 162 MODULE_FIRMWARE("nvidia/ga104/sec2/image.bin"); 163 MODULE_FIRMWARE("nvidia/ga104/sec2/sig.bin"); 164 MODULE_FIRMWARE("nvidia/ga104/sec2/hs_bl_sig.bin"); 165 166 MODULE_FIRMWARE("nvidia/ga106/sec2/desc.bin"); 167 MODULE_FIRMWARE("nvidia/ga106/sec2/image.bin"); 168 MODULE_FIRMWARE("nvidia/ga106/sec2/sig.bin"); 169 MODULE_FIRMWARE("nvidia/ga106/sec2/hs_bl_sig.bin"); 170 171 MODULE_FIRMWARE("nvidia/ga107/sec2/desc.bin"); 172 MODULE_FIRMWARE("nvidia/ga107/sec2/image.bin"); 173 MODULE_FIRMWARE("nvidia/ga107/sec2/sig.bin"); 174 MODULE_FIRMWARE("nvidia/ga107/sec2/hs_bl_sig.bin"); 175 176 static int 177 ga102_sec2_load(struct nvkm_sec2 *sec2, int ver, 178 const struct nvkm_sec2_fwif *fwif) 179 { 180 return nvkm_acr_lsfw_load_sig_image_desc_v2(&sec2->engine.subdev, &sec2->falcon, 181 NVKM_ACR_LSF_SEC2, "sec2/", ver, fwif->acr); 182 } 183 184 static const struct nvkm_sec2_fwif 185 ga102_sec2_fwif[] = { 186 { 0, ga102_sec2_load, &ga102_sec2, &ga102_sec2_acr_0 }, 187 { -1, gp102_sec2_nofw, &ga102_sec2 } 188 }; 189 190 int 191 ga102_sec2_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, 192 struct nvkm_sec2 **psec2) 193 { 194 /* TOP info wasn't updated on Turing to reflect the PRI 195 * address change for some reason. We override it here. 196 */ 197 const u32 addr = 0x840000; 198 199 if (nvkm_gsp_rm(device->gsp)) 200 return r535_sec2_new(&ga102_sec2, device, type, inst, addr, psec2); 201 202 return nvkm_sec2_new_(ga102_sec2_fwif, device, type, inst, addr, psec2); 203 } 204