1/* 2 * Copyright (c) 2015, 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#ifndef __NVKM_SECBOOT_PRIV_H__ 24#define __NVKM_SECBOOT_PRIV_H__ 25 26#include <subdev/secboot.h> 27#include <subdev/mmu.h> 28 29struct nvkm_secboot_func { 30 int (*init)(struct nvkm_secboot *); 31 int (*fini)(struct nvkm_secboot *, bool suspend); 32 void *(*dtor)(struct nvkm_secboot *); 33 int (*reset)(struct nvkm_secboot *, enum nvkm_secboot_falcon); 34 int (*start)(struct nvkm_secboot *, enum nvkm_secboot_falcon); 35 36 /* ID of the falcon that will perform secure boot */ 37 enum nvkm_secboot_falcon boot_falcon; 38 /* Bit-mask of IDs of managed falcons */ 39 unsigned long managed_falcons; 40}; 41 42int nvkm_secboot_ctor(const struct nvkm_secboot_func *, struct nvkm_device *, 43 int index, struct nvkm_secboot *); 44int nvkm_secboot_falcon_reset(struct nvkm_secboot *); 45int nvkm_secboot_falcon_run(struct nvkm_secboot *); 46 47struct flcn_u64 { 48 u32 lo; 49 u32 hi; 50}; 51static inline u64 flcn64_to_u64(const struct flcn_u64 f) 52{ 53 return ((u64)f.hi) << 32 | f.lo; 54} 55 56/** 57 * struct gm200_flcn_bl_desc - DMEM bootloader descriptor 58 * @signature: 16B signature for secure code. 0s if no secure code 59 * @ctx_dma: DMA context to be used by BL while loading code/data 60 * @code_dma_base: 256B-aligned Physical FB Address where code is located 61 * (falcon's $xcbase register) 62 * @non_sec_code_off: offset from code_dma_base where the non-secure code is 63 * located. The offset must be multiple of 256 to help perf 64 * @non_sec_code_size: the size of the nonSecure code part. 65 * @sec_code_off: offset from code_dma_base where the secure code is 66 * located. The offset must be multiple of 256 to help perf 67 * @sec_code_size: offset from code_dma_base where the secure code is 68 * located. The offset must be multiple of 256 to help perf 69 * @code_entry_point: code entry point which will be invoked by BL after 70 * code is loaded. 71 * @data_dma_base: 256B aligned Physical FB Address where data is located. 72 * (falcon's $xdbase register) 73 * @data_size: size of data block. Should be multiple of 256B 74 * 75 * Structure used by the bootloader to load the rest of the code. This has 76 * to be filled by host and copied into DMEM at offset provided in the 77 * hsflcn_bl_desc.bl_desc_dmem_load_off. 78 */ 79struct gm200_flcn_bl_desc { 80 u32 reserved[4]; 81 u32 signature[4]; 82 u32 ctx_dma; 83 struct flcn_u64 code_dma_base; 84 u32 non_sec_code_off; 85 u32 non_sec_code_size; 86 u32 sec_code_off; 87 u32 sec_code_size; 88 u32 code_entry_point; 89 struct flcn_u64 data_dma_base; 90 u32 data_size; 91}; 92 93/** 94 * struct hsflcn_acr_desc - data section of the HS firmware 95 * 96 * This header is to be copied at the beginning of DMEM by the HS bootloader. 97 * 98 * @signature: signature of ACR ucode 99 * @wpr_region_id: region ID holding the WPR header and its details 100 * @wpr_offset: offset from the WPR region holding the wpr header 101 * @regions: region descriptors 102 * @nonwpr_ucode_blob_size: size of LS blob 103 * @nonwpr_ucode_blob_start: FB location of LS blob is 104 */ 105struct hsflcn_acr_desc { 106 union { 107 u8 reserved_dmem[0x200]; 108 u32 signatures[4]; 109 } ucode_reserved_space; 110 u32 wpr_region_id; 111 u32 wpr_offset; 112 u32 mmu_mem_range; 113#define FLCN_ACR_MAX_REGIONS 2 114 struct { 115 u32 no_regions; 116 struct { 117 u32 start_addr; 118 u32 end_addr; 119 u32 region_id; 120 u32 read_mask; 121 u32 write_mask; 122 u32 client_mask; 123 } region_props[FLCN_ACR_MAX_REGIONS]; 124 } regions; 125 u32 ucode_blob_size; 126 u64 ucode_blob_base __aligned(8); 127 struct { 128 u32 vpr_enabled; 129 u32 vpr_start; 130 u32 vpr_end; 131 u32 hdcp_policies; 132 } vpr_desc; 133}; 134 135/** 136 * Contains the whole secure boot state, allowing it to be performed as needed 137 * @wpr_addr: physical address of the WPR region 138 * @wpr_size: size in bytes of the WPR region 139 * @ls_blob: LS blob of all the LS firmwares, signatures, bootloaders 140 * @ls_blob_size: size of the LS blob 141 * @ls_blob_nb_regions: number of LS firmwares that will be loaded 142 * @acr_blob: HS blob 143 * @acr_blob_vma: mapping of the HS blob into the secure falcon's VM 144 * @acr_bl_desc: bootloader descriptor of the HS blob 145 * @hsbl_blob: HS blob bootloader 146 * @inst: instance block for HS falcon 147 * @pgd: page directory for the HS falcon 148 * @vm: address space used by the HS falcon 149 * @falcon_state: current state of the managed falcons 150 * @firmware_ok: whether the firmware blobs have been created 151 */ 152struct gm200_secboot { 153 struct nvkm_secboot base; 154 const struct gm200_secboot_func *func; 155 156 /* 157 * Address and size of the WPR region. On dGPU this will be the 158 * address of the LS blob. On Tegra this is a fixed region set by the 159 * bootloader 160 */ 161 u64 wpr_addr; 162 u32 wpr_size; 163 164 /* 165 * HS FW - lock WPR region (dGPU only) and load LS FWs 166 * on Tegra the HS FW copies the LS blob into the fixed WPR instead 167 */ 168 struct nvkm_gpuobj *acr_load_blob; 169 struct gm200_flcn_bl_desc acr_load_bl_desc; 170 171 /* HS FW - unlock WPR region (dGPU only) */ 172 struct nvkm_gpuobj *acr_unload_blob; 173 struct gm200_flcn_bl_desc acr_unload_bl_desc; 174 175 /* HS bootloader */ 176 void *hsbl_blob; 177 178 /* LS FWs, to be loaded by the HS ACR */ 179 struct nvkm_gpuobj *ls_blob; 180 181 /* Instance block & address space used for HS FW execution */ 182 struct nvkm_gpuobj *inst; 183 struct nvkm_gpuobj *pgd; 184 struct nvkm_vm *vm; 185 186 /* To keep track of the state of all managed falcons */ 187 enum { 188 /* In non-secure state, no firmware loaded, no privileges*/ 189 NON_SECURE = 0, 190 /* In low-secure mode and ready to be started */ 191 RESET, 192 /* In low-secure mode and running */ 193 RUNNING, 194 } falcon_state[NVKM_SECBOOT_FALCON_END]; 195 196 bool firmware_ok; 197}; 198#define gm200_secboot(sb) container_of(sb, struct gm200_secboot, base) 199 200/** 201 * Contains functions we wish to abstract between GM200-like implementations 202 * @bl_desc_size: size of the BL descriptor used by this chip. 203 * @fixup_bl_desc: hook that generates the proper BL descriptor format from 204 * the generic GM200 format into a data array of size 205 * bl_desc_size 206 * @fixup_hs_desc: hook that twiddles the HS descriptor before it is used 207 * @prepare_blobs: prepares the various blobs needed for secure booting 208 */ 209struct gm200_secboot_func { 210 /* 211 * Size of the bootloader descriptor for this chip. A block of this 212 * size is allocated before booting a falcon and the fixup_bl_desc 213 * callback is called on it 214 */ 215 u32 bl_desc_size; 216 void (*fixup_bl_desc)(const struct gm200_flcn_bl_desc *, void *); 217 218 /* 219 * Chip-specific modifications of the HS descriptor can be done here. 220 * On dGPU this is used to fill the information about the WPR region 221 * we want the HS FW to set up. 222 */ 223 void (*fixup_hs_desc)(struct gm200_secboot *, struct hsflcn_acr_desc *); 224 int (*prepare_blobs)(struct gm200_secboot *); 225}; 226 227int gm200_secboot_init(struct nvkm_secboot *); 228void *gm200_secboot_dtor(struct nvkm_secboot *); 229int gm200_secboot_reset(struct nvkm_secboot *, u32); 230int gm200_secboot_start(struct nvkm_secboot *, u32); 231 232int gm20x_secboot_prepare_blobs(struct gm200_secboot *); 233 234#endif 235