xref: /linux/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c (revision b08494a8f7416e5f09907318c5460ad6f6e2a548)
1 /* SPDX-License-Identifier: MIT
2  *
3  * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
4  */
5 #include "priv.h"
6 
7 #include <linux/elf.h>
8 #include <linux/crc32.h>
9 
10 #include <subdev/fb.h>
11 #include <subdev/fsp.h>
12 
13 #include <rm/r570/nvrm/gsp.h>
14 
15 #include <nvhw/drf.h>
16 #include <nvhw/ref/gh100/dev_falcon_v4.h>
17 #include <nvhw/ref/gh100/dev_riscv_pri.h>
18 
19 int
20 gh100_gsp_fini(struct nvkm_gsp *gsp, bool suspend)
21 {
22 	struct nvkm_falcon *falcon = &gsp->falcon;
23 	int ret, time = 4000;
24 
25 	/* Shutdown RM. */
26 	ret = r535_gsp_fini(gsp, suspend);
27 	if (ret && suspend)
28 		return ret;
29 
30 	/* Wait for RISC-V to halt. */
31 	do {
32 		u32 data = nvkm_falcon_rd32(falcon, falcon->addr2 + NV_PRISCV_RISCV_CPUCTL);
33 
34 		if (NVVAL_GET(data, NV_PRISCV, RISCV_CPUCTL, HALTED))
35 			return 0;
36 
37 		usleep_range(1000, 2000);
38 	} while(time--);
39 
40 	return -ETIMEDOUT;
41 }
42 
43 static bool
44 gh100_gsp_lockdown_released(struct nvkm_gsp *gsp, u32 *mbox0)
45 {
46 	u32 data;
47 
48 	/* Wait for GSP access via BAR0 to be allowed. */
49 	*mbox0 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX0);
50 
51 	if (*mbox0 && (*mbox0 & 0xffffff00) == 0xbadf4100)
52 		return false;
53 
54 	/* Check if an error code has been reported. */
55 	if (*mbox0) {
56 		u32 mbox1 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX1);
57 
58 		/* Any value that's not GSP_FMC_BOOT_PARAMS addr is an error. */
59 		if ((((u64)mbox1 << 32) | *mbox0) != gsp->fmc.args.addr)
60 			return true;
61 	}
62 
63 	/* Check if lockdown has been released. */
64 	data = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_HWCFG2);
65 	return !NVVAL_GET(data, NV_PFALCON, FALCON_HWCFG2, RISCV_BR_PRIV_LOCKDOWN);
66 }
67 
68 int
69 gh100_gsp_init(struct nvkm_gsp *gsp)
70 {
71 	struct nvkm_subdev *subdev = &gsp->subdev;
72 	struct nvkm_device *device = subdev->device;
73 	const bool resume = gsp->sr.meta.data != NULL;
74 	struct nvkm_gsp_mem *meta;
75 	GSP_FMC_BOOT_PARAMS *args;
76 	int ret, time = 4000;
77 	u32 rsvd_size;
78 	u32 mbox0;
79 
80 	if (!resume) {
81 		ret = nvkm_gsp_mem_ctor(gsp, sizeof(*args), &gsp->fmc.args);
82 		if (ret)
83 			return ret;
84 
85 		meta = &gsp->wpr_meta;
86 	} else {
87 		gsp->rm->api->gsp->set_rmargs(gsp, true);
88 		meta = &gsp->sr.meta;
89 	}
90 
91 	args = gsp->fmc.args.data;
92 
93 	args->bootGspRmParams.gspRmDescOffset = meta->addr;
94 	args->bootGspRmParams.gspRmDescSize = meta->size;
95 	args->bootGspRmParams.target = GSP_DMA_TARGET_COHERENT_SYSTEM;
96 	args->bootGspRmParams.bIsGspRmBoot = 1;
97 
98 	args->gspRmParams.target = GSP_DMA_TARGET_NONCOHERENT_SYSTEM;
99 	args->gspRmParams.bootArgsOffset = gsp->libos.addr;
100 
101 	rsvd_size = gsp->fb.heap.size;
102 	if (gsp->rm->wpr->rsvd_size_pmu)
103 		rsvd_size = ALIGN(rsvd_size + gsp->rm->wpr->rsvd_size_pmu, 0x200000);
104 
105 	ret = nvkm_fsp_boot_gsp_fmc(device->fsp, gsp->fmc.args.addr, rsvd_size, resume,
106 				    gsp->fmc.fw.addr, gsp->fmc.hash, gsp->fmc.pkey, gsp->fmc.sig);
107 	if (ret)
108 		return ret;
109 
110 	do {
111 		if (gh100_gsp_lockdown_released(gsp, &mbox0))
112 			break;
113 
114 		usleep_range(1000, 2000);
115 	} while(time--);
116 
117 	if (time < 0) {
118 		nvkm_error(subdev, "GSP-FMC boot timed out\n");
119 		return -ETIMEDOUT;
120 	}
121 
122 	if (mbox0) {
123 		nvkm_error(subdev, "GSP-FMC boot failed (mbox: 0x%08x)\n", mbox0);
124 		return -EIO;
125 	}
126 
127 	return r535_gsp_init(gsp);
128 }
129 
130 static int
131 gh100_gsp_wpr_meta_init(struct nvkm_gsp *gsp)
132 {
133 	GspFwWprMeta *meta;
134 	int ret;
135 
136 	ret = nvkm_gsp_mem_ctor(gsp, sizeof(*meta), &gsp->wpr_meta);
137 	if (ret)
138 		return ret;
139 
140 	gsp->fb.size = nvkm_fb_vidmem_size(gsp->subdev.device);
141 	gsp->fb.bios.vga_workspace.size = 128 * 1024;
142 	gsp->fb.heap.size = gsp->rm->wpr->heap_size_non_wpr;
143 
144 	meta = gsp->wpr_meta.data;
145 
146 	meta->magic = GSP_FW_WPR_META_MAGIC;
147 	meta->revision = GSP_FW_WPR_META_REVISION;
148 
149 	meta->sizeOfRadix3Elf = gsp->fw.len;
150 	meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr;
151 
152 	meta->sizeOfBootloader = gsp->boot.fw.size;
153 	meta->sysmemAddrOfBootloader = gsp->boot.fw.addr;
154 	meta->bootloaderCodeOffset = gsp->boot.code_offset;
155 	meta->bootloaderDataOffset = gsp->boot.data_offset;
156 	meta->bootloaderManifestOffset = gsp->boot.manifest_offset;
157 
158 	meta->sysmemAddrOfSignature = gsp->sig.addr;
159 	meta->sizeOfSignature = gsp->sig.size;
160 
161 	meta->nonWprHeapSize = gsp->fb.heap.size;
162 	meta->gspFwHeapSize = tu102_gsp_wpr_heap_size(gsp);
163 	meta->frtsSize = 0x100000;
164 	meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size;
165 	meta->pmuReservedSize = gsp->rm->wpr->rsvd_size_pmu;
166 	return 0;
167 }
168 
169 /* The sh_flags value for the binary blobs in the ELF image */
170 #define FMC_SHF_FLAGS (SHF_MASKPROC | SHF_MASKOS | SHF_OS_NONCONFORMING | SHF_ALLOC)
171 
172 #define ELF_HDR_SIZE ((u8)sizeof(struct elf32_hdr))
173 #define ELF_SHDR_SIZE ((u8)sizeof(struct elf32_shdr))
174 
175 /* The FMC ELF header must be exactly this */
176 static const u8 elf_header[] = {
177 	0x7f, 'E', 'L', 'F', 1, 1, 1, 0,
178 	0, 0, 0, 0, 0, 0, 0, 0,
179 
180 	0, 0, 0, 0, 1, 0, 0, 0, /* e_type, e_machine, e_version */
181 	0, 0, 0, 0, 0, 0, 0, 0, /* e_entry, e_phoff */
182 
183 	ELF_HDR_SIZE, 0, 0, 0, 0, 0, 0, 0, /* e_shoff, e_flags */
184 	ELF_HDR_SIZE, 0, 0, 0, /* e_ehsize, e_phentsize */
185 	0, 0, ELF_SHDR_SIZE, 0, /* e_phnum, e_shentsize */
186 
187 	6, 0, 1, 0, /* e_shnum, e_shstrndx */
188 };
189 
190 /**
191  * elf_validate_sections - validate each section in the FMC ELF image
192  * @elf: ELF image
193  * @length: size of the entire ELF image
194  */
195 static bool
196 elf_validate_sections(const void *elf, size_t length)
197 {
198 	const struct elf32_hdr *ehdr = elf;
199 	const struct elf32_shdr *shdr = elf + ehdr->e_shoff;
200 
201 	/* The offset of the first section */
202 	Elf32_Off section_begin = ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize;
203 
204 	if (section_begin > length)
205 		return false;
206 
207 	/* The first section header is the null section, so skip it */
208 	for (unsigned int i = 1; i < ehdr->e_shnum; i++) {
209 		if (i == ehdr->e_shstrndx) {
210 			if (shdr[i].sh_type != SHT_STRTAB)
211 				return false;
212 			if (shdr[i].sh_flags != SHF_STRINGS)
213 				return false;
214 		} else {
215 			if (shdr[i].sh_type != SHT_PROGBITS)
216 				return false;
217 			if (shdr[i].sh_flags != FMC_SHF_FLAGS)
218 				return false;
219 		}
220 
221 		/* Ensure that each section is inside the image */
222 		if (shdr[i].sh_offset < section_begin ||
223 		    (u64)shdr[i].sh_offset + shdr[i].sh_size > length)
224 			return false;
225 
226 		/* Non-zero sh_info is a CRC */
227 		if (shdr[i].sh_info) {
228 			/* The kernel's CRC32 needs a pre- and post-xor to match standard CRCs */
229 			u32 crc32 = crc32_le(~0, elf + shdr[i].sh_offset, shdr[i].sh_size) ^ ~0;
230 
231 			if (shdr[i].sh_info != crc32)
232 				return false;
233 		}
234 	}
235 
236 	return true;
237 }
238 
239 /**
240  * elf_section - return a pointer to the data for a given section
241  * @elf: ELF image
242  * @name: section name to search for
243  * @len: pointer to returned length of found section
244  */
245 static const void *
246 elf_section(const void *elf, const char *name, unsigned int *len)
247 {
248 	const struct elf32_hdr *ehdr = elf;
249 	const struct elf32_shdr *shdr = elf + ehdr->e_shoff;
250 	const char *names = elf + shdr[ehdr->e_shstrndx].sh_offset;
251 
252 	for (unsigned int i = 1; i < ehdr->e_shnum; i++) {
253 		if (!strcmp(&names[shdr[i].sh_name], name)) {
254 			*len = shdr[i].sh_size;
255 			return elf + shdr[i].sh_offset;
256 		}
257 	}
258 
259 	return NULL;
260 }
261 
262 int
263 gh100_gsp_oneinit(struct nvkm_gsp *gsp)
264 {
265 	struct nvkm_subdev *subdev = &gsp->subdev;
266 	struct nvkm_device *device = subdev->device;
267 	struct nvkm_fsp *fsp = device->fsp;
268 	const void *fw = gsp->fws.fmc->data;
269 	const void *hash, *sig, *pkey, *img;
270 	unsigned int img_len = 0, hash_len = 0, pkey_len = 0, sig_len = 0;
271 	int ret;
272 
273 	if (gsp->fws.fmc->size < ELF_HDR_SIZE ||
274 	    memcmp(fw, elf_header, sizeof(elf_header)) ||
275 	    !elf_validate_sections(fw, gsp->fws.fmc->size)) {
276 		nvkm_error(subdev, "fmc firmware image is invalid\n");
277 		return -ENODATA;
278 	}
279 
280 	hash = elf_section(fw, "hash", &hash_len);
281 	sig = elf_section(fw, "signature", &sig_len);
282 	pkey = elf_section(fw, "publickey", &pkey_len);
283 	img = elf_section(fw, "image", &img_len);
284 
285 	if (!hash || !sig || !pkey || !img) {
286 		nvkm_error(subdev, "fmc firmware image is invalid\n");
287 		return -ENODATA;
288 	}
289 
290 	if (!nvkm_fsp_verify_gsp_fmc(fsp, hash_len, pkey_len, sig_len))
291 		return -EINVAL;
292 
293 	/* Load GSP-FMC FW into memory. */
294 	ret = nvkm_gsp_mem_ctor(gsp, img_len, &gsp->fmc.fw);
295 	if (ret)
296 		return ret;
297 
298 	memcpy(gsp->fmc.fw.data, img, img_len);
299 
300 	gsp->fmc.hash = kmemdup(hash, hash_len, GFP_KERNEL);
301 	gsp->fmc.pkey = kmemdup(pkey, pkey_len, GFP_KERNEL);
302 	gsp->fmc.sig = kmemdup(sig, sig_len, GFP_KERNEL);
303 	if (!gsp->fmc.hash || !gsp->fmc.pkey || !gsp->fmc.sig)
304 		return -ENOMEM;
305 
306 	ret = r535_gsp_oneinit(gsp);
307 	if (ret)
308 		return ret;
309 
310 	return gh100_gsp_wpr_meta_init(gsp);
311 }
312 
313 static const struct nvkm_gsp_func
314 gh100_gsp = {
315 	.flcn = &ga102_gsp_flcn,
316 
317 	.sig_section = ".fwsignature_gh100",
318 
319 	.dtor = r535_gsp_dtor,
320 	.oneinit = gh100_gsp_oneinit,
321 	.init = gh100_gsp_init,
322 	.fini = gh100_gsp_fini,
323 
324 	.rm.gpu = &gh100_gpu,
325 };
326 
327 int
328 gh100_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif)
329 {
330 	int ret;
331 
332 	ret = tu102_gsp_load_rm(gsp, fwif);
333 	if (ret)
334 		goto done;
335 
336 	ret = nvkm_gsp_load_fw(gsp, "fmc", fwif->ver, &gsp->fws.fmc);
337 
338 done:
339 	if (ret)
340 		nvkm_gsp_dtor_fws(gsp);
341 
342 	return ret;
343 }
344 
345 static struct nvkm_gsp_fwif
346 gh100_gsps[] = {
347 	{ 0, gh100_gsp_load, &gh100_gsp, &r570_rm_gh100, "570.144", true },
348 	{}
349 };
350 
351 int
352 gh100_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
353 	      struct nvkm_gsp **pgsp)
354 {
355 	return nvkm_gsp_new_(gh100_gsps, device, type, inst, pgsp);
356 }
357 
358 NVKM_GSP_FIRMWARE_FMC(gh100, 570.144);
359