Skip to content

Commit

Permalink
drm/i915/huc: Unified css_header struct for GuC and HuC
Browse files Browse the repository at this point in the history
HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v4: rebased on top of drm-tip.Update dev to dev_priv in
intel_uc_fw_fetch.
v5: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.
v6: rebased. Change fw_type to enum.
v7: rebased. Rename the enum fw_type to intel_uc_fw_type.

Cc: Michal Wajdeczko <michal.wajdeczko.@intel.com>
Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1484356631-16139-3-git-send-email-anusha.srivatsa@intel.com
  • Loading branch information
Anusha Srivatsa authored and Jani Nikula committed Jan 18, 2017
1 parent db0a091 commit fbbad73
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 17 deletions.
23 changes: 19 additions & 4 deletions drivers/gpu/drm/i915/intel_guc_fwif.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
* The GuC firmware layout looks like this:
*
* +-------------------------------+
* | guc_css_header |
* | uc_css_header |
* | |
* | contains major/minor version |
* +-------------------------------+
Expand All @@ -172,9 +172,16 @@
* 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.
*
* HuC firmware layout is same as GuC firmware.
*
* HuC firmware css header is different. However, the only difference is where
* the version information is saved. The uc_css_header is unified to support
* both. Driver should get HuC version from uc_css_header.huc_sw_version, while
* uc_css_header.guc_sw_version for GuC.
*/

struct guc_css_header {
struct uc_css_header {
uint32_t module_type;
/* header_size includes all non-uCode bits, including css_header, rsa
* key, modulus key and exponent data. */
Expand Down Expand Up @@ -205,8 +212,16 @@ struct guc_css_header {

char username[8];
char buildnumber[12];
uint32_t device_id;
uint32_t guc_sw_version;
union {
struct {
uint32_t branch_client_version;
uint32_t sw_version;
} guc;
struct {
uint32_t sw_version;
uint32_t reserved;
} huc;
};
uint32_t prod_preprod_fw;
uint32_t reserved[12];
uint32_t header_info;
Expand Down
41 changes: 28 additions & 13 deletions drivers/gpu/drm/i915/intel_guc_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
struct pci_dev *pdev = dev_priv->drm.pdev;
struct drm_i915_gem_object *obj;
const struct firmware *fw = NULL;
struct guc_css_header *css;
struct uc_css_header *css;
size_t size;
int err;

Expand All @@ -606,19 +606,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
uc_fw->path, fw);

/* Check the size of the blob before examining buffer contents */
if (fw->size < sizeof(struct guc_css_header)) {
if (fw->size < sizeof(struct uc_css_header)) {
DRM_NOTE("Firmware header is missing\n");
goto fail;
}

css = (struct guc_css_header *)fw->data;
css = (struct uc_css_header *)fw->data;

/* Firmware bits always start from header */
uc_fw->header_offset = 0;
uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
css->key_size_dw - css->exponent_size_dw) * sizeof(u32);

if (uc_fw->header_size != sizeof(struct guc_css_header)) {
if (uc_fw->header_size != sizeof(struct uc_css_header)) {
DRM_NOTE("CSS header definition mismatch\n");
goto fail;
}
Expand All @@ -642,21 +642,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
goto fail;
}

/* Header and uCode will be loaded to WOPCM. Size of the two. */
size = uc_fw->header_size + uc_fw->ucode_size;
if (size > guc_wopcm_size(dev_priv)) {
DRM_NOTE("Firmware is too large to fit in WOPCM\n");
goto fail;
}

/*
* The GuC firmware image has the version number embedded at a well-known
* offset within the firmware blob; note that major / minor version are
* TWO bytes each (i.e. u16), although all pointers and offsets are defined
* in terms of bytes (u8).
*/
uc_fw->major_ver_found = css->guc_sw_version >> 16;
uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
switch (uc_fw->fw) {
case INTEL_UC_FW_TYPE_GUC:
/* Header and uCode will be loaded to WOPCM. Size of the two. */
size = uc_fw->header_size + uc_fw->ucode_size;

/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
if (size > guc_wopcm_size(dev_priv)) {
DRM_ERROR("Firmware is too large to fit in WOPCM\n");
goto fail;
}
uc_fw->major_ver_found = css->guc.sw_version >> 16;
uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
break;

case INTEL_UC_FW_TYPE_HUC:
uc_fw->major_ver_found = css->huc.sw_version >> 16;
uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
break;

default:
DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
err = -ENOEXEC;
goto fail;
}

if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/i915/intel_uc.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ enum intel_uc_fw_status {
INTEL_UC_FIRMWARE_SUCCESS
};

enum intel_uc_fw_type {
INTEL_UC_FW_TYPE_GUC,
INTEL_UC_FW_TYPE_HUC
};

/*
* This structure encapsulates all the data needed during the process
* of fetching, caching, and loading the firmware image into the GuC.
Expand All @@ -116,6 +121,7 @@ struct intel_uc_fw {
uint16_t major_ver_found;
uint16_t minor_ver_found;

enum intel_uc_fw_type fw;
uint32_t header_size;
uint32_t header_offset;
uint32_t rsa_size;
Expand Down

0 comments on commit fbbad73

Please sign in to comment.