// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 */

#include <linux/bitfield.h>
#include <linux/fault-inject.h>
#include <linux/firmware.h>

#include <drm/drm_managed.h>

#include "regs/xe_guc_regs.h"
#include "xe_bo.h"
#include "xe_device_types.h"
#include "xe_force_wake.h"
#include "xe_gsc.h"
#include "xe_gt.h"
#include "xe_gt_printk.h"
#include "xe_gt_sriov_vf.h"
#include "xe_guc.h"
#include "xe_map.h"
#include "xe_mmio.h"
#include "xe_module.h"
#include "xe_sriov.h"
#include "xe_uc_fw.h"

/*
 * List of required GuC and HuC binaries per-platform. They must be ordered
 * based on platform, from newer to older.
 *
 * Versioning follows the guidelines from
 * Documentation/driver-api/firmware/firmware-usage-guidelines.rst. There is a
 * distinction for platforms being officially supported by the driver or not.
 * Platforms not available publicly or not yet officially supported by the
 * driver (under force-probe), use the mmp_ver(): the firmware autoselect logic
 * will select the firmware from disk with filename that matches the full
 * "mpp version", i.e. major.minor.patch. mmp_ver() should only be used for
 * this case.
 *
 * For platforms officially supported by the driver, the filename always only
 * ever contains the major version (GuC) or no version at all (HuC).
 *
 * After loading the file, the driver parses the versions embedded in the blob.
 * The major version needs to match a major version supported by the driver (if
 * any). The minor version is also checked and a notice emitted to the log if
 * the version found is smaller than the version wanted. This is done only for
 * informational purposes so users may have a chance to upgrade, but the driver
 * still loads and use the older firmware.
 *
 * Examples:
 *
 *	1) Platform officially supported by i915 - using Tigerlake as example.
 *	   Driver loads the following firmware blobs from disk:
 *
 *		- i915/tgl_guc_<major>.bin
 *		- i915/tgl_huc.bin
 *
 *	   <major> number for GuC is checked that it matches the version inside
 *	   the blob. <minor> version is checked and if smaller than the expected
 *	   an info message is emitted about that.
 *
 *	1) XE_<FUTUREINTELPLATFORM>, still under require_force_probe. Using
 *	   "wipplat" as a short-name. Driver loads the following firmware blobs
 *	   from disk:
 *
 *		- xe/wipplat_guc_<major>.<minor>.<patch>.bin
 *		- xe/wipplat_huc_<major>.<minor>.<patch>.bin
 *
 *	   <major> and <minor> are checked that they match the version inside
 *	   the blob. Both of them need to match exactly what the driver is
 *	   expecting, otherwise it fails.
 *
 *	3) Platform officially supported by xe and out of force-probe. Using
 *	   "plat" as a short-name. Except for the different directory, the
 *	   behavior is the same as (1). Driver loads the following firmware
 *	   blobs from disk:
 *
 *		- xe/plat_guc_<major>.bin
 *		- xe/plat_huc.bin
 *
 *	   <major> number for GuC is checked that it matches the version inside
 *	   the blob. <minor> version is checked and if smaller than the expected
 *	   an info message is emitted about that.
 *
 * For the platforms already released with a major version, they should never be
 * removed from the table. Instead new entries with newer versions may be added
 * before them, so they take precedence.
 *
 * TODO: Currently there's no fallback on major version. That's because xe
 * driver only supports the one major version of each firmware in the table.
 * This needs to be fixed when the major version of GuC is updated.
 */

struct uc_fw_entry {
	enum xe_platform platform;
	enum xe_gt_type gt_type;

	struct {
		const char *path;
		u16 major;
		u16 minor;
		u16 patch;
		bool full_ver_required;
	};
};

struct fw_blobs_by_type {
	const struct uc_fw_entry *entries;
	u32 count;
};

/*
 * Add an "ANY" define just to convey the meaning it's given here.
 */
#define XE_GT_TYPE_ANY XE_GT_TYPE_UNINITIALIZED

