blob: 87ade41209d0d6f10bd74e52b329a931d1903082 [file] [log] [blame]
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2022 Intel Corporation
*/
#ifndef _XE_UC_FW_ABI_H
#define _XE_UC_FW_ABI_H
#include <linux/build_bug.h>
#include <linux/types.h>
/**
* DOC: CSS-based Firmware Layout
*
* The CSS-based firmware structure is used for GuC releases on all platforms
* and for HuC releases up to DG1. Starting from DG2/MTL the HuC uses the GSC
* layout instead.
* The CSS firmware layout looks like this::
*
* +======================================================================+
* | Firmware blob |
* +===============+===============+============+============+============+
* | CSS header | uCode | RSA key | modulus | exponent |
* +===============+===============+============+============+============+
* <-header size-> <---header size continued ----------->
* <--- size ----------------------------------------------------------->
* <-key size->
* <-mod size->
* <-exp size->
*
* The firmware may or may not have modulus key and exponent data. The header,
* uCode and RSA signature are must-have components that will be used by driver.
* Length of each components, which is all in dwords, can be found in header.
* In the case that modulus and exponent are not present in fw, a.k.a truncated
* image, the length value still appears in header.
*
* Driver will do some basic fw size validation based on the following rules:
*
* 1. Header, uCode and RSA are must-have components.
* 2. All firmware components, if they present, are in the sequence illustrated
* in the layout table above.
* 3. Length info of each component can be found in header, in dwords.
* 4. Modulus and exponent key are not required by driver. They may not appear
* in fw. So driver will load a truncated firmware in this case.
*/
struct uc_css_header {
u32 module_type;
/*
* header_size includes all non-uCode bits, including css_header, rsa
* key, modulus key and exponent data.
*/
u32 header_size_dw;
u32 header_version;
u32 module_id;
u32 module_vendor;
u32 date;
#define CSS_DATE_DAY (0xFF << 0)
#define CSS_DATE_MONTH (0xFF << 8)
#define CSS_DATE_YEAR (0xFFFF << 16)
u32 size_dw; /* uCode plus header_size_dw */
u32 key_size_dw;
u32 modulus_size_dw;
u32 exponent_size_dw;
u32 time;
#define CSS_TIME_HOUR (0xFF << 0)
#define CSS_DATE_MIN (0xFF << 8)
#define CSS_DATE_SEC (0xFFFF << 16)
char username[8];
char buildnumber[12];
u32 sw_version;
#define CSS_SW_VERSION_UC_MAJOR (0xFF << 16)
#define CSS_SW_VERSION_UC_MINOR (0xFF << 8)
#define CSS_SW_VERSION_UC_PATCH (0xFF << 0)
union {
u32 submission_version; /* only applies to GuC */
u32 reserved2;
};
u32 reserved0[12];
union {
u32 private_data_size; /* only applies to GuC */
u32 reserved1;
};
u32 header_info;
} __packed;
static_assert(sizeof(struct uc_css_header) == 128);
/**
* DOC: GSC-based Firmware Layout
*
* The GSC-based firmware structure is used for GSC releases on all platforms
* and for HuC releases starting from DG2/MTL. Older HuC releases use the
* CSS-based layout instead. Differently from the CSS headers, the GSC headers
* uses a directory + entries structure (i.e., there is array of addresses
* pointing to specific header extensions identified by a name). Although the
* header structures are the same, some of the entries are specific to GSC while
* others are specific to HuC. The manifest header entry, which includes basic
* information about the binary (like the version) is always present, but it is
* named differently based on the binary type.
*
* The HuC binary starts with a Code Partition Directory (CPD) header. The
* entries we're interested in for use in the driver are:
*
* 1. "HUCP.man": points to the manifest header for the HuC.
* 2. "huc_fw": points to the FW code. On platforms that support load via DMA
* and 2-step HuC authentication (i.e. MTL+) this is a full CSS-based binary,
* while if the GSC is the one doing the load (which only happens on DG2)
* this section only contains the uCode.
*
* The GSC-based HuC firmware layout looks like this::
*
* +================================================+
* | CPD Header |
* +================================================+
* | CPD entries[] |
* | entry1 |
* | ... |
* | entryX |
* | "HUCP.man" |
* | ... |
* | offset >----------------------------|------o
* | ... | |
* | entryY | |
* | "huc_fw" | |
* | ... | |
* | offset >----------------------------|----------o
* +================================================+ | |
* | |
* +================================================+ | |
* | Manifest Header |<-----o |
* | ... | |
* | FW version | |
* | ... | |
* +================================================+ |
* |
* +================================================+ |
* | FW binary |<---------o
* | CSS (MTL+ only) |
* | uCode |
* | RSA Key (MTL+ only) |
* | ... |
* +================================================+
*
* The GSC binary starts instead with a layout header, which contains the
* locations of the various partitions of the binary. The one we're interested
* in is the boot1 partition, where we can find a BPDT header followed by
* entries, one of which points to the RBE sub-section of the partition, which
* contains the CPD. The GSC blob does not contain a CSS-based binary, so we
* only need to look for the manifest, which is under the "RBEP.man" CPD entry.
* Note that we have no need to find where the actual FW code is inside the
* image because the GSC ROM will itself parse the headers to find it and load
* it.
* The GSC firmware header layout looks like this::
*
* +================================================+
* | Layout Pointers |
* | ... |
* | Boot1 offset >---------------------------|------o
* | ... | |
* +================================================+ |
* |
* +================================================+ |
* | BPDT header |<-----o
* +================================================+
* | BPDT entries[] |
* | entry1 |
* | ... |
* | entryX |
* | type == GSC_RBE |
* | offset >-----------------------------|------o
* | ... | |
* +================================================+ |
* |
* +================================================+ |
* | CPD Header |<-----o
* +================================================+
* | CPD entries[] |
* | entry1 |
* | ... |
* | entryX |
* | "RBEP.man" |
* | ... |
* | offset >----------------------------|------o
* | ... | |
* +================================================+ |
* |
* +================================================+ |
* | Manifest Header |<-----o
* | ... |
* | FW version |
* | ... |
* | Security version |
* | ... |
* +================================================+
*/
struct gsc_version {
u16 major;
u16 minor;
u16 hotfix;
u16 build;
} __packed;
struct gsc_partition {
u32 offset;
u32 size;
} __packed;
struct gsc_layout_pointers {
u8 rom_bypass_vector[16];
/* size of this header section, not including ROM bypass vector */
u16 size;
/*
* bit0: Backup copy of layout pointers exists
* bits1-15: reserved
*/
u8 flags;
u8 reserved;
u32 crc32;
struct gsc_partition datap;
struct gsc_partition boot1;
struct gsc_partition boot2;
struct gsc_partition boot3;
struct gsc_partition boot4;
struct gsc_partition boot5;
struct gsc_partition temp_pages;
} __packed;
/* Boot partition structures */
struct gsc_bpdt_header {
u32 signature;
#define GSC_BPDT_HEADER_SIGNATURE 0x000055AA
u16 descriptor_count; /* num of entries after the header */
u8 version;
u8 configuration;
u32 crc32;
u32 build_version;
struct gsc_version tool_version;
} __packed;
struct gsc_bpdt_entry {
/*
* Bits 0-15: BPDT entry type
* Bits 16-17: reserved
* Bit 18: code sub-partition
* Bits 19-31: reserved
*/
u32 type;
#define GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15, 0)
#define GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1
u32 sub_partition_offset; /* from the base of the BPDT header */
u32 sub_partition_size;
} __packed;
/* Code partition directory (CPD) structures */
struct gsc_cpd_header_v2 {
u32 header_marker;
#define GSC_CPD_HEADER_MARKER 0x44504324
u32 num_of_entries;
u8 header_version;
u8 entry_version;
u8 header_length; /* in bytes */
u8 flags;
u32 partition_name;
u32 crc32;
} __packed;
struct gsc_cpd_entry {
u8 name[12];
/*
* Bits 0-24: offset from the beginning of the code partition
* Bit 25: huffman compressed
* Bits 26-31: reserved
*/
u32 offset;
#define GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
#define GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
/*
* Module/Item length, in bytes. For Huffman-compressed modules, this
* refers to the uncompressed size. For software-compressed modules,
* this refers to the compressed size.
*/
u32 length;
u8 reserved[4];
} __packed;
struct gsc_manifest_header {
u32 header_type; /* 0x4 for manifest type */
u32 header_length; /* in dwords */
u32 header_version;
u32 flags;
u32 vendor;
u32 date;
u32 size; /* In dwords, size of entire manifest (header + extensions) */
u32 header_id;
u32 internal_data;
struct gsc_version fw_version;
u32 security_version;
struct gsc_version meu_kit_version;
u32 meu_manifest_version;
u8 general_data[4];
u8 reserved3[56];
u32 modulus_size; /* in dwords */
u32 exponent_size; /* in dwords */
} __packed;
#endif