return -ENOEXEC;
 }
 
-int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
+/* 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_gt *gt = uc_fw_to_gt(uc_fw);
-       struct xe_tile *tile = gt_to_tile(gt);
-       struct device *dev = xe->drm.dev;
-       const struct firmware *fw = NULL;
        struct uc_css_header *css;
-       struct xe_bo *obj;
        size_t size;
-       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_assert(xe, !uc_fw->status);
-       xe_assert(xe, !uc_fw->path);
-
-       uc_fw_auto_select(xe, 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))
-               return 0;
-
-       uc_fw_override(uc_fw);
-
-       /* 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);
-               drm_dbg(&xe->drm, "%s disabled", xe_uc_fw_type_repr(uc_fw->type));
-               return 0;
-       }
-
-       err = request_firmware(&fw, uc_fw->path, dev);
-       if (err)
-               goto fail;
 
        /* Check the size of the blob before examining buffer contents */
-       if (unlikely(fw->size < sizeof(struct uc_css_header))) {
+       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));
-               err = -ENODATA;
-               goto fail;
+                        fw_size, sizeof(struct uc_css_header));
+               return -ENODATA;
        }
 
-       css = (struct uc_css_header *)fw->data;
+       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 -
                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));
-               err = -EPROTO;
-               goto fail;
+                        fw_size, sizeof(struct uc_css_header));
+               return -EPROTO;
        }
 
        /* uCode size must calculated from other sizes */
        /* 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)) {
+       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);
-               err = -ENOEXEC;
-               goto fail;
+                        fw_size, size);
+               return -ENOEXEC;
        }
 
        /* Get version numbers from the CSS header */
        uc_fw->patch_ver_found = FIELD_GET(CSS_SW_VERSION_UC_PATCH,
                                           css->sw_version);
 
+       if (uc_fw->type == XE_UC_FW_TYPE_GUC)
+               guc_read_css_info(uc_fw, css);
+
+       return 0;
+}
+
+static int parse_headers(struct xe_uc_fw *uc_fw, const struct firmware *fw)
+{
+       return parse_css_header(uc_fw, fw->data, fw->size);
+}
+
+int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
+{
+       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 device *dev = xe->drm.dev;
+       const struct firmware *fw = NULL;
+       struct xe_bo *obj;
+       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_assert(xe, !uc_fw->status);
+       xe_assert(xe, !uc_fw->path);
+
+       uc_fw_auto_select(xe, 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))
+               return 0;
+
+       uc_fw_override(uc_fw);
+
+       /* 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);
+               drm_dbg(&xe->drm, "%s disabled", 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;
+
        drm_info(&xe->drm, "Using %s firmware from %s version %u.%u.%u\n",
                 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
                 uc_fw->major_ver_found, uc_fw->minor_ver_found, uc_fw->patch_ver_found);
        if (err)
                goto fail;
 
-       if (uc_fw->type == XE_UC_FW_TYPE_GUC)
-               guc_read_css_info(uc_fw, css);
-
        obj = xe_bo_create_from_data(xe, tile, fw->data, fw->size,
                                     ttm_bo_type_kernel,
                                     XE_BO_CREATE_VRAM_IF_DGFX(tile) |