1/* 2 * Copyright © 2021 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include <stdio.h> 25#include <stdlib.h> 26 27#include "drm-uapi/i915_drm.h" 28#include "intel_device_info.h" 29#include "intel_hwconfig.h" 30#include "intel_hwconfig_types.h" 31#include "intel/common/intel_gem.h" 32 33#include "util/log.h" 34 35#ifdef NDEBUG 36#define DEBUG_BUILD false 37#else 38#define DEBUG_BUILD true 39#endif 40 41struct hwconfig { 42 uint32_t key; 43 uint32_t len; 44 uint32_t val[]; 45}; 46 47static char * 48key_to_name(uint32_t key) 49{ 50#define HANDLE(key_name) case key_name: return #key_name 51 switch (key) { 52 HANDLE(INTEL_HWCONFIG_MAX_SLICES_SUPPORTED); 53 HANDLE(INTEL_HWCONFIG_MAX_DUAL_SUBSLICES_SUPPORTED); 54 HANDLE(INTEL_HWCONFIG_MAX_NUM_EU_PER_DSS); 55 HANDLE(INTEL_HWCONFIG_NUM_PIXEL_PIPES); 56 HANDLE(INTEL_HWCONFIG_DEPRECATED_MAX_NUM_GEOMETRY_PIPES); 57 HANDLE(INTEL_HWCONFIG_DEPRECATED_L3_CACHE_SIZE_IN_KB); 58 HANDLE(INTEL_HWCONFIG_DEPRECATED_L3_BANK_COUNT); 59 HANDLE(INTEL_HWCONFIG_L3_CACHE_WAYS_SIZE_IN_BYTES); 60 HANDLE(INTEL_HWCONFIG_L3_CACHE_WAYS_PER_SECTOR); 61 HANDLE(INTEL_HWCONFIG_MAX_MEMORY_CHANNELS); 62 HANDLE(INTEL_HWCONFIG_MEMORY_TYPE); 63 HANDLE(INTEL_HWCONFIG_CACHE_TYPES); 64 HANDLE(INTEL_HWCONFIG_LOCAL_MEMORY_PAGE_SIZES_SUPPORTED); 65 HANDLE(INTEL_HWCONFIG_DEPRECATED_SLM_SIZE_IN_KB); 66 HANDLE(INTEL_HWCONFIG_NUM_THREADS_PER_EU); 67 HANDLE(INTEL_HWCONFIG_TOTAL_VS_THREADS); 68 HANDLE(INTEL_HWCONFIG_TOTAL_GS_THREADS); 69 HANDLE(INTEL_HWCONFIG_TOTAL_HS_THREADS); 70 HANDLE(INTEL_HWCONFIG_TOTAL_DS_THREADS); 71 HANDLE(INTEL_HWCONFIG_TOTAL_VS_THREADS_POCS); 72 HANDLE(INTEL_HWCONFIG_TOTAL_PS_THREADS); 73 HANDLE(INTEL_HWCONFIG_DEPRECATED_MAX_FILL_RATE); 74 HANDLE(INTEL_HWCONFIG_MAX_RCS); 75 HANDLE(INTEL_HWCONFIG_MAX_CCS); 76 HANDLE(INTEL_HWCONFIG_MAX_VCS); 77 HANDLE(INTEL_HWCONFIG_MAX_VECS); 78 HANDLE(INTEL_HWCONFIG_MAX_COPY_CS); 79 HANDLE(INTEL_HWCONFIG_DEPRECATED_URB_SIZE_IN_KB); 80 HANDLE(INTEL_HWCONFIG_MIN_VS_URB_ENTRIES); 81 HANDLE(INTEL_HWCONFIG_MAX_VS_URB_ENTRIES); 82 HANDLE(INTEL_HWCONFIG_MIN_PCS_URB_ENTRIES); 83 HANDLE(INTEL_HWCONFIG_MAX_PCS_URB_ENTRIES); 84 HANDLE(INTEL_HWCONFIG_MIN_HS_URB_ENTRIES); 85 HANDLE(INTEL_HWCONFIG_MAX_HS_URB_ENTRIES); 86 HANDLE(INTEL_HWCONFIG_MIN_GS_URB_ENTRIES); 87 HANDLE(INTEL_HWCONFIG_MAX_GS_URB_ENTRIES); 88 HANDLE(INTEL_HWCONFIG_MIN_DS_URB_ENTRIES); 89 HANDLE(INTEL_HWCONFIG_MAX_DS_URB_ENTRIES); 90 HANDLE(INTEL_HWCONFIG_PUSH_CONSTANT_URB_RESERVED_SIZE); 91 HANDLE(INTEL_HWCONFIG_POCS_PUSH_CONSTANT_URB_RESERVED_SIZE); 92 HANDLE(INTEL_HWCONFIG_URB_REGION_ALIGNMENT_SIZE_IN_BYTES); 93 HANDLE(INTEL_HWCONFIG_URB_ALLOCATION_SIZE_UNITS_IN_BYTES); 94 HANDLE(INTEL_HWCONFIG_MAX_URB_SIZE_CCS_IN_BYTES); 95 HANDLE(INTEL_HWCONFIG_VS_MIN_DEREF_BLOCK_SIZE_HANDLE_COUNT); 96 HANDLE(INTEL_HWCONFIG_DS_MIN_DEREF_BLOCK_SIZE_HANDLE_COUNT); 97 HANDLE(INTEL_HWCONFIG_NUM_RT_STACKS_PER_DSS); 98 HANDLE(INTEL_HWCONFIG_MAX_URB_STARTING_ADDRESS); 99 HANDLE(INTEL_HWCONFIG_MIN_CS_URB_ENTRIES); 100 HANDLE(INTEL_HWCONFIG_MAX_CS_URB_ENTRIES); 101 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_URB); 102 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_REST); 103 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_DC); 104 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_RO); 105 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_Z); 106 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_COLOR); 107 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_UNIFIED_TILE_CACHE); 108 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_COMMAND_BUFFER); 109 HANDLE(INTEL_HWCONFIG_L3_ALLOC_PER_BANK_RW); 110 HANDLE(INTEL_HWCONFIG_MAX_NUM_L3_CONFIGS); 111 HANDLE(INTEL_HWCONFIG_BINDLESS_SURFACE_OFFSET_BIT_COUNT); 112 HANDLE(INTEL_HWCONFIG_RESERVED_CCS_WAYS); 113 HANDLE(INTEL_HWCONFIG_CSR_SIZE_IN_MB); 114 HANDLE(INTEL_HWCONFIG_GEOMETRY_PIPES_PER_SLICE); 115 HANDLE(INTEL_HWCONFIG_L3_BANK_SIZE_IN_KB); 116 HANDLE(INTEL_HWCONFIG_SLM_SIZE_PER_DSS); 117 HANDLE(INTEL_HWCONFIG_MAX_PIXEL_FILL_RATE_PER_SLICE); 118 HANDLE(INTEL_HWCONFIG_MAX_PIXEL_FILL_RATE_PER_DSS); 119 HANDLE(INTEL_HWCONFIG_URB_SIZE_PER_SLICE_IN_KB); 120 HANDLE(INTEL_HWCONFIG_URB_SIZE_PER_L3_BANK_COUNT_IN_KB); 121 HANDLE(INTEL_HWCONFIG_MAX_SUBSLICE); 122 HANDLE(INTEL_HWCONFIG_MAX_EU_PER_SUBSLICE); 123 HANDLE(INTEL_HWCONFIG_RAMBO_L3_BANK_SIZE_IN_KB); 124 HANDLE(INTEL_HWCONFIG_SLM_SIZE_PER_SS_IN_KB); 125#undef HANDLE 126 } 127 return "UNKNOWN_INTEL_HWCONFIG"; 128} 129 130typedef void (*hwconfig_item_cb)(struct intel_device_info *devinfo, 131 const struct hwconfig *item); 132 133static void 134intel_process_hwconfig_table(struct intel_device_info *devinfo, 135 const struct hwconfig *hwconfig, 136 int32_t hwconfig_len, 137 hwconfig_item_cb item_callback_func) 138{ 139 assert(hwconfig); 140 assert(hwconfig_len % 4 == 0); 141 const struct hwconfig *current = hwconfig; 142 const struct hwconfig *end = 143 (struct hwconfig*)(((uint32_t*)hwconfig) + (hwconfig_len / 4)); 144 while (current < end) { 145 assert(current + 1 < end); 146 struct hwconfig *next = 147 (struct hwconfig*)((uint32_t*)current + 2 + current->len); 148 assert(next <= end); 149 item_callback_func(devinfo, current); 150 current = next; 151 } 152 assert(current == end); 153} 154 155/* If devinfo->apply_hwconfig is true, then we apply the hwconfig value. 156 * 157 * For debug builds, if devinfo->apply_hwconfig is false, we will compare the 158 * hwconfig value with the current value in the devinfo and log a warning 159 * message if they differ. This should help to make sure the values in our 160 * devinfo structures match what hwconfig is specified. 161 */ 162#define DEVINFO_HWCONFIG(F, V) \ 163 do { \ 164 if (devinfo->apply_hwconfig) \ 165 devinfo->F = V; \ 166 else if (DEBUG_BUILD && devinfo->F != (V)) \ 167 mesa_logw("%s (%u) != devinfo->%s (%u)", \ 168 key_to_name(item->key), (V), #F, \ 169 devinfo->F); \ 170 } while (0) 171 172static void 173apply_hwconfig_item(struct intel_device_info *devinfo, 174 const struct hwconfig *item) 175{ 176 switch (item->key) { 177 case INTEL_HWCONFIG_MAX_SLICES_SUPPORTED: 178 case INTEL_HWCONFIG_MAX_DUAL_SUBSLICES_SUPPORTED: 179 case INTEL_HWCONFIG_NUM_PIXEL_PIPES: 180 case INTEL_HWCONFIG_DEPRECATED_MAX_NUM_GEOMETRY_PIPES: 181 case INTEL_HWCONFIG_DEPRECATED_L3_CACHE_SIZE_IN_KB: 182 case INTEL_HWCONFIG_DEPRECATED_L3_BANK_COUNT: 183 case INTEL_HWCONFIG_L3_CACHE_WAYS_SIZE_IN_BYTES: 184 case INTEL_HWCONFIG_L3_CACHE_WAYS_PER_SECTOR: 185 case INTEL_HWCONFIG_MAX_MEMORY_CHANNELS: 186 case INTEL_HWCONFIG_MEMORY_TYPE: 187 case INTEL_HWCONFIG_CACHE_TYPES: 188 case INTEL_HWCONFIG_LOCAL_MEMORY_PAGE_SIZES_SUPPORTED: 189 case INTEL_HWCONFIG_DEPRECATED_SLM_SIZE_IN_KB: 190 break; /* ignore */ 191 case INTEL_HWCONFIG_MAX_NUM_EU_PER_DSS: 192 DEVINFO_HWCONFIG(max_eus_per_subslice, item->val[0]); 193 break; 194 case INTEL_HWCONFIG_NUM_THREADS_PER_EU: 195 DEVINFO_HWCONFIG(num_thread_per_eu, item->val[0]); 196 break; 197 case INTEL_HWCONFIG_TOTAL_VS_THREADS: 198 DEVINFO_HWCONFIG(max_vs_threads, item->val[0]); 199 break; 200 case INTEL_HWCONFIG_TOTAL_GS_THREADS: 201 DEVINFO_HWCONFIG(max_gs_threads, item->val[0]); 202 break; 203 case INTEL_HWCONFIG_TOTAL_HS_THREADS: 204 DEVINFO_HWCONFIG(max_tcs_threads, item->val[0]); 205 break; 206 case INTEL_HWCONFIG_TOTAL_DS_THREADS: 207 DEVINFO_HWCONFIG(max_tes_threads, item->val[0]); 208 break; 209 case INTEL_HWCONFIG_TOTAL_VS_THREADS_POCS: 210 break; /* ignore */ 211 case INTEL_HWCONFIG_TOTAL_PS_THREADS: 212 DEVINFO_HWCONFIG(max_threads_per_psd, item->val[0] / 2); 213 break; 214 case INTEL_HWCONFIG_URB_SIZE_PER_SLICE_IN_KB: 215 DEVINFO_HWCONFIG(urb.size, item->val[0]); 216 break; 217 case INTEL_HWCONFIG_DEPRECATED_MAX_FILL_RATE: 218 case INTEL_HWCONFIG_MAX_RCS: 219 case INTEL_HWCONFIG_MAX_CCS: 220 case INTEL_HWCONFIG_MAX_VCS: 221 case INTEL_HWCONFIG_MAX_VECS: 222 case INTEL_HWCONFIG_MAX_COPY_CS: 223 case INTEL_HWCONFIG_DEPRECATED_URB_SIZE_IN_KB: 224 case INTEL_HWCONFIG_MIN_VS_URB_ENTRIES: 225 case INTEL_HWCONFIG_MAX_VS_URB_ENTRIES: 226 case INTEL_HWCONFIG_MIN_PCS_URB_ENTRIES: 227 case INTEL_HWCONFIG_MAX_PCS_URB_ENTRIES: 228 case INTEL_HWCONFIG_MIN_HS_URB_ENTRIES: 229 case INTEL_HWCONFIG_MAX_HS_URB_ENTRIES: 230 case INTEL_HWCONFIG_MIN_GS_URB_ENTRIES: 231 case INTEL_HWCONFIG_MAX_GS_URB_ENTRIES: 232 case INTEL_HWCONFIG_MIN_DS_URB_ENTRIES: 233 case INTEL_HWCONFIG_MAX_DS_URB_ENTRIES: 234 case INTEL_HWCONFIG_PUSH_CONSTANT_URB_RESERVED_SIZE: 235 case INTEL_HWCONFIG_POCS_PUSH_CONSTANT_URB_RESERVED_SIZE: 236 case INTEL_HWCONFIG_URB_REGION_ALIGNMENT_SIZE_IN_BYTES: 237 case INTEL_HWCONFIG_URB_ALLOCATION_SIZE_UNITS_IN_BYTES: 238 case INTEL_HWCONFIG_MAX_URB_SIZE_CCS_IN_BYTES: 239 case INTEL_HWCONFIG_VS_MIN_DEREF_BLOCK_SIZE_HANDLE_COUNT: 240 case INTEL_HWCONFIG_DS_MIN_DEREF_BLOCK_SIZE_HANDLE_COUNT: 241 case INTEL_HWCONFIG_NUM_RT_STACKS_PER_DSS: 242 case INTEL_HWCONFIG_MAX_URB_STARTING_ADDRESS: 243 case INTEL_HWCONFIG_MIN_CS_URB_ENTRIES: 244 case INTEL_HWCONFIG_MAX_CS_URB_ENTRIES: 245 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_URB: 246 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_REST: 247 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_DC: 248 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_RO: 249 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_Z: 250 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_COLOR: 251 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_UNIFIED_TILE_CACHE: 252 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_COMMAND_BUFFER: 253 case INTEL_HWCONFIG_L3_ALLOC_PER_BANK_RW: 254 case INTEL_HWCONFIG_MAX_NUM_L3_CONFIGS: 255 case INTEL_HWCONFIG_BINDLESS_SURFACE_OFFSET_BIT_COUNT: 256 case INTEL_HWCONFIG_RESERVED_CCS_WAYS: 257 case INTEL_HWCONFIG_CSR_SIZE_IN_MB: 258 case INTEL_HWCONFIG_GEOMETRY_PIPES_PER_SLICE: 259 case INTEL_HWCONFIG_L3_BANK_SIZE_IN_KB: 260 case INTEL_HWCONFIG_SLM_SIZE_PER_DSS: 261 case INTEL_HWCONFIG_MAX_PIXEL_FILL_RATE_PER_SLICE: 262 case INTEL_HWCONFIG_MAX_PIXEL_FILL_RATE_PER_DSS: 263 case INTEL_HWCONFIG_URB_SIZE_PER_L3_BANK_COUNT_IN_KB: 264 case INTEL_HWCONFIG_MAX_SUBSLICE: 265 case INTEL_HWCONFIG_MAX_EU_PER_SUBSLICE: 266 case INTEL_HWCONFIG_RAMBO_L3_BANK_SIZE_IN_KB: 267 case INTEL_HWCONFIG_SLM_SIZE_PER_SS_IN_KB: 268 default: 269 break; /* ignore */ 270 } 271} 272 273bool 274intel_get_and_process_hwconfig_table(int fd, 275 struct intel_device_info *devinfo) 276{ 277 struct hwconfig *hwconfig; 278 int32_t hwconfig_len = 0; 279 hwconfig = intel_i915_query_alloc(fd, DRM_I915_QUERY_HWCONFIG_BLOB, 280 &hwconfig_len); 281 if (hwconfig) { 282 intel_process_hwconfig_table(devinfo, hwconfig, hwconfig_len, 283 apply_hwconfig_item); 284 free(hwconfig); 285 if (devinfo->apply_hwconfig) 286 return true; 287 } 288 289 return false; 290} 291 292static void 293print_hwconfig_item(struct intel_device_info *devinfo, 294 const struct hwconfig *item) 295{ 296 printf("%s: ", key_to_name(item->key)); 297 for (int i = 0; i < item->len; i++) 298 printf(i ? ", 0x%x (%d)" : "0x%x (%d)", item->val[i], 299 item->val[i]); 300 printf("\n"); 301} 302 303static void 304intel_print_hwconfig_table(const struct hwconfig *hwconfig, 305 int32_t hwconfig_len) 306{ 307 intel_process_hwconfig_table(NULL, hwconfig, hwconfig_len, 308 print_hwconfig_item); 309} 310 311void 312intel_get_and_print_hwconfig_table(int fd) 313{ 314 struct hwconfig *hwconfig; 315 int32_t hwconfig_len = 0; 316 hwconfig = intel_i915_query_alloc(fd, DRM_I915_QUERY_HWCONFIG_BLOB, 317 &hwconfig_len); 318 if (hwconfig) { 319 intel_print_hwconfig_table(hwconfig, hwconfig_len); 320 free(hwconfig); 321 } 322} 323