322 lines · c
1/* SPDX-License-Identifier: MIT */2/*3 * Copyright © 2022 Intel Corporation4 */5 6#ifndef _XE_UC_FW_ABI_H7#define _XE_UC_FW_ABI_H8 9#include <linux/build_bug.h>10#include <linux/types.h>11 12/**13 * DOC: CSS-based Firmware Layout14 *15 * The CSS-based firmware structure is used for GuC releases on all platforms16 * and for HuC releases up to DG1. Starting from DG2/MTL the HuC uses the GSC17 * 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 truncated35 * 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 illustrated41 * 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 appear44 * in fw. So driver will load a truncated firmware in this case.45 */46 47struct uc_css_header {48 u32 module_type;49 /*50 * header_size includes all non-uCode bits, including css_header, rsa51 * 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;86static_assert(sizeof(struct uc_css_header) == 128);87 88/**89 * DOC: GSC-based Firmware Layout90 *91 * The GSC-based firmware structure is used for GSC releases on all platforms92 * and for HuC releases starting from DG2/MTL. Older HuC releases use the93 * CSS-based layout instead. Differently from the CSS headers, the GSC headers94 * uses a directory + entries structure (i.e., there is array of addresses95 * pointing to specific header extensions identified by a name). Although the96 * header structures are the same, some of the entries are specific to GSC while97 * others are specific to HuC. The manifest header entry, which includes basic98 * information about the binary (like the version) is always present, but it is99 * named differently based on the binary type.100 *101 * The HuC binary starts with a Code Partition Directory (CPD) header. The102 * 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 DMA106 * 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 >----------------------------|------o122 * | ... | |123 * | entryY | |124 * | "huc_fw" | |125 * | ... | |126 * | offset >----------------------------|----------o127 * +================================================+ | |128 * | |129 * +================================================+ | |130 * | Manifest Header |<-----o |131 * | ... | |132 * | FW version | |133 * | ... | |134 * +================================================+ |135 * |136 * +================================================+ |137 * | FW binary |<---------o138 * | 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 the145 * locations of the various partitions of the binary. The one we're interested146 * in is the boot1 partition, where we can find a BPDT header followed by147 * entries, one of which points to the RBE sub-section of the partition, which148 * contains the CPD. The GSC blob does not contain a CSS-based binary, so we149 * 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 the151 * image because the GSC ROM will itself parse the headers to find it and load152 * it.153 * The GSC firmware header layout looks like this::154 *155 * +================================================+156 * | Layout Pointers |157 * | ... |158 * | Boot1 offset >---------------------------|------o159 * | ... | |160 * +================================================+ |161 * |162 * +================================================+ |163 * | BPDT header |<-----o164 * +================================================+165 * | BPDT entries[] |166 * | entry1 |167 * | ... |168 * | entryX |169 * | type == GSC_RBE |170 * | offset >-----------------------------|------o171 * | ... | |172 * +================================================+ |173 * |174 * +================================================+ |175 * | CPD Header |<-----o176 * +================================================+177 * | CPD entries[] |178 * | entry1 |179 * | ... |180 * | entryX |181 * | "RBEP.man" |182 * | ... |183 * | offset >----------------------------|------o184 * | ... | |185 * +================================================+ |186 * |187 * +================================================+ |188 * | Manifest Header |<-----o189 * | ... |190 * | FW version |191 * | ... |192 * | Security version |193 * | ... |194 * +================================================+195 */196 197struct gsc_version {198 u16 major;199 u16 minor;200 u16 hotfix;201 u16 build;202} __packed;203 204struct gsc_partition {205 u32 offset;206 u32 size;207} __packed;208 209struct 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 exists217 * bits1-15: reserved218 */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 */235struct gsc_bpdt_header {236 u32 signature;237#define GSC_BPDT_HEADER_SIGNATURE 0x000055AA238 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 250struct gsc_bpdt_entry {251 /*252 * Bits 0-15: BPDT entry type253 * Bits 16-17: reserved254 * Bit 18: code sub-partition255 * Bits 19-31: reserved256 */257 u32 type;258#define GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15, 0)259#define GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1260 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 */266struct gsc_cpd_header_v2 {267 u32 header_marker;268#define GSC_CPD_HEADER_MARKER 0x44504324269 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 279struct gsc_cpd_entry {280 u8 name[12];281 282 /*283 * Bits 0-24: offset from the beginning of the code partition284 * Bit 25: huffman compressed285 * Bits 26-31: reserved286 */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, this293 * 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 301struct 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#endif322