1 /**
2 * \file intel_debug_identifier.c
3 *
4 *
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "git_sha1.h"
12
13 #include "common/intel_debug_identifier.h"
14 #include "dev/intel_debug.h"
15 #include "util/macros.h"
16 #include "util/u_math.h"
17
18 static uint64_t debug_identifier[4] = {
19 0xffeeddccbbaa9988,
20 0x7766554433221100,
21 0xffeeddccbbaa9988,
22 0x7766554433221100,
23 };
24
25 void *
intel_debug_identifier(void)26 intel_debug_identifier(void)
27 {
28 return debug_identifier;
29 }
30
31 uint32_t
intel_debug_identifier_size(void)32 intel_debug_identifier_size(void)
33 {
34 return sizeof(debug_identifier);
35 }
36
37 uint32_t
intel_debug_write_identifiers(void * _output,uint32_t output_size,const char * driver_name)38 intel_debug_write_identifiers(void *_output,
39 uint32_t output_size,
40 const char *driver_name)
41 {
42 void *output = _output, *output_end = _output + output_size;
43
44 assert(output_size > intel_debug_identifier_size());
45
46 memcpy(output, intel_debug_identifier(), intel_debug_identifier_size());
47 output += intel_debug_identifier_size();
48
49 for (uint32_t id = INTEL_DEBUG_BLOCK_TYPE_DRIVER; id < INTEL_DEBUG_BLOCK_TYPE_MAX; id++) {
50 switch (id) {
51 case INTEL_DEBUG_BLOCK_TYPE_DRIVER: {
52 struct intel_debug_block_driver driver_desc = {
53 .base = {
54 .type = id,
55 },
56 };
57 int len = snprintf(output + sizeof(driver_desc),
58 output_end - (output + sizeof(driver_desc)),
59 "%s " PACKAGE_VERSION " build " MESA_GIT_SHA1,
60 driver_name);
61 driver_desc.base.length = sizeof(driver_desc) + len + 1;
62 memcpy(output, &driver_desc, sizeof(driver_desc));
63 output += driver_desc.base.length;
64 break;
65 }
66
67 case INTEL_DEBUG_BLOCK_TYPE_FRAME: {
68 struct intel_debug_block_frame frame_desc = {
69 .base = {
70 .type = INTEL_DEBUG_BLOCK_TYPE_FRAME,
71 .length = sizeof(frame_desc),
72 },
73 };
74 memcpy(output, &frame_desc, sizeof(frame_desc));
75 output += sizeof(frame_desc);
76 break;
77 }
78
79 default:
80 unreachable("Missing identifier write");
81 }
82
83 assert(output < output_end);
84 }
85
86 struct intel_debug_block_base end = {
87 .type = INTEL_DEBUG_BLOCK_TYPE_END,
88 .length = sizeof(end),
89 };
90 memcpy(output, &end, sizeof(end));
91 output += sizeof(end);
92
93 assert(output < output_end);
94
95 /* Add at least a full aligned uint64_t of zero padding at the end
96 * to make the identifiers easier to spot.
97 */
98 const unsigned unpadded_len = output - _output;
99 const unsigned padding = align(unpadded_len + 8, 8) - unpadded_len;
100 memset(output, 0, padding);
101 output += padding;
102
103 assert(output < output_end);
104
105 /* Return the how many bytes where written, so that the rest of the buffer
106 * can be used for other things.
107 */
108 return output - _output;
109 }
110
111 void *
intel_debug_get_identifier_block(void * _buffer,uint32_t buffer_size,enum intel_debug_block_type type)112 intel_debug_get_identifier_block(void *_buffer,
113 uint32_t buffer_size,
114 enum intel_debug_block_type type)
115 {
116 void *buffer = _buffer + intel_debug_identifier_size(),
117 *end_buffer = _buffer + buffer_size;
118
119 while (buffer < end_buffer) {
120 struct intel_debug_block_base *item = buffer;
121
122 if (item->type == type)
123 return item;
124 if (item->type == INTEL_DEBUG_BLOCK_TYPE_END)
125 return NULL;
126
127 buffer += item->length;
128 }
129
130 return NULL;
131 }
132
133 /**
134 * Check if in valid frame range for batch dumping
135 */
136 bool
intel_debug_batch_in_range(uint64_t frame_id)137 intel_debug_batch_in_range(uint64_t frame_id)
138 {
139 return frame_id >= intel_debug_batch_frame_start &&
140 frame_id < intel_debug_batch_frame_stop;
141 }
142