1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2024 Intel Corporation 4 */ 5 6 #include <linux/bitfield.h> 7 #include <drm/drm_print.h> 8 9 #include "abi/guc_klvs_abi.h" 10 #include "xe_guc_klv_helpers.h" 11 #include "xe_guc_klv_thresholds_set.h" 12 13 #define make_u64(hi, lo) ((u64)((u64)(u32)(hi) << 32 | (u32)(lo))) 14 15 /** 16 * xe_guc_klv_key_to_string - Convert KLV key into friendly name. 17 * @key: the `GuC KLV`_ key 18 * 19 * Return: name of the KLV key. 20 */ 21 const char *xe_guc_klv_key_to_string(u16 key) 22 { 23 switch (key) { 24 /* VGT POLICY keys */ 25 case GUC_KLV_VGT_POLICY_SCHED_IF_IDLE_KEY: 26 return "sched_if_idle"; 27 case GUC_KLV_VGT_POLICY_ADVERSE_SAMPLE_PERIOD_KEY: 28 return "sample_period"; 29 case GUC_KLV_VGT_POLICY_RESET_AFTER_VF_SWITCH_KEY: 30 return "reset_engine"; 31 /* VF CFG keys */ 32 case GUC_KLV_VF_CFG_GGTT_START_KEY: 33 return "ggtt_start"; 34 case GUC_KLV_VF_CFG_GGTT_SIZE_KEY: 35 return "ggtt_size"; 36 case GUC_KLV_VF_CFG_LMEM_SIZE_KEY: 37 return "lmem_size"; 38 case GUC_KLV_VF_CFG_NUM_CONTEXTS_KEY: 39 return "num_contexts"; 40 case GUC_KLV_VF_CFG_TILE_MASK_KEY: 41 return "tile_mask"; 42 case GUC_KLV_VF_CFG_NUM_DOORBELLS_KEY: 43 return "num_doorbells"; 44 case GUC_KLV_VF_CFG_EXEC_QUANTUM_KEY: 45 return "exec_quantum"; 46 case GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_KEY: 47 return "preempt_timeout"; 48 case GUC_KLV_VF_CFG_BEGIN_DOORBELL_ID_KEY: 49 return "begin_db_id"; 50 case GUC_KLV_VF_CFG_BEGIN_CONTEXT_ID_KEY: 51 return "begin_ctx_id"; 52 53 /* VF CFG threshold keys */ 54 #define define_threshold_key_to_string_case(TAG, NAME, ...) \ 55 \ 56 case MAKE_GUC_KLV_VF_CFG_THRESHOLD_KEY(TAG): \ 57 return #NAME; 58 59 /* private: auto-generated case statements */ 60 MAKE_XE_GUC_KLV_THRESHOLDS_SET(define_threshold_key_to_string_case) 61 #undef define_threshold_key_to_string_case 62 63 default: 64 return "(unknown)"; 65 } 66 } 67 68 /** 69 * xe_guc_klv_print - Print content of the buffer with `GuC KLV`_. 70 * @klvs: the buffer with KLVs 71 * @num_dwords: number of dwords (u32) available in the buffer 72 * @p: the &drm_printer 73 * 74 * The buffer may contain more than one KLV. 75 */ 76 void xe_guc_klv_print(const u32 *klvs, u32 num_dwords, struct drm_printer *p) 77 { 78 while (num_dwords >= GUC_KLV_LEN_MIN) { 79 u32 key = FIELD_GET(GUC_KLV_0_KEY, klvs[0]); 80 u32 len = FIELD_GET(GUC_KLV_0_LEN, klvs[0]); 81 82 klvs += GUC_KLV_LEN_MIN; 83 num_dwords -= GUC_KLV_LEN_MIN; 84 85 if (num_dwords < len) { 86 drm_printf(p, "{ key %#06x : truncated %zu of %zu bytes %*ph } # %s\n", 87 key, num_dwords * sizeof(u32), len * sizeof(u32), 88 (int)(num_dwords * sizeof(u32)), klvs, 89 xe_guc_klv_key_to_string(key)); 90 return; 91 } 92 93 switch (len) { 94 case 0: 95 drm_printf(p, "{ key %#06x : no value } # %s\n", 96 key, xe_guc_klv_key_to_string(key)); 97 break; 98 case 1: 99 drm_printf(p, "{ key %#06x : 32b value %u } # %s\n", 100 key, klvs[0], xe_guc_klv_key_to_string(key)); 101 break; 102 case 2: 103 drm_printf(p, "{ key %#06x : 64b value %#llx } # %s\n", 104 key, make_u64(klvs[1], klvs[0]), 105 xe_guc_klv_key_to_string(key)); 106 break; 107 default: 108 drm_printf(p, "{ key %#06x : %zu bytes %*ph } # %s\n", 109 key, len * sizeof(u32), (int)(len * sizeof(u32)), 110 klvs, xe_guc_klv_key_to_string(key)); 111 break; 112 } 113 114 klvs += len; 115 num_dwords -= len; 116 } 117 118 /* we don't expect any leftovers, fix if KLV header is ever changed */ 119 BUILD_BUG_ON(GUC_KLV_LEN_MIN > 1); 120 } 121 122 /** 123 * xe_guc_klv_count - Count KLVs present in the buffer. 124 * @klvs: the buffer with KLVs 125 * @num_dwords: number of dwords (u32) in the buffer 126 * 127 * Return: number of recognized KLVs or 128 * a negative error code if KLV buffer is truncated. 129 */ 130 int xe_guc_klv_count(const u32 *klvs, u32 num_dwords) 131 { 132 int num_klvs = 0; 133 134 while (num_dwords >= GUC_KLV_LEN_MIN) { 135 u32 len = FIELD_GET(GUC_KLV_0_LEN, klvs[0]); 136 137 if (num_dwords < len + GUC_KLV_LEN_MIN) 138 break; 139 140 klvs += GUC_KLV_LEN_MIN + len; 141 num_dwords -= GUC_KLV_LEN_MIN + len; 142 num_klvs++; 143 } 144 145 return num_dwords ? -ENODATA : num_klvs; 146 } 147