#define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver)					\
	fw_def(PANTHERLAKE,	GT_TYPE_ANY,	major_ver(xe,	guc,	ptl,	70, 47, 0))	\
	fw_def(BATTLEMAGE,	GT_TYPE_ANY,	major_ver(xe,	guc,	bmg,	70, 45, 2))	\
	fw_def(LUNARLAKE,	GT_TYPE_ANY,	major_ver(xe,	guc,	lnl,	70, 45, 2))	\
	fw_def(METEORLAKE,	GT_TYPE_ANY,	major_ver(i915,	guc,	mtl,	70, 44, 1))	\
	fw_def(DG2,		GT_TYPE_ANY,	major_ver(i915,	guc,	dg2,	70, 45, 2))	\
	fw_def(DG1,		GT_TYPE_ANY,	major_ver(i915,	guc,	dg1,	70, 44, 1))	\
	fw_def(ALDERLAKE_N,	GT_TYPE_ANY,	major_ver(i915,	guc,	tgl,	70, 44, 1))	\
	fw_def(ALDERLAKE_P,	GT_TYPE_ANY,	major_ver(i915,	guc,	adlp,	70, 44, 1))	\
	fw_def(ALDERLAKE_S,	GT_TYPE_ANY,	major_ver(i915,	guc,	tgl,	70, 44, 1))	\
	fw_def(ROCKETLAKE,	GT_TYPE_ANY,	major_ver(i915,	guc,	tgl,	70, 44, 1))	\
	fw_def(TIGERLAKE,	GT_TYPE_ANY,	major_ver(i915,	guc,	tgl,	70, 44, 1))

#define XE_HUC_FIRMWARE_DEFS(fw_def, mmp_ver, no_ver)		\
	fw_def(PANTHERLAKE,	GT_TYPE_ANY,	no_ver(xe,	huc,		ptl))		\
	fw_def(BATTLEMAGE,	GT_TYPE_ANY,	no_ver(xe,	huc,		bmg))		\
	fw_def(LUNARLAKE,	GT_TYPE_ANY,	no_ver(xe,	huc,		lnl))		\
	fw_def(METEORLAKE,	GT_TYPE_ANY,	no_ver(i915,	huc_gsc,	mtl))		\
	fw_def(DG1,		GT_TYPE_ANY,	no_ver(i915,	huc,		dg1))		\
	fw_def(ALDERLAKE_P,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))		\
	fw_def(ALDERLAKE_S,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))		\
	fw_def(ROCKETLAKE,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))		\
	fw_def(TIGERLAKE,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))

/* for the GSC FW we match the compatibility version and not the release one */
#define XE_GSC_FIRMWARE_DEFS(fw_def, major_ver)		\
	fw_def(LUNARLAKE,	GT_TYPE_ANY,	major_ver(xe,	gsc,	lnl,	104, 1, 0))	\
	fw_def(METEORLAKE,	GT_TYPE_ANY,	major_ver(i915,	gsc,	mtl,	102, 1, 0))

#define MAKE_FW_PATH(dir__, uc__, shortname__, version__)			\
	__stringify(dir__) "/" __stringify(shortname__) "_" __stringify(uc__) version__ ".bin"

#define fw_filename_mmp_ver(dir_, uc_, shortname_, a, b, c)			\
	MAKE_FW_PATH(dir_, uc_, shortname_, "_" __stringify(a ## . ## b ## . ## c))
#define fw_filename_major_ver(dir_, uc_, shortname_, a, b, c)			\
	MAKE_FW_PATH(dir_, uc_, shortname_, "_" __stringify(a))
#define fw_filename_no_ver(dir_, uc_, shortname_)				\
	MAKE_FW_PATH(dir_, uc_, shortname_, "")
#define fw_filename_gsc(dir_, uc_, shortname_, a, b, c)				\
	MAKE_FW_PATH(dir_, uc_, shortname_, "_" __stringify(b))

#define uc_fw_entry_mmp_ver(dir_, uc_, shortname_, a, b, c)			\
	{ fw_filename_mmp_ver(dir_, uc_, shortname_, a, b, c),			\
	  a, b, c, true }
#define uc_fw_entry_major_ver(dir_, uc_, shortname_, a, b, c)			\
	{ fw_filename_major_ver(dir_, uc_, shortname_, a, b, c),		\
	  a, b, c }
#define uc_fw_entry_no_ver(dir_, uc_, shortname_)				\
	{ fw_filename_no_ver(dir_, uc_, shortname_),				\
	  0, 0 }
#define uc_fw_entry_gsc(dir_, uc_, shortname_, a, b, c)				\
	{ fw_filename_gsc(dir_, uc_, shortname_, a, b, c),			\
	  a, b, c }

/* All blobs need to be declared via MODULE_FIRMWARE() */
#define XE_UC_MODULE_FIRMWARE(platform__, gt_type__, fw_filename)		\
	MODULE_FIRMWARE(fw_filename);

#define XE_UC_FW_ENTRY(platform__, gt_type__, entry__)				\
	{									\
		.platform = XE_ ## platform__,					\
		.gt_type = XE_ ## gt_type__,					\
		entry__,							\
	},

XE_GUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
		     fw_filename_mmp_ver, fw_filename_major_ver)
XE_HUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
		     fw_filename_mmp_ver, fw_filename_no_ver)
