From: "Ceraolo Spurio, Daniele" <daniele.ceraolospurio@intel.com>
To: Badal Nilawar <badal.nilawar@intel.com>,
<intel-xe@lists.freedesktop.org>
Cc: <anshuman.gupta@intel.com>, <rodrigo.vivi@intel.com>,
<michael.j.ruhl@intel.com>, <alexander.usyskin@intel.com>,
<anoop.c.vijay@intel.com>, <shamim.begum@intel.com>,
<kelvin.gardiner@intel.com>
Subject: Re: [PATCH v6 4/6] drm/xe/xe_late_bind_fw: Add support to load Ocode firmware
Date: Fri, 30 Oct 2026 15:46:13 -0700 [thread overview]
Message-ID: <b623c308-ea2b-4b34-9a5e-db1fad870c16@intel.com> (raw)
In-Reply-To: <20261030144547.2532309-12-badal.nilawar@intel.com>
On 10/30/2026 7:45 AM, Badal Nilawar wrote:
> Enable loading of Ocode, the legacy OOBMSM firmware, through the
> late binding flow. The payload size check is no longer needed as
> late binding supports larger payloads.
>
> Ocode may not remain backward compatible across IFWI updates. Query
> the SDK API version from the System Controller mailbox and load the
> corresponding xe/cri_ocode_<ver>.bin. Skip loading the firmware if
> the SDK API version in its manifest does not match.
>
> v2:
> - Make sdk_api_version part of ip_specific_data union (Daniele)
>
> Assisted-by: LLM
> Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Please get an ack from a maintainer if you want to merge this ahead of
the FW being published.
Daniele
> ---
> drivers/gpu/drm/xe/abi/uc_fw_abi.h | 11 ++++-
> drivers/gpu/drm/xe/xe_late_bind_fw.c | 48 +++++++++++++++----
> drivers/gpu/drm/xe/xe_late_bind_fw_types.h | 6 ++-
> drivers/gpu/drm/xe/xe_sysctrl.c | 32 +++++++++++++
> drivers/gpu/drm/xe/xe_sysctrl.h | 1 +
> drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h | 12 +++++
> 6 files changed, 97 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/abi/uc_fw_abi.h b/drivers/gpu/drm/xe/abi/uc_fw_abi.h
> index 198e949660e0..59699ba4def5 100644
> --- a/drivers/gpu/drm/xe/abi/uc_fw_abi.h
> +++ b/drivers/gpu/drm/xe/abi/uc_fw_abi.h
> @@ -316,6 +316,11 @@ struct gsc_cpd_entry {
> u8 reserved[4];
> } __packed;
>
> +struct ocode_manifest_data {
> + u16 sdk_api_version;
> + u8 reserved[22];
> +} __packed;
> +
> struct gsc_manifest_header {
> u32 header_type; /* 0x4 for manifest type */
> u32 header_length; /* in dwords */
> @@ -331,7 +336,11 @@ struct gsc_manifest_header {
> struct gsc_version meu_kit_version;
> u32 meu_manifest_version;
> u8 general_data[4];
> - u8 reserved3[56];
> + union {
> + u8 ip_specific_data[24];
> + struct ocode_manifest_data ocode_data;
> + };
> + u8 reserved3[32];
> u32 modulus_size; /* in dwords */
> u32 exponent_size; /* in dwords */
> } __packed;
> diff --git a/drivers/gpu/drm/xe/xe_late_bind_fw.c b/drivers/gpu/drm/xe/xe_late_bind_fw.c
> index c5f3a3b8d404..b62a4c15c738 100644
> --- a/drivers/gpu/drm/xe/xe_late_bind_fw.c
> +++ b/drivers/gpu/drm/xe/xe_late_bind_fw.c
> @@ -17,6 +17,12 @@
> #include "xe_pcode.h"
> #include "xe_pcode_api.h"
> #include "xe_pm.h"
> +#include "xe_sysctrl.h"
> +
> +/*
> + * TODO: Add MODULE_FIRMWARE() for xe/cri_ocode_<ver>.bin once the
> + * Ocode firmware binary is available upstream.
> + */
>
> /*
> * The component should load quite quickly in most cases, but it could take
> @@ -33,10 +39,12 @@
>
> static const u32 fw_id_to_type[] = {
> [XE_LB_FW_FAN_CONTROL] = INTEL_LB_TYPE_FAN_CONTROL,
> + [XE_LB_FW_OCODE] = INTEL_LB_TYPE_OCODE,
> };
>
> static const char * const fw_id_to_name[] = {
> [XE_LB_FW_FAN_CONTROL] = "fan_control",
> + [XE_LB_FW_OCODE] = "ocode",
> };
>
> static struct xe_device *
> @@ -104,6 +112,7 @@ static int parse_cpd_header(struct xe_late_bind_fw *lb_fw,
> manifest = data + offset;
>
> lb_fw->version = manifest->fw_version;
> + lb_fw->sdk_api_version = manifest->ocode_data.sdk_api_version;
>
> return 0;
> }
> @@ -324,6 +333,7 @@ static int __xe_late_bind_fw_init(struct xe_late_bind *late_bind, u32 fw_id)
> struct xe_late_bind_fw *lb_fw;
> const struct firmware *fw;
> u32 num_fans;
> + u16 sdk_ver = 0;
> int ret;
>
> if (fw_id >= XE_LB_FW_MAX_ID)
> @@ -346,9 +356,23 @@ static int __xe_late_bind_fw_init(struct xe_late_bind *late_bind, u32 fw_id)
> return 0;
> }
>
> - snprintf(lb_fw->blob_path, sizeof(lb_fw->blob_path), "xe/%s_8086_%04x_%04x_%04x.bin",
> - fw_id_to_name[lb_fw->id], pdev->device,
> - pdev->subsystem_vendor, pdev->subsystem_device);
> + if (lb_fw->type == INTEL_LB_TYPE_OCODE) {
> + /* Get SDK API version */
> + ret = xe_sysctrl_sdk_api_version(xe, &sdk_ver);
> + if (ret) {
> + drm_warn(&xe->drm, "Failed to get OCODE SDK API version: %pe\n",
> + ERR_PTR(ret));
> + return 0;
> + }
> +
> + snprintf(lb_fw->blob_path, sizeof(lb_fw->blob_path),
> + "xe/cri_ocode_%u.bin", sdk_ver);
> + } else {
> + snprintf(lb_fw->blob_path, sizeof(lb_fw->blob_path),
> + "xe/%s_8086_%04x_%04x_%04x.bin",
> + fw_id_to_name[lb_fw->id], pdev->device,
> + pdev->subsystem_vendor, pdev->subsystem_device);
> + }
>
> drm_dbg(&xe->drm, "Request late binding firmware %s\n", lb_fw->blob_path);
> ret = firmware_request_nowarn(&fw, lb_fw->blob_path, xe->drm.dev);
> @@ -358,17 +382,17 @@ static int __xe_late_bind_fw_init(struct xe_late_bind *late_bind, u32 fw_id)
> return 0;
> }
>
> - if (fw->size > XE_LB_MAX_PAYLOAD_SIZE) {
> - drm_err(&xe->drm, "Firmware %s size %zu is larger than max pay load size %u\n",
> - lb_fw->blob_path, fw->size, XE_LB_MAX_PAYLOAD_SIZE);
> - ret = -ENODATA;
> - goto release_fw;
> - }
> -
> ret = parse_lb_layout(lb_fw, fw->data, fw->size, "LTES");
> if (ret)
> goto release_fw;
>
> + if (lb_fw->type == INTEL_LB_TYPE_OCODE && lb_fw->sdk_api_version != sdk_ver) {
> + drm_warn(&xe->drm, "%s late binding fw: SDK API version mismatch %u != %u\n",
> + fw_id_to_name[lb_fw->id], lb_fw->sdk_api_version, sdk_ver);
> + ret = 0;
> + goto release_fw;
> + }
> +
> lb_fw->payload_size = fw->size;
> lb_fw->payload = drmm_kzalloc(&xe->drm, lb_fw->payload_size, GFP_KERNEL);
> if (!lb_fw->payload) {
> @@ -381,6 +405,10 @@ static int __xe_late_bind_fw_init(struct xe_late_bind *late_bind, u32 fw_id)
> lb_fw->version.major, lb_fw->version.minor,
> lb_fw->version.hotfix, lb_fw->version.build);
>
> + if (lb_fw->type == INTEL_LB_TYPE_OCODE)
> + drm_info(&xe->drm, "%s firmware SDK API version %u\n",
> + fw_id_to_name[lb_fw->id], lb_fw->sdk_api_version);
> +
> memcpy((void *)lb_fw->payload, fw->data, lb_fw->payload_size);
> INIT_WORK(&lb_fw->work, xe_late_bind_work);
>
> diff --git a/drivers/gpu/drm/xe/xe_late_bind_fw_types.h b/drivers/gpu/drm/xe/xe_late_bind_fw_types.h
> index ee5efe60774e..c7b3ffc743cf 100644
> --- a/drivers/gpu/drm/xe/xe_late_bind_fw_types.h
> +++ b/drivers/gpu/drm/xe/xe_late_bind_fw_types.h
> @@ -13,14 +13,14 @@
>
> #include "abi/uc_fw_abi.h"
>
> -#define XE_LB_MAX_PAYLOAD_SIZE SZ_4K
> -
> /**
> * enum xe_late_bind_fw_id - enum to determine late binding fw index
> */
> enum xe_late_bind_fw_id {
> /** @XE_LB_FW_FAN_CONTROL: Fan control */
> XE_LB_FW_FAN_CONTROL = 0,
> + /** @XE_LB_FW_OCODE: Ocode firmware */
> + XE_LB_FW_OCODE,
> /** @XE_LB_FW_MAX_ID: Number of IDs */
> XE_LB_FW_MAX_ID
> };
> @@ -45,6 +45,8 @@ struct xe_late_bind_fw {
> struct work_struct work;
> /** @version: late binding blob manifest version */
> struct gsc_version version;
> + /** @sdk_api_version: late binding blob manifest SDK API version */
> + u16 sdk_api_version;
> };
>
> /**
> diff --git a/drivers/gpu/drm/xe/xe_sysctrl.c b/drivers/gpu/drm/xe/xe_sysctrl.c
> index 4067e1dfdcd5..27a59e8e4487 100644
> --- a/drivers/gpu/drm/xe/xe_sysctrl.c
> +++ b/drivers/gpu/drm/xe/xe_sysctrl.c
> @@ -217,3 +217,35 @@ bool xe_sysctrl_is_diag_fw_ready(struct xe_device *xe)
> return xe_sysctrl_check_app_status(xe, XE_SYSCTRL_APP_DIAG) ==
> XE_SYSCTRL_FIRMWARE_APP_INITIALIZED;
> }
> +
> +/**
> + * xe_sysctrl_sdk_api_version - Get SDK API version
> + * @xe: Xe device
> + * @version: SDK API version
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int xe_sysctrl_sdk_api_version(struct xe_device *xe, u16 *version)
> +{
> + struct xe_sysctrl_sdk_api_resp resp = {};
> + struct xe_sysctrl_mailbox_command cmd = {};
> + size_t out_len = 0;
> + int ret;
> +
> + xe_sysctrl_create_command(&cmd, XE_SYSCTRL_GROUP_CORE, XE_SYSCTRL_CMD_SDK_API_VERSION,
> + 0, 0, &resp, sizeof(resp));
> +
> + ret = xe_sysctrl_send_command(&xe->sc, &cmd, &out_len);
> + if (ret)
> + return ret;
> +
> + if (out_len != sizeof(resp)) {
> + xe_err(xe, "sysctrl: unexpected SDK API version length %zu (expected %zu)\n",
> + out_len, sizeof(resp));
> + return -EPROTO;
> + }
> +
> + *version = resp.sdk_api_version;
> +
> + return 0;
> +}
> diff --git a/drivers/gpu/drm/xe/xe_sysctrl.h b/drivers/gpu/drm/xe/xe_sysctrl.h
> index b69a3f474236..c0b6d4330c88 100644
> --- a/drivers/gpu/drm/xe/xe_sysctrl.h
> +++ b/drivers/gpu/drm/xe/xe_sysctrl.h
> @@ -22,5 +22,6 @@ void xe_sysctrl_irq_handler(struct xe_device *xe, u32 master_ctl);
> void xe_sysctrl_pm_resume(struct xe_device *xe);
> bool xe_sysctrl_is_oobmsm_fw_ready(struct xe_device *xe);
> bool xe_sysctrl_is_diag_fw_ready(struct xe_device *xe);
> +int xe_sysctrl_sdk_api_version(struct xe_device *xe, u16 *version);
>
> #endif
> diff --git a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
> index 1f3f782d770e..cdacceebca06 100644
> --- a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
> +++ b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
> @@ -57,10 +57,12 @@ enum xe_sysctrl_gfsp_cmd {
> *
> * @XE_SYSCTRL_CMD_LOOPBACK: Loopback test command
> * @XE_SYSCTRL_CMD_GET_APP_STATUS_BY_ID: Retrieve application status by ID
> + * @XE_SYSCTRL_CMD_SDK_API_VERSION: Get SDK API version
> */
> enum xe_sysctrl_core_cmd {
> XE_SYSCTRL_CMD_LOOPBACK = 0x03,
> XE_SYSCTRL_CMD_GET_APP_STATUS_BY_ID = 0x05,
> + XE_SYSCTRL_CMD_SDK_API_VERSION = 0x06,
> };
>
> /**
> @@ -126,6 +128,16 @@ enum xe_sysctrl_fw_status {
> XE_SYSCTRL_FIRMWARE_COMM_FAILURE,
> };
>
> +/**
> + * struct xe_sysctrl_sdk_api_resp - Get sdk api version response
> + */
> +struct xe_sysctrl_sdk_api_resp {
> + /** @sdk_api_version: SDK API version */
> + u16 sdk_api_version;
> + /** @reserved: Reserved for future use */
> + u16 reserved;
> +} __packed;
> +
> /**
> * struct xe_sysctrl_mailbox_command - System Controller mailbox command
> */
next prev parent reply other threads:[~2026-10-30 22:46 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 14:45 [PATCH v6 0/6] Add ocode late binding support for CRI Badal Nilawar
2026-10-30 14:45 ` [PATCH v6 1/6] drm/xe/xe_late_bind_fw: Fix firmware leak on missing manifest entry Badal Nilawar
2026-10-30 14:45 ` [PATCH v6 2/6] drm/xe/xe_late_bind_fw: Add string mappings of status codes Badal Nilawar
2026-10-30 14:55 ` sashiko-bot
2026-10-30 22:44 ` Ceraolo Spurio, Daniele
2026-10-30 14:45 ` [PATCH v6 3/6] drm/xe/xe_late_bind_fw: Convert late bind flag to mask Badal Nilawar
2026-10-30 14:45 ` [PATCH v6 4/6] drm/xe/xe_late_bind_fw: Add support to load Ocode firmware Badal Nilawar
2026-10-30 22:46 ` Ceraolo Spurio, Daniele [this message]
2026-10-30 14:45 ` [PATCH v6 5/6] drm/xe/xe_late_bind_fw: Enable late binding support for CRI Badal Nilawar
2026-10-30 14:59 ` sashiko-bot
2026-10-30 14:45 ` [PATCH v6 6/6] drm/xe/xe_late_bind_fw: Refactor pm flow Badal Nilawar
2026-10-30 15:16 ` ✓ CI.KUnit: success for Add ocode late binding support for CRI (rev6) Patchwork
2026-10-30 15:52 ` ✓ Xe.CI.BAT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b623c308-ea2b-4b34-9a5e-db1fad870c16@intel.com \
--to=daniele.ceraolospurio@intel.com \
--cc=alexander.usyskin@intel.com \
--cc=anoop.c.vijay@intel.com \
--cc=anshuman.gupta@intel.com \
--cc=badal.nilawar@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=kelvin.gardiner@intel.com \
--cc=michael.j.ruhl@intel.com \
--cc=rodrigo.vivi@intel.com \
--cc=shamim.begum@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox