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