XE_GSC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE, fw_filename_gsc)

static struct xe_gt *
__uc_fw_to_gt(struct xe_uc_fw *uc_fw, enum xe_uc_fw_type type)
{
	XE_WARN_ON(type >= XE_UC_FW_NUM_TYPES);

	switch (type) {
	case XE_UC_FW_TYPE_GUC:
		return container_of(uc_fw, struct xe_gt, uc.guc.fw);
	case XE_UC_FW_TYPE_HUC:
		return container_of(uc_fw, struct xe_gt, uc.huc.fw);
	case XE_UC_FW_TYPE_GSC:
		return container_of(uc_fw, struct xe_gt, uc.gsc.fw);
	default:
		return NULL;
	}
}

static struct xe_gt *uc_fw_to_gt(struct xe_uc_fw *uc_fw)
{
	return __uc_fw_to_gt(uc_fw, uc_fw->type);
}

static struct xe_device *uc_fw_to_xe(struct xe_uc_fw *uc_fw)
{
	return gt_to_xe(uc_fw_to_gt(uc_fw));
}

static void
uc_fw_auto_select(struct xe_device *xe, struct xe_uc_fw *uc_fw)
{
	static const struct uc_fw_entry entries_guc[] = {
		XE_GUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
				     uc_fw_entry_mmp_ver,
				     uc_fw_entry_major_ver)
	};
	static const struct uc_fw_entry entries_huc[] = {
		XE_HUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
				     uc_fw_entry_mmp_ver,
				     uc_fw_entry_no_ver)
	};
	static const struct uc_fw_entry entries_gsc[] = {
		XE_GSC_FIRMWARE_DEFS(XE_UC_FW_ENTRY, uc_fw_entry_gsc)
	};
	static const struct fw_blobs_by_type blobs_all[XE_UC_FW_NUM_TYPES] = {
		[XE_UC_FW_TYPE_GUC] = { entries_guc, ARRAY_SIZE(entries_guc) },
		[XE_UC_FW_TYPE_HUC] = { entries_huc, ARRAY_SIZE(entries_huc) },
		[XE_UC_FW_TYPE_GSC] = { entries_gsc, ARRAY_SIZE(entries_gsc) },
	};
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	enum xe_platform p = xe->info.platform;
	const struct uc_fw_entry *entries;
	u32 count;
	int i;

	xe_gt_assert(gt, uc_fw->type < ARRAY_SIZE(blobs_all));
	xe_gt_assert(gt, gt->info.type != XE_GT_TYPE_UNINITIALIZED);

	entries = blobs_all[uc_fw->type].entries;
	count = blobs_all[uc_fw->type].count;

	for (i = 0; i < count && p <= entries[i].platform; i++) {
		if (p != entries[i].platform)
			continue;

		if (entries[i].gt_type != XE_GT_TYPE_ANY &&
		    entries[i].gt_type != gt->info.type)
			continue;

		uc_fw->path = entries[i].path;
		uc_fw->versions.wanted.major = entries[i].major;
		uc_fw->versions.wanted.minor = entries[i].minor;
		uc_fw->versions.wanted.patch = entries[i].patch;
		uc_fw->full_ver_required = entries[i].full_ver_required;

		if (uc_fw->type == XE_UC_FW_TYPE_GSC)
			uc_fw->versions.wanted_type = XE_UC_FW_VER_COMPATIBILITY;
		else
			uc_fw->versions.wanted_type = XE_UC_FW_VER_RELEASE;

		break;
	}
}

static void
uc_fw_override(struct xe_uc_fw *uc_fw)
{
	char *path_override = NULL;

	/* empty string disables, but it's not allowed for GuC */
	switch (uc_fw->type) {
	case XE_UC_FW_TYPE_GUC:
		if (xe_modparam.guc_firmware_path && *xe_modparam.guc_firmware_path)
			path_override = xe_modparam.guc_firmware_path;
		break;
	case XE_UC_FW_TYPE_HUC:
		path_override = xe_modparam.huc_firmware_path;
		break;
	case XE_UC_FW_TYPE_GSC:
		path_override = xe_modparam.gsc_firmware_path;
		break;
	default:
		break;
	}

	if (path_override) {
		uc_fw->path = path_override;
		uc_fw->user_overridden = true;
	}
}

