/* 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 { … } __packed; static_assert(…); /** * 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 { … } __packed; struct gsc_partition { … } __packed; struct gsc_layout_pointers { … } __packed; /* Boot partition structures */ struct gsc_bpdt_header { … } __packed; struct gsc_bpdt_entry { … } __packed; /* Code partition directory (CPD) structures */ struct gsc_cpd_header_v2 { … } __packed; struct gsc_cpd_entry { … } __packed; struct gsc_manifest_header { … } __packed; #endif