root/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ls_ucode_img_build
  2. ls_ucode_img_load_gr
  3. acr_ls_ucode_load_fecs
  4. acr_ls_ucode_load_gpccs

   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 
  24 #include "ls_ucode.h"
  25 #include "acr.h"
  26 
  27 #include <core/firmware.h>
  28 
  29 #define BL_DESC_BLK_SIZE 256
  30 /**
  31  * Build a ucode image and descriptor from provided bootloader, code and data.
  32  *
  33  * @bl:         bootloader image, including 16-bytes descriptor
  34  * @code:       LS firmware code segment
  35  * @data:       LS firmware data segment
  36  * @desc:       ucode descriptor to be written
  37  *
  38  * Return: allocated ucode image with corresponding descriptor information. desc
  39  *         is also updated to contain the right offsets within returned image.
  40  */
  41 static void *
  42 ls_ucode_img_build(const struct firmware *bl, const struct firmware *code,
  43                    const struct firmware *data, struct ls_ucode_img_desc *desc)
  44 {
  45         struct fw_bin_header *bin_hdr = (void *)bl->data;
  46         struct fw_bl_desc *bl_desc = (void *)bl->data + bin_hdr->header_offset;
  47         void *bl_data = (void *)bl->data + bin_hdr->data_offset;
  48         u32 pos = 0;
  49         void *image;
  50 
  51         desc->bootloader_start_offset = pos;
  52         desc->bootloader_size = ALIGN(bl_desc->code_size, sizeof(u32));
  53         desc->bootloader_imem_offset = bl_desc->start_tag * 256;
  54         desc->bootloader_entry_point = bl_desc->start_tag * 256;
  55 
  56         pos = ALIGN(pos + desc->bootloader_size, BL_DESC_BLK_SIZE);
  57         desc->app_start_offset = pos;
  58         desc->app_size = ALIGN(code->size, BL_DESC_BLK_SIZE) +
  59                          ALIGN(data->size, BL_DESC_BLK_SIZE);
  60         desc->app_imem_offset = 0;
  61         desc->app_imem_entry = 0;
  62         desc->app_dmem_offset = 0;
  63         desc->app_resident_code_offset = 0;
  64         desc->app_resident_code_size = ALIGN(code->size, BL_DESC_BLK_SIZE);
  65 
  66         pos = ALIGN(pos + desc->app_resident_code_size, BL_DESC_BLK_SIZE);
  67         desc->app_resident_data_offset = pos - desc->app_start_offset;
  68         desc->app_resident_data_size = ALIGN(data->size, BL_DESC_BLK_SIZE);
  69 
  70         desc->image_size = ALIGN(bl_desc->code_size, BL_DESC_BLK_SIZE) +
  71                            desc->app_size;
  72 
  73         image = kzalloc(desc->image_size, GFP_KERNEL);
  74         if (!image)
  75                 return ERR_PTR(-ENOMEM);
  76 
  77         memcpy(image + desc->bootloader_start_offset, bl_data,
  78                bl_desc->code_size);
  79         memcpy(image + desc->app_start_offset, code->data, code->size);
  80         memcpy(image + desc->app_start_offset + desc->app_resident_data_offset,
  81                data->data, data->size);
  82 
  83         return image;
  84 }
  85 
  86 /**
  87  * ls_ucode_img_load_gr() - load and prepare a LS GR ucode image
  88  *
  89  * Load the LS microcode, bootloader and signature and pack them into a single
  90  * blob. Also generate the corresponding ucode descriptor.
  91  */
  92 static int
  93 ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, int maxver,
  94                      struct ls_ucode_img *img, const char *falcon_name)
  95 {
  96         const struct firmware *bl, *code, *data, *sig;
  97         char f[64];
  98         int ret;
  99 
 100         snprintf(f, sizeof(f), "gr/%s_bl", falcon_name);
 101         ret = nvkm_firmware_get(subdev, f, &bl);
 102         if (ret)
 103                 goto error;
 104 
 105         snprintf(f, sizeof(f), "gr/%s_inst", falcon_name);
 106         ret = nvkm_firmware_get(subdev, f, &code);
 107         if (ret)
 108                 goto free_bl;
 109 
 110         snprintf(f, sizeof(f), "gr/%s_data", falcon_name);
 111         ret = nvkm_firmware_get(subdev, f, &data);
 112         if (ret)
 113                 goto free_inst;
 114 
 115         snprintf(f, sizeof(f), "gr/%s_sig", falcon_name);
 116         ret = nvkm_firmware_get(subdev, f, &sig);
 117         if (ret)
 118                 goto free_data;
 119 
 120         img->sig = kmemdup(sig->data, sig->size, GFP_KERNEL);
 121         if (!img->sig) {
 122                 ret = -ENOMEM;
 123                 goto free_sig;
 124         }
 125         img->sig_size = sig->size;
 126 
 127         img->ucode_data = ls_ucode_img_build(bl, code, data,
 128                                              &img->ucode_desc);
 129         if (IS_ERR(img->ucode_data)) {
 130                 kfree(img->sig);
 131                 ret = PTR_ERR(img->ucode_data);
 132                 goto free_sig;
 133         }
 134         img->ucode_size = img->ucode_desc.image_size;
 135 
 136 free_sig:
 137         nvkm_firmware_put(sig);
 138 free_data:
 139         nvkm_firmware_put(data);
 140 free_inst:
 141         nvkm_firmware_put(code);
 142 free_bl:
 143         nvkm_firmware_put(bl);
 144 error:
 145         return ret;
 146 }
 147 
 148 int
 149 acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, int maxver,
 150                        struct ls_ucode_img *img)
 151 {
 152         return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "fecs");
 153 }
 154 
 155 int
 156 acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, int maxver,
 157                         struct ls_ucode_img *img)
 158 {
 159         return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "gpccs");
 160 }

/* [<][>][^][v][top][bottom][index][help] */