/**
 * xe_uc_fw_copy_rsa - copy fw RSA to buffer
 *
 * @uc_fw: uC firmware
 * @dst: dst buffer
 * @max_len: max number of bytes to copy
 *
 * Return: number of copied bytes.
 */
size_t xe_uc_fw_copy_rsa(struct xe_uc_fw *uc_fw, void *dst, u32 max_len)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	u32 size = min_t(u32, uc_fw->rsa_size, max_len);

	xe_assert(xe, !(size % 4));
	xe_assert(xe, xe_uc_fw_is_available(uc_fw));

	xe_map_memcpy_from(xe, dst, &uc_fw->bo->vmap,
			   xe_uc_fw_rsa_offset(uc_fw), size);

	return size;
}

static void uc_fw_fini(struct drm_device *drm, void *arg)
{
	struct xe_uc_fw *uc_fw = arg;

	if (!xe_uc_fw_is_available(uc_fw))
		return;

	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_SELECTED);
}

static int guc_read_css_info(struct xe_uc_fw *uc_fw, struct uc_css_header *css)
{
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
	struct xe_uc_fw_version *compatibility = &uc_fw->versions.found[XE_UC_FW_VER_COMPATIBILITY];

	xe_gt_assert(gt, uc_fw->type == XE_UC_FW_TYPE_GUC);

	/* We don't support GuC releases older than 70.29.2 */
	if (MAKE_GUC_VER_STRUCT(*release) < MAKE_GUC_VER(70, 29, 2)) {
		xe_gt_err(gt, "Unsupported GuC v%u.%u.%u! v70.29.2 or newer is required\n",
			  release->major, release->minor, release->patch);
		return -EINVAL;
	}

	compatibility->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css->submission_version);
	compatibility->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css->submission_version);
	compatibility->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css->submission_version);

	uc_fw->private_data_size = css->private_data_size;

	return 0;
}

int xe_uc_fw_check_version_requirements(struct xe_uc_fw *uc_fw)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_uc_fw_version *wanted = &uc_fw->versions.wanted;
	struct xe_uc_fw_version *found = &uc_fw->versions.found[uc_fw->versions.wanted_type];

	/* Driver has no requirement on any version, any is good. */
	if (!wanted->major)
		return 0;

	/*
	 * If full version is required, both major and minor should match.
	 * Otherwise, at least the major version.
	 */
	if (wanted->major != found->major ||
	    (uc_fw->full_ver_required &&
	     ((wanted->minor != found->minor) ||
	      (wanted->patch != found->patch)))) {
		drm_notice(&xe->drm, "%s firmware %s: unexpected version: %u.%u.%u != %u.%u.%u\n",
			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			   found->major, found->minor, found->patch,
			   wanted->major, wanted->minor, wanted->patch);
		goto fail;
	}

	if (wanted->minor > found->minor ||
	    (wanted->minor == found->minor && wanted->patch > found->patch)) {
		drm_notice(&xe->drm, "%s firmware (%u.%u.%u) is recommended, but only (%u.%u.%u) was found in %s\n",
			   xe_uc_fw_type_repr(uc_fw->type),
			   wanted->major, wanted->minor, wanted->patch,
			   found->major, found->minor, found->patch,
			   uc_fw->path);
		drm_info(&xe->drm, "Consider updating your linux-firmware pkg or downloading from %s\n",
			 XE_UC_FIRMWARE_URL);
	}

	return 0;

fail:
	if (xe_uc_fw_is_overridden(uc_fw))
		return 0;

	return -ENOEXEC;
}

