]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
drm/nouveau/secboot: add LS flags to LS func structure
[karo-tx-linux.git] / drivers / gpu / drm / nouveau / nvkm / subdev / secboot / acr_r352.c
1 /*
2  * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22
23 #include "acr_r352.h"
24 #include "ls_ucode.h"
25
26 #include <core/gpuobj.h>
27 #include <core/firmware.h>
28 #include <engine/falcon.h>
29
30 /**
31  * struct hsf_fw_header - HS firmware descriptor
32  * @sig_dbg_offset:     offset of the debug signature
33  * @sig_dbg_size:       size of the debug signature
34  * @sig_prod_offset:    offset of the production signature
35  * @sig_prod_size:      size of the production signature
36  * @patch_loc:          offset of the offset (sic) of where the signature is
37  * @patch_sig:          offset of the offset (sic) to add to sig_*_offset
38  * @hdr_offset:         offset of the load header (see struct hs_load_header)
39  * @hdr_size:           size of above header
40  *
41  * This structure is embedded in the HS firmware image at
42  * hs_bin_hdr.header_offset.
43  */
44 struct hsf_fw_header {
45         u32 sig_dbg_offset;
46         u32 sig_dbg_size;
47         u32 sig_prod_offset;
48         u32 sig_prod_size;
49         u32 patch_loc;
50         u32 patch_sig;
51         u32 hdr_offset;
52         u32 hdr_size;
53 };
54
55 /**
56  * struct acr_r352_flcn_bl_desc - DMEM bootloader descriptor
57  * @signature:          16B signature for secure code. 0s if no secure code
58  * @ctx_dma:            DMA context to be used by BL while loading code/data
59  * @code_dma_base:      256B-aligned Physical FB Address where code is located
60  *                      (falcon's $xcbase register)
61  * @non_sec_code_off:   offset from code_dma_base where the non-secure code is
62  *                      located. The offset must be multiple of 256 to help perf
63  * @non_sec_code_size:  the size of the nonSecure code part.
64  * @sec_code_off:       offset from code_dma_base where the secure code is
65  *                      located. The offset must be multiple of 256 to help perf
66  * @sec_code_size:      offset from code_dma_base where the secure code is
67  *                      located. The offset must be multiple of 256 to help perf
68  * @code_entry_point:   code entry point which will be invoked by BL after
69  *                      code is loaded.
70  * @data_dma_base:      256B aligned Physical FB Address where data is located.
71  *                      (falcon's $xdbase register)
72  * @data_size:          size of data block. Should be multiple of 256B
73  *
74  * Structure used by the bootloader to load the rest of the code. This has
75  * to be filled by host and copied into DMEM at offset provided in the
76  * hsflcn_bl_desc.bl_desc_dmem_load_off.
77  */
78 struct acr_r352_flcn_bl_desc {
79         u32 reserved[4];
80         u32 signature[4];
81         u32 ctx_dma;
82         u32 code_dma_base;
83         u32 non_sec_code_off;
84         u32 non_sec_code_size;
85         u32 sec_code_off;
86         u32 sec_code_size;
87         u32 code_entry_point;
88         u32 data_dma_base;
89         u32 data_size;
90 };
91
92 /**
93  * acr_r352_generate_flcn_bl_desc - generate generic BL descriptor for LS image
94  */
95 static void
96 acr_r352_generate_flcn_bl_desc(const struct nvkm_acr *acr,
97                                const struct ls_ucode_img *img, u64 wpr_addr,
98                                void *_desc)
99 {
100         struct acr_r352_flcn_bl_desc *desc = _desc;
101         const struct ls_ucode_img_desc *pdesc = &img->ucode_desc;
102         u64 base, addr_code, addr_data;
103
104         base = wpr_addr + img->lsb_header.ucode_off + pdesc->app_start_offset;
105         addr_code = (base + pdesc->app_resident_code_offset) >> 8;
106         addr_data = (base + pdesc->app_resident_data_offset) >> 8;
107
108         memset(desc, 0, sizeof(*desc));
109         desc->ctx_dma = FALCON_DMAIDX_UCODE;
110         desc->code_dma_base = lower_32_bits(addr_code);
111         desc->non_sec_code_off = pdesc->app_resident_code_offset;
112         desc->non_sec_code_size = pdesc->app_resident_code_size;
113         desc->code_entry_point = pdesc->app_imem_entry;
114         desc->data_dma_base = lower_32_bits(addr_data);
115         desc->data_size = pdesc->app_resident_data_size;
116 }
117
118
119 /**
120  * struct hsflcn_acr_desc - data section of the HS firmware
121  *
122  * This header is to be copied at the beginning of DMEM by the HS bootloader.
123  *
124  * @signature:          signature of ACR ucode
125  * @wpr_region_id:      region ID holding the WPR header and its details
126  * @wpr_offset:         offset from the WPR region holding the wpr header
127  * @regions:            region descriptors
128  * @nonwpr_ucode_blob_size:     size of LS blob
129  * @nonwpr_ucode_blob_start:    FB location of LS blob is
130  */
131 struct hsflcn_acr_desc {
132         union {
133                 u8 reserved_dmem[0x200];
134                 u32 signatures[4];
135         } ucode_reserved_space;
136         u32 wpr_region_id;
137         u32 wpr_offset;
138         u32 mmu_mem_range;
139 #define FLCN_ACR_MAX_REGIONS 2
140         struct {
141                 u32 no_regions;
142                 struct {
143                         u32 start_addr;
144                         u32 end_addr;
145                         u32 region_id;
146                         u32 read_mask;
147                         u32 write_mask;
148                         u32 client_mask;
149                 } region_props[FLCN_ACR_MAX_REGIONS];
150         } regions;
151         u32 ucode_blob_size;
152         u64 ucode_blob_base __aligned(8);
153         struct {
154                 u32 vpr_enabled;
155                 u32 vpr_start;
156                 u32 vpr_end;
157                 u32 hdcp_policies;
158         } vpr_desc;
159 };
160
161
162 /*
163  * Low-secure blob creation
164  */
165
166 typedef int (*lsf_load_func)(const struct nvkm_subdev *, struct ls_ucode_img *);
167
168 /**
169  * ls_ucode_img_load() - create a lsf_ucode_img and load it
170  */
171 static struct ls_ucode_img *
172 ls_ucode_img_load(const struct nvkm_subdev *subdev, lsf_load_func load_func)
173 {
174         struct ls_ucode_img *img;
175         int ret;
176
177         img = kzalloc(sizeof(*img), GFP_KERNEL);
178         if (!img)
179                 return ERR_PTR(-ENOMEM);
180
181         ret = load_func(subdev, img);
182
183         if (ret) {
184                 kfree(img);
185                 return ERR_PTR(ret);
186         }
187
188         return img;
189 }
190
191 #define LSF_LSB_HEADER_ALIGN 256
192 #define LSF_BL_DATA_ALIGN 256
193 #define LSF_BL_DATA_SIZE_ALIGN 256
194 #define LSF_BL_CODE_SIZE_ALIGN 256
195 #define LSF_UCODE_DATA_ALIGN 4096
196
197 /**
198  * ls_ucode_img_fill_headers - fill the WPR and LSB headers of an image
199  * @acr:        ACR to use
200  * @img:        image to generate for
201  * @offset:     offset in the WPR region where this image starts
202  *
203  * Allocate space in the WPR area from offset and write the WPR and LSB headers
204  * accordingly.
205  *
206  * Return: offset at the end of this image.
207  */
208 static u32
209 ls_ucode_img_fill_headers(struct acr_r352 *acr, struct ls_ucode_img *img,
210                           u32 offset)
211 {
212         struct lsf_wpr_header *whdr = &img->wpr_header;
213         struct lsf_lsb_header *lhdr = &img->lsb_header;
214         struct ls_ucode_img_desc *desc = &img->ucode_desc;
215         const struct acr_r352_ls_func *func =
216                                             acr->func->ls_func[img->falcon_id];
217
218         if (img->ucode_header) {
219                 nvkm_fatal(acr->base.subdev,
220                            "images withough loader are not supported yet!\n");
221                 return offset;
222         }
223
224         /* Fill WPR header */
225         whdr->falcon_id = img->falcon_id;
226         whdr->bootstrap_owner = acr->base.boot_falcon;
227         whdr->status = LSF_IMAGE_STATUS_COPY;
228
229         /* Align, save off, and include an LSB header size */
230         offset = ALIGN(offset, LSF_LSB_HEADER_ALIGN);
231         whdr->lsb_offset = offset;
232         offset += sizeof(struct lsf_lsb_header);
233
234         /*
235          * Align, save off, and include the original (static) ucode
236          * image size
237          */
238         offset = ALIGN(offset, LSF_UCODE_DATA_ALIGN);
239         lhdr->ucode_off = offset;
240         offset += img->ucode_size;
241
242         /*
243          * For falcons that use a boot loader (BL), we append a loader
244          * desc structure on the end of the ucode image and consider
245          * this the boot loader data. The host will then copy the loader
246          * desc args to this space within the WPR region (before locking
247          * down) and the HS bin will then copy them to DMEM 0 for the
248          * loader.
249          */
250         lhdr->bl_code_size = ALIGN(desc->bootloader_size,
251                                    LSF_BL_CODE_SIZE_ALIGN);
252         lhdr->ucode_size = ALIGN(desc->app_resident_data_offset,
253                                  LSF_BL_CODE_SIZE_ALIGN) + lhdr->bl_code_size;
254         lhdr->data_size = ALIGN(desc->app_size, LSF_BL_CODE_SIZE_ALIGN) +
255                                 lhdr->bl_code_size - lhdr->ucode_size;
256         /*
257          * Though the BL is located at 0th offset of the image, the VA
258          * is different to make sure that it doesn't collide the actual
259          * OS VA range
260          */
261         lhdr->bl_imem_off = desc->bootloader_imem_offset;
262         lhdr->app_code_off = desc->app_start_offset +
263                              desc->app_resident_code_offset;
264         lhdr->app_code_size = desc->app_resident_code_size;
265         lhdr->app_data_off = desc->app_start_offset +
266                              desc->app_resident_data_offset;
267         lhdr->app_data_size = desc->app_resident_data_size;
268
269         lhdr->flags = func->lhdr_flags;
270         if (img->falcon_id == acr->base.boot_falcon)
271                 lhdr->flags |= LSF_FLAG_DMACTL_REQ_CTX;
272
273         /* Align and save off BL descriptor size */
274         lhdr->bl_data_size = ALIGN(func->bl_desc_size, LSF_BL_DATA_SIZE_ALIGN);
275
276         /*
277          * Align, save off, and include the additional BL data
278          */
279         offset = ALIGN(offset, LSF_BL_DATA_ALIGN);
280         lhdr->bl_data_off = offset;
281         offset += lhdr->bl_data_size;
282
283         return offset;
284 }
285
286 /**
287  * struct ls_ucode_mgr - manager for all LS falcon firmwares
288  * @count:      number of managed LS falcons
289  * @wpr_size:   size of the required WPR region in bytes
290  * @img_list:   linked list of lsf_ucode_img
291  */
292 struct ls_ucode_mgr {
293         u16 count;
294         u32 wpr_size;
295         struct list_head img_list;
296 };
297
298 static void
299 ls_ucode_mgr_init(struct ls_ucode_mgr *mgr)
300 {
301         memset(mgr, 0, sizeof(*mgr));
302         INIT_LIST_HEAD(&mgr->img_list);
303 }
304
305 static void
306 ls_ucode_mgr_cleanup(struct ls_ucode_mgr *mgr)
307 {
308         struct ls_ucode_img *img, *t;
309
310         list_for_each_entry_safe(img, t, &mgr->img_list, node) {
311                 kfree(img->ucode_data);
312                 kfree(img->ucode_header);
313                 kfree(img);
314         }
315 }
316
317 static void
318 ls_ucode_mgr_add_img(struct ls_ucode_mgr *mgr, struct ls_ucode_img *img)
319 {
320         mgr->count++;
321         list_add_tail(&img->node, &mgr->img_list);
322 }
323
324 /**
325  * ls_ucode_mgr_fill_headers - fill WPR and LSB headers of all managed images
326  */
327 static void
328 ls_ucode_mgr_fill_headers(struct acr_r352 *acr, struct ls_ucode_mgr *mgr)
329 {
330         struct ls_ucode_img *img;
331         u32 offset;
332
333         /*
334          * Start with an array of WPR headers at the base of the WPR.
335          * The expectation here is that the secure falcon will do a single DMA
336          * read of this array and cache it internally so it's ok to pack these.
337          * Also, we add 1 to the falcon count to indicate the end of the array.
338          */
339         offset = sizeof(struct lsf_wpr_header) * (mgr->count + 1);
340
341         /*
342          * Walk the managed falcons, accounting for the LSB structs
343          * as well as the ucode images.
344          */
345         list_for_each_entry(img, &mgr->img_list, node) {
346                 offset = ls_ucode_img_fill_headers(acr, img, offset);
347         }
348
349         mgr->wpr_size = offset;
350 }
351
352 /**
353  * ls_ucode_mgr_write_wpr - write the WPR blob contents
354  */
355 static int
356 ls_ucode_mgr_write_wpr(struct acr_r352 *acr, struct ls_ucode_mgr *mgr,
357                        struct nvkm_gpuobj *wpr_blob, u32 wpr_addr)
358 {
359         struct ls_ucode_img *img;
360         u32 pos = 0;
361
362         nvkm_kmap(wpr_blob);
363
364         list_for_each_entry(img, &mgr->img_list, node) {
365                 nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header,
366                                       sizeof(img->wpr_header));
367
368                 nvkm_gpuobj_memcpy_to(wpr_blob, img->wpr_header.lsb_offset,
369                                      &img->lsb_header, sizeof(img->lsb_header));
370
371                 /* Generate and write BL descriptor */
372                 if (!img->ucode_header) {
373                         const struct acr_r352_ls_func *ls_func =
374                                              acr->func->ls_func[img->falcon_id];
375                         u8 gdesc[ls_func->bl_desc_size];
376
377                         ls_func->generate_bl_desc(&acr->base, img, wpr_addr,
378                                                   gdesc);
379
380                         nvkm_gpuobj_memcpy_to(wpr_blob,
381                                               img->lsb_header.bl_data_off,
382                                               gdesc, ls_func->bl_desc_size);
383                 }
384
385                 /* Copy ucode */
386                 nvkm_gpuobj_memcpy_to(wpr_blob, img->lsb_header.ucode_off,
387                                       img->ucode_data, img->ucode_size);
388
389                 pos += sizeof(img->wpr_header);
390         }
391
392         nvkm_wo32(wpr_blob, pos, NVKM_SECBOOT_FALCON_INVALID);
393
394         nvkm_done(wpr_blob);
395
396         return 0;
397 }
398
399 /* Both size and address of WPR need to be 128K-aligned */
400 #define WPR_ALIGNMENT   0x20000
401 /**
402  * acr_r352_prepare_ls_blob() - prepare the LS blob
403  *
404  * For each securely managed falcon, load the FW, signatures and bootloaders and
405  * prepare a ucode blob. Then, compute the offsets in the WPR region for each
406  * blob, and finally write the headers and ucode blobs into a GPU object that
407  * will be copied into the WPR region by the HS firmware.
408  */
409 static int
410 acr_r352_prepare_ls_blob(struct acr_r352 *acr, u64 wpr_addr, u32 wpr_size)
411 {
412         const struct nvkm_subdev *subdev = acr->base.subdev;
413         struct ls_ucode_mgr mgr;
414         unsigned long managed_falcons = acr->base.managed_falcons;
415         int falcon_id;
416         int ret;
417
418         ls_ucode_mgr_init(&mgr);
419
420         /* Load all LS blobs */
421         for_each_set_bit(falcon_id, &managed_falcons, NVKM_SECBOOT_FALCON_END) {
422                 struct ls_ucode_img *img;
423
424                 img = ls_ucode_img_load(subdev,
425                                         acr->func->ls_func[falcon_id]->load);
426
427                 if (IS_ERR(img)) {
428                         ret = PTR_ERR(img);
429                         goto cleanup;
430                 }
431                 ls_ucode_mgr_add_img(&mgr, img);
432         }
433
434         /*
435          * Fill the WPR and LSF headers with the right offsets and compute
436          * required WPR size
437          */
438         ls_ucode_mgr_fill_headers(acr, &mgr);
439         mgr.wpr_size = ALIGN(mgr.wpr_size, WPR_ALIGNMENT);
440
441         /* Allocate GPU object that will contain the WPR region */
442         ret = nvkm_gpuobj_new(subdev->device, mgr.wpr_size, WPR_ALIGNMENT,
443                               false, NULL, &acr->ls_blob);
444         if (ret)
445                 goto cleanup;
446
447         nvkm_debug(subdev, "%d managed LS falcons, WPR size is %d bytes\n",
448                     mgr.count, mgr.wpr_size);
449
450         /* If WPR address and size are not fixed, set them to fit the LS blob */
451         if (wpr_size == 0) {
452                 wpr_addr = acr->ls_blob->addr;
453                 wpr_size = mgr.wpr_size;
454         /*
455          * But if the WPR region is set by the bootloader, it is illegal for
456          * the HS blob to be larger than this region.
457          */
458         } else if (mgr.wpr_size > wpr_size) {
459                 nvkm_error(subdev, "WPR region too small for FW blob!\n");
460                 nvkm_error(subdev, "required: %dB\n", mgr.wpr_size);
461                 nvkm_error(subdev, "available: %dB\n", wpr_size);
462                 ret = -ENOSPC;
463                 goto cleanup;
464         }
465
466         /* Write LS blob */
467         ret = ls_ucode_mgr_write_wpr(acr, &mgr, acr->ls_blob, wpr_addr);
468         if (ret)
469                 nvkm_gpuobj_del(&acr->ls_blob);
470
471 cleanup:
472         ls_ucode_mgr_cleanup(&mgr);
473
474         return ret;
475 }
476
477
478
479
480 /**
481  * acr_r352_hsf_patch_signature() - patch HS blob with correct signature
482  */
483 static void
484 acr_r352_hsf_patch_signature(struct nvkm_secboot *sb, void *acr_image)
485 {
486         struct fw_bin_header *hsbin_hdr = acr_image;
487         struct hsf_fw_header *fw_hdr = acr_image + hsbin_hdr->header_offset;
488         void *hs_data = acr_image + hsbin_hdr->data_offset;
489         void *sig;
490         u32 sig_size;
491
492         /* Falcon in debug or production mode? */
493         if (sb->boot_falcon->debug) {
494                 sig = acr_image + fw_hdr->sig_dbg_offset;
495                 sig_size = fw_hdr->sig_dbg_size;
496         } else {
497                 sig = acr_image + fw_hdr->sig_prod_offset;
498                 sig_size = fw_hdr->sig_prod_size;
499         }
500
501         /* Patch signature */
502         memcpy(hs_data + fw_hdr->patch_loc, sig + fw_hdr->patch_sig, sig_size);
503 }
504
505 static void
506 acr_r352_fixup_hs_desc(struct acr_r352 *acr, struct nvkm_secboot *sb,
507                        struct hsflcn_acr_desc *desc)
508 {
509         struct nvkm_gpuobj *ls_blob = acr->ls_blob;
510
511         desc->ucode_blob_base = ls_blob->addr;
512         desc->ucode_blob_size = ls_blob->size;
513
514         desc->wpr_offset = 0;
515
516         /* WPR region information if WPR is not fixed */
517         if (sb->wpr_size == 0) {
518                 desc->wpr_region_id = 1;
519                 desc->regions.no_regions = 1;
520                 desc->regions.region_props[0].region_id = 1;
521                 desc->regions.region_props[0].start_addr = ls_blob->addr >> 8;
522                 desc->regions.region_props[0].end_addr =
523                                            (ls_blob->addr + ls_blob->size) >> 8;
524         }
525 }
526
527 static void
528 acr_r352_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc,
529                              u64 offset)
530 {
531         struct acr_r352_flcn_bl_desc *bl_desc = _bl_desc;
532         u64 addr_code, addr_data;
533
534         memset(bl_desc, 0, sizeof(*bl_desc));
535         addr_code = offset >> 8;
536         addr_data = (offset + hdr->data_dma_base) >> 8;
537
538         bl_desc->ctx_dma = FALCON_DMAIDX_VIRT;
539         bl_desc->code_dma_base = lower_32_bits(addr_code);
540         bl_desc->non_sec_code_off = hdr->non_sec_code_off;
541         bl_desc->non_sec_code_size = hdr->non_sec_code_size;
542         bl_desc->sec_code_off = hdr->app[0].sec_code_off;
543         bl_desc->sec_code_size = hdr->app[0].sec_code_size;
544         bl_desc->code_entry_point = 0;
545         bl_desc->data_dma_base = lower_32_bits(addr_data);
546         bl_desc->data_size = hdr->data_size;
547 }
548
549 /**
550  * acr_r352_prepare_hs_blob - load and prepare a HS blob and BL descriptor
551  *
552  * @sb secure boot instance to prepare for
553  * @fw name of the HS firmware to load
554  * @blob pointer to gpuobj that will be allocated to receive the HS FW payload
555  * @bl_desc pointer to the BL descriptor to write for this firmware
556  * @patch whether we should patch the HS descriptor (only for HS loaders)
557  */
558 static int
559 acr_r352_prepare_hs_blob(struct acr_r352 *acr, struct nvkm_secboot *sb,
560                          const char *fw, struct nvkm_gpuobj **blob,
561                          struct hsf_load_header *load_header, bool patch)
562 {
563         struct nvkm_subdev *subdev = &sb->subdev;
564         void *acr_image;
565         struct fw_bin_header *hsbin_hdr;
566         struct hsf_fw_header *fw_hdr;
567         struct hsf_load_header *load_hdr;
568         void *acr_data;
569         int ret;
570
571         acr_image = nvkm_acr_load_firmware(subdev, fw, 0);
572         if (IS_ERR(acr_image))
573                 return PTR_ERR(acr_image);
574
575         hsbin_hdr = acr_image;
576         fw_hdr = acr_image + hsbin_hdr->header_offset;
577         load_hdr = acr_image + fw_hdr->hdr_offset;
578         acr_data = acr_image + hsbin_hdr->data_offset;
579
580         /* Patch signature */
581         acr_r352_hsf_patch_signature(sb, acr_image);
582
583         /* Patch descriptor with WPR information? */
584         if (patch) {
585                 struct hsflcn_acr_desc *desc;
586
587                 desc = acr_data + load_hdr->data_dma_base;
588                 acr_r352_fixup_hs_desc(acr, sb, desc);
589         }
590
591         if (load_hdr->num_apps > ACR_R352_MAX_APPS) {
592                 nvkm_error(subdev, "more apps (%d) than supported (%d)!",
593                            load_hdr->num_apps, ACR_R352_MAX_APPS);
594                 ret = -EINVAL;
595                 goto cleanup;
596         }
597         memcpy(load_header, load_hdr, sizeof(*load_header) +
598                                (sizeof(load_hdr->app[0]) * load_hdr->num_apps));
599
600         /* Create ACR blob and copy HS data to it */
601         ret = nvkm_gpuobj_new(subdev->device, ALIGN(hsbin_hdr->data_size, 256),
602                               0x1000, false, NULL, blob);
603         if (ret)
604                 goto cleanup;
605
606         nvkm_kmap(*blob);
607         nvkm_gpuobj_memcpy_to(*blob, 0, acr_data, hsbin_hdr->data_size);
608         nvkm_done(*blob);
609
610 cleanup:
611         kfree(acr_image);
612
613         return ret;
614 }
615
616 static int
617 acr_r352_prepare_hsbl_blob(struct acr_r352 *acr)
618 {
619         const struct nvkm_subdev *subdev = acr->base.subdev;
620         struct fw_bin_header *hdr;
621         struct fw_bl_desc *hsbl_desc;
622
623         acr->hsbl_blob = nvkm_acr_load_firmware(subdev, "acr/bl", 0);
624         if (IS_ERR(acr->hsbl_blob)) {
625                 int ret = PTR_ERR(acr->hsbl_blob);
626
627                 acr->hsbl_blob = NULL;
628                 return ret;
629         }
630
631         hdr = acr->hsbl_blob;
632         hsbl_desc = acr->hsbl_blob + hdr->header_offset;
633
634         /* virtual start address for boot vector */
635         acr->base.start_address = hsbl_desc->start_tag << 8;
636
637         return 0;
638 }
639
640 /**
641  * acr_r352_load_blobs - load blobs common to all ACR V1 versions.
642  *
643  * This includes the LS blob, HS ucode loading blob, and HS bootloader.
644  *
645  * The HS ucode unload blob is only used on dGPU if the WPR region is variable.
646  */
647 int
648 acr_r352_load_blobs(struct acr_r352 *acr, struct nvkm_secboot *sb)
649 {
650         int ret;
651
652         /* Firmware already loaded? */
653         if (acr->firmware_ok)
654                 return 0;
655
656         /* Load and prepare the managed falcon's firmwares */
657         ret = acr_r352_prepare_ls_blob(acr, sb->wpr_addr, sb->wpr_size);
658         if (ret)
659                 return ret;
660
661         /* Load the HS firmware that will load the LS firmwares */
662         if (!acr->load_blob) {
663                 ret = acr_r352_prepare_hs_blob(acr, sb, "acr/ucode_load",
664                                                &acr->load_blob,
665                                                &acr->load_bl_header, true);
666                 if (ret)
667                         return ret;
668         }
669
670         /* If the ACR region is dynamically programmed, we need an unload FW */
671         if (sb->wpr_size == 0) {
672                 ret = acr_r352_prepare_hs_blob(acr, sb, "acr/ucode_unload",
673                                                &acr->unload_blob,
674                                                &acr->unload_bl_header, false);
675                 if (ret)
676                         return ret;
677         }
678
679         /* Load the HS firmware bootloader */
680         if (!acr->hsbl_blob) {
681                 ret = acr_r352_prepare_hsbl_blob(acr);
682                 if (ret)
683                         return ret;
684         }
685
686         acr->firmware_ok = true;
687         nvkm_debug(&sb->subdev, "LS blob successfully created\n");
688
689         return 0;
690 }
691
692 /**
693  * acr_r352_load() - prepare HS falcon to run the specified blob, mapped
694  * at GPU address offset.
695  */
696 static int
697 acr_r352_load(struct nvkm_acr *_acr, struct nvkm_secboot *sb,
698               struct nvkm_gpuobj *blob, u64 offset)
699 {
700         struct acr_r352 *acr = acr_r352(_acr);
701         struct nvkm_falcon *falcon = sb->boot_falcon;
702         struct fw_bin_header *hdr = acr->hsbl_blob;
703         struct fw_bl_desc *hsbl_desc = acr->hsbl_blob + hdr->header_offset;
704         void *blob_data = acr->hsbl_blob + hdr->data_offset;
705         void *hsbl_code = blob_data + hsbl_desc->code_off;
706         void *hsbl_data = blob_data + hsbl_desc->data_off;
707         u32 code_size = ALIGN(hsbl_desc->code_size, 256);
708         const struct hsf_load_header *load_hdr;
709         const u32 bl_desc_size = acr->func->hs_bl_desc_size;
710         u8 bl_desc[bl_desc_size];
711
712         /* Find the bootloader descriptor for our blob and copy it */
713         if (blob == acr->load_blob) {
714                 load_hdr = &acr->load_bl_header;
715         } else if (blob == acr->unload_blob) {
716                 load_hdr = &acr->unload_bl_header;
717         } else {
718                 nvkm_error(_acr->subdev, "invalid secure boot blob!\n");
719                 return -EINVAL;
720         }
721
722         /*
723          * Copy HS bootloader data
724          */
725         nvkm_falcon_load_dmem(falcon, hsbl_data, 0x0, hsbl_desc->data_size, 0);
726
727         /* Copy HS bootloader code to end of IMEM */
728         nvkm_falcon_load_imem(falcon, hsbl_code, falcon->code.limit - code_size,
729                               code_size, hsbl_desc->start_tag, 0, false);
730
731         /* Generate the BL header */
732         acr->func->generate_hs_bl_desc(load_hdr, bl_desc, offset);
733
734         /*
735          * Copy HS BL header where the HS descriptor expects it to be
736          */
737         nvkm_falcon_load_dmem(falcon, bl_desc, hsbl_desc->dmem_load_off,
738                               bl_desc_size, 0);
739
740         return 0;
741 }
742
743 /*
744  * acr_r352_reset() - execute secure boot from the prepared state
745  *
746  * Load the HS bootloader and ask the falcon to run it. This will in turn
747  * load the HS firmware and run it, so once the falcon stops all the managed
748  * falcons should have their LS firmware loaded and be ready to run.
749  */
750 static int
751 acr_r352_reset(struct nvkm_acr *_acr, struct nvkm_secboot *sb,
752                enum nvkm_secboot_falcon falcon)
753 {
754         struct acr_r352 *acr = acr_r352(_acr);
755         int ret;
756
757         /* Make sure all blobs are ready */
758         ret = acr_r352_load_blobs(acr, sb);
759         if (ret)
760                 return ret;
761
762         /*
763          * Dummy GM200 implementation: perform secure boot each time we are
764          * called on FECS. Since only FECS and GPCCS are managed and started
765          * together, this ought to be safe.
766          *
767          * Once we have proper PMU firmware and support, this will be changed
768          * to a proper call to the PMU method.
769          */
770         if (falcon != NVKM_SECBOOT_FALCON_FECS)
771                 goto end;
772
773         /* If WPR is set and we have an unload blob, run it to unlock WPR */
774         if (acr->unload_blob &&
775             acr->falcon_state[NVKM_SECBOOT_FALCON_FECS] != NON_SECURE) {
776                 ret = sb->func->run_blob(sb, acr->unload_blob);
777                 if (ret)
778                         return ret;
779         }
780
781         /* Reload all managed falcons */
782         ret = sb->func->run_blob(sb, acr->load_blob);
783         if (ret)
784                 return ret;
785
786 end:
787         acr->falcon_state[falcon] = RESET;
788         return 0;
789 }
790
791 static int
792 acr_r352_start(struct nvkm_acr *_acr, struct nvkm_secboot *sb,
793                     enum nvkm_secboot_falcon falcon)
794 {
795         struct acr_r352 *acr = acr_r352(_acr);
796         const struct nvkm_subdev *subdev = &sb->subdev;
797         int base;
798
799         switch (falcon) {
800         case NVKM_SECBOOT_FALCON_FECS:
801                 base = 0x409000;
802                 break;
803         case NVKM_SECBOOT_FALCON_GPCCS:
804                 base = 0x41a000;
805                 break;
806         default:
807                 nvkm_error(subdev, "cannot start unhandled falcon!\n");
808                 return -EINVAL;
809         }
810
811         nvkm_wr32(subdev->device, base + 0x130, 0x00000002);
812         acr->falcon_state[falcon] = RUNNING;
813
814         return 0;
815 }
816
817 static int
818 acr_r352_fini(struct nvkm_acr *_acr, struct nvkm_secboot *sb, bool suspend)
819 {
820         struct acr_r352 *acr = acr_r352(_acr);
821         int ret = 0;
822         int i;
823
824         /* Run the unload blob to unprotect the WPR region */
825         if (acr->unload_blob &&
826             acr->falcon_state[NVKM_SECBOOT_FALCON_FECS] != NON_SECURE)
827                 ret = sb->func->run_blob(sb, acr->unload_blob);
828
829         for (i = 0; i < NVKM_SECBOOT_FALCON_END; i++)
830                 acr->falcon_state[i] = NON_SECURE;
831
832         return ret;
833 }
834
835 static void
836 acr_r352_dtor(struct nvkm_acr *_acr)
837 {
838         struct acr_r352 *acr = acr_r352(_acr);
839
840         nvkm_gpuobj_del(&acr->unload_blob);
841
842         kfree(acr->hsbl_blob);
843         nvkm_gpuobj_del(&acr->load_blob);
844         nvkm_gpuobj_del(&acr->ls_blob);
845
846         kfree(acr);
847 }
848
849 const struct acr_r352_ls_func
850 acr_r352_ls_fecs_func = {
851         .load = acr_ls_ucode_load_fecs,
852         .generate_bl_desc = acr_r352_generate_flcn_bl_desc,
853         .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc),
854 };
855
856 const struct acr_r352_ls_func
857 acr_r352_ls_gpccs_func = {
858         .load = acr_ls_ucode_load_gpccs,
859         .generate_bl_desc = acr_r352_generate_flcn_bl_desc,
860         .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc),
861         /* GPCCS will be loaded using PRI */
862         .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
863 };
864
865 const struct acr_r352_func
866 acr_r352_func = {
867         .generate_hs_bl_desc = acr_r352_generate_hs_bl_desc,
868         .hs_bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc),
869         .ls_func = {
870                 [NVKM_SECBOOT_FALCON_FECS] = &acr_r352_ls_fecs_func,
871                 [NVKM_SECBOOT_FALCON_GPCCS] = &acr_r352_ls_gpccs_func,
872         },
873 };
874
875 static const struct nvkm_acr_func
876 acr_r352_base_func = {
877         .dtor = acr_r352_dtor,
878         .fini = acr_r352_fini,
879         .load = acr_r352_load,
880         .reset = acr_r352_reset,
881         .start = acr_r352_start,
882 };
883
884 struct nvkm_acr *
885 acr_r352_new_(const struct acr_r352_func *func,
886               enum nvkm_secboot_falcon boot_falcon,
887               unsigned long managed_falcons)
888 {
889         struct acr_r352 *acr;
890
891         acr = kzalloc(sizeof(*acr), GFP_KERNEL);
892         if (!acr)
893                 return ERR_PTR(-ENOMEM);
894
895         acr->base.boot_falcon = boot_falcon;
896         acr->base.managed_falcons = managed_falcons;
897         acr->base.func = &acr_r352_base_func;
898         acr->func = func;
899
900         return &acr->base;
901 }
902
903 struct nvkm_acr *
904 acr_r352_new(unsigned long managed_falcons)
905 {
906         return acr_r352_new_(&acr_r352_func, NVKM_SECBOOT_FALCON_PMU,
907                              managed_falcons);
908 }