linux/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2017, 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_r367.h"
  24
  25#include <engine/falcon.h>
  26#include <core/msgqueue.h>
  27#include <subdev/pmu.h>
  28
  29/*
  30 * r375 ACR: similar to r367, but with a unified bootloader descriptor
  31 * structure for GR and PMU falcons.
  32 */
  33
  34/* Same as acr_r361_flcn_bl_desc, plus argc/argv */
  35struct acr_r375_flcn_bl_desc {
  36        u32 reserved[4];
  37        u32 signature[4];
  38        u32 ctx_dma;
  39        struct flcn_u64 code_dma_base;
  40        u32 non_sec_code_off;
  41        u32 non_sec_code_size;
  42        u32 sec_code_off;
  43        u32 sec_code_size;
  44        u32 code_entry_point;
  45        struct flcn_u64 data_dma_base;
  46        u32 data_size;
  47        u32 argc;
  48        u32 argv;
  49};
  50
  51static void
  52acr_r375_generate_flcn_bl_desc(const struct nvkm_acr *acr,
  53                               const struct ls_ucode_img *img, u64 wpr_addr,
  54                               void *_desc)
  55{
  56        struct acr_r375_flcn_bl_desc *desc = _desc;
  57        const struct ls_ucode_img_desc *pdesc = &img->ucode_desc;
  58        u64 base, addr_code, addr_data;
  59
  60        base = wpr_addr + img->ucode_off + pdesc->app_start_offset;
  61        addr_code = base + pdesc->app_resident_code_offset;
  62        addr_data = base + pdesc->app_resident_data_offset;
  63
  64        desc->ctx_dma = FALCON_DMAIDX_UCODE;
  65        desc->code_dma_base = u64_to_flcn64(addr_code);
  66        desc->non_sec_code_off = pdesc->app_resident_code_offset;
  67        desc->non_sec_code_size = pdesc->app_resident_code_size;
  68        desc->code_entry_point = pdesc->app_imem_entry;
  69        desc->data_dma_base = u64_to_flcn64(addr_data);
  70        desc->data_size = pdesc->app_resident_data_size;
  71}
  72
  73static void
  74acr_r375_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc,
  75                             u64 offset)
  76{
  77        struct acr_r375_flcn_bl_desc *bl_desc = _bl_desc;
  78
  79        bl_desc->ctx_dma = FALCON_DMAIDX_VIRT;
  80        bl_desc->non_sec_code_off = hdr->non_sec_code_off;
  81        bl_desc->non_sec_code_size = hdr->non_sec_code_size;
  82        bl_desc->sec_code_off = hsf_load_header_app_off(hdr, 0);
  83        bl_desc->sec_code_size = hsf_load_header_app_size(hdr, 0);
  84        bl_desc->code_entry_point = 0;
  85        bl_desc->code_dma_base = u64_to_flcn64(offset);
  86        bl_desc->data_dma_base = u64_to_flcn64(offset + hdr->data_dma_base);
  87        bl_desc->data_size = hdr->data_size;
  88}
  89
  90const struct acr_r352_ls_func
  91acr_r375_ls_fecs_func = {
  92        .load = acr_ls_ucode_load_fecs,
  93        .generate_bl_desc = acr_r375_generate_flcn_bl_desc,
  94        .bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
  95};
  96
  97const struct acr_r352_ls_func
  98acr_r375_ls_gpccs_func = {
  99        .load = acr_ls_ucode_load_gpccs,
 100        .generate_bl_desc = acr_r375_generate_flcn_bl_desc,
 101        .bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
 102        /* GPCCS will be loaded using PRI */
 103        .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
 104};
 105
 106
 107static void
 108acr_r375_generate_pmu_bl_desc(const struct nvkm_acr *acr,
 109                              const struct ls_ucode_img *img, u64 wpr_addr,
 110                              void *_desc)
 111{
 112        const struct ls_ucode_img_desc *pdesc = &img->ucode_desc;
 113        const struct nvkm_pmu *pmu = acr->subdev->device->pmu;
 114        struct acr_r375_flcn_bl_desc *desc = _desc;
 115        u64 base, addr_code, addr_data;
 116        u32 addr_args;
 117
 118        base = wpr_addr + img->ucode_off + pdesc->app_start_offset;
 119        addr_code = base + pdesc->app_resident_code_offset;
 120        addr_data = base + pdesc->app_resident_data_offset;
 121        addr_args = pmu->falcon->data.limit;
 122        addr_args -= NVKM_MSGQUEUE_CMDLINE_SIZE;
 123
 124        desc->ctx_dma = FALCON_DMAIDX_UCODE;
 125        desc->code_dma_base = u64_to_flcn64(addr_code);
 126        desc->non_sec_code_off = pdesc->app_resident_code_offset;
 127        desc->non_sec_code_size = pdesc->app_resident_code_size;
 128        desc->code_entry_point = pdesc->app_imem_entry;
 129        desc->data_dma_base = u64_to_flcn64(addr_data);
 130        desc->data_size = pdesc->app_resident_data_size;
 131        desc->argc = 1;
 132        desc->argv = addr_args;
 133}
 134
 135const struct acr_r352_ls_func
 136acr_r375_ls_pmu_func = {
 137        .load = acr_ls_ucode_load_pmu,
 138        .generate_bl_desc = acr_r375_generate_pmu_bl_desc,
 139        .bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
 140        .post_run = acr_ls_pmu_post_run,
 141};
 142
 143
 144const struct acr_r352_func
 145acr_r375_func = {
 146        .fixup_hs_desc = acr_r367_fixup_hs_desc,
 147        .generate_hs_bl_desc = acr_r375_generate_hs_bl_desc,
 148        .hs_bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
 149        .shadow_blob = true,
 150        .ls_ucode_img_load = acr_r367_ls_ucode_img_load,
 151        .ls_fill_headers = acr_r367_ls_fill_headers,
 152        .ls_write_wpr = acr_r367_ls_write_wpr,
 153        .ls_func = {
 154                [NVKM_SECBOOT_FALCON_FECS] = &acr_r375_ls_fecs_func,
 155                [NVKM_SECBOOT_FALCON_GPCCS] = &acr_r375_ls_gpccs_func,
 156                [NVKM_SECBOOT_FALCON_PMU] = &acr_r375_ls_pmu_func,
 157        },
 158};
 159
 160struct nvkm_acr *
 161acr_r375_new(enum nvkm_secboot_falcon boot_falcon,
 162             unsigned long managed_falcons)
 163{
 164        return acr_r352_new_(&acr_r375_func, boot_falcon, managed_falcons);
 165}
 166