/* Refer to the "CSS-based Firmware Layout" documentation entry for details */
static int parse_css_header(struct xe_uc_fw *uc_fw, const void *fw_data, size_t fw_size)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
	struct uc_css_header *css;
	size_t size;

	/* Check the size of the blob before examining buffer contents */
	if (unlikely(fw_size < sizeof(struct uc_css_header))) {
		drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n",
			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			 fw_size, sizeof(struct uc_css_header));
		return -ENODATA;
	}

	css = (struct uc_css_header *)fw_data;

	/* Check integrity of size values inside CSS header */
	size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
		css->exponent_size_dw) * sizeof(u32);
	if (unlikely(size != sizeof(struct uc_css_header))) {
		drm_warn(&xe->drm,
			 "%s firmware %s: unexpected header size: %zu != %zu\n",
			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			 fw_size, sizeof(struct uc_css_header));
		return -EPROTO;
	}

	/* uCode size must calculated from other sizes */
	uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);

	/* now RSA */
	uc_fw->rsa_size = css->key_size_dw * sizeof(u32);

	/* At least, it should have header, uCode and RSA. Size of all three. */
	size = sizeof(struct uc_css_header) + uc_fw->ucode_size +
		uc_fw->rsa_size;
	if (unlikely(fw_size < size)) {
		drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n",
			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			 fw_size, size);
		return -ENOEXEC;
	}

	/* Get version numbers from the CSS header */
	release->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css->sw_version);
	release->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css->sw_version);
	release->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css->sw_version);

	if (uc_fw->type == XE_UC_FW_TYPE_GUC)
		return guc_read_css_info(uc_fw, css);

	return 0;
}

static bool is_cpd_header(const void *data)
{
	const u32 *marker = data;

	return *marker == GSC_CPD_HEADER_MARKER;
}

static u32 entry_offset(const struct gsc_cpd_header_v2 *header, const char *name)
{
	const struct gsc_cpd_entry *entry;
	int i;

	entry = (void *)header + header->header_length;

	for (i = 0; i < header->num_of_entries; i++, entry++)
		if (strcmp(entry->name, name) == 0)
			return entry->offset & GSC_CPD_ENTRY_OFFSET_MASK;

	return 0;
}

/* Refer to the "GSC-based Firmware Layout" documentation entry for details */
static int parse_cpd_header(struct xe_uc_fw *uc_fw, const void *data, size_t size,
			    const char *manifest_entry, const char *css_entry)
{
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct xe_device *xe = gt_to_xe(gt);
	const struct gsc_cpd_header_v2 *header = data;
	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
	const struct gsc_manifest_header *manifest;
	size_t min_size = sizeof(*header);
	u32 offset;

	/* manifest_entry is mandatory, css_entry is optional */
	xe_assert(xe, manifest_entry);

	if (size < min_size || !is_cpd_header(header))
		return -ENOENT;

	if (header->header_length < sizeof(struct gsc_cpd_header_v2)) {
		xe_gt_err(gt, "invalid CPD header length %u!\n", header->header_length);
		return -EINVAL;
	}

	min_size = header->header_length + sizeof(struct gsc_cpd_entry) * header->num_of_entries;
	if (size < min_size) {
		xe_gt_err(gt, "FW too small! %zu < %zu\n", size, min_size);
		return -ENODATA;
	}

	/* Look for the manifest first */
	offset = entry_offset(header, manifest_entry);
	if (!offset) {
		xe_gt_err(gt, "Failed to find %s manifest!\n",
			  xe_uc_fw_type_repr(uc_fw->type));
		return -ENODATA;
	}

	min_size = offset + sizeof(struct gsc_manifest_header);
	if (size < min_size) {
		xe_gt_err(gt, "FW too small! %zu < %zu\n", size, min_size);
		return -ENODATA;
	}

	manifest = data + offset;

	release->major = manifest->fw_version.major;
	release->minor = manifest->fw_version.minor;
	release->patch = manifest->fw_version.hotfix;

	if (uc_fw->type == XE_UC_FW_TYPE_GSC) {
		struct xe_gsc *gsc = container_of(uc_fw, struct xe_gsc, fw);

		release->build = manifest->fw_version.build;
		gsc->security_version = manifest->security_version;
	}

	/* then optionally look for the css header */
	if (css_entry) {
		int ret;

		/*
		 * This section does not contain a CSS entry on DG2. We
		 * don't support DG2 HuC right now, so no need to handle
		 * it, just add a reminder in case that changes.
		 */
		xe_assert(xe, xe->info.platform != XE_DG2);

		offset = entry_offset(header, css_entry);

		/* the CSS header parser will check that the CSS header fits */
		if (offset > size) {
			xe_gt_err(gt, "FW too small! %zu < %u\n", size, offset);
			return -ENODATA;
		}

		ret = parse_css_header(uc_fw, data + offset, size - offset);
		if (ret)
			return ret;

		uc_fw->css_offset = offset;
	}

	uc_fw->has_gsc_headers = true;

	return 0;
}

