1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #ifndef _XE_UC_FW_ABI_H 7 #define _XE_UC_FW_ABI_H 8 9 #include <linux/build_bug.h> 10 #include <linux/types.h> 11 12 /** 13 * DOC: CSS-based Firmware Layout 14 * 15 * The CSS-based firmware structure is used for GuC releases on all platforms 16 * and for HuC releases up to DG1. Starting from DG2/MTL the HuC uses the GSC 17 * layout instead. 18 * The CSS firmware layout looks like this:: 19 * 20 * +======================================================================+ 21 * | Firmware blob | 22 * +===============+===============+============+============+============+ 23 * | CSS header | uCode | RSA key | modulus | exponent | 24 * +===============+===============+============+============+============+ 25 * <-header size-> <---header size continued -----------> 26 * <--- size -----------------------------------------------------------> 27 * <-key size-> 28 * <-mod size-> 29 * <-exp size-> 30 * 31 * The firmware may or may not have modulus key and exponent data. The header, 32 * uCode and RSA signature are must-have components that will be used by driver. 33 * Length of each components, which is all in dwords, can be found in header. 34 * In the case that modulus and exponent are not present in fw, a.k.a truncated 35 * image, the length value still appears in header. 36 * 37 * Driver will do some basic fw size validation based on the following rules: 38 * 39 * 1. Header, uCode and RSA are must-have components. 40 * 2. All firmware components, if they present, are in the sequence illustrated 41 * in the layout table above. 42 * 3. Length info of each component can be found in header, in dwords. 43 * 4. Modulus and exponent key are not required by driver. They may not appear 44 * in fw. So driver will load a truncated firmware in this case. 45 */ 46 47 struct uc_css_rsa_info { 48 u32 key_size_dw; 49 u32 modulus_size_dw; 50 u32 exponent_size_dw; 51 } __packed; 52 53 struct uc_css_guc_info { 54 u32 time; 55 #define CSS_TIME_HOUR (0xFF << 0) 56 #define CSS_TIME_MIN (0xFF << 8) 57 #define CSS_TIME_SEC (0xFFFF << 16) 58 u32 reserved0[5]; 59 u32 sw_version; 60 #define CSS_SW_VERSION_UC_MAJOR (0xFF << 16) 61 #define CSS_SW_VERSION_UC_MINOR (0xFF << 8) 62 #define CSS_SW_VERSION_UC_PATCH (0xFF << 0) 63 u32 submission_version; 64 u32 reserved1[11]; 65 u32 header_info; 66 #define CSS_HEADER_INFO_SVN (0xFF) 67 #define CSS_HEADER_INFO_COPY_VALID (0x1 << 31) 68 u32 private_data_size; 69 u32 ukernel_info; 70 #define CSS_UKERNEL_INFO_DEVICEID (0xFFFF << 16) 71 #define CSS_UKERNEL_INFO_PRODKEY (0xFF << 8) 72 #define CSS_UKERNEL_INFO_BUILDTYPE (0x3 << 2) 73 #define CSS_UKERNEL_INFO_BUILDTYPE_PROD 0 74 #define CSS_UKERNEL_INFO_BUILDTYPE_PREPROD 1 75 #define CSS_UKERNEL_INFO_BUILDTYPE_DEBUG 2 76 #define CSS_UKERNEL_INFO_ENCSTATUS (0x1 << 1) 77 #define CSS_UKERNEL_INFO_COPY_VALID (0x1 << 0) 78 } __packed; 79 80 struct uc_css_header { 81 u32 module_type; 82 /* 83 * header_size includes all non-uCode bits, including css_header, rsa 84 * key, modulus key and exponent data. 85 */ 86 u32 header_size_dw; 87 u32 header_version; 88 u32 reserved0; 89 u32 module_vendor; 90 u32 date; 91 #define CSS_DATE_DAY (0xFF << 0) 92 #define CSS_DATE_MONTH (0xFF << 8) 93 #define CSS_DATE_YEAR (0xFFFF << 16) 94 u32 size_dw; /* uCode plus header_size_dw */ 95 union { 96 u32 reserved1[3]; 97 struct uc_css_rsa_info rsa_info; 98 }; 99 union { 100 u32 reserved2[22]; 101 struct uc_css_guc_info guc_info; 102 }; 103 } __packed; 104 static_assert(sizeof(struct uc_css_header) == 128); 105 106 /** 107 * DOC: GSC-based Firmware Layout 108 * 109 * The GSC-based firmware structure is used for GSC releases on all platforms 110 * and for HuC releases starting from DG2/MTL. Older HuC releases use the 111 * CSS-based layout instead. Differently from the CSS headers, the GSC headers 112 * uses a directory + entries structure (i.e., there is array of addresses 113 * pointing to specific header extensions identified by a name). Although the 114 * header structures are the same, some of the entries are specific to GSC while 115 * others are specific to HuC. The manifest header entry, which includes basic 116 * information about the binary (like the version) is always present, but it is 117 * named differently based on the binary type. 118 * 119 * The HuC binary starts with a Code Partition Directory (CPD) header. The 120 * entries we're interested in for use in the driver are: 121 * 122 * 1. "HUCP.man": points to the manifest header for the HuC. 123 * 2. "huc_fw": points to the FW code. On platforms that support load via DMA 124 * and 2-step HuC authentication (i.e. MTL+) this is a full CSS-based binary, 125 * while if the GSC is the one doing the load (which only happens on DG2) 126 * this section only contains the uCode. 127 * 128 * The GSC-based HuC firmware layout looks like this:: 129 * 130 * +================================================+ 131 * | CPD Header | 132 * +================================================+ 133 * | CPD entries[] | 134 * | entry1 | 135 * | ... | 136 * | entryX | 137 * | "HUCP.man" | 138 * | ... | 139 * | offset >----------------------------|------o 140 * | ... | | 141 * | entryY | | 142 * | "huc_fw" | | 143 * | ... | | 144 * | offset >----------------------------|----------o 145 * +================================================+ | | 146 * | | 147 * +================================================+ | | 148 * | Manifest Header |<-----o | 149 * | ... | | 150 * | FW version | | 151 * | ... | | 152 * +================================================+ | 153 * | 154 * +================================================+ | 155 * | FW binary |<---------o 156 * | CSS (MTL+ only) | 157 * | uCode | 158 * | RSA Key (MTL+ only) | 159 * | ... | 160 * +================================================+ 161 * 162 * The GSC binary starts instead with a layout header, which contains the 163 * locations of the various partitions of the binary. The one we're interested 164 * in is the boot1 partition, where we can find a BPDT header followed by 165 * entries, one of which points to the RBE sub-section of the partition, which 166 * contains the CPD. The GSC blob does not contain a CSS-based binary, so we 167 * only need to look for the manifest, which is under the "RBEP.man" CPD entry. 168 * Note that we have no need to find where the actual FW code is inside the 169 * image because the GSC ROM will itself parse the headers to find it and load 170 * it. 171 * The GSC firmware header layout looks like this:: 172 * 173 * +================================================+ 174 * | Layout Pointers | 175 * | ... | 176 * | Boot1 offset >---------------------------|------o 177 * | ... | | 178 * +================================================+ | 179 * | 180 * +================================================+ | 181 * | BPDT header |<-----o 182 * +================================================+ 183 * | BPDT entries[] | 184 * | entry1 | 185 * | ... | 186 * | entryX | 187 * | type == GSC_RBE | 188 * | offset >-----------------------------|------o 189 * | ... | | 190 * +================================================+ | 191 * | 192 * +================================================+ | 193 * | CPD Header |<-----o 194 * +================================================+ 195 * | CPD entries[] | 196 * | entry1 | 197 * | ... | 198 * | entryX | 199 * | "RBEP.man" | 200 * | ... | 201 * | offset >----------------------------|------o 202 * | ... | | 203 * +================================================+ | 204 * | 205 * +================================================+ | 206 * | Manifest Header |<-----o 207 * | ... | 208 * | FW version | 209 * | ... | 210 * | Security version | 211 * | ... | 212 * +================================================+ 213 */ 214 215 struct gsc_version { 216 u16 major; 217 u16 minor; 218 u16 hotfix; 219 u16 build; 220 } __packed; 221 222 struct gsc_partition { 223 u32 offset; 224 u32 size; 225 } __packed; 226 227 struct gsc_layout_pointers { 228 u8 rom_bypass_vector[16]; 229 230 /* size of this header section, not including ROM bypass vector */ 231 u16 size; 232 233 /* 234 * bit0: Backup copy of layout pointers exists 235 * bits1-15: reserved 236 */ 237 u8 flags; 238 239 u8 reserved; 240 241 u32 crc32; 242 243 struct gsc_partition datap; 244 struct gsc_partition boot1; 245 struct gsc_partition boot2; 246 struct gsc_partition boot3; 247 struct gsc_partition boot4; 248 struct gsc_partition boot5; 249 struct gsc_partition temp_pages; 250 } __packed; 251 252 /* Boot partition structures */ 253 struct gsc_bpdt_header { 254 u32 signature; 255 #define GSC_BPDT_HEADER_SIGNATURE 0x000055AA 256 257 u16 descriptor_count; /* num of entries after the header */ 258 259 u8 version; 260 u8 configuration; 261 262 u32 crc32; 263 264 u32 build_version; 265 struct gsc_version tool_version; 266 } __packed; 267 268 struct gsc_bpdt_entry { 269 /* 270 * Bits 0-15: BPDT entry type 271 * Bits 16-17: reserved 272 * Bit 18: code sub-partition 273 * Bits 19-31: reserved 274 */ 275 u32 type; 276 #define GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15, 0) 277 #define GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1 278 279 u32 sub_partition_offset; /* from the base of the BPDT header */ 280 u32 sub_partition_size; 281 } __packed; 282 283 /* Code partition directory (CPD) structures */ 284 struct gsc_cpd_header_v2 { 285 u32 header_marker; 286 #define GSC_CPD_HEADER_MARKER 0x44504324 287 288 u32 num_of_entries; 289 u8 header_version; 290 u8 entry_version; 291 u8 header_length; /* in bytes */ 292 u8 flags; 293 u32 partition_name; 294 u32 crc32; 295 } __packed; 296 297 struct gsc_cpd_entry { 298 u8 name[12]; 299 300 /* 301 * Bits 0-24: offset from the beginning of the code partition 302 * Bit 25: huffman compressed 303 * Bits 26-31: reserved 304 */ 305 u32 offset; 306 #define GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0) 307 #define GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25) 308 309 /* 310 * Module/Item length, in bytes. For Huffman-compressed modules, this 311 * refers to the uncompressed size. For software-compressed modules, 312 * this refers to the compressed size. 313 */ 314 u32 length; 315 316 u8 reserved[4]; 317 } __packed; 318 319 struct gsc_manifest_header { 320 u32 header_type; /* 0x4 for manifest type */ 321 u32 header_length; /* in dwords */ 322 u32 header_version; 323 u32 flags; 324 u32 vendor; 325 u32 date; 326 u32 size; /* In dwords, size of entire manifest (header + extensions) */ 327 u32 header_id; 328 u32 internal_data; 329 struct gsc_version fw_version; 330 u32 security_version; 331 struct gsc_version meu_kit_version; 332 u32 meu_manifest_version; 333 u8 general_data[4]; 334 u8 reserved3[56]; 335 u32 modulus_size; /* in dwords */ 336 u32 exponent_size; /* in dwords */ 337 } __packed; 338 339 /** 340 * DOC: Late binding Firmware Layout 341 * 342 * The Late binding binary starts with FPT header, which contains locations 343 * of various partitions of the binary. Here we're interested in finding out 344 * manifest version. To the manifest version, we need to locate CPD header 345 * one of the entry in CPD header points to manifest header. Manifest header 346 * contains the version. 347 * 348 * +================================================+ 349 * | FPT Header | 350 * +================================================+ 351 * | FPT entries[] | 352 * | entry1 | 353 * | ... | 354 * | entryX | 355 * | "LTES" | 356 * | ... | 357 * | offset >-----------------------------|------o 358 * +================================================+ | 359 * | 360 * +================================================+ | 361 * | CPD Header |<-----o 362 * +================================================+ 363 * | CPD entries[] | 364 * | entry1 | 365 * | ... | 366 * | entryX | 367 * | "LTES.man" | 368 * | ... | 369 * | offset >----------------------------|------o 370 * +================================================+ | 371 * | 372 * +================================================+ | 373 * | Manifest Header |<-----o 374 * | ... | 375 * | FW version | 376 * | ... | 377 * +================================================+ 378 */ 379 380 /* FPT Headers */ 381 struct csc_fpt_header { 382 u32 header_marker; 383 #define CSC_FPT_HEADER_MARKER 0x54504624 384 u32 num_of_entries; 385 u8 header_version; 386 u8 entry_version; 387 u8 header_length; /* in bytes */ 388 u8 flags; 389 u16 ticks_to_add; 390 u16 tokens_to_add; 391 u32 uma_size; 392 u32 crc32; 393 struct gsc_version fitc_version; 394 } __packed; 395 396 struct csc_fpt_entry { 397 u8 name[4]; /* partition name */ 398 u32 reserved1; 399 u32 offset; /* offset from beginning of CSE region */ 400 u32 length; /* partition length in bytes */ 401 u32 reserved2[3]; 402 u32 partition_flags; 403 } __packed; 404 405 #endif 406