[Intel-gfx] [PATCH] drm/i915/uc: Move intel_uc_fw_fetch() to intel_uc.c
Michal Wajdeczko
michal.wajdeczko at intel.com
Fri Mar 3 14:13:08 UTC 2017
On Fri, Mar 03, 2017 at 01:36:34PM +0100, Arkadiusz Hiler wrote:
> The file fits better.
>
> Additionally rename it to intel_uc_prepare_fw(), as the function does
> more than simple fetch.
>
> `obj` cleanup in the function is also fixed (i.e. removed). In the fail
> scenario it was always 'put' but there's no possible flow that
> initializes the obj properly and then goes to the fail label.
>
> v2: remove second declaration, reorder (M. Wajdeczko)
> v3: non-trivial rebase
> v4: remove obj cleanup in the fail scenario (C. Wilson)
>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Michal Wajdeczko <michal.wajdeczko at intel.com>
> Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler at intel.com>
> ---
Reviewed-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
but also added some more comments how to improve of existing messages.
-Michal
<snip>
> @@ -114,3 +115,133 @@ int intel_guc_sample_forcewake(struct intel_guc *guc)
> return intel_guc_send(guc, action, ARRAY_SIZE(action));
> }
>
> +void intel_uc_prepare_fw(struct drm_i915_private *dev_priv,
> + struct intel_uc_fw *uc_fw)
> +{
> + struct pci_dev *pdev = dev_priv->drm.pdev;
> + struct drm_i915_gem_object *obj;
> + const struct firmware *fw = NULL;
> + struct uc_css_header *css;
> + size_t size;
> + int err;
> +
> + DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n",
> + intel_uc_fw_status_repr(uc_fw->fetch_status));
> +
> + err = request_firmware(&fw, uc_fw->path, &pdev->dev);
> + if (err)
> + goto fail;
> + if (!fw)
> + goto fail;
I'm not sure that we need this extra check for null fw.
> +
> + DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
> + uc_fw->path, fw);
> +
> + /* Check the size of the blob before examining buffer contents */
> + if (fw->size < sizeof(struct uc_css_header)) {
> + DRM_NOTE("Firmware header is missing\n");
Btw, this message is little inaccurate. What about
DRM_ERROR("uC firmare is too small"
> + goto fail;
> + }
> +
> + 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 uc_css_header)) {
> + DRM_NOTE("CSS header definition mismatch\n");
Btw, this message is inaccurate too. What about
DRM_ERROR("uC firmware header is invalid"
> + goto fail;
> + }
> +
> + /* then, uCode */
> + uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
> + uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
> +
> + /* now RSA */
> + if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
> + DRM_NOTE("RSA key size is bad\n");
Btw, this message can be improved too. What about
DRM_ERROR("uC firmware signature is corrupted"
> + goto fail;
> + }
> + uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
> + uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
> +
> + /* At least, it should have header, uCode and RSA. Size of all three. */
> + size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
> + if (fw->size < size) {
> + DRM_NOTE("Missing firmware components\n");
Btw, this message can be improved too. What about
"uC firmware blob is truncated"
> + 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).
> + */
> + 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 > intel_guc_wopcm_size(dev_priv)) {
Hmm, is it right place to perform such check ?
Maybe we can move it to guc_ucode_xfer() ?
> + DRM_ERROR("Firmware is too large to fit in WOPCM\n");
Btw, this message can be improved too. s/Firmware/uC firmware/
> + 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) {
> + DRM_NOTE("uC firmware version %d.%d, required %d.%d\n",
> + uc_fw->major_ver_found, uc_fw->minor_ver_found,
> + uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
s/DRM_NOTE/DRM_ERROR ?
> + err = -ENOEXEC;
> + goto fail;
> + }
> +
> + DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
> + uc_fw->major_ver_found, uc_fw->minor_ver_found,
> + uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
> +
> + mutex_lock(&dev_priv->drm.struct_mutex);
> + obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size);
> + mutex_unlock(&dev_priv->drm.struct_mutex);
> + if (IS_ERR_OR_NULL(obj)) {
> + err = obj ? PTR_ERR(obj) : -ENOMEM;
> + goto fail;
> + }
> +
> + uc_fw->obj = obj;
> + uc_fw->size = fw->size;
> +
> + DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
> + uc_fw->obj);
> +
> + release_firmware(fw);
> + uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
> + return;
> +
> +fail:
> + DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
> + uc_fw->path, err);
> + DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n",
> + err, fw, uc_fw->obj);
Please drop "obj" from the message (as it will be always invalid at this point)
Also drop "err" as it is already in DRM_WARN.
Then reconsider if we still need to log "fw" pointer.
> +
> + release_firmware(fw); /* OK even if fw is NULL */
> + uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
> +}
More information about the Intel-gfx
mailing list