static int parse_gsc_layout(struct xe_uc_fw *uc_fw, const void *data, size_t size)
{
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	const struct gsc_layout_pointers *layout = data;
	const struct gsc_bpdt_header *bpdt_header = NULL;
	const struct gsc_bpdt_entry *bpdt_entry = NULL;
	size_t min_size = sizeof(*layout);
	int i;

	if (size < min_size) {
		xe_gt_err(gt, "GSC FW too small! %zu < %zu\n", size, min_size);
		return -ENODATA;
	}

	min_size = layout->boot1.offset + layout->boot1.size;
	if (size < min_size) {
		xe_gt_err(gt, "GSC FW too small for boot section! %zu < %zu\n",
			  size, min_size);
		return -ENODATA;
	}

	min_size = sizeof(*bpdt_header);
	if (layout->boot1.size < min_size) {
		xe_gt_err(gt, "GSC FW boot section too small for BPDT header: %u < %zu\n",
			  layout->boot1.size, min_size);
		return -ENODATA;
	}

	bpdt_header = data + layout->boot1.offset;
	if (bpdt_header->signature != GSC_BPDT_HEADER_SIGNATURE) {
		xe_gt_err(gt, "invalid signature for BPDT header: 0x%08x!\n",
			  bpdt_header->signature);
		return -EINVAL;
	}

	min_size += sizeof(*bpdt_entry) * bpdt_header->descriptor_count;
	if (layout->boot1.size < min_size) {
		xe_gt_err(gt, "GSC FW boot section too small for BPDT entries: %u < %zu\n",
			  layout->boot1.size, min_size);
		return -ENODATA;
	}

	bpdt_entry = (void *)bpdt_header + sizeof(*bpdt_header);
	for (i = 0; i < bpdt_header->descriptor_count; i++, bpdt_entry++) {
		if ((bpdt_entry->type & GSC_BPDT_ENTRY_TYPE_MASK) !=
		    GSC_BPDT_ENTRY_TYPE_GSC_RBE)
			continue;

		min_size = bpdt_entry->sub_partition_offset;

		/* the CPD header parser will check that the CPD header fits */
		if (layout->boot1.size < min_size) {
			xe_gt_err(gt, "GSC FW boot section too small for CPD offset: %u < %zu\n",
				  layout->boot1.size, min_size);
			return -ENODATA;
		}

		return parse_cpd_header(uc_fw,
					(void *)bpdt_header + min_size,
					layout->boot1.size - min_size,
					"RBEP.man", NULL);
	}

	xe_gt_err(gt, "couldn't find CPD header in GSC binary!\n");
	return -ENODATA;
}

static int parse_headers(struct xe_uc_fw *uc_fw, const struct firmware *fw)
{
	int ret;

	/*
	 * All GuC releases and older HuC ones use CSS headers, while newer HuC
	 * releases use GSC CPD headers.
	 */
	switch (uc_fw->type) {
	case XE_UC_FW_TYPE_GSC:
		return parse_gsc_layout(uc_fw, fw->data, fw->size);
	case XE_UC_FW_TYPE_HUC:
		ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw");
		if (!ret || ret != -ENOENT)
			return ret;
		fallthrough;
	case XE_UC_FW_TYPE_GUC:
		return parse_css_header(uc_fw, fw->data, fw->size);
	default:
		return -EINVAL;
	}

	return 0;
}

#define print_uc_fw_version(p_, version_, prefix_, ...) \
do { \
	struct xe_uc_fw_version *ver_ = (version_); \
	if (ver_->build) \
		drm_printf(p_, prefix_ " version %u.%u.%u.%u\n", ##__VA_ARGS__, \
			   ver_->major, ver_->minor, \
			   ver_->patch, ver_->build); \
	else \
		drm_printf(p_, prefix_ " version %u.%u.%u\n", ##__VA_ARGS__, \
			  ver_->major, ver_->minor, ver_->patch); \
} while (0)

