xref: /third_party/mesa3d/src/amd/common/ac_rgp.c (revision bf215546)
1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2020 Advanced Micro Devices, Inc.
3bf215546Sopenharmony_ci * Copyright © 2020 Valve Corporation
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22bf215546Sopenharmony_ci * IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci#include "ac_rgp.h"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "util/macros.h"
27bf215546Sopenharmony_ci#include "util/os_misc.h"
28bf215546Sopenharmony_ci#include "util/os_time.h"
29bf215546Sopenharmony_ci#include "util/u_process.h"
30bf215546Sopenharmony_ci#include "util/u_math.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "ac_spm.h"
33bf215546Sopenharmony_ci#include "ac_sqtt.h"
34bf215546Sopenharmony_ci#include "ac_gpu_info.h"
35bf215546Sopenharmony_ci#ifdef _WIN32
36bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_UNKNOWN 0
37bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_GDDR1 1
38bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_DDR2  2
39bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_GDDR3 3
40bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_GDDR4 4
41bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_GDDR5 5
42bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_HBM   6
43bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_DDR3  7
44bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_DDR4  8
45bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_GDDR6 9
46bf215546Sopenharmony_ci#define AMDGPU_VRAM_TYPE_DDR5  10
47bf215546Sopenharmony_ci#else
48bf215546Sopenharmony_ci#include "drm-uapi/amdgpu_drm.h"
49bf215546Sopenharmony_ci#endif
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci#include <stdbool.h>
52bf215546Sopenharmony_ci#include <string.h>
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci#define SQTT_FILE_MAGIC_NUMBER  0x50303042
55bf215546Sopenharmony_ci#define SQTT_FILE_VERSION_MAJOR 1
56bf215546Sopenharmony_ci#define SQTT_FILE_VERSION_MINOR 5
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci#define SQTT_GPU_NAME_MAX_SIZE 256
59bf215546Sopenharmony_ci#define SQTT_MAX_NUM_SE        32
60bf215546Sopenharmony_ci#define SQTT_SA_PER_SE         2
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_cienum sqtt_version
63bf215546Sopenharmony_ci{
64bf215546Sopenharmony_ci   SQTT_VERSION_NONE = 0x0,
65bf215546Sopenharmony_ci   SQTT_VERSION_2_2 = 0x5, /* GFX8 */
66bf215546Sopenharmony_ci   SQTT_VERSION_2_3 = 0x6, /* GFX9 */
67bf215546Sopenharmony_ci   SQTT_VERSION_2_4 = 0x7  /* GFX10+ */
68bf215546Sopenharmony_ci};
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci/**
71bf215546Sopenharmony_ci * SQTT chunks.
72bf215546Sopenharmony_ci */
73bf215546Sopenharmony_cienum sqtt_file_chunk_type
74bf215546Sopenharmony_ci{
75bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_ASIC_INFO,
76bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_SQTT_DESC,
77bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_SQTT_DATA,
78bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_API_INFO,
79bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_RESERVED,
80bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_QUEUE_EVENT_TIMINGS,
81bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_CLOCK_CALIBRATION,
82bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_CPU_INFO,
83bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_SPM_DB,
84bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_DATABASE,
85bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_LOADER_EVENTS,
86bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_PSO_CORRELATION,
87bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_INSTRUMENTATION_TABLE,
88bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_TYPE_COUNT
89bf215546Sopenharmony_ci};
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_cistruct sqtt_file_chunk_id {
92bf215546Sopenharmony_ci   enum sqtt_file_chunk_type type : 8;
93bf215546Sopenharmony_ci   int32_t index : 8;
94bf215546Sopenharmony_ci   int32_t reserved : 16;
95bf215546Sopenharmony_ci};
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_cistruct sqtt_file_chunk_header {
98bf215546Sopenharmony_ci   struct sqtt_file_chunk_id chunk_id;
99bf215546Sopenharmony_ci   uint16_t minor_version;
100bf215546Sopenharmony_ci   uint16_t major_version;
101bf215546Sopenharmony_ci   int32_t size_in_bytes;
102bf215546Sopenharmony_ci   int32_t padding;
103bf215546Sopenharmony_ci};
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci/**
106bf215546Sopenharmony_ci * SQTT file header.
107bf215546Sopenharmony_ci */
108bf215546Sopenharmony_cistruct sqtt_file_header_flags {
109bf215546Sopenharmony_ci   union {
110bf215546Sopenharmony_ci      struct {
111bf215546Sopenharmony_ci         int32_t is_semaphore_queue_timing_etw : 1;
112bf215546Sopenharmony_ci         int32_t no_queue_semaphore_timestamps : 1;
113bf215546Sopenharmony_ci         int32_t reserved : 30;
114bf215546Sopenharmony_ci      };
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci      uint32_t value;
117bf215546Sopenharmony_ci   };
118bf215546Sopenharmony_ci};
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_cistruct sqtt_file_header {
121bf215546Sopenharmony_ci   uint32_t magic_number;
122bf215546Sopenharmony_ci   uint32_t version_major;
123bf215546Sopenharmony_ci   uint32_t version_minor;
124bf215546Sopenharmony_ci   struct sqtt_file_header_flags flags;
125bf215546Sopenharmony_ci   int32_t chunk_offset;
126bf215546Sopenharmony_ci   int32_t second;
127bf215546Sopenharmony_ci   int32_t minute;
128bf215546Sopenharmony_ci   int32_t hour;
129bf215546Sopenharmony_ci   int32_t day_in_month;
130bf215546Sopenharmony_ci   int32_t month;
131bf215546Sopenharmony_ci   int32_t year;
132bf215546Sopenharmony_ci   int32_t day_in_week;
133bf215546Sopenharmony_ci   int32_t day_in_year;
134bf215546Sopenharmony_ci   int32_t is_daylight_savings;
135bf215546Sopenharmony_ci};
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_header) == 56, "sqtt_file_header doesn't match RGP spec");
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_cistatic void ac_sqtt_fill_header(struct sqtt_file_header *header)
140bf215546Sopenharmony_ci{
141bf215546Sopenharmony_ci   struct tm *timep, result;
142bf215546Sopenharmony_ci   time_t raw_time;
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci   header->magic_number = SQTT_FILE_MAGIC_NUMBER;
145bf215546Sopenharmony_ci   header->version_major = SQTT_FILE_VERSION_MAJOR;
146bf215546Sopenharmony_ci   header->version_minor = SQTT_FILE_VERSION_MINOR;
147bf215546Sopenharmony_ci   header->flags.value = 0;
148bf215546Sopenharmony_ci   header->flags.is_semaphore_queue_timing_etw = 1;
149bf215546Sopenharmony_ci   header->flags.no_queue_semaphore_timestamps = 0;
150bf215546Sopenharmony_ci   header->chunk_offset = sizeof(*header);
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   time(&raw_time);
153bf215546Sopenharmony_ci   timep = os_localtime(&raw_time, &result);
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   header->second = timep->tm_sec;
156bf215546Sopenharmony_ci   header->minute = timep->tm_min;
157bf215546Sopenharmony_ci   header->hour = timep->tm_hour;
158bf215546Sopenharmony_ci   header->day_in_month = timep->tm_mday;
159bf215546Sopenharmony_ci   header->month = timep->tm_mon;
160bf215546Sopenharmony_ci   header->year = timep->tm_year;
161bf215546Sopenharmony_ci   header->day_in_week = timep->tm_wday;
162bf215546Sopenharmony_ci   header->day_in_year = timep->tm_yday;
163bf215546Sopenharmony_ci   header->is_daylight_savings = timep->tm_isdst;
164bf215546Sopenharmony_ci}
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci/**
167bf215546Sopenharmony_ci * SQTT CPU info.
168bf215546Sopenharmony_ci */
169bf215546Sopenharmony_cistruct sqtt_file_chunk_cpu_info {
170bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
171bf215546Sopenharmony_ci   uint32_t vendor_id[4];
172bf215546Sopenharmony_ci   uint32_t processor_brand[12];
173bf215546Sopenharmony_ci   uint32_t reserved[2];
174bf215546Sopenharmony_ci   uint64_t cpu_timestamp_freq;
175bf215546Sopenharmony_ci   uint32_t clock_speed;
176bf215546Sopenharmony_ci   uint32_t num_logical_cores;
177bf215546Sopenharmony_ci   uint32_t num_physical_cores;
178bf215546Sopenharmony_ci   uint32_t system_ram_size;
179bf215546Sopenharmony_ci};
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_cpu_info) == 112,
182bf215546Sopenharmony_ci              "sqtt_file_chunk_cpu_info doesn't match RGP spec");
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_cistatic void ac_sqtt_fill_cpu_info(struct sqtt_file_chunk_cpu_info *chunk)
185bf215546Sopenharmony_ci{
186bf215546Sopenharmony_ci   uint32_t cpu_clock_speed_total = 0;
187bf215546Sopenharmony_ci   uint64_t system_ram_size = 0;
188bf215546Sopenharmony_ci   char line[1024];
189bf215546Sopenharmony_ci   FILE *f;
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_CPU_INFO;
192bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
193bf215546Sopenharmony_ci   chunk->header.major_version = 0;
194bf215546Sopenharmony_ci   chunk->header.minor_version = 0;
195bf215546Sopenharmony_ci   chunk->header.size_in_bytes = sizeof(*chunk);
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci   chunk->cpu_timestamp_freq = 1000000000; /* tick set to 1ns */
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci   strncpy((char *)chunk->vendor_id, "Unknown", sizeof(chunk->vendor_id));
200bf215546Sopenharmony_ci   strncpy((char *)chunk->processor_brand, "Unknown", sizeof(chunk->processor_brand));
201bf215546Sopenharmony_ci   chunk->clock_speed = 0;
202bf215546Sopenharmony_ci   chunk->num_logical_cores = 0;
203bf215546Sopenharmony_ci   chunk->num_physical_cores = 0;
204bf215546Sopenharmony_ci   chunk->system_ram_size = 0;
205bf215546Sopenharmony_ci   if (os_get_total_physical_memory(&system_ram_size))
206bf215546Sopenharmony_ci      chunk->system_ram_size = system_ram_size / (1024 * 1024);
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   /* Parse cpuinfo to get more detailled information. */
209bf215546Sopenharmony_ci   f = fopen("/proc/cpuinfo", "r");
210bf215546Sopenharmony_ci   if (!f)
211bf215546Sopenharmony_ci      return;
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci   while (fgets(line, sizeof(line), f)) {
214bf215546Sopenharmony_ci      char *str;
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci      /* Parse vendor name. */
217bf215546Sopenharmony_ci      str = strstr(line, "vendor_id");
218bf215546Sopenharmony_ci      if (str) {
219bf215546Sopenharmony_ci         char *ptr = (char *)chunk->vendor_id;
220bf215546Sopenharmony_ci         char *v = strtok(str, ":");
221bf215546Sopenharmony_ci         v = strtok(NULL, ":");
222bf215546Sopenharmony_ci         strncpy(ptr, v + 1, sizeof(chunk->vendor_id) - 1);
223bf215546Sopenharmony_ci         ptr[sizeof(chunk->vendor_id) - 1] = '\0';
224bf215546Sopenharmony_ci      }
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci      /* Parse processor name. */
227bf215546Sopenharmony_ci      str = strstr(line, "model name");
228bf215546Sopenharmony_ci      if (str) {
229bf215546Sopenharmony_ci         char *ptr = (char *)chunk->processor_brand;
230bf215546Sopenharmony_ci         char *v = strtok(str, ":");
231bf215546Sopenharmony_ci         v = strtok(NULL, ":");
232bf215546Sopenharmony_ci         strncpy(ptr, v + 1, sizeof(chunk->processor_brand) - 1);
233bf215546Sopenharmony_ci         ptr[sizeof(chunk->processor_brand) - 1] = '\0';
234bf215546Sopenharmony_ci      }
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_ci      /* Parse the current CPU clock speed for each cores. */
237bf215546Sopenharmony_ci      str = strstr(line, "cpu MHz");
238bf215546Sopenharmony_ci      if (str) {
239bf215546Sopenharmony_ci         uint32_t v = 0;
240bf215546Sopenharmony_ci         if (sscanf(str, "cpu MHz : %d", &v) == 1)
241bf215546Sopenharmony_ci            cpu_clock_speed_total += v;
242bf215546Sopenharmony_ci      }
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci      /* Parse the number of logical cores. */
245bf215546Sopenharmony_ci      str = strstr(line, "siblings");
246bf215546Sopenharmony_ci      if (str) {
247bf215546Sopenharmony_ci         uint32_t v = 0;
248bf215546Sopenharmony_ci         if (sscanf(str, "siblings : %d", &v) == 1)
249bf215546Sopenharmony_ci            chunk->num_logical_cores = v;
250bf215546Sopenharmony_ci      }
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci      /* Parse the number of physical cores. */
253bf215546Sopenharmony_ci      str = strstr(line, "cpu cores");
254bf215546Sopenharmony_ci      if (str) {
255bf215546Sopenharmony_ci         uint32_t v = 0;
256bf215546Sopenharmony_ci         if (sscanf(str, "cpu cores : %d", &v) == 1)
257bf215546Sopenharmony_ci            chunk->num_physical_cores = v;
258bf215546Sopenharmony_ci      }
259bf215546Sopenharmony_ci   }
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci   if (chunk->num_logical_cores)
262bf215546Sopenharmony_ci      chunk->clock_speed = cpu_clock_speed_total / chunk->num_logical_cores;
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci   fclose(f);
265bf215546Sopenharmony_ci}
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci/**
268bf215546Sopenharmony_ci * SQTT ASIC info.
269bf215546Sopenharmony_ci */
270bf215546Sopenharmony_cienum sqtt_file_chunk_asic_info_flags
271bf215546Sopenharmony_ci{
272bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_ASIC_INFO_FLAG_SC_PACKER_NUMBERING = (1 << 0),
273bf215546Sopenharmony_ci   SQTT_FILE_CHUNK_ASIC_INFO_FLAG_PS1_EVENT_TOKENS_ENABLED = (1 << 1)
274bf215546Sopenharmony_ci};
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_cienum sqtt_gpu_type
277bf215546Sopenharmony_ci{
278bf215546Sopenharmony_ci   SQTT_GPU_TYPE_UNKNOWN = 0x0,
279bf215546Sopenharmony_ci   SQTT_GPU_TYPE_INTEGRATED = 0x1,
280bf215546Sopenharmony_ci   SQTT_GPU_TYPE_DISCRETE = 0x2,
281bf215546Sopenharmony_ci   SQTT_GPU_TYPE_VIRTUAL = 0x3
282bf215546Sopenharmony_ci};
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_cienum sqtt_gfxip_level
285bf215546Sopenharmony_ci{
286bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_NONE = 0x0,
287bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_GFXIP_6 = 0x1,
288bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_GFXIP_7 = 0x2,
289bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_GFXIP_8 = 0x3,
290bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_GFXIP_8_1 = 0x4,
291bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_GFXIP_9 = 0x5,
292bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_GFXIP_10_1 = 0x7,
293bf215546Sopenharmony_ci   SQTT_GFXIP_LEVEL_GFXIP_10_3 = 0x9,
294bf215546Sopenharmony_ci};
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_cienum sqtt_memory_type
297bf215546Sopenharmony_ci{
298bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_UNKNOWN = 0x0,
299bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_DDR = 0x1,
300bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_DDR2 = 0x2,
301bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_DDR3 = 0x3,
302bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_DDR4 = 0x4,
303bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_GDDR3 = 0x10,
304bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_GDDR4 = 0x11,
305bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_GDDR5 = 0x12,
306bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_GDDR6 = 0x13,
307bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_HBM = 0x20,
308bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_HBM2 = 0x21,
309bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_HBM3 = 0x22,
310bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_LPDDR4 = 0x30,
311bf215546Sopenharmony_ci   SQTT_MEMORY_TYPE_LPDDR5 = 0x31,
312bf215546Sopenharmony_ci};
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_cistruct sqtt_file_chunk_asic_info {
315bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
316bf215546Sopenharmony_ci   uint64_t flags;
317bf215546Sopenharmony_ci   uint64_t trace_shader_core_clock;
318bf215546Sopenharmony_ci   uint64_t trace_memory_clock;
319bf215546Sopenharmony_ci   int32_t device_id;
320bf215546Sopenharmony_ci   int32_t device_revision_id;
321bf215546Sopenharmony_ci   int32_t vgprs_per_simd;
322bf215546Sopenharmony_ci   int32_t sgprs_per_simd;
323bf215546Sopenharmony_ci   int32_t shader_engines;
324bf215546Sopenharmony_ci   int32_t compute_unit_per_shader_engine;
325bf215546Sopenharmony_ci   int32_t simd_per_compute_unit;
326bf215546Sopenharmony_ci   int32_t wavefronts_per_simd;
327bf215546Sopenharmony_ci   int32_t minimum_vgpr_alloc;
328bf215546Sopenharmony_ci   int32_t vgpr_alloc_granularity;
329bf215546Sopenharmony_ci   int32_t minimum_sgpr_alloc;
330bf215546Sopenharmony_ci   int32_t sgpr_alloc_granularity;
331bf215546Sopenharmony_ci   int32_t hardware_contexts;
332bf215546Sopenharmony_ci   enum sqtt_gpu_type gpu_type;
333bf215546Sopenharmony_ci   enum sqtt_gfxip_level gfxip_level;
334bf215546Sopenharmony_ci   int32_t gpu_index;
335bf215546Sopenharmony_ci   int32_t gds_size;
336bf215546Sopenharmony_ci   int32_t gds_per_shader_engine;
337bf215546Sopenharmony_ci   int32_t ce_ram_size;
338bf215546Sopenharmony_ci   int32_t ce_ram_size_graphics;
339bf215546Sopenharmony_ci   int32_t ce_ram_size_compute;
340bf215546Sopenharmony_ci   int32_t max_number_of_dedicated_cus;
341bf215546Sopenharmony_ci   int64_t vram_size;
342bf215546Sopenharmony_ci   int32_t vram_bus_width;
343bf215546Sopenharmony_ci   int32_t l2_cache_size;
344bf215546Sopenharmony_ci   int32_t l1_cache_size;
345bf215546Sopenharmony_ci   int32_t lds_size;
346bf215546Sopenharmony_ci   char gpu_name[SQTT_GPU_NAME_MAX_SIZE];
347bf215546Sopenharmony_ci   float alu_per_clock;
348bf215546Sopenharmony_ci   float texture_per_clock;
349bf215546Sopenharmony_ci   float prims_per_clock;
350bf215546Sopenharmony_ci   float pixels_per_clock;
351bf215546Sopenharmony_ci   uint64_t gpu_timestamp_frequency;
352bf215546Sopenharmony_ci   uint64_t max_shader_core_clock;
353bf215546Sopenharmony_ci   uint64_t max_memory_clock;
354bf215546Sopenharmony_ci   uint32_t memory_ops_per_clock;
355bf215546Sopenharmony_ci   enum sqtt_memory_type memory_chip_type;
356bf215546Sopenharmony_ci   uint32_t lds_granularity;
357bf215546Sopenharmony_ci   uint16_t cu_mask[SQTT_MAX_NUM_SE][SQTT_SA_PER_SE];
358bf215546Sopenharmony_ci   char reserved1[128];
359bf215546Sopenharmony_ci   char padding[4];
360bf215546Sopenharmony_ci};
361bf215546Sopenharmony_ci
362bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_asic_info) == 720,
363bf215546Sopenharmony_ci              "sqtt_file_chunk_asic_info doesn't match RGP spec");
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_cistatic enum sqtt_gfxip_level ac_gfx_level_to_sqtt_gfxip_level(enum amd_gfx_level gfx_level)
366bf215546Sopenharmony_ci{
367bf215546Sopenharmony_ci   switch (gfx_level) {
368bf215546Sopenharmony_ci   case GFX8:
369bf215546Sopenharmony_ci      return SQTT_GFXIP_LEVEL_GFXIP_8;
370bf215546Sopenharmony_ci   case GFX9:
371bf215546Sopenharmony_ci      return SQTT_GFXIP_LEVEL_GFXIP_9;
372bf215546Sopenharmony_ci   case GFX10:
373bf215546Sopenharmony_ci      return SQTT_GFXIP_LEVEL_GFXIP_10_1;
374bf215546Sopenharmony_ci   case GFX10_3:
375bf215546Sopenharmony_ci      return SQTT_GFXIP_LEVEL_GFXIP_10_3;
376bf215546Sopenharmony_ci   default:
377bf215546Sopenharmony_ci      unreachable("Invalid gfx level");
378bf215546Sopenharmony_ci   }
379bf215546Sopenharmony_ci}
380bf215546Sopenharmony_ci
381bf215546Sopenharmony_cistatic enum sqtt_memory_type ac_vram_type_to_sqtt_memory_type(uint32_t vram_type)
382bf215546Sopenharmony_ci{
383bf215546Sopenharmony_ci   switch (vram_type) {
384bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_UNKNOWN:
385bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_UNKNOWN;
386bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR2:
387bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_DDR2;
388bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR3:
389bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_DDR3;
390bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR4:
391bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_DDR4;
392bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR5:
393bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_GDDR5;
394bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_HBM:
395bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_HBM;
396bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR6:
397bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_GDDR6;
398bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR5:
399bf215546Sopenharmony_ci      return SQTT_MEMORY_TYPE_LPDDR5;
400bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR1:
401bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR3:
402bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR4:
403bf215546Sopenharmony_ci   default:
404bf215546Sopenharmony_ci      unreachable("Invalid vram type");
405bf215546Sopenharmony_ci   }
406bf215546Sopenharmony_ci}
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_cistatic uint32_t ac_memory_ops_per_clock(uint32_t vram_type)
409bf215546Sopenharmony_ci{
410bf215546Sopenharmony_ci   switch (vram_type) {
411bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_UNKNOWN:
412bf215546Sopenharmony_ci      return 0;
413bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR2:
414bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR3:
415bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR4:
416bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_HBM:
417bf215546Sopenharmony_ci      return 2;
418bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_DDR5:
419bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR5:
420bf215546Sopenharmony_ci      return 4;
421bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR6:
422bf215546Sopenharmony_ci      return 16;
423bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR1:
424bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR3:
425bf215546Sopenharmony_ci   case AMDGPU_VRAM_TYPE_GDDR4:
426bf215546Sopenharmony_ci   default:
427bf215546Sopenharmony_ci      unreachable("Invalid vram type");
428bf215546Sopenharmony_ci   }
429bf215546Sopenharmony_ci}
430bf215546Sopenharmony_ci
431bf215546Sopenharmony_cistatic void ac_sqtt_fill_asic_info(struct radeon_info *rad_info,
432bf215546Sopenharmony_ci                                   struct sqtt_file_chunk_asic_info *chunk)
433bf215546Sopenharmony_ci{
434bf215546Sopenharmony_ci   bool has_wave32 = rad_info->gfx_level >= GFX10;
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_ASIC_INFO;
437bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
438bf215546Sopenharmony_ci   chunk->header.major_version = 0;
439bf215546Sopenharmony_ci   chunk->header.minor_version = 4;
440bf215546Sopenharmony_ci   chunk->header.size_in_bytes = sizeof(*chunk);
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ci   chunk->flags = 0;
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci   /* All chips older than GFX9 are affected by the "SPI not
445bf215546Sopenharmony_ci    * differentiating pkr_id for newwave commands" bug.
446bf215546Sopenharmony_ci    */
447bf215546Sopenharmony_ci   if (rad_info->gfx_level < GFX9)
448bf215546Sopenharmony_ci      chunk->flags |= SQTT_FILE_CHUNK_ASIC_INFO_FLAG_SC_PACKER_NUMBERING;
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_ci   /* Only GFX9+ support PS1 events. */
451bf215546Sopenharmony_ci   if (rad_info->gfx_level >= GFX9)
452bf215546Sopenharmony_ci      chunk->flags |= SQTT_FILE_CHUNK_ASIC_INFO_FLAG_PS1_EVENT_TOKENS_ENABLED;
453bf215546Sopenharmony_ci
454bf215546Sopenharmony_ci   chunk->trace_shader_core_clock = rad_info->max_gpu_freq_mhz * 1000000ull;
455bf215546Sopenharmony_ci   chunk->trace_memory_clock = rad_info->memory_freq_mhz * 1000000ull;
456bf215546Sopenharmony_ci
457bf215546Sopenharmony_ci   /* RGP gets very confused if these clocks are 0. The numbers here are for profile_peak on
458bf215546Sopenharmony_ci    * VGH since that is the chips where we've seen the need for this workaround. */
459bf215546Sopenharmony_ci   if (!chunk->trace_shader_core_clock)
460bf215546Sopenharmony_ci      chunk->trace_shader_core_clock = 1300000000;
461bf215546Sopenharmony_ci   if (!chunk->trace_memory_clock)
462bf215546Sopenharmony_ci      chunk->trace_memory_clock = 687000000;
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ci   chunk->device_id = rad_info->pci_id;
465bf215546Sopenharmony_ci   chunk->device_revision_id = rad_info->pci_rev_id;
466bf215546Sopenharmony_ci   chunk->vgprs_per_simd = rad_info->num_physical_wave64_vgprs_per_simd * (has_wave32 ? 2 : 1);
467bf215546Sopenharmony_ci   chunk->sgprs_per_simd = rad_info->num_physical_sgprs_per_simd;
468bf215546Sopenharmony_ci   chunk->shader_engines = rad_info->max_se;
469bf215546Sopenharmony_ci   chunk->compute_unit_per_shader_engine = rad_info->min_good_cu_per_sa * rad_info->max_sa_per_se;
470bf215546Sopenharmony_ci   chunk->simd_per_compute_unit = rad_info->num_simd_per_compute_unit;
471bf215546Sopenharmony_ci   chunk->wavefronts_per_simd = rad_info->max_wave64_per_simd;
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci   chunk->minimum_vgpr_alloc = rad_info->min_wave64_vgpr_alloc;
474bf215546Sopenharmony_ci   chunk->vgpr_alloc_granularity = rad_info->wave64_vgpr_alloc_granularity * (has_wave32 ? 2 : 1);
475bf215546Sopenharmony_ci   chunk->minimum_sgpr_alloc = rad_info->min_sgpr_alloc;
476bf215546Sopenharmony_ci   chunk->sgpr_alloc_granularity = rad_info->sgpr_alloc_granularity;
477bf215546Sopenharmony_ci
478bf215546Sopenharmony_ci   chunk->hardware_contexts = 8;
479bf215546Sopenharmony_ci   chunk->gpu_type =
480bf215546Sopenharmony_ci      rad_info->has_dedicated_vram ? SQTT_GPU_TYPE_DISCRETE : SQTT_GPU_TYPE_INTEGRATED;
481bf215546Sopenharmony_ci   chunk->gfxip_level = ac_gfx_level_to_sqtt_gfxip_level(rad_info->gfx_level);
482bf215546Sopenharmony_ci   chunk->gpu_index = 0;
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci   chunk->max_number_of_dedicated_cus = 0;
485bf215546Sopenharmony_ci   chunk->ce_ram_size = 0;
486bf215546Sopenharmony_ci   chunk->ce_ram_size_graphics = 0;
487bf215546Sopenharmony_ci   chunk->ce_ram_size_compute = 0;
488bf215546Sopenharmony_ci
489bf215546Sopenharmony_ci   chunk->vram_bus_width = rad_info->memory_bus_width;
490bf215546Sopenharmony_ci   chunk->vram_size = (uint64_t)rad_info->vram_size_kb * 1024;
491bf215546Sopenharmony_ci   chunk->l2_cache_size = rad_info->l2_cache_size;
492bf215546Sopenharmony_ci   chunk->l1_cache_size = rad_info->l1_cache_size;
493bf215546Sopenharmony_ci   chunk->lds_size = rad_info->lds_size_per_workgroup;
494bf215546Sopenharmony_ci   if (rad_info->gfx_level >= GFX10) {
495bf215546Sopenharmony_ci      /* RGP expects the LDS size in CU mode. */
496bf215546Sopenharmony_ci      chunk->lds_size /= 2;
497bf215546Sopenharmony_ci   }
498bf215546Sopenharmony_ci
499bf215546Sopenharmony_ci   strncpy(chunk->gpu_name, rad_info->name, SQTT_GPU_NAME_MAX_SIZE - 1);
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ci   chunk->alu_per_clock = 0.0;
502bf215546Sopenharmony_ci   chunk->texture_per_clock = 0.0;
503bf215546Sopenharmony_ci   chunk->prims_per_clock = rad_info->max_se;
504bf215546Sopenharmony_ci   if (rad_info->gfx_level == GFX10)
505bf215546Sopenharmony_ci      chunk->prims_per_clock *= 2;
506bf215546Sopenharmony_ci   chunk->pixels_per_clock = 0.0;
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci   chunk->gpu_timestamp_frequency = rad_info->clock_crystal_freq * 1000;
509bf215546Sopenharmony_ci   chunk->max_shader_core_clock = rad_info->max_gpu_freq_mhz * 1000000;
510bf215546Sopenharmony_ci   chunk->max_memory_clock = rad_info->memory_freq_mhz * 1000000;
511bf215546Sopenharmony_ci   chunk->memory_ops_per_clock = ac_memory_ops_per_clock(rad_info->vram_type);
512bf215546Sopenharmony_ci   chunk->memory_chip_type = ac_vram_type_to_sqtt_memory_type(rad_info->vram_type);
513bf215546Sopenharmony_ci   chunk->lds_granularity = rad_info->lds_encode_granularity;
514bf215546Sopenharmony_ci
515bf215546Sopenharmony_ci   for (unsigned se = 0; se < AMD_MAX_SE; se++) {
516bf215546Sopenharmony_ci      for (unsigned sa = 0; sa < AMD_MAX_SA_PER_SE; sa++) {
517bf215546Sopenharmony_ci         chunk->cu_mask[se][sa] = rad_info->cu_mask[se][sa];
518bf215546Sopenharmony_ci      }
519bf215546Sopenharmony_ci   }
520bf215546Sopenharmony_ci}
521bf215546Sopenharmony_ci
522bf215546Sopenharmony_ci/**
523bf215546Sopenharmony_ci * SQTT API info.
524bf215546Sopenharmony_ci */
525bf215546Sopenharmony_cienum sqtt_api_type
526bf215546Sopenharmony_ci{
527bf215546Sopenharmony_ci   SQTT_API_TYPE_DIRECTX_12,
528bf215546Sopenharmony_ci   SQTT_API_TYPE_VULKAN,
529bf215546Sopenharmony_ci   SQTT_API_TYPE_GENERIC,
530bf215546Sopenharmony_ci   SQTT_API_TYPE_OPENCL
531bf215546Sopenharmony_ci};
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_cienum sqtt_instruction_trace_mode
534bf215546Sopenharmony_ci{
535bf215546Sopenharmony_ci   SQTT_INSTRUCTION_TRACE_DISABLED = 0x0,
536bf215546Sopenharmony_ci   SQTT_INSTRUCTION_TRACE_FULL_FRAME = 0x1,
537bf215546Sopenharmony_ci   SQTT_INSTRUCTION_TRACE_API_PSO = 0x2,
538bf215546Sopenharmony_ci};
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_cienum sqtt_profiling_mode
541bf215546Sopenharmony_ci{
542bf215546Sopenharmony_ci   SQTT_PROFILING_MODE_PRESENT = 0x0,
543bf215546Sopenharmony_ci   SQTT_PROFILING_MODE_USER_MARKERS = 0x1,
544bf215546Sopenharmony_ci   SQTT_PROFILING_MODE_INDEX = 0x2,
545bf215546Sopenharmony_ci   SQTT_PROFILING_MODE_TAG = 0x3,
546bf215546Sopenharmony_ci};
547bf215546Sopenharmony_ci
548bf215546Sopenharmony_ciunion sqtt_profiling_mode_data {
549bf215546Sopenharmony_ci   struct {
550bf215546Sopenharmony_ci      char start[256];
551bf215546Sopenharmony_ci      char end[256];
552bf215546Sopenharmony_ci   } user_marker_profiling_data;
553bf215546Sopenharmony_ci
554bf215546Sopenharmony_ci   struct {
555bf215546Sopenharmony_ci      uint32_t start;
556bf215546Sopenharmony_ci      uint32_t end;
557bf215546Sopenharmony_ci   } index_profiling_data;
558bf215546Sopenharmony_ci
559bf215546Sopenharmony_ci   struct {
560bf215546Sopenharmony_ci      uint32_t begin_hi;
561bf215546Sopenharmony_ci      uint32_t begin_lo;
562bf215546Sopenharmony_ci      uint32_t end_hi;
563bf215546Sopenharmony_ci      uint32_t end_lo;
564bf215546Sopenharmony_ci   } tag_profiling_data;
565bf215546Sopenharmony_ci};
566bf215546Sopenharmony_ci
567bf215546Sopenharmony_ciunion sqtt_instruction_trace_data {
568bf215546Sopenharmony_ci   struct {
569bf215546Sopenharmony_ci      uint64_t api_pso_filter;
570bf215546Sopenharmony_ci   } api_pso_data;
571bf215546Sopenharmony_ci
572bf215546Sopenharmony_ci   struct {
573bf215546Sopenharmony_ci      char start[256];
574bf215546Sopenharmony_ci      char end[256];
575bf215546Sopenharmony_ci   } user_marker_data;
576bf215546Sopenharmony_ci};
577bf215546Sopenharmony_ci
578bf215546Sopenharmony_cistruct sqtt_file_chunk_api_info {
579bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
580bf215546Sopenharmony_ci   enum sqtt_api_type api_type;
581bf215546Sopenharmony_ci   uint16_t major_version;
582bf215546Sopenharmony_ci   uint16_t minor_version;
583bf215546Sopenharmony_ci   enum sqtt_profiling_mode profiling_mode;
584bf215546Sopenharmony_ci   uint32_t reserved;
585bf215546Sopenharmony_ci   union sqtt_profiling_mode_data profiling_mode_data;
586bf215546Sopenharmony_ci   enum sqtt_instruction_trace_mode instruction_trace_mode;
587bf215546Sopenharmony_ci   uint32_t reserved2;
588bf215546Sopenharmony_ci   union sqtt_instruction_trace_data instruction_trace_data;
589bf215546Sopenharmony_ci};
590bf215546Sopenharmony_ci
591bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_api_info) == 1064,
592bf215546Sopenharmony_ci              "sqtt_file_chunk_api_info doesn't match RGP spec");
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_cistatic void ac_sqtt_fill_api_info(struct sqtt_file_chunk_api_info *chunk)
595bf215546Sopenharmony_ci{
596bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_API_INFO;
597bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
598bf215546Sopenharmony_ci   chunk->header.major_version = 0;
599bf215546Sopenharmony_ci   chunk->header.minor_version = 1;
600bf215546Sopenharmony_ci   chunk->header.size_in_bytes = sizeof(*chunk);
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci   chunk->api_type = SQTT_API_TYPE_VULKAN;
603bf215546Sopenharmony_ci   chunk->major_version = 0;
604bf215546Sopenharmony_ci   chunk->minor_version = 0;
605bf215546Sopenharmony_ci   chunk->profiling_mode = SQTT_PROFILING_MODE_PRESENT;
606bf215546Sopenharmony_ci   chunk->instruction_trace_mode = SQTT_INSTRUCTION_TRACE_DISABLED;
607bf215546Sopenharmony_ci}
608bf215546Sopenharmony_ci
609bf215546Sopenharmony_cistruct sqtt_code_object_database_record {
610bf215546Sopenharmony_ci   uint32_t size;
611bf215546Sopenharmony_ci};
612bf215546Sopenharmony_ci
613bf215546Sopenharmony_cistruct sqtt_file_chunk_code_object_database {
614bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
615bf215546Sopenharmony_ci   uint32_t offset;
616bf215546Sopenharmony_ci   uint32_t flags;
617bf215546Sopenharmony_ci   uint32_t size;
618bf215546Sopenharmony_ci   uint32_t record_count;
619bf215546Sopenharmony_ci};
620bf215546Sopenharmony_ci
621bf215546Sopenharmony_cistatic void
622bf215546Sopenharmony_ciac_sqtt_fill_code_object(struct rgp_code_object *rgp_code_object,
623bf215546Sopenharmony_ci                         struct sqtt_file_chunk_code_object_database *chunk,
624bf215546Sopenharmony_ci                         size_t file_offset, uint32_t chunk_size)
625bf215546Sopenharmony_ci{
626bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_DATABASE;
627bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
628bf215546Sopenharmony_ci   chunk->header.major_version = 0;
629bf215546Sopenharmony_ci   chunk->header.minor_version = 0;
630bf215546Sopenharmony_ci   chunk->header.size_in_bytes = chunk_size;
631bf215546Sopenharmony_ci   chunk->offset = file_offset;
632bf215546Sopenharmony_ci   chunk->flags = 0;
633bf215546Sopenharmony_ci   chunk->size = chunk_size;
634bf215546Sopenharmony_ci   chunk->record_count = rgp_code_object->record_count;
635bf215546Sopenharmony_ci}
636bf215546Sopenharmony_ci
637bf215546Sopenharmony_cistruct sqtt_code_object_loader_events_record {
638bf215546Sopenharmony_ci   uint32_t loader_event_type;
639bf215546Sopenharmony_ci   uint32_t reserved;
640bf215546Sopenharmony_ci   uint64_t base_address;
641bf215546Sopenharmony_ci   uint64_t code_object_hash[2];
642bf215546Sopenharmony_ci   uint64_t time_stamp;
643bf215546Sopenharmony_ci};
644bf215546Sopenharmony_ci
645bf215546Sopenharmony_cistruct sqtt_file_chunk_code_object_loader_events {
646bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
647bf215546Sopenharmony_ci   uint32_t offset;
648bf215546Sopenharmony_ci   uint32_t flags;
649bf215546Sopenharmony_ci   uint32_t record_size;
650bf215546Sopenharmony_ci   uint32_t record_count;
651bf215546Sopenharmony_ci};
652bf215546Sopenharmony_ci
653bf215546Sopenharmony_cistatic void
654bf215546Sopenharmony_ciac_sqtt_fill_loader_events(struct rgp_loader_events *rgp_loader_events,
655bf215546Sopenharmony_ci                           struct sqtt_file_chunk_code_object_loader_events *chunk,
656bf215546Sopenharmony_ci                           size_t file_offset)
657bf215546Sopenharmony_ci{
658bf215546Sopenharmony_ci   chunk->header.chunk_id.type =
659bf215546Sopenharmony_ci                               SQTT_FILE_CHUNK_TYPE_CODE_OBJECT_LOADER_EVENTS;
660bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
661bf215546Sopenharmony_ci   chunk->header.major_version = 1;
662bf215546Sopenharmony_ci   chunk->header.minor_version = 0;
663bf215546Sopenharmony_ci   chunk->header.size_in_bytes = (rgp_loader_events->record_count *
664bf215546Sopenharmony_ci                                 sizeof(struct sqtt_code_object_loader_events_record)) +
665bf215546Sopenharmony_ci                                 sizeof(*chunk);
666bf215546Sopenharmony_ci   chunk->offset = file_offset;
667bf215546Sopenharmony_ci   chunk->flags = 0;
668bf215546Sopenharmony_ci   chunk->record_size = sizeof(struct sqtt_code_object_loader_events_record);
669bf215546Sopenharmony_ci   chunk->record_count = rgp_loader_events->record_count;
670bf215546Sopenharmony_ci}
671bf215546Sopenharmony_cistruct sqtt_pso_correlation_record {
672bf215546Sopenharmony_ci   uint64_t api_pso_hash;
673bf215546Sopenharmony_ci   uint64_t pipeline_hash[2];
674bf215546Sopenharmony_ci   char api_level_obj_name[64];
675bf215546Sopenharmony_ci};
676bf215546Sopenharmony_ci
677bf215546Sopenharmony_cistruct sqtt_file_chunk_pso_correlation {
678bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
679bf215546Sopenharmony_ci   uint32_t offset;
680bf215546Sopenharmony_ci   uint32_t flags;
681bf215546Sopenharmony_ci   uint32_t record_size;
682bf215546Sopenharmony_ci   uint32_t record_count;
683bf215546Sopenharmony_ci};
684bf215546Sopenharmony_ci
685bf215546Sopenharmony_cistatic void
686bf215546Sopenharmony_ciac_sqtt_fill_pso_correlation(struct rgp_pso_correlation *rgp_pso_correlation,
687bf215546Sopenharmony_ci                             struct sqtt_file_chunk_pso_correlation *chunk,
688bf215546Sopenharmony_ci                             size_t file_offset)
689bf215546Sopenharmony_ci{
690bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_PSO_CORRELATION;
691bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
692bf215546Sopenharmony_ci   chunk->header.major_version = 0;
693bf215546Sopenharmony_ci   chunk->header.minor_version = 0;
694bf215546Sopenharmony_ci   chunk->header.size_in_bytes = (rgp_pso_correlation->record_count *
695bf215546Sopenharmony_ci                                 sizeof(struct sqtt_pso_correlation_record)) +
696bf215546Sopenharmony_ci                                 sizeof(*chunk);
697bf215546Sopenharmony_ci   chunk->offset = file_offset;
698bf215546Sopenharmony_ci   chunk->flags = 0;
699bf215546Sopenharmony_ci   chunk->record_size = sizeof(struct sqtt_pso_correlation_record);
700bf215546Sopenharmony_ci   chunk->record_count = rgp_pso_correlation->record_count;
701bf215546Sopenharmony_ci}
702bf215546Sopenharmony_ci
703bf215546Sopenharmony_ci/**
704bf215546Sopenharmony_ci * SQTT desc info.
705bf215546Sopenharmony_ci */
706bf215546Sopenharmony_cistruct sqtt_file_chunk_sqtt_desc {
707bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
708bf215546Sopenharmony_ci   int32_t shader_engine_index;
709bf215546Sopenharmony_ci   enum sqtt_version sqtt_version;
710bf215546Sopenharmony_ci   union {
711bf215546Sopenharmony_ci      struct {
712bf215546Sopenharmony_ci         int32_t instrumentation_version;
713bf215546Sopenharmony_ci      } v0;
714bf215546Sopenharmony_ci      struct {
715bf215546Sopenharmony_ci         int16_t instrumentation_spec_version;
716bf215546Sopenharmony_ci         int16_t instrumentation_api_version;
717bf215546Sopenharmony_ci         int32_t compute_unit_index;
718bf215546Sopenharmony_ci      } v1;
719bf215546Sopenharmony_ci   };
720bf215546Sopenharmony_ci};
721bf215546Sopenharmony_ci
722bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_sqtt_desc) == 32,
723bf215546Sopenharmony_ci              "sqtt_file_chunk_sqtt_desc doesn't match RGP spec");
724bf215546Sopenharmony_ci
725bf215546Sopenharmony_cistatic enum sqtt_version ac_gfx_level_to_sqtt_version(enum amd_gfx_level gfx_level)
726bf215546Sopenharmony_ci{
727bf215546Sopenharmony_ci   switch (gfx_level) {
728bf215546Sopenharmony_ci   case GFX8:
729bf215546Sopenharmony_ci      return SQTT_VERSION_2_2;
730bf215546Sopenharmony_ci   case GFX9:
731bf215546Sopenharmony_ci      return SQTT_VERSION_2_3;
732bf215546Sopenharmony_ci   case GFX10:
733bf215546Sopenharmony_ci      return SQTT_VERSION_2_4;
734bf215546Sopenharmony_ci   case GFX10_3:
735bf215546Sopenharmony_ci      return SQTT_VERSION_2_4;
736bf215546Sopenharmony_ci   default:
737bf215546Sopenharmony_ci      unreachable("Invalid gfx level");
738bf215546Sopenharmony_ci   }
739bf215546Sopenharmony_ci}
740bf215546Sopenharmony_ci
741bf215546Sopenharmony_cistatic void ac_sqtt_fill_sqtt_desc(struct radeon_info *info,
742bf215546Sopenharmony_ci                                   struct sqtt_file_chunk_sqtt_desc *chunk, int32_t chunk_index,
743bf215546Sopenharmony_ci                                   int32_t shader_engine_index, int32_t compute_unit_index)
744bf215546Sopenharmony_ci{
745bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_SQTT_DESC;
746bf215546Sopenharmony_ci   chunk->header.chunk_id.index = chunk_index;
747bf215546Sopenharmony_ci   chunk->header.major_version = 0;
748bf215546Sopenharmony_ci   chunk->header.minor_version = 2;
749bf215546Sopenharmony_ci   chunk->header.size_in_bytes = sizeof(*chunk);
750bf215546Sopenharmony_ci
751bf215546Sopenharmony_ci   chunk->sqtt_version =
752bf215546Sopenharmony_ci      ac_gfx_level_to_sqtt_version(info->gfx_level);
753bf215546Sopenharmony_ci   chunk->shader_engine_index = shader_engine_index;
754bf215546Sopenharmony_ci   chunk->v1.instrumentation_spec_version = 1;
755bf215546Sopenharmony_ci   chunk->v1.instrumentation_api_version = 0;
756bf215546Sopenharmony_ci   chunk->v1.compute_unit_index = compute_unit_index;
757bf215546Sopenharmony_ci}
758bf215546Sopenharmony_ci
759bf215546Sopenharmony_ci/**
760bf215546Sopenharmony_ci * SQTT data info.
761bf215546Sopenharmony_ci */
762bf215546Sopenharmony_cistruct sqtt_file_chunk_sqtt_data {
763bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
764bf215546Sopenharmony_ci   int32_t offset; /* in bytes */
765bf215546Sopenharmony_ci   int32_t size;   /* in bytes */
766bf215546Sopenharmony_ci};
767bf215546Sopenharmony_ci
768bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_sqtt_data) == 24,
769bf215546Sopenharmony_ci              "sqtt_file_chunk_sqtt_data doesn't match RGP spec");
770bf215546Sopenharmony_ci
771bf215546Sopenharmony_cistatic void ac_sqtt_fill_sqtt_data(struct sqtt_file_chunk_sqtt_data *chunk, int32_t chunk_index,
772bf215546Sopenharmony_ci                                   int32_t offset, int32_t size)
773bf215546Sopenharmony_ci{
774bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_SQTT_DATA;
775bf215546Sopenharmony_ci   chunk->header.chunk_id.index = chunk_index;
776bf215546Sopenharmony_ci   chunk->header.major_version = 0;
777bf215546Sopenharmony_ci   chunk->header.minor_version = 0;
778bf215546Sopenharmony_ci   chunk->header.size_in_bytes = sizeof(*chunk) + size;
779bf215546Sopenharmony_ci
780bf215546Sopenharmony_ci   chunk->offset = sizeof(*chunk) + offset;
781bf215546Sopenharmony_ci   chunk->size = size;
782bf215546Sopenharmony_ci}
783bf215546Sopenharmony_ci
784bf215546Sopenharmony_ci/**
785bf215546Sopenharmony_ci * SQTT queue event timings info.
786bf215546Sopenharmony_ci */
787bf215546Sopenharmony_cistruct sqtt_file_chunk_queue_event_timings {
788bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
789bf215546Sopenharmony_ci   uint32_t queue_info_table_record_count;
790bf215546Sopenharmony_ci   uint32_t queue_info_table_size;
791bf215546Sopenharmony_ci   uint32_t queue_event_table_record_count;
792bf215546Sopenharmony_ci   uint32_t queue_event_table_size;
793bf215546Sopenharmony_ci};
794bf215546Sopenharmony_ci
795bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_queue_event_timings) == 32,
796bf215546Sopenharmony_ci	      "sqtt_file_chunk_queue_event_timings doesn't match RGP spec");
797bf215546Sopenharmony_ci
798bf215546Sopenharmony_cistruct sqtt_queue_info_record {
799bf215546Sopenharmony_ci   uint64_t queue_id;
800bf215546Sopenharmony_ci   uint64_t queue_context;
801bf215546Sopenharmony_ci   struct sqtt_queue_hardware_info hardware_info;
802bf215546Sopenharmony_ci   uint32_t reserved;
803bf215546Sopenharmony_ci};
804bf215546Sopenharmony_ci
805bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_queue_info_record) == 24,
806bf215546Sopenharmony_ci	      "sqtt_queue_info_record doesn't match RGP spec");
807bf215546Sopenharmony_ci
808bf215546Sopenharmony_cistruct sqtt_queue_event_record {
809bf215546Sopenharmony_ci   enum sqtt_queue_event_type event_type;
810bf215546Sopenharmony_ci   uint32_t sqtt_cb_id;
811bf215546Sopenharmony_ci   uint64_t frame_index;
812bf215546Sopenharmony_ci   uint32_t queue_info_index;
813bf215546Sopenharmony_ci   uint32_t submit_sub_index;
814bf215546Sopenharmony_ci   uint64_t api_id;
815bf215546Sopenharmony_ci   uint64_t cpu_timestamp;
816bf215546Sopenharmony_ci   uint64_t gpu_timestamps[2];
817bf215546Sopenharmony_ci};
818bf215546Sopenharmony_ci
819bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_queue_event_record) == 56,
820bf215546Sopenharmony_ci	      "sqtt_queue_event_record doesn't match RGP spec");
821bf215546Sopenharmony_ci
822bf215546Sopenharmony_cistatic void
823bf215546Sopenharmony_ciac_sqtt_fill_queue_event_timings(struct rgp_queue_info *rgp_queue_info,
824bf215546Sopenharmony_ci                                 struct rgp_queue_event *rgp_queue_event,
825bf215546Sopenharmony_ci                                 struct sqtt_file_chunk_queue_event_timings *chunk)
826bf215546Sopenharmony_ci{
827bf215546Sopenharmony_ci   unsigned queue_info_size =
828bf215546Sopenharmony_ci      rgp_queue_info->record_count * sizeof(struct sqtt_queue_info_record);
829bf215546Sopenharmony_ci   unsigned queue_event_size =
830bf215546Sopenharmony_ci      rgp_queue_event->record_count * sizeof(struct sqtt_queue_event_record);
831bf215546Sopenharmony_ci
832bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_QUEUE_EVENT_TIMINGS;
833bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
834bf215546Sopenharmony_ci   chunk->header.major_version = 1;
835bf215546Sopenharmony_ci   chunk->header.minor_version = 1;
836bf215546Sopenharmony_ci   chunk->header.size_in_bytes = queue_info_size + queue_event_size +
837bf215546Sopenharmony_ci                                 sizeof(*chunk);
838bf215546Sopenharmony_ci
839bf215546Sopenharmony_ci   chunk->queue_info_table_record_count = rgp_queue_info->record_count;
840bf215546Sopenharmony_ci   chunk->queue_info_table_size = queue_info_size;
841bf215546Sopenharmony_ci   chunk->queue_event_table_record_count = rgp_queue_event->record_count;
842bf215546Sopenharmony_ci   chunk->queue_event_table_size = queue_event_size;
843bf215546Sopenharmony_ci}
844bf215546Sopenharmony_ci
845bf215546Sopenharmony_ci/**
846bf215546Sopenharmony_ci * SQTT clock calibration info.
847bf215546Sopenharmony_ci */
848bf215546Sopenharmony_cistruct sqtt_file_chunk_clock_calibration {
849bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
850bf215546Sopenharmony_ci   uint64_t cpu_timestamp;
851bf215546Sopenharmony_ci   uint64_t gpu_timestamp;
852bf215546Sopenharmony_ci   uint64_t reserved;
853bf215546Sopenharmony_ci};
854bf215546Sopenharmony_ci
855bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_clock_calibration) == 40,
856bf215546Sopenharmony_ci	      "sqtt_file_chunk_clock_calibration doesn't match RGP spec");
857bf215546Sopenharmony_ci
858bf215546Sopenharmony_cistatic void
859bf215546Sopenharmony_ciac_sqtt_fill_clock_calibration(struct sqtt_file_chunk_clock_calibration *chunk,
860bf215546Sopenharmony_ci                               int32_t chunk_index)
861bf215546Sopenharmony_ci{
862bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_CLOCK_CALIBRATION;
863bf215546Sopenharmony_ci   chunk->header.chunk_id.index = chunk_index;
864bf215546Sopenharmony_ci   chunk->header.major_version = 0;
865bf215546Sopenharmony_ci   chunk->header.minor_version = 0;
866bf215546Sopenharmony_ci   chunk->header.size_in_bytes = sizeof(*chunk);
867bf215546Sopenharmony_ci}
868bf215546Sopenharmony_ci
869bf215546Sopenharmony_ci/* Below values are from from llvm project
870bf215546Sopenharmony_ci * llvm/include/llvm/BinaryFormat/ELF.h
871bf215546Sopenharmony_ci */
872bf215546Sopenharmony_cienum elf_gfxip_level
873bf215546Sopenharmony_ci{
874bf215546Sopenharmony_ci   EF_AMDGPU_MACH_AMDGCN_GFX801 = 0x028,
875bf215546Sopenharmony_ci   EF_AMDGPU_MACH_AMDGCN_GFX900 = 0x02c,
876bf215546Sopenharmony_ci   EF_AMDGPU_MACH_AMDGCN_GFX1010 = 0x033,
877bf215546Sopenharmony_ci   EF_AMDGPU_MACH_AMDGCN_GFX1030 = 0x036,
878bf215546Sopenharmony_ci};
879bf215546Sopenharmony_ci
880bf215546Sopenharmony_cistatic enum elf_gfxip_level ac_gfx_level_to_elf_gfxip_level(enum amd_gfx_level gfx_level)
881bf215546Sopenharmony_ci{
882bf215546Sopenharmony_ci   switch (gfx_level) {
883bf215546Sopenharmony_ci   case GFX8:
884bf215546Sopenharmony_ci      return EF_AMDGPU_MACH_AMDGCN_GFX801;
885bf215546Sopenharmony_ci   case GFX9:
886bf215546Sopenharmony_ci      return EF_AMDGPU_MACH_AMDGCN_GFX900;
887bf215546Sopenharmony_ci   case GFX10:
888bf215546Sopenharmony_ci      return EF_AMDGPU_MACH_AMDGCN_GFX1010;
889bf215546Sopenharmony_ci   case GFX10_3:
890bf215546Sopenharmony_ci      return EF_AMDGPU_MACH_AMDGCN_GFX1030;
891bf215546Sopenharmony_ci   default:
892bf215546Sopenharmony_ci      unreachable("Invalid gfx level");
893bf215546Sopenharmony_ci   }
894bf215546Sopenharmony_ci}
895bf215546Sopenharmony_ci
896bf215546Sopenharmony_ci/**
897bf215546Sopenharmony_ci * SQTT SPM DB info.
898bf215546Sopenharmony_ci */
899bf215546Sopenharmony_cistruct sqtt_spm_counter_info {
900bf215546Sopenharmony_ci   enum ac_pc_gpu_block block;
901bf215546Sopenharmony_ci   uint32_t instance;
902bf215546Sopenharmony_ci   uint32_t data_offset; /* offset of counter from the beginning of the chunk */
903bf215546Sopenharmony_ci   uint32_t event_index; /* index of counter within the block */
904bf215546Sopenharmony_ci};
905bf215546Sopenharmony_ci
906bf215546Sopenharmony_cistruct sqtt_file_chunk_spm_db {
907bf215546Sopenharmony_ci   struct sqtt_file_chunk_header header;
908bf215546Sopenharmony_ci   uint32_t flags;
909bf215546Sopenharmony_ci   uint32_t num_timestamps;
910bf215546Sopenharmony_ci   uint32_t num_spm_counter_info;
911bf215546Sopenharmony_ci   uint32_t sample_interval;
912bf215546Sopenharmony_ci};
913bf215546Sopenharmony_ci
914bf215546Sopenharmony_cistatic_assert(sizeof(struct sqtt_file_chunk_spm_db) == 32,
915bf215546Sopenharmony_ci              "sqtt_file_chunk_spm_db doesn't match RGP spec");
916bf215546Sopenharmony_ci
917bf215546Sopenharmony_cistatic void ac_sqtt_fill_spm_db(const struct ac_spm_trace_data *spm_trace,
918bf215546Sopenharmony_ci                                struct sqtt_file_chunk_spm_db *chunk,
919bf215546Sopenharmony_ci                                uint32_t num_samples,
920bf215546Sopenharmony_ci                                uint32_t chunk_size)
921bf215546Sopenharmony_ci{
922bf215546Sopenharmony_ci   chunk->header.chunk_id.type = SQTT_FILE_CHUNK_TYPE_SPM_DB;
923bf215546Sopenharmony_ci   chunk->header.chunk_id.index = 0;
924bf215546Sopenharmony_ci   chunk->header.major_version = 1;
925bf215546Sopenharmony_ci   chunk->header.minor_version = 3;
926bf215546Sopenharmony_ci   chunk->header.size_in_bytes = chunk_size;
927bf215546Sopenharmony_ci
928bf215546Sopenharmony_ci   chunk->flags = 0;
929bf215546Sopenharmony_ci   chunk->num_timestamps = num_samples;
930bf215546Sopenharmony_ci   chunk->num_spm_counter_info = spm_trace->num_counters;
931bf215546Sopenharmony_ci   chunk->sample_interval = spm_trace->sample_interval;
932bf215546Sopenharmony_ci}
933bf215546Sopenharmony_ci
934bf215546Sopenharmony_cistatic void ac_sqtt_dump_spm(const struct ac_spm_trace_data *spm_trace,
935bf215546Sopenharmony_ci                             size_t file_offset,
936bf215546Sopenharmony_ci                             FILE *output)
937bf215546Sopenharmony_ci{
938bf215546Sopenharmony_ci   uint32_t sample_size_in_bytes = ac_spm_get_sample_size(spm_trace);
939bf215546Sopenharmony_ci   uint32_t num_samples = ac_spm_get_num_samples(spm_trace);
940bf215546Sopenharmony_ci   uint8_t *spm_data_ptr = (uint8_t *)spm_trace->ptr;
941bf215546Sopenharmony_ci   struct sqtt_file_chunk_spm_db spm_db;
942bf215546Sopenharmony_ci   size_t file_spm_db_offset = file_offset;
943bf215546Sopenharmony_ci
944bf215546Sopenharmony_ci   fseek(output, sizeof(struct sqtt_file_chunk_spm_db), SEEK_CUR);
945bf215546Sopenharmony_ci   file_offset += sizeof(struct sqtt_file_chunk_spm_db);
946bf215546Sopenharmony_ci
947bf215546Sopenharmony_ci   /* Skip the reserved 32 bytes of data at beginning. */
948bf215546Sopenharmony_ci   spm_data_ptr += 32;
949bf215546Sopenharmony_ci
950bf215546Sopenharmony_ci   /* SPM timestamps. */
951bf215546Sopenharmony_ci   uint32_t sample_size_in_qwords = sample_size_in_bytes / sizeof(uint64_t);
952bf215546Sopenharmony_ci   uint64_t *timestamp_ptr = (uint64_t *)spm_data_ptr;
953bf215546Sopenharmony_ci
954bf215546Sopenharmony_ci   for (uint32_t s = 0; s < num_samples; s++) {
955bf215546Sopenharmony_ci      uint64_t index = s * sample_size_in_qwords;
956bf215546Sopenharmony_ci      uint64_t timestamp = timestamp_ptr[index];
957bf215546Sopenharmony_ci
958bf215546Sopenharmony_ci      file_offset += sizeof(timestamp);
959bf215546Sopenharmony_ci      fwrite(&timestamp, sizeof(timestamp), 1, output);
960bf215546Sopenharmony_ci   }
961bf215546Sopenharmony_ci
962bf215546Sopenharmony_ci   /* SPM counter info. */
963bf215546Sopenharmony_ci   uint64_t counter_values_size = num_samples * sizeof(uint16_t);
964bf215546Sopenharmony_ci   uint64_t counter_values_offset = num_samples * sizeof(uint64_t) +
965bf215546Sopenharmony_ci                                    spm_trace->num_counters * sizeof(struct sqtt_spm_counter_info);
966bf215546Sopenharmony_ci
967bf215546Sopenharmony_ci   for (uint32_t c = 0; c < spm_trace->num_counters; c++) {
968bf215546Sopenharmony_ci      struct sqtt_spm_counter_info cntr_info = {
969bf215546Sopenharmony_ci         .block = spm_trace->counters[c].gpu_block,
970bf215546Sopenharmony_ci         .instance = spm_trace->counters[c].instance,
971bf215546Sopenharmony_ci         .data_offset = counter_values_offset,
972bf215546Sopenharmony_ci         .event_index = spm_trace->counters[c].event_id,
973bf215546Sopenharmony_ci      };
974bf215546Sopenharmony_ci
975bf215546Sopenharmony_ci      file_offset += sizeof(cntr_info);
976bf215546Sopenharmony_ci      fwrite(&cntr_info, sizeof(cntr_info), 1, output);
977bf215546Sopenharmony_ci
978bf215546Sopenharmony_ci      counter_values_offset += counter_values_size;
979bf215546Sopenharmony_ci   }
980bf215546Sopenharmony_ci
981bf215546Sopenharmony_ci   /* SPM counter values. */
982bf215546Sopenharmony_ci   uint32_t sample_size_in_hwords = sample_size_in_bytes / sizeof(uint16_t);
983bf215546Sopenharmony_ci   uint16_t *counter_values_ptr = (uint16_t *)spm_data_ptr;
984bf215546Sopenharmony_ci
985bf215546Sopenharmony_ci   for (uint32_t c = 0; c < spm_trace->num_counters; c++) {
986bf215546Sopenharmony_ci      uint64_t offset = spm_trace->counters[c].offset;
987bf215546Sopenharmony_ci
988bf215546Sopenharmony_ci      for (uint32_t s = 0; s < num_samples; s++) {
989bf215546Sopenharmony_ci         uint64_t index = offset + (s * sample_size_in_hwords);
990bf215546Sopenharmony_ci         uint16_t value = counter_values_ptr[index];
991bf215546Sopenharmony_ci
992bf215546Sopenharmony_ci         file_offset += sizeof(value);
993bf215546Sopenharmony_ci         fwrite(&value, sizeof(value), 1, output);
994bf215546Sopenharmony_ci      }
995bf215546Sopenharmony_ci   }
996bf215546Sopenharmony_ci
997bf215546Sopenharmony_ci   /* SQTT SPM DB chunk. */
998bf215546Sopenharmony_ci   ac_sqtt_fill_spm_db(spm_trace, &spm_db, num_samples,
999bf215546Sopenharmony_ci                       file_offset - file_spm_db_offset);
1000bf215546Sopenharmony_ci   fseek(output, file_spm_db_offset, SEEK_SET);
1001bf215546Sopenharmony_ci   fwrite(&spm_db, sizeof(struct sqtt_file_chunk_spm_db), 1, output);
1002bf215546Sopenharmony_ci   fseek(output, file_offset, SEEK_SET);
1003bf215546Sopenharmony_ci}
1004bf215546Sopenharmony_ci
1005bf215546Sopenharmony_ci#ifndef _WIN32
1006bf215546Sopenharmony_cistatic void ac_sqtt_dump_data(struct radeon_info *rad_info,
1007bf215546Sopenharmony_ci                              struct ac_thread_trace *thread_trace,
1008bf215546Sopenharmony_ci                              const struct ac_spm_trace_data *spm_trace,
1009bf215546Sopenharmony_ci                              FILE *output)
1010bf215546Sopenharmony_ci{
1011bf215546Sopenharmony_ci   struct ac_thread_trace_data *thread_trace_data = thread_trace->data;
1012bf215546Sopenharmony_ci   struct sqtt_file_chunk_asic_info asic_info = {0};
1013bf215546Sopenharmony_ci   struct sqtt_file_chunk_cpu_info cpu_info = {0};
1014bf215546Sopenharmony_ci   struct sqtt_file_chunk_api_info api_info = {0};
1015bf215546Sopenharmony_ci   struct sqtt_file_header header = {0};
1016bf215546Sopenharmony_ci   size_t file_offset = 0;
1017bf215546Sopenharmony_ci   struct rgp_code_object *rgp_code_object =
1018bf215546Sopenharmony_ci                                          &thread_trace_data->rgp_code_object;
1019bf215546Sopenharmony_ci   struct rgp_loader_events *rgp_loader_events =
1020bf215546Sopenharmony_ci                                        &thread_trace_data->rgp_loader_events;
1021bf215546Sopenharmony_ci   struct rgp_pso_correlation *rgp_pso_correlation =
1022bf215546Sopenharmony_ci                                      &thread_trace_data->rgp_pso_correlation;
1023bf215546Sopenharmony_ci   struct rgp_queue_info *rgp_queue_info = &thread_trace_data->rgp_queue_info;
1024bf215546Sopenharmony_ci   struct rgp_queue_event *rgp_queue_event = &thread_trace_data->rgp_queue_event;
1025bf215546Sopenharmony_ci   struct rgp_clock_calibration *rgp_clock_calibration = &thread_trace_data->rgp_clock_calibration;
1026bf215546Sopenharmony_ci
1027bf215546Sopenharmony_ci   /* SQTT header file. */
1028bf215546Sopenharmony_ci   ac_sqtt_fill_header(&header);
1029bf215546Sopenharmony_ci   file_offset += sizeof(header);
1030bf215546Sopenharmony_ci   fwrite(&header, sizeof(header), 1, output);
1031bf215546Sopenharmony_ci
1032bf215546Sopenharmony_ci   /* SQTT cpu chunk. */
1033bf215546Sopenharmony_ci   ac_sqtt_fill_cpu_info(&cpu_info);
1034bf215546Sopenharmony_ci   file_offset += sizeof(cpu_info);
1035bf215546Sopenharmony_ci   fwrite(&cpu_info, sizeof(cpu_info), 1, output);
1036bf215546Sopenharmony_ci
1037bf215546Sopenharmony_ci   /* SQTT asic chunk. */
1038bf215546Sopenharmony_ci   ac_sqtt_fill_asic_info(rad_info, &asic_info);
1039bf215546Sopenharmony_ci   file_offset += sizeof(asic_info);
1040bf215546Sopenharmony_ci   fwrite(&asic_info, sizeof(asic_info), 1, output);
1041bf215546Sopenharmony_ci
1042bf215546Sopenharmony_ci   /* SQTT api chunk. */
1043bf215546Sopenharmony_ci   ac_sqtt_fill_api_info(&api_info);
1044bf215546Sopenharmony_ci   file_offset += sizeof(api_info);
1045bf215546Sopenharmony_ci   fwrite(&api_info, sizeof(api_info), 1, output);
1046bf215546Sopenharmony_ci
1047bf215546Sopenharmony_ci    /* SQTT code object database chunk. */
1048bf215546Sopenharmony_ci   if (rgp_code_object->record_count) {
1049bf215546Sopenharmony_ci      size_t file_code_object_offset = file_offset;
1050bf215546Sopenharmony_ci      struct sqtt_file_chunk_code_object_database code_object;
1051bf215546Sopenharmony_ci      struct sqtt_code_object_database_record code_object_record;
1052bf215546Sopenharmony_ci      uint32_t elf_size_calc = 0;
1053bf215546Sopenharmony_ci      uint32_t flags = ac_gfx_level_to_elf_gfxip_level(rad_info->gfx_level);
1054bf215546Sopenharmony_ci
1055bf215546Sopenharmony_ci      fseek(output, sizeof(struct sqtt_file_chunk_code_object_database), SEEK_CUR);
1056bf215546Sopenharmony_ci      file_offset += sizeof(struct sqtt_file_chunk_code_object_database);
1057bf215546Sopenharmony_ci      list_for_each_entry_safe(struct rgp_code_object_record, record,
1058bf215546Sopenharmony_ci                               &rgp_code_object->record, list) {
1059bf215546Sopenharmony_ci         fseek(output, sizeof(struct sqtt_code_object_database_record), SEEK_CUR);
1060bf215546Sopenharmony_ci         ac_rgp_file_write_elf_object(output, file_offset +
1061bf215546Sopenharmony_ci                                      sizeof(struct sqtt_code_object_database_record),
1062bf215546Sopenharmony_ci                                      record, &elf_size_calc, flags);
1063bf215546Sopenharmony_ci         /* Align to 4 bytes per the RGP file spec. */
1064bf215546Sopenharmony_ci         code_object_record.size = ALIGN(elf_size_calc, 4);
1065bf215546Sopenharmony_ci         fseek(output, file_offset, SEEK_SET);
1066bf215546Sopenharmony_ci         fwrite(&code_object_record, sizeof(struct sqtt_code_object_database_record),
1067bf215546Sopenharmony_ci                1, output);
1068bf215546Sopenharmony_ci         file_offset += (sizeof(struct sqtt_code_object_database_record) +
1069bf215546Sopenharmony_ci                         code_object_record.size);
1070bf215546Sopenharmony_ci         fseek(output, file_offset, SEEK_SET);
1071bf215546Sopenharmony_ci      }
1072bf215546Sopenharmony_ci      ac_sqtt_fill_code_object(rgp_code_object, &code_object,
1073bf215546Sopenharmony_ci                               file_code_object_offset,
1074bf215546Sopenharmony_ci                               file_offset - file_code_object_offset);
1075bf215546Sopenharmony_ci      fseek(output, file_code_object_offset, SEEK_SET);
1076bf215546Sopenharmony_ci      fwrite(&code_object, sizeof(struct sqtt_file_chunk_code_object_database), 1, output);
1077bf215546Sopenharmony_ci      fseek(output, file_offset, SEEK_SET);
1078bf215546Sopenharmony_ci   }
1079bf215546Sopenharmony_ci
1080bf215546Sopenharmony_ci   /* SQTT code object loader events chunk. */
1081bf215546Sopenharmony_ci   if (rgp_loader_events->record_count) {
1082bf215546Sopenharmony_ci      struct sqtt_file_chunk_code_object_loader_events loader_events;
1083bf215546Sopenharmony_ci
1084bf215546Sopenharmony_ci      ac_sqtt_fill_loader_events(rgp_loader_events, &loader_events,
1085bf215546Sopenharmony_ci                                 file_offset);
1086bf215546Sopenharmony_ci      fwrite(&loader_events, sizeof(struct sqtt_file_chunk_code_object_loader_events),
1087bf215546Sopenharmony_ci             1, output);
1088bf215546Sopenharmony_ci      file_offset += sizeof(struct sqtt_file_chunk_code_object_loader_events);
1089bf215546Sopenharmony_ci      list_for_each_entry_safe(struct rgp_loader_events_record, record,
1090bf215546Sopenharmony_ci                               &rgp_loader_events->record, list) {
1091bf215546Sopenharmony_ci         fwrite(record, sizeof(struct sqtt_code_object_loader_events_record), 1, output);
1092bf215546Sopenharmony_ci      }
1093bf215546Sopenharmony_ci      file_offset += (rgp_loader_events->record_count *
1094bf215546Sopenharmony_ci                      sizeof(struct sqtt_code_object_loader_events_record));
1095bf215546Sopenharmony_ci   }
1096bf215546Sopenharmony_ci
1097bf215546Sopenharmony_ci   /* SQTT pso correlation chunk. */
1098bf215546Sopenharmony_ci   if (rgp_pso_correlation->record_count) {
1099bf215546Sopenharmony_ci      struct sqtt_file_chunk_pso_correlation pso_correlation;
1100bf215546Sopenharmony_ci
1101bf215546Sopenharmony_ci      ac_sqtt_fill_pso_correlation(rgp_pso_correlation,
1102bf215546Sopenharmony_ci                                   &pso_correlation, file_offset);
1103bf215546Sopenharmony_ci      fwrite(&pso_correlation, sizeof(struct sqtt_file_chunk_pso_correlation), 1,
1104bf215546Sopenharmony_ci             output);
1105bf215546Sopenharmony_ci      file_offset += sizeof(struct sqtt_file_chunk_pso_correlation);
1106bf215546Sopenharmony_ci      list_for_each_entry_safe(struct rgp_pso_correlation_record, record,
1107bf215546Sopenharmony_ci                               &rgp_pso_correlation->record, list) {
1108bf215546Sopenharmony_ci         fwrite(record, sizeof(struct sqtt_pso_correlation_record),
1109bf215546Sopenharmony_ci                1, output);
1110bf215546Sopenharmony_ci      }
1111bf215546Sopenharmony_ci      file_offset += (rgp_pso_correlation->record_count *
1112bf215546Sopenharmony_ci                      sizeof(struct sqtt_pso_correlation_record));
1113bf215546Sopenharmony_ci   }
1114bf215546Sopenharmony_ci
1115bf215546Sopenharmony_ci   /* SQTT queue event timings. */
1116bf215546Sopenharmony_ci   if (rgp_queue_info->record_count || rgp_queue_event->record_count) {
1117bf215546Sopenharmony_ci      struct sqtt_file_chunk_queue_event_timings queue_event_timings;
1118bf215546Sopenharmony_ci
1119bf215546Sopenharmony_ci      ac_sqtt_fill_queue_event_timings(rgp_queue_info, rgp_queue_event,
1120bf215546Sopenharmony_ci                                       &queue_event_timings);
1121bf215546Sopenharmony_ci      fwrite(&queue_event_timings, sizeof(struct sqtt_file_chunk_queue_event_timings), 1,
1122bf215546Sopenharmony_ci             output);
1123bf215546Sopenharmony_ci      file_offset += sizeof(struct sqtt_file_chunk_queue_event_timings);
1124bf215546Sopenharmony_ci
1125bf215546Sopenharmony_ci      /* Queue info. */
1126bf215546Sopenharmony_ci      list_for_each_entry_safe(struct rgp_queue_info_record, record,
1127bf215546Sopenharmony_ci                               &rgp_queue_info->record, list) {
1128bf215546Sopenharmony_ci         fwrite(record, sizeof(struct sqtt_queue_info_record), 1, output);
1129bf215546Sopenharmony_ci      }
1130bf215546Sopenharmony_ci      file_offset += (rgp_queue_info->record_count *
1131bf215546Sopenharmony_ci                      sizeof(struct sqtt_queue_info_record));
1132bf215546Sopenharmony_ci
1133bf215546Sopenharmony_ci      /* Queue event. */
1134bf215546Sopenharmony_ci      list_for_each_entry_safe(struct rgp_queue_event_record, record,
1135bf215546Sopenharmony_ci                               &rgp_queue_event->record, list) {
1136bf215546Sopenharmony_ci         fwrite(record, sizeof(struct sqtt_queue_event_record), 1, output);
1137bf215546Sopenharmony_ci      }
1138bf215546Sopenharmony_ci      file_offset += (rgp_queue_event->record_count *
1139bf215546Sopenharmony_ci                      sizeof(struct sqtt_queue_event_record));
1140bf215546Sopenharmony_ci   }
1141bf215546Sopenharmony_ci
1142bf215546Sopenharmony_ci   /* SQTT clock calibration. */
1143bf215546Sopenharmony_ci   if (rgp_clock_calibration->record_count) {
1144bf215546Sopenharmony_ci      uint32_t num_records = 0;
1145bf215546Sopenharmony_ci
1146bf215546Sopenharmony_ci      list_for_each_entry_safe(struct rgp_clock_calibration_record, record,
1147bf215546Sopenharmony_ci                               &rgp_clock_calibration->record, list) {
1148bf215546Sopenharmony_ci         struct sqtt_file_chunk_clock_calibration clock_calibration;
1149bf215546Sopenharmony_ci         memset(&clock_calibration, 0, sizeof(clock_calibration));
1150bf215546Sopenharmony_ci
1151bf215546Sopenharmony_ci         ac_sqtt_fill_clock_calibration(&clock_calibration, num_records);
1152bf215546Sopenharmony_ci
1153bf215546Sopenharmony_ci         clock_calibration.cpu_timestamp = record->cpu_timestamp;
1154bf215546Sopenharmony_ci         clock_calibration.gpu_timestamp = record->gpu_timestamp;
1155bf215546Sopenharmony_ci
1156bf215546Sopenharmony_ci         fwrite(&clock_calibration, sizeof(struct sqtt_file_chunk_clock_calibration), 1,
1157bf215546Sopenharmony_ci             output);
1158bf215546Sopenharmony_ci         file_offset += sizeof(struct sqtt_file_chunk_clock_calibration);
1159bf215546Sopenharmony_ci
1160bf215546Sopenharmony_ci         num_records++;
1161bf215546Sopenharmony_ci      }
1162bf215546Sopenharmony_ci   }
1163bf215546Sopenharmony_ci
1164bf215546Sopenharmony_ci   if (thread_trace) {
1165bf215546Sopenharmony_ci      for (unsigned i = 0; i < thread_trace->num_traces; i++) {
1166bf215546Sopenharmony_ci         const struct ac_thread_trace_se *se = &thread_trace->traces[i];
1167bf215546Sopenharmony_ci         const struct ac_thread_trace_info *info = &se->info;
1168bf215546Sopenharmony_ci         struct sqtt_file_chunk_sqtt_desc desc = {0};
1169bf215546Sopenharmony_ci         struct sqtt_file_chunk_sqtt_data data = {0};
1170bf215546Sopenharmony_ci         uint64_t size = info->cur_offset * 32; /* unit of 32 bytes */
1171bf215546Sopenharmony_ci
1172bf215546Sopenharmony_ci         /* SQTT desc chunk. */
1173bf215546Sopenharmony_ci         ac_sqtt_fill_sqtt_desc(rad_info, &desc, i, se->shader_engine, se->compute_unit);
1174bf215546Sopenharmony_ci         file_offset += sizeof(desc);
1175bf215546Sopenharmony_ci         fwrite(&desc, sizeof(desc), 1, output);
1176bf215546Sopenharmony_ci
1177bf215546Sopenharmony_ci         /* SQTT data chunk. */
1178bf215546Sopenharmony_ci         ac_sqtt_fill_sqtt_data(&data, i, file_offset, size);
1179bf215546Sopenharmony_ci         file_offset += sizeof(data);
1180bf215546Sopenharmony_ci         fwrite(&data, sizeof(data), 1, output);
1181bf215546Sopenharmony_ci
1182bf215546Sopenharmony_ci         /* Copy thread trace data generated by the hardware. */
1183bf215546Sopenharmony_ci         file_offset += size;
1184bf215546Sopenharmony_ci         fwrite(se->data_ptr, size, 1, output);
1185bf215546Sopenharmony_ci      }
1186bf215546Sopenharmony_ci   }
1187bf215546Sopenharmony_ci
1188bf215546Sopenharmony_ci   if (spm_trace) {
1189bf215546Sopenharmony_ci      ac_sqtt_dump_spm(spm_trace, file_offset, output);
1190bf215546Sopenharmony_ci   }
1191bf215546Sopenharmony_ci}
1192bf215546Sopenharmony_ci#endif
1193bf215546Sopenharmony_ci
1194bf215546Sopenharmony_ciint ac_dump_rgp_capture(struct radeon_info *info,
1195bf215546Sopenharmony_ci                        struct ac_thread_trace *thread_trace,
1196bf215546Sopenharmony_ci                        const struct ac_spm_trace_data *spm_trace)
1197bf215546Sopenharmony_ci{
1198bf215546Sopenharmony_ci#ifdef _WIN32
1199bf215546Sopenharmony_ci   return -1;
1200bf215546Sopenharmony_ci#else
1201bf215546Sopenharmony_ci   char filename[2048];
1202bf215546Sopenharmony_ci   struct tm now;
1203bf215546Sopenharmony_ci   time_t t;
1204bf215546Sopenharmony_ci   FILE *f;
1205bf215546Sopenharmony_ci
1206bf215546Sopenharmony_ci   t = time(NULL);
1207bf215546Sopenharmony_ci   now = *localtime(&t);
1208bf215546Sopenharmony_ci
1209bf215546Sopenharmony_ci   snprintf(filename, sizeof(filename), "/tmp/%s_%04d.%02d.%02d_%02d.%02d.%02d.rgp",
1210bf215546Sopenharmony_ci            util_get_process_name(), 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour,
1211bf215546Sopenharmony_ci            now.tm_min, now.tm_sec);
1212bf215546Sopenharmony_ci
1213bf215546Sopenharmony_ci   f = fopen(filename, "w+");
1214bf215546Sopenharmony_ci   if (!f)
1215bf215546Sopenharmony_ci      return -1;
1216bf215546Sopenharmony_ci
1217bf215546Sopenharmony_ci   ac_sqtt_dump_data(info, thread_trace, spm_trace, f);
1218bf215546Sopenharmony_ci
1219bf215546Sopenharmony_ci   fprintf(stderr, "RGP capture saved to '%s'\n", filename);
1220bf215546Sopenharmony_ci
1221bf215546Sopenharmony_ci   fclose(f);
1222bf215546Sopenharmony_ci   return 0;
1223bf215546Sopenharmony_ci#endif
1224bf215546Sopenharmony_ci}
1225