From b088da030362ae3e4437f8eb900e007c99750566 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Wed, 8 Jul 2026 00:08:07 +0200 Subject: [PATCH] drm/xe/guc: Add object KLV encoding helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We plan to encode larger objects as single KLV or set of KLVs. Add helper for that. Signed-off-by: Michal Wajdeczko Reviewed-by: MichaƂ Winiarski Link: https://patch.msgid.link/20260707220816.677-6-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_guc_klv_helpers.c | 39 +++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_guc_klv_helpers.h | 2 ++ 2 files changed, 41 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_guc_klv_helpers.c b/drivers/gpu/drm/xe/xe_guc_klv_helpers.c index fa5590b23ba0..54d977252431 100644 --- a/drivers/gpu/drm/xe/xe_guc_klv_helpers.c +++ b/drivers/gpu/drm/xe/xe_guc_klv_helpers.c @@ -280,3 +280,42 @@ u32 *xe_guc_klv_encode_string(u32 *klvs, u32 avail, u16 key, const char *s) strscpy_pad((void *)klvs, s, to_num_bytes(len)); return klvs + len; } + +/** + * xe_guc_klv_encode_object() - Encode object using custom encoder as single KLV. + * @klvs: the buffer where to place KLV + * @avail: number of dwords (u32) available in the buffer + * @key: key to be used + * @obj: opaque object pointer + * @encoder: function pointer to the custom encoder + * + * Return: pointer to the buffer location past the encoded KLV or + * an ERR_PTR if there was no space to encode the KLV. + */ +u32 *xe_guc_klv_encode_object(u32 *klvs, u32 avail, u16 key, const void *obj, + u32 *(*encoder)(u32 *klvs, u32 avail, const void *obj)) +{ + u32 *end; + + if (IS_ERR(klvs)) + return klvs; + + if (avail < GUC_KLV_LEN_MIN) + return ERR_PTR(-ENOSPC); + + if (avail > GUC_KLV_LEN_MIN + FIELD_MAX(GUC_KLV_0_LEN)) + avail = GUC_KLV_LEN_MIN + FIELD_MAX(GUC_KLV_0_LEN); + + end = encoder(klvs + GUC_KLV_LEN_MIN, avail - GUC_KLV_LEN_MIN, obj); + if (IS_ERR(end)) + return end; + + if (WARN_ON(end < klvs + GUC_KLV_LEN_MIN)) + return ERR_PTR(-EPIPE); + + if (WARN_ON(end > klvs + avail)) + return ERR_PTR(-EFBIG); + + *klvs = PREP_GUC_KLV(key, end - (klvs + GUC_KLV_LEN_MIN)); + return end; +} diff --git a/drivers/gpu/drm/xe/xe_guc_klv_helpers.h b/drivers/gpu/drm/xe/xe_guc_klv_helpers.h index 1c576456efc5..855805f4463d 100644 --- a/drivers/gpu/drm/xe/xe_guc_klv_helpers.h +++ b/drivers/gpu/drm/xe/xe_guc_klv_helpers.h @@ -20,6 +20,8 @@ int xe_guc_klv_count(const u32 *klvs, u32 num_dwords); u32 *xe_guc_klv_encode_u32(u32 *klvs, u32 avail, u16 key, u32 value); u32 *xe_guc_klv_encode_u64(u32 *klvs, u32 avail, u16 key, u64 value); u32 *xe_guc_klv_encode_string(u32 *klvs, u32 avail, u16 key, const char *s); +u32 *xe_guc_klv_encode_object(u32 *klvs, u32 avail, u16 key, const void *obj, + u32 *(*encoder)(u32 *klvs, u32 avail, const void *obj)); /** * PREP_GUC_KLV - Prepare KLV header value based on provided key and len.