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_header { 48 u32 module_type; 49 /* 50 * header_size includes all non-uCode bits, including css_header, rsa 51 * key, modulus key and exponent data. 52 */ 53 u32 header_size_dw; 54 u32 header_version; 55 u32 module_id; 56 u32 module_vendor; 57 u32 date; 58 #define CSS_DATE_DAY (0xFF << 0) 59 #define CSS_DATE_MONTH (0xFF << 8) 60 #define CSS_DATE_YEAR (0xFFFF << 16) 61 u32 size_dw; /* uCode plus header_size_dw */ 62 u32 key_size_dw; 63 u32 modulus_size_dw; 64 u32 exponent_size_dw; 65 u32 time; 66 #define CSS_TIME_HOUR (0xFF << 0) 67 #define CSS_DATE_MIN (0xFF << 8) 68 #define CSS_DATE_SEC (0xFFFF << 16) 69 char username[8]; 70 char buildnumber[12]; 71 u32 sw_version; 72 #define CSS_SW_VERSION_UC_MAJOR (0xFF << 16) 73 #define CSS_SW_VERSION_UC_MINOR (0xFF << 8) 74 #define CSS_SW_VERSION_UC_PATCH (0xFF << 0) 75 union { 76 u32 submission_version; /* only applies to GuC */ 77 u32 reserved2; 78 }; 79 u32 reserved0[12]; 80 union { 81 u32 private_data_size; /* only applies to GuC */ 82 u32 reserved1; 83 }; 84 u32 header_info; 85 } __packed; 86 static_assert(sizeof(struct uc_css_header) == 128); 87 88 /** 89 * DOC: GSC-based Firmware Layout 90 * 91 * The GSC-based firmware structure is used for GSC releases on all platforms 92 * and for HuC releases starting from DG2/MTL. Older HuC releases use the 93 * CSS-based layout instead. Differently from the CSS headers, the GSC headers 94 * uses a directory + entries structure (i.e., there is array of addresses 95 * pointing to specific header extensions identified by a name). Although the 96 * header structures are the same, some of the entries are specific to GSC while 97 * others are specific to HuC. The manifest header entry, which includes basic 98 * information about the binary (like the version) is always present, but it is 99 * named differently based on the binary type. 100 * 101 * The HuC binary starts with a Code Partition Directory (CPD) header. The 102 * entries we're interested in for use in the driver are: 103 * 104 * 1. "HUCP.man": points to the manifest header for the HuC. 105 * 2. "huc_fw": points to the FW code. On platforms that support load via DMA 106 * and 2-step HuC authentication (i.e. MTL+) this is a full CSS-based binary, 107 * while if the GSC is the one doing the load (which only happens on DG2) 108 * this section only contains the uCode. 109 * 110 * The GSC-based HuC firmware layout looks like this:: 111 * 112 * +================================================+ 113 * | CPD Header | 114 * +================================================+ 115 * | CPD entries[] | 116 * | entry1 | 117 * | ... | 118 * | entryX | 119 * | "HUCP.man" | 120 * | ... | 121 * | offset >----------------------------|------o 122 * | ... | | 123 * | entryY | | 124 * | "huc_fw" | | 125 * | ... | | 126 * | offset >----------------------------|----------o 127 * +================================================+ | | 128 * | | 129 * +================================================+ | | 130 * | Manifest Header |<-----o | 131 * | ... | | 132 * | FW version | | 133 * | ... | | 134 * +================================================+ | 135 * | 136 * +================================================+ | 137 * | FW binary |<---------o 138 * | CSS (MTL+ only) | 139 * | uCode | 140 * | RSA Key (MTL+ only) | 141 * | ... | 142 * +================================================+ 143 * 144 * The GSC binary starts instead with a layout header, which contains the 145 * locations of the various partitions of the binary. The one we're interested 146 * in is the boot1 partition, where we can find a BPDT header followed by 147 * entries, one of which points to the RBE sub-section of the partition, which 148 * contains the CPD. The GSC blob does not contain a CSS-based binary, so we 149 * only need to look for the manifest, which is under the "RBEP.man" CPD entry. 150 * Note that we have no need to find where the actual FW code is inside the 151 * image because the GSC ROM will itself parse the headers to find it and load 152 * it. 153 * The GSC firmware header layout looks like this:: 154 * 155 * +================================================+ 156 * | Layout Pointers | 157 * | ... | 158 * | Boot1 offset >---------------------------|------o 159 * | ... | | 160 * +================================================+ | 161 * | 162 * +================================================+ | 163 * | BPDT header |<-----o 164 * +================================================+ 165 * | BPDT entries[] | 166 * | entry1 | 167 * | ... | 168 * | entryX | 169 * | type == GSC_RBE | 170 * | offset >-----------------------------|------o 171 * | ... | | 172 * +================================================+ | 173 * | 174 * +================================================+ | 175 * | CPD Header |<-----o 176 * +================================================+ 177 * | CPD entries[] | 178 * | entry1 | 179 * | ... | 180 * | entryX | 181 * | "RBEP.man" | 182 * | ... | 183 * | offset >----------------------------|------o 184 * | ... | | 185 * +================================================+ | 186 * | 187 * +================================================+ | 188 * | Manifest Header |<-----o 189 * | ... | 190 * | FW version | 191 * | ... | 192 * | Security version | 193 * | ... | 194 * +================================================+ 195 */ 196 197 struct gsc_version { 198 u16 major; 199 u16 minor; 200 u16 hotfix; 201 u16 build; 202 } __packed; 203 204 struct gsc_partition { 205 u32 offset; 206 u32 size; 207 } __packed; 208 209 struct gsc_layout_pointers { 210 u8 rom_bypass_vector[16]; 211 212 /* size of this header section, not including ROM bypass vector */ 213 u16 size; 214 215 /* 216 * bit0: Backup copy of layout pointers exists 217 * bits1-15: reserved 218 */ 219 u8 flags; 220 221 u8 reserved; 222 223 u32 crc32; 224 225 struct gsc_partition datap; 226 struct gsc_partition boot1; 227 struct gsc_partition boot2; 228 struct gsc_partition boot3; 229 struct gsc_partition boot4; 230 struct gsc_partition boot5; 231 struct gsc_partition temp_pages; 232 } __packed; 233 234 /* Boot partition structures */ 235 struct gsc_bpdt_header { 236 u32 signature; 237 #define GSC_BPDT_HEADER_SIGNATURE 0x000055AA 238 239 u16 descriptor_count; /* num of entries after the header */ 240 241 u8 version; 242 u8 configuration; 243 244 u32 crc32; 245 246 u32 build_version; 247 struct gsc_version tool_version; 248 } __packed; 249 250 struct gsc_bpdt_entry { 251 /* 252 * Bits 0-15: BPDT entry type 253 * Bits 16-17: reserved 254 * Bit 18: code sub-partition 255 * Bits 19-31: reserved 256 */ 257 u32 type; 258 #define GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15, 0) 259 #define GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1 260 261 u32 sub_partition_offset; /* from the base of the BPDT header */ 262 u32 sub_partition_size; 263 } __packed; 264 265 /* Code partition directory (CPD) structures */ 266 struct gsc_cpd_header_v2 { 267 u32 header_marker; 268 #define GSC_CPD_HEADER_MARKER 0x44504324 269 270 u32 num_of_entries; 271 u8 header_version; 272 u8 entry_version; 273 u8 header_length; /* in bytes */ 274 u8 flags; 275 u32 partition_name; 276 u32 crc32; 277 } __packed; 278 279 struct gsc_cpd_entry { 280 u8 name[12]; 281 282 /* 283 * Bits 0-24: offset from the beginning of the code partition 284 * Bit 25: huffman compressed 285 * Bits 26-31: reserved 286 */ 287 u32 offset; 288 #define GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0) 289 #define GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25) 290 291 /* 292 * Module/Item length, in bytes. For Huffman-compressed modules, this 293 * refers to the uncompressed size. For software-compressed modules, 294 * this refers to the compressed size. 295 */ 296 u32 length; 297 298 u8 reserved[4]; 299 } __packed; 300 301 struct gsc_manifest_header { 302 u32 header_type; /* 0x4 for manifest type */ 303 u32 header_length; /* in dwords */ 304 u32 header_version; 305 u32 flags; 306 u32 vendor; 307 u32 date; 308 u32 size; /* In dwords, size of entire manifest (header + extensions) */ 309 u32 header_id; 310 u32 internal_data; 311 struct gsc_version fw_version; 312 u32 security_version; 313 struct gsc_version meu_kit_version; 314 u32 meu_manifest_version; 315 u8 general_data[4]; 316 u8 reserved3[56]; 317 u32 modulus_size; /* in dwords */ 318 u32 exponent_size; /* in dwords */ 319 } __packed; 320 321 #endif 322