static void uc_fw_vf_override(struct xe_uc_fw *uc_fw)
{
	struct xe_uc_fw_version *compat = &uc_fw->versions.found[XE_UC_FW_VER_COMPATIBILITY];
	struct xe_uc_fw_version *wanted = &uc_fw->versions.wanted;

	/* Only GuC/HuC are supported */
	if (uc_fw->type != XE_UC_FW_TYPE_GUC && uc_fw->type != XE_UC_FW_TYPE_HUC)
		uc_fw->path = NULL;

	/* VF will support only firmwares that driver can autoselect */
	xe_uc_fw_change_status(uc_fw, uc_fw->path ?
			       XE_UC_FIRMWARE_PRELOADED :
			       XE_UC_FIRMWARE_NOT_SUPPORTED);

	if (!xe_uc_fw_is_supported(uc_fw))
		return;

	/* PF is doing the loading, so we don't need a path on the VF */
	uc_fw->path = "Loaded by PF";

	/* The GuC versions are set up during the VF bootstrap */
	if (uc_fw->type == XE_UC_FW_TYPE_GUC) {
		uc_fw->versions.wanted_type = XE_UC_FW_VER_COMPATIBILITY;
		xe_gt_sriov_vf_guc_versions(uc_fw_to_gt(uc_fw), wanted, compat);
	}
}

static int uc_fw_request(struct xe_uc_fw *uc_fw, const struct firmware **firmware_p)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct drm_printer p = xe_gt_info_printer(gt);
	struct device *dev = xe->drm.dev;
	const struct firmware *fw = NULL;
	int err;

	/*
	 * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
	 * before we're looked at the HW caps to see if we have uc support
	 */
	BUILD_BUG_ON(XE_UC_FIRMWARE_UNINITIALIZED);
	xe_gt_assert(gt, !uc_fw->status);
	xe_gt_assert(gt, !uc_fw->path);

	uc_fw_auto_select(xe, uc_fw);

	if (IS_SRIOV_VF(xe)) {
		uc_fw_vf_override(uc_fw);
		return 0;
	}

	uc_fw_override(uc_fw);

	xe_uc_fw_change_status(uc_fw, uc_fw->path ?
			       XE_UC_FIRMWARE_SELECTED :
			       XE_UC_FIRMWARE_NOT_SUPPORTED);

	if (!xe_uc_fw_is_supported(uc_fw)) {
		if (uc_fw->type == XE_UC_FW_TYPE_GUC) {
			xe_gt_err(gt, "No GuC firmware defined for platform\n");
			return -ENOENT;
		}
		return 0;
	}

	/* an empty path means the firmware is disabled */
	if (!xe_device_uc_enabled(xe) || !(*uc_fw->path)) {
		xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_DISABLED);
		xe_gt_dbg(gt, "%s disabled\n", xe_uc_fw_type_repr(uc_fw->type));
		return 0;
	}

	err = request_firmware(&fw, uc_fw->path, dev);
	if (err)
		goto fail;

	err = parse_headers(uc_fw, fw);
	if (err)
		goto fail;

	print_uc_fw_version(&p,
			    &uc_fw->versions.found[XE_UC_FW_VER_RELEASE],
			    "Using %s firmware from %s",
			    xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);

	/* for GSC FW we want the compatibility version, which we query after load */
	if (uc_fw->type != XE_UC_FW_TYPE_GSC) {
		err = xe_uc_fw_check_version_requirements(uc_fw);
		if (err)
			goto fail;
	}

	*firmware_p = fw;

	return 0;

fail:
	xe_uc_fw_change_status(uc_fw, err == -ENOENT ?
			       XE_UC_FIRMWARE_MISSING :
			       XE_UC_FIRMWARE_ERROR);

	xe_gt_notice(gt, "%s firmware %s: fetch failed with error %pe\n",
		     xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, ERR_PTR(err));
	xe_gt_info(gt, "%s firmware(s) can be downloaded from %s\n",
		   xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);

	release_firmware(fw);		/* OK even if fw is NULL */

	return err;
}

static void uc_fw_release(const struct firmware *fw)
{
	release_firmware(fw);
}

static int uc_fw_copy(struct xe_uc_fw *uc_fw, const void *data, size_t size, u32 flags)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct xe_tile *tile = gt_to_tile(gt);
	struct xe_bo *obj;
	int err;

	obj = xe_managed_bo_create_from_data(xe, tile, data, size, flags);
	if (IS_ERR(obj)) {
		drm_notice(&xe->drm, "%s firmware %s: failed to create / populate bo",
			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
		err = PTR_ERR(obj);
		goto fail;
	}

	uc_fw->bo = obj;
	uc_fw->size = size;

	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_AVAILABLE);

	err = drmm_add_action_or_reset(&xe->drm, uc_fw_fini, uc_fw);
	if (err)
		goto fail;

	return 0;

fail:
	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_ERROR);
	drm_notice(&xe->drm, "%s firmware %s: copy failed with error %d\n",
		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);

	return err;
}

int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
{
	const struct firmware *fw = NULL;
	int err;

	err = uc_fw_request(uc_fw, &fw);
	if (err)
		return err;

	/* no error and no firmware means nothing to copy */
	if (!fw)
		return 0;

	err = uc_fw_copy(uc_fw, fw->data, fw->size,
			 XE_BO_FLAG_SYSTEM | XE_BO_FLAG_GGTT |
			 XE_BO_FLAG_GGTT_INVALIDATE);

	uc_fw_release(fw);

	return err;
}
ALLOW_ERROR_INJECTION(xe_uc_fw_init, ERRNO); /* See xe_pci_probe() */

static u32 uc_fw_ggtt_offset(struct xe_uc_fw *uc_fw)
{
	return xe_bo_ggtt_addr(uc_fw->bo);
}

static int uc_fw_xfer(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct xe_mmio *mmio = &gt->mmio;
	u64 src_offset;
	u32 dma_ctrl;
	int ret;

	xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);

	/* Set the source address for the uCode */
	src_offset = uc_fw_ggtt_offset(uc_fw) + uc_fw->css_offset;
	xe_mmio_write32(mmio, DMA_ADDR_0_LOW, lower_32_bits(src_offset));
	xe_mmio_write32(mmio, DMA_ADDR_0_HIGH,
			upper_32_bits(src_offset) | DMA_ADDRESS_SPACE_GGTT);

	/* Set the DMA destination */
	xe_mmio_write32(mmio, DMA_ADDR_1_LOW, offset);
	xe_mmio_write32(mmio, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);

	/*
	 * Set the transfer size. The header plus uCode will be copied to WOPCM
	 * via DMA, excluding any other components
	 */
	xe_mmio_write32(mmio, DMA_COPY_SIZE,
			sizeof(struct uc_css_header) + uc_fw->ucode_size);

	/* Start the DMA */
	xe_mmio_write32(mmio, DMA_CTRL,
			_MASKED_BIT_ENABLE(dma_flags | START_DMA));

	/* Wait for DMA to finish */
	ret = xe_mmio_wait32(mmio, DMA_CTRL, START_DMA, 0, 100000, &dma_ctrl,
			     false);
	if (ret)
		drm_err(&xe->drm, "DMA for %s fw failed, DMA_CTRL=%u\n",
			xe_uc_fw_type_repr(uc_fw->type), dma_ctrl);

	/* Disable the bits once DMA is over */
	xe_mmio_write32(mmio, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags));

	return ret;
}

int xe_uc_fw_upload(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	int err;

	/* make sure the status was cleared the last time we reset the uc */
	xe_assert(xe, !xe_uc_fw_is_loaded(uc_fw));

	if (!xe_uc_fw_is_loadable(uc_fw))
		return -ENOEXEC;

	/* Call custom loader */
	err = uc_fw_xfer(uc_fw, offset, dma_flags);
	if (err)
		goto fail;

	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_TRANSFERRED);
	return 0;

fail:
	drm_err(&xe->drm, "Failed to load %s firmware %s (%d)\n",
		xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
		err);
	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_LOAD_FAIL);
	return err;
}

static const char *version_type_repr(enum xe_uc_fw_version_types type)
{
	switch (type) {
	case XE_UC_FW_VER_RELEASE:
		return "release";
	case XE_UC_FW_VER_COMPATIBILITY:
		return "compatibility";
	default:
		return "Unknown version type";
	}
}

void xe_uc_fw_print(struct xe_uc_fw *uc_fw, struct drm_printer *p)
{
	int i;

	drm_printf(p, "%s firmware: %s\n",
		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
	drm_printf(p, "\tstatus: %s\n",
		   xe_uc_fw_status_repr(uc_fw->status));

	print_uc_fw_version(p, &uc_fw->versions.wanted, "\twanted %s",
			    version_type_repr(uc_fw->versions.wanted_type));

	for (i = 0; i < XE_UC_FW_VER_TYPE_COUNT; i++) {
		struct xe_uc_fw_version *ver = &uc_fw->versions.found[i];

		if (ver->major)
			print_uc_fw_version(p, ver, "\tfound %s",
					    version_type_repr(i));
	}

	if (uc_fw->ucode_size)
		drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size);
	if (uc_fw->rsa_size)
		drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size);
}
