• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2
3import sys, io, re, json
4from canonicalize import json_canonicalize
5
6######### BEGIN HARDCODED CONFIGURATION
7
8gfx_versions = {
9    'gfx6': [
10        None,
11        'asic_reg/gca/gfx_6_0_d.h',
12        'asic_reg/gca/gfx_6_0_sh_mask.h',
13        'asic_reg/gca/gfx_7_2_enum.h' # the file for gfx6 doesn't exist
14    ],
15    'gfx7': [
16        None,
17        'asic_reg/gca/gfx_7_2_d.h',
18        'asic_reg/gca/gfx_7_2_sh_mask.h',
19        'asic_reg/gca/gfx_7_2_enum.h'
20    ],
21    'gfx8': [
22        None,
23        'asic_reg/gca/gfx_8_0_d.h',
24        'asic_reg/gca/gfx_8_0_sh_mask.h',
25        'asic_reg/gca/gfx_8_0_enum.h',
26    ],
27    'gfx81': [
28        None,
29        'asic_reg/gca/gfx_8_1_d.h',
30        'asic_reg/gca/gfx_8_1_sh_mask.h',
31        'asic_reg/gca/gfx_8_1_enum.h',
32    ],
33    'gfx9': [
34        'vega10_ip_offset.h',
35        'asic_reg/gc/gc_9_2_1_offset.h',
36        'asic_reg/gc/gc_9_2_1_sh_mask.h',
37        'vega10_enum.h',
38    ],
39    'gfx10': [
40        'navi14_ip_offset.h',
41        'asic_reg/gc/gc_10_1_0_offset.h',
42        'asic_reg/gc/gc_10_1_0_sh_mask.h',
43        'navi10_enum.h',
44    ],
45    'gfx103': [
46        'sienna_cichlid_ip_offset.h',
47        'asic_reg/gc/gc_10_3_0_offset.h',
48        'asic_reg/gc/gc_10_3_0_sh_mask.h',
49        'navi10_enum.h', # the file for gfx10.3 doesn't exist
50    ],
51}
52
53# match: static const struct IP_BASE GC_BASE ={ { { { 0x00001260, 0x0000A000, 0x02402C00, 0, 0 } },
54re_base = re.compile(r'^static const struct IP_BASE GC_BASE\s*=\s*{ { { { (\w+), (\w+), (\w+), (\w+), (\w+) } },\n')
55
56# match: #define mmSDMA0_DEC_START                              0x0000
57# match: #define ixSDMA0_DEC_START                              0x0000
58re_offset = re.compile(r'^#define (?P<mm>[mi][mx])(?P<name>\w+)\s+(?P<value>\w+)\n')
59
60# match: #define SDMA0_DEC_START__START__SHIFT                  0x0
61re_shift = re.compile(r'^#define (?P<name>\w+)__(?P<field>\w+)__SHIFT\s+(?P<value>\w+)\n')
62
63# match: #define SDMA0_DEC_START__START_MASK                    0xFFFFFFFFL
64# match: #define SDMA0_DEC_START__START_MASK                    0xFFFFFFFF
65re_mask = re.compile(r'^#define (?P<name>\w+)__(?P<field>\w+)_MASK\s+(?P<value>[0-9a-fA-Fx]+)L?\n')
66
67def register_filter(gfx_version, name, offset, already_added):
68    # Only accept writeable registers and debug registers
69    return ((offset // 0x1000 in [0xB, 0x28, 0x30, 0x31, 0x34, 0x35, 0x36, 0x37] or
70             # Add SQ_WAVE registers for trap handlers
71             name.startswith('SQ_WAVE_') or
72             # Add registers in the 0x8000 range used by all generations
73             (offset // 0x1000 == 0x8 and
74              (name.startswith('SQ_IMG_') or
75               name.startswith('SQ_BUF_') or
76               name.startswith('SQ_THREAD') or
77               name.startswith('GRBM_STATUS') or
78               name.startswith('CP_CP'))) or
79             # Add all registers in the 0x8000 range for gfx6
80             (gfx_version == 'gfx6' and offset // 0x1000 == 0x8) or
81             # Add registers in the 0x9000 range
82             (offset // 0x1000 == 0x9 and
83              (name in ['TA_CS_BC_BASE_ADDR', 'GB_ADDR_CONFIG', 'SPI_CONFIG_CNTL'] or
84               (name.startswith('GB') and 'TILE_MODE' in name)))) and
85            # Remove SQ compiler definitions
86            offset // 4 not in (0x23B0, 0x23B1, 0x237F) and
87            # Remove conflicts (multiple definitions for the same offset)
88            not already_added and
89            'PREF_PRI_ACCUM' not in name)
90
91# Mapping from field names to enum types
92enum_map = {
93    # Format:
94    #    field: [type1]                          - all registers use the same enum
95    # OR:
96    #    field: [type1, reg1, type2, reg2, ...]  - apply different enums to different registers
97    "ALPHA_COMB_FCN": ["CombFunc", "CB_BLEND0_CONTROL", "SX_OPT_COMB_FCN", "SX_MRT0_BLEND_OPT"],
98    "ALPHA_DESTBLEND": ["BlendOp"],
99    "ALPHA_DST_OPT": ["SX_BLEND_OPT"],
100    "ALPHA_SRCBLEND": ["BlendOp"],
101    "ALPHA_SRC_OPT": ["SX_BLEND_OPT"],
102    "ARRAY_MODE": ["ArrayMode"],
103    "BANK_HEIGHT": ["BankHeight"],
104    "BANK_WIDTH": ["BankWidth"],
105    "BC_SWIZZLE": ["SQ_IMG_RSRC_WORD4__BC_SWIZZLE"],
106    "BIN_MAPPING_MODE": ["BinMapMode"],
107    "BINNING_MODE": ["BinningMode"],
108    "BIN_SIZE_X_EXTEND": ["BinSizeExtend"],
109    "BIN_SIZE_Y_EXTEND": ["BinSizeExtend"],
110    "BLEND_OPT_DISCARD_PIXEL": ["BlendOpt"],
111    "BLEND_OPT_DONT_RD_DST": ["BlendOpt"],
112    "BORDER_COLOR_TYPE": ["SQ_TEX_BORDER_COLOR"],
113    "BUF_TYPE": ["VGT_DMA_BUF_TYPE"],
114    "CLAMP_X": ["SQ_TEX_CLAMP"],
115    "CLAMP_Y": ["SQ_TEX_CLAMP"],
116    "CLAMP_Z": ["SQ_TEX_CLAMP"],
117    "CLEAR_FILTER_SEL": ["CBPerfClearFilterSel"],
118    "CLIP_RULE": ["CLIP_RULE"],
119    "CMASK_ADDR_TYPE": ["CmaskAddr"],
120    "CMASK_RD_POLICY": ["ReadPolicy"],
121    "CMASK_WR_POLICY": ["WritePolicy"],
122    "COL0_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
123    "COL1_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
124    "COL2_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
125    "COL3_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
126    "COL4_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
127    "COL5_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
128    "COL6_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
129    "COL7_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
130    "COLOR_COMB_FCN": ["CombFunc", "CB_BLEND0_CONTROL", "SX_OPT_COMB_FCN", "SX_MRT0_BLEND_OPT"],
131    "COLOR_DESTBLEND": ["BlendOp"],
132    "COLOR_DST_OPT": ["SX_BLEND_OPT"],
133    "COLOR_RD_POLICY": ["ReadPolicy"],
134    "COLOR_SRCBLEND": ["BlendOp"],
135    "COLOR_SRC_OPT": ["SX_BLEND_OPT"],
136    "COLOR_WR_POLICY": ["WritePolicy"],
137    "COMPAREFUNC0": ["CompareFrag"],
138    "COMPAREFUNC1": ["CompareFrag"],
139    "COMP_SWAP": ["SurfaceSwap"],
140    "CONSERVATIVE_Z_EXPORT": ["ConservativeZExport"],
141    "COVERAGE_TO_SHADER_SELECT": ["CovToShaderSel"],
142    "CUT_MODE": ["VGT_GS_CUT_MODE"],
143    "DATA_FORMAT": ["BUF_DATA_FORMAT", "SQ_BUF_RSRC_WORD3", "IMG_DATA_FORMAT", "SQ_IMG_RSRC_WORD1"],
144    "DCC_RD_POLICY": ["ReadPolicy"],
145    "DCC_WR_POLICY": ["WritePolicy"],
146    "DEPTH_COMPARE_FUNC": ["SQ_TEX_DEPTH_COMPARE"],
147    "DETECT_ONE": ["VGT_DETECT_ONE"],
148    "DETECT_ZERO": ["VGT_DETECT_ZERO"],
149    "DISTRIBUTION_MODE": ["VGT_DIST_MODE"],
150    "DST_SEL_W": ["SQ_SEL_XYZW01"],
151    "DST_SEL_X": ["SQ_SEL_XYZW01"],
152    "DST_SEL_Y": ["SQ_SEL_XYZW01"],
153    "DST_SEL_Z": ["SQ_SEL_XYZW01"],
154    "ENDIAN": ["SurfaceEndian"],
155    "ES_EN": ["VGT_STAGES_ES_EN"],
156    "EVENT_TYPE": ["VGT_EVENT_TYPE"],
157    "EXCP": ["EXCP_EN"],
158    "EXCP_EN": ["EXCP_EN"],
159    "FAULT_BEHAVIOR": ["DbPRTFaultBehavior"],
160    "FILTER_MODE": ["SQ_IMG_FILTER_TYPE"],
161    "FLOAT_MODE": ["FLOAT_MODE"],
162    "FMASK_RD_POLICY": ["ReadPolicy"],
163    "FMASK_WR_POLICY": ["WritePolicy"],
164    "FORCE_FULL_Z_RANGE": ["ForceControl"],
165    "FORCE_HIS_ENABLE0": ["ForceControl"],
166    "FORCE_HIS_ENABLE1": ["ForceControl"],
167    "FORCE_HIZ_ENABLE": ["ForceControl"],
168    "FORCE_Z_LIMIT_SUMM": ["ZLimitSumm"],
169    "FORMAT": ["ColorFormat", "CB_COLOR0_INFO", "StencilFormat", "DB_STENCIL_INFO", "ZFormat", "DB_Z_INFO"],
170    "GS_EN": ["VGT_STAGES_GS_EN"],
171    "HIZ_ZFUNC": ["CompareFrag"],
172    "HS_EN": ["VGT_STAGES_HS_EN"],
173    "HTILE_RD_POLICY": ["ReadPolicy"],
174    "HTILE_WR_POLICY": ["WritePolicy"],
175    "IDX0_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"],
176    "INDEX_TYPE": ["VGT_INDEX_TYPE_MODE"],
177    "LS_EN": ["VGT_STAGES_LS_EN"],
178    "MACRO_TILE_ASPECT": ["MacroTileAspect"],
179    "MAJOR_MODE": ["VGT_DI_MAJOR_MODE_SELECT"],
180    "MAX_UNCOMPRESSED_BLOCK_SIZE": ["CB_COLOR_DCC_CONTROL__MAX_UNCOMPRESSED_BLOCK_SIZE"],
181    "MICRO_TILE_MODE": ["GB_TILE_MODE0__MICRO_TILE_MODE"],
182    "MICRO_TILE_MODE_NEW": ["MicroTileMode"],
183    "MIN_COMPRESSED_BLOCK_SIZE": ["CB_COLOR_DCC_CONTROL__MIN_COMPRESSED_BLOCK_SIZE"],
184    "MIP_FILTER": ["SQ_TEX_MIP_FILTER"],
185    "MODE": ["CBMode", "CB_COLOR_CONTROL", "VGT_GS_MODE_TYPE", "VGT_GS_MODE"],
186    "MRT0_EPSILON": ["SX_BLEND_OPT_EPSILON__MRT0_EPSILON"],
187    "MRT0": ["SX_DOWNCONVERT_FORMAT"],
188    "MRT1": ["SX_DOWNCONVERT_FORMAT"],
189    "MRT2": ["SX_DOWNCONVERT_FORMAT"],
190    "MRT3": ["SX_DOWNCONVERT_FORMAT"],
191    "MRT4": ["SX_DOWNCONVERT_FORMAT"],
192    "MRT5": ["SX_DOWNCONVERT_FORMAT"],
193    "MRT6": ["SX_DOWNCONVERT_FORMAT"],
194    "MRT7": ["SX_DOWNCONVERT_FORMAT"],
195    "NUM_BANKS": ["NumBanks"],
196    "NUM_FORMAT": ["BUF_NUM_FORMAT", "SQ_BUF_RSRC_WORD3", "IMG_NUM_FORMAT", "SQ_IMG_RSRC_WORD1"],
197    "NUMBER_TYPE": ["SurfaceNumber"],
198    "OFFCHIP_GRANULARITY": ["VGT_HS_OFFCHIP_PARAM__OFFCHIP_GRANULARITY"],
199    "OP_FILTER_SEL": ["CBPerfOpFilterSel"],
200    "OUTPRIM_TYPE_1": ["VGT_GS_OUTPRIM_TYPE"],
201    "OUTPRIM_TYPE_2": ["VGT_GS_OUTPRIM_TYPE"],
202    "OUTPRIM_TYPE_3": ["VGT_GS_OUTPRIM_TYPE"],
203    "OUTPRIM_TYPE": ["VGT_GS_OUTPRIM_TYPE"],
204    "PARTIAL_SQUAD_LAUNCH_CONTROL": ["DbPSLControl"],
205    "PARTITIONING": ["VGT_TESS_PARTITION"],
206    "PERFMON_ENABLE_MODE": ["CP_PERFMON_ENABLE_MODE"],
207    "PERFMON_STATE": ["CP_PERFMON_STATE"],
208    "PIPE_CONFIG": ["PipeConfig"],
209    "PKR_MAP": ["PkrMap"],
210    "PKR_XSEL2": ["PkrXsel2"],
211    "PKR_XSEL": ["PkrXsel"],
212    "PKR_YSEL": ["PkrYsel"],
213    "PNT_SPRITE_OVRD_W": ["SPI_PNT_SPRITE_OVERRIDE"],
214    "PNT_SPRITE_OVRD_X": ["SPI_PNT_SPRITE_OVERRIDE"],
215    "PNT_SPRITE_OVRD_Y": ["SPI_PNT_SPRITE_OVERRIDE"],
216    "PNT_SPRITE_OVRD_Z": ["SPI_PNT_SPRITE_OVERRIDE"],
217    "POLYMODE_BACK_PTYPE": ["PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE"],
218    "POLYMODE_FRONT_PTYPE": ["PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE"],
219    "POLY_MODE": ["PA_SU_SC_MODE_CNTL__POLY_MODE"],
220    "POS0_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"],
221    "POS1_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"],
222    "POS2_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"],
223    "POS3_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"],
224    "POS4_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"],
225    "PRIM_TYPE": ["VGT_DI_PRIM_TYPE"],
226    "PUNCHOUT_MODE": ["DB_DFSM_CONTROL__PUNCHOUT_MODE"],
227    "QUANT_MODE": ["QUANT_MODE"],
228    "RB_MAP_PKR0": ["RbMap"],
229    "RB_MAP_PKR1": ["RbMap"],
230    "RB_XSEL2": ["RbXsel2"],
231    "RB_XSEL": ["RbXsel"],
232    "RB_YSEL": ["RbYsel"],
233    "ROP3": ["ROP3"],
234    "RDREQ_POLICY": ["VGT_RDREQ_POLICY"],
235    "REG_INCLUDE": ["ThreadTraceRegInclude"],
236    "ROUND_MODE": ["PA_SU_VTX_CNTL__ROUND_MODE", "PA_SU_VTX_CNTL"],
237    "SC_MAP": ["ScMap"],
238    "SC_XSEL": ["ScXsel"],
239    "SC_YSEL": ["ScYsel"],
240    "SE_MAP": ["SeMap"],
241    "SE_PAIR_MAP": ["SePairMap"],
242    "SE_PAIR_XSEL": ["SePairXsel"],
243    "SE_PAIR_YSEL": ["SePairYsel"],
244    "SE_XSEL": ["SeXsel"],
245    "SE_YSEL": ["SeYsel"],
246    "SOURCE_SELECT": ["VGT_DI_SOURCE_SELECT"],
247    "SPM_PERFMON_STATE": ["SPM_PERFMON_STATE"],
248    "S_RD_POLICY": ["ReadPolicy"],
249    "STENCILFAIL_BF": ["StencilOp"],
250    "STENCILFAIL": ["StencilOp"],
251    "STENCILFUNC_BF": ["CompareFrag"],
252    "STENCILFUNC": ["CompareFrag"],
253    "STENCILZFAIL_BF": ["StencilOp"],
254    "STENCILZFAIL": ["StencilOp"],
255    "STENCILZPASS_BF": ["StencilOp"],
256    "STENCILZPASS": ["StencilOp"],
257    "SWAP_MODE": ["VGT_DMA_SWAP_MODE"],
258    "S_WR_POLICY": ["WritePolicy"],
259    "TILE_SPLIT": ["TileSplit"],
260    "TOKEN_EXCLUDE": ["ThreadTraceTokenExclude"],
261    "TOPOLOGY": ["VGT_TESS_TOPOLOGY"],
262    "TYPE": ["SQ_RSRC_BUF_TYPE", "SQ_BUF_RSRC_WORD3", "SQ_RSRC_IMG_TYPE", "SQ_IMG_RSRC_WORD3", "VGT_TESS_TYPE", "VGT_TF_PARAM"],
263    "UNCERTAINTY_REGION_MODE": ["ScUncertaintyRegionMode"],
264    "VS_EN": ["VGT_STAGES_VS_EN"],
265    "XY_MAG_FILTER": ["SQ_TEX_XY_FILTER"],
266    "XY_MIN_FILTER": ["SQ_TEX_XY_FILTER"],
267    "Z_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"],
268    "Z_FILTER": ["SQ_TEX_Z_FILTER"],
269    "ZFUNC": ["CompareFrag"],
270    "Z_ORDER": ["ZOrder"],
271    "ZPCPSD_WR_POLICY": ["WritePolicy"],
272    "Z_RD_POLICY": ["ReadPolicy"],
273    "Z_WR_POLICY": ["WritePolicy"],
274}
275
276# Enum definitions that are incomplete or missing in kernel headers
277DB_DFSM_CONTROL__PUNCHOUT_MODE = {
278 "entries": [
279  {"name": "AUTO", "value": 0},
280  {"name": "FORCE_ON", "value": 1},
281  {"name": "FORCE_OFF", "value": 2},
282  {"name": "RESERVED", "value": 3}
283 ]
284}
285
286ColorFormat = {
287 "entries": [
288  {"name": "COLOR_INVALID", "value": 0},
289  {"name": "COLOR_8", "value": 1},
290  {"name": "COLOR_16", "value": 2},
291  {"name": "COLOR_8_8", "value": 3},
292  {"name": "COLOR_32", "value": 4},
293  {"name": "COLOR_16_16", "value": 5},
294  {"name": "COLOR_10_11_11", "value": 6},
295  {"name": "COLOR_11_11_10", "value": 7},
296  {"name": "COLOR_10_10_10_2", "value": 8},
297  {"name": "COLOR_2_10_10_10", "value": 9},
298  {"name": "COLOR_8_8_8_8", "value": 10},
299  {"name": "COLOR_32_32", "value": 11},
300  {"name": "COLOR_16_16_16_16", "value": 12},
301  {"name": "COLOR_32_32_32_32", "value": 14},
302  {"name": "COLOR_5_6_5", "value": 16},
303  {"name": "COLOR_1_5_5_5", "value": 17},
304  {"name": "COLOR_5_5_5_1", "value": 18},
305  {"name": "COLOR_4_4_4_4", "value": 19},
306  {"name": "COLOR_8_24", "value": 20},
307  {"name": "COLOR_24_8", "value": 21},
308  {"name": "COLOR_X24_8_32_FLOAT", "value": 22},
309  {"name": "COLOR_5_9_9_9", "value": 24}
310 ]
311}
312
313SQ_IMG_RSRC_WORD4__BC_SWIZZLE = {
314 "entries": [
315  {"name": "BC_SWIZZLE_XYZW", "value": 0},
316  {"name": "BC_SWIZZLE_XWYZ", "value": 1},
317  {"name": "BC_SWIZZLE_WZYX", "value": 2},
318  {"name": "BC_SWIZZLE_WXYZ", "value": 3},
319  {"name": "BC_SWIZZLE_ZYXW", "value": 4},
320  {"name": "BC_SWIZZLE_YXWZ", "value": 5}
321 ]
322}
323
324SX_DOWNCONVERT_FORMAT = {
325 "entries": [
326  {"name": "SX_RT_EXPORT_NO_CONVERSION", "value": 0},
327  {"name": "SX_RT_EXPORT_32_R", "value": 1},
328  {"name": "SX_RT_EXPORT_32_A", "value": 2},
329  {"name": "SX_RT_EXPORT_10_11_11", "value": 3},
330  {"name": "SX_RT_EXPORT_2_10_10_10", "value": 4},
331  {"name": "SX_RT_EXPORT_8_8_8_8", "value": 5},
332  {"name": "SX_RT_EXPORT_5_6_5", "value": 6},
333  {"name": "SX_RT_EXPORT_1_5_5_5", "value": 7},
334  {"name": "SX_RT_EXPORT_4_4_4_4", "value": 8},
335  {"name": "SX_RT_EXPORT_16_16_GR", "value": 9},
336  {"name": "SX_RT_EXPORT_16_16_AR", "value": 10},
337  {"name": "SX_RT_EXPORT_9_9_9_E5", "value": 11}
338 ]
339}
340
341ThreadTraceRegInclude = {
342  "entries": [
343   {"name": "REG_INCLUDE_SQDEC", "value": 1},
344   {"name": "REG_INCLUDE_SHDEC", "value": 2},
345   {"name": "REG_INCLUDE_GFXUDEC", "value": 4},
346   {"name": "REG_INCLUDE_COMP", "value": 8},
347   {"name": "REG_INCLUDE_CONTEXT", "value": 16},
348   {"name": "REG_INCLUDE_CONFIG", "value": 32},
349   {"name": "REG_INCLUDE_OTHER", "value": 64},
350   {"name": "REG_INCLUDE_READS", "value": 128}
351  ]
352}
353
354ThreadTraceTokenExclude = {
355  "entries": [
356   {"name": "TOKEN_EXCLUDE_VMEMEXEC", "value": 1},
357   {"name": "TOKEN_EXCLUDE_ALUEXEC", "value": 2},
358   {"name": "TOKEN_EXCLUDE_VALUINST", "value": 4},
359   {"name": "TOKEN_EXCLUDE_WAVERDY", "value": 8},
360   {"name": "TOKEN_EXCLUDE_IMMED1", "value": 16},
361   {"name": "TOKEN_EXCLUDE_IMMEDIATE", "value": 32},
362   {"name": "TOKEN_EXCLUDE_REG", "value": 64},
363   {"name": "TOKEN_EXCLUDE_EVENT", "value": 128},
364   {"name": "TOKEN_EXCLUDE_INST", "value": 256},
365   {"name": "TOKEN_EXCLUDE_UTILCTR", "value": 512},
366   {"name": "TOKEN_EXCLUDE_WAVEALLOC", "value": 1024},
367   {"name": "TOKEN_EXCLUDE_PERF", "value": 2048}
368  ]
369}
370
371GB_TILE_MODE0__MICRO_TILE_MODE = {
372 "entries": [
373  {"name": "ADDR_SURF_DISPLAY_MICRO_TILING", "value": 0},
374  {"name": "ADDR_SURF_THIN_MICRO_TILING", "value": 1},
375  {"name": "ADDR_SURF_DEPTH_MICRO_TILING", "value": 2},
376  {"name": "ADDR_SURF_THICK_MICRO_TILING_GFX6", "value": 3}
377 ]
378}
379
380IMG_DATA_FORMAT_STENCIL = {
381 "entries": [
382  {"name": "IMG_DATA_FORMAT_S8_16", "value": 59},
383  {"name": "IMG_DATA_FORMAT_S8_32", "value": 60},
384 ]
385}
386
387missing_enums_all = {
388  'FLOAT_MODE': {
389    "entries": [
390      {"name": "FP_32_DENORMS", "value": 48},
391      {"name": "FP_64_DENORMS", "value": 192},
392      {"name": "FP_ALL_DENORMS", "value": 240}
393    ]
394  },
395  'QUANT_MODE': {
396    "entries": [
397      {"name": "X_16_8_FIXED_POINT_1_16TH", "value": 0},
398      {"name": "X_16_8_FIXED_POINT_1_8TH", "value": 1},
399      {"name": "X_16_8_FIXED_POINT_1_4TH", "value": 2},
400      {"name": "X_16_8_FIXED_POINT_1_2", "value": 3},
401      {"name": "X_16_8_FIXED_POINT_1", "value": 4},
402      {"name": "X_16_8_FIXED_POINT_1_256TH", "value": 5},
403      {"name": "X_14_10_FIXED_POINT_1_1024TH", "value": 6},
404      {"name": "X_12_12_FIXED_POINT_1_4096TH", "value": 7}
405    ]
406  },
407  "CLIP_RULE": {
408   "entries": [
409    {"name": "OUT", "value": 1},
410    {"name": "IN_0", "value": 2},
411    {"name": "IN_1", "value": 4},
412    {"name": "IN_10", "value": 8},
413    {"name": "IN_2", "value": 16},
414    {"name": "IN_20", "value": 32},
415    {"name": "IN_21", "value": 64},
416    {"name": "IN_210", "value": 128},
417    {"name": "IN_3", "value": 256},
418    {"name": "IN_30", "value": 512},
419    {"name": "IN_31", "value": 1024},
420    {"name": "IN_310", "value": 2048},
421    {"name": "IN_32", "value": 4096},
422    {"name": "IN_320", "value": 8192},
423    {"name": "IN_321", "value": 16384},
424    {"name": "IN_3210", "value": 32768}
425   ]
426  },
427  'PA_SU_VTX_CNTL__ROUND_MODE': {
428    "entries": [
429      {"name": "X_TRUNCATE", "value": 0},
430      {"name": "X_ROUND", "value": 1},
431      {"name": "X_ROUND_TO_EVEN", "value": 2},
432      {"name": "X_ROUND_TO_ODD", "value": 3}
433    ]
434  },
435  "PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE": {
436   "entries": [
437    {"name": "X_DRAW_POINTS", "value": 0},
438    {"name": "X_DRAW_LINES", "value": 1},
439    {"name": "X_DRAW_TRIANGLES", "value": 2}
440   ]
441  },
442  "PA_SU_SC_MODE_CNTL__POLY_MODE": {
443   "entries": [
444    {"name": "X_DISABLE_POLY_MODE", "value": 0},
445    {"name": "X_DUAL_MODE", "value": 1}
446   ]
447  },
448  'VGT_HS_OFFCHIP_PARAM__OFFCHIP_GRANULARITY': {
449    "entries": [
450      {"name": "X_8K_DWORDS", "value": 0},
451      {"name": "X_4K_DWORDS", "value": 1},
452      {"name": "X_2K_DWORDS", "value": 2},
453      {"name": "X_1K_DWORDS", "value": 3}
454    ]
455  },
456  "ROP3": {
457   "entries": [
458    {"name": "ROP3_CLEAR", "value": 0},
459    {"name": "X_0X05", "value": 5},
460    {"name": "X_0X0A", "value": 10},
461    {"name": "X_0X0F", "value": 15},
462    {"name": "ROP3_NOR", "value": 17},
463    {"name": "ROP3_AND_INVERTED", "value": 34},
464    {"name": "ROP3_COPY_INVERTED", "value": 51},
465    {"name": "ROP3_AND_REVERSE", "value": 68},
466    {"name": "X_0X50", "value": 80},
467    {"name": "ROP3_INVERT", "value": 85},
468    {"name": "X_0X5A", "value": 90},
469    {"name": "X_0X5F", "value": 95},
470    {"name": "ROP3_XOR", "value": 102},
471    {"name": "ROP3_NAND", "value": 119},
472    {"name": "ROP3_AND", "value": 136},
473    {"name": "ROP3_EQUIVALENT", "value": 153},
474    {"name": "X_0XA0", "value": 160},
475    {"name": "X_0XA5", "value": 165},
476    {"name": "ROP3_NO_OP", "value": 170},
477    {"name": "X_0XAF", "value": 175},
478    {"name": "ROP3_OR_INVERTED", "value": 187},
479    {"name": "ROP3_COPY", "value": 204},
480    {"name": "ROP3_OR_REVERSE", "value": 221},
481    {"name": "ROP3_OR", "value": 238},
482    {"name": "X_0XF0", "value": 240},
483    {"name": "X_0XF5", "value": 245},
484    {"name": "X_0XFA", "value": 250},
485    {"name": "ROP3_SET", "value": 255}
486   ]
487  },
488  "EXCP_EN": {
489   "entries": [
490    {"name": "INVALID", "value": 1},
491    {"name": "INPUT_DENORMAL", "value": 2},
492    {"name": "DIVIDE_BY_ZERO", "value": 4},
493    {"name": "OVERFLOW", "value": 8},
494    {"name": "UNDERFLOW", "value": 16},
495    {"name": "INEXACT", "value": 32},
496    {"name": "INT_DIVIDE_BY_ZERO", "value": 64},
497    {"name": "ADDRESS_WATCH", "value": 128},
498    {"name": "MEMORY_VIOLATION", "value": 256}
499   ]
500  }
501}
502
503missing_enums_gfx8plus = {
504  **missing_enums_all,
505  'CB_COLOR_DCC_CONTROL__MAX_UNCOMPRESSED_BLOCK_SIZE': {
506    "entries": [
507      {"name": "MAX_BLOCK_SIZE_64B", "value": 0},
508      {"name": "MAX_BLOCK_SIZE_128B", "value": 1},
509      {"name": "MAX_BLOCK_SIZE_256B", "value": 2}
510    ]
511  },
512  'CB_COLOR_DCC_CONTROL__MIN_COMPRESSED_BLOCK_SIZE': {
513    "entries": [
514      {"name": "MIN_BLOCK_SIZE_32B", "value": 0},
515      {"name": "MIN_BLOCK_SIZE_64B", "value": 1}
516    ]
517  },
518}
519
520missing_enums_gfx81plus = {
521  **missing_enums_gfx8plus,
522  "SX_BLEND_OPT_EPSILON__MRT0_EPSILON": {
523    "entries": [
524      {"name": "EXACT", "value": 0},
525      {"name": "11BIT_FORMAT", "value": 1},
526      {"name": "10BIT_FORMAT", "value": 3},
527      {"name": "8BIT_FORMAT", "value": 6},
528      {"name": "6BIT_FORMAT", "value": 11},
529      {"name": "5BIT_FORMAT", "value": 13},
530      {"name": "4BIT_FORMAT", "value": 15}
531    ]
532  },
533}
534
535enums_missing = {
536  'gfx6': {
537    **missing_enums_all,
538   "GB_TILE_MODE0__MICRO_TILE_MODE": GB_TILE_MODE0__MICRO_TILE_MODE,
539  },
540  'gfx7': {
541    **missing_enums_all,
542  },
543  'gfx8': {
544    **missing_enums_gfx8plus,
545  },
546  'gfx81': {
547    **missing_enums_gfx81plus,
548  },
549  'gfx9': {
550    **missing_enums_gfx81plus,
551    "DB_DFSM_CONTROL__PUNCHOUT_MODE": DB_DFSM_CONTROL__PUNCHOUT_MODE,
552    "IMG_DATA_FORMAT_STENCIL": IMG_DATA_FORMAT_STENCIL,
553    "SQ_IMG_RSRC_WORD4__BC_SWIZZLE": SQ_IMG_RSRC_WORD4__BC_SWIZZLE,
554  },
555  'gfx10': {
556    **missing_enums_gfx81plus,
557    "DB_DFSM_CONTROL__PUNCHOUT_MODE": DB_DFSM_CONTROL__PUNCHOUT_MODE,
558    "ThreadTraceRegInclude": ThreadTraceRegInclude,
559    "ThreadTraceTokenExclude": ThreadTraceTokenExclude,
560  },
561  'gfx103': {
562    **missing_enums_gfx81plus,
563    "ColorFormat": ColorFormat,
564    "SX_DOWNCONVERT_FORMAT": SX_DOWNCONVERT_FORMAT,
565    "DB_DFSM_CONTROL__PUNCHOUT_MODE": DB_DFSM_CONTROL__PUNCHOUT_MODE,
566    "ThreadTraceRegInclude": ThreadTraceRegInclude,
567    "ThreadTraceTokenExclude": ThreadTraceTokenExclude,
568  },
569}
570
571# Register field definitions that are missing in kernel headers
572fields_missing = {
573  # Format:
574  #   Register: [[Field, StartBit, EndBit, EnumType(optional), ReplaceField=True/False(optional)], ...]
575  'gfx6': {
576    "COMPUTE_RESOURCE_LIMITS": [["WAVES_PER_SH_GFX6", 0, 5]],
577    "GB_TILE_MODE0": [["MICRO_TILE_MODE", 0, 1, "GB_TILE_MODE0__MICRO_TILE_MODE"]],
578    "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]],
579    "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]],
580  },
581  'gfx7': {
582    "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]],
583    "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]],
584  },
585  'gfx8': {
586    "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]],
587    "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]],
588  },
589  'gfx81': {
590    "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]],
591    "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]],
592  },
593  'gfx9': {
594    "SQ_IMG_RSRC_WORD1": [
595      ["DATA_FORMAT_STENCIL", 20, 25, "IMG_DATA_FORMAT_STENCIL"],
596      ["NUM_FORMAT_FMASK", 26, 29, "IMG_NUM_FORMAT_FMASK"]
597    ],
598  },
599  'gfx10': {
600    "DB_RESERVED_REG_2": [["RESOURCE_LEVEL", 28, 31, None, True]],
601  },
602  'gfx103': {
603    "DB_RESERVED_REG_2": [["RESOURCE_LEVEL", 28, 31, None, True]],
604  },
605}
606
607######### END HARDCODED CONFIGURATION
608
609def bitcount(n):
610    return bin(n).count('1')
611
612def generate_json(gfx_version, amd_headers_path):
613    # Add the path to the filenames
614    filenames = [amd_headers_path + '/' + a if a is not None else None for a in gfx_versions[gfx_version]]
615    old_gen = filenames[0] is None
616
617    # Open the files
618    files = [open(a, 'r').readlines() if a is not None else None for a in filenames]
619
620    # Parse the ip_offset.h file
621    base_offsets = None
622    if not old_gen:
623        for line in files[0]:
624            r = re_base.match(line)
625            if r is not None:
626                base_offsets = r.groups()
627
628        if base_offsets is None:
629            print('Can\'t parse: ' + filenames[0], file=sys.stderr)
630            sys.exit(1)
631
632
633    # Parse the offset.h file
634    name = None
635    offset = None
636    added_offsets = set()
637    regs = {}
638    for line in files[1]:
639        r = re_offset.match(line)
640        if r is None:
641            continue
642
643        if '_BASE_IDX' not in r.group('name'):
644            name = r.group('name')
645            offset = int(r.group('value'), 0) * 4
646            if not old_gen and r.group('mm') == 'mm':
647                continue
648        else:
649            assert name == r.group('name')[:-9]
650            idx = int(r.group('value'))
651            assert idx < len(base_offsets)
652            offset += int(base_offsets[idx], 0) * 4
653
654        # Only accept writeable registers and debug registers
655        if register_filter(gfx_version, name, offset, offset in added_offsets):
656            regs[name] = {
657                'chips': [gfx_version],
658                'map': {'at': offset, 'to': 'mm'},
659                'name': name,
660            }
661            added_offsets.add(offset)
662
663
664    # Parse the sh_mask.h file
665    shifts = {}
666    masks = {}
667    for line in files[2]:
668        r = re_shift.match(line)
669        is_shift = r is not None
670        r = re_mask.match(line) if r is None else r
671        if r is None:
672            continue
673
674        name = r.group('name')
675        if name not in regs.keys():
676            continue
677
678        field = r.group('field')
679        value = int(r.group('value'), 0)
680        assert not is_shift or value < 32
681
682        d = shifts if is_shift else masks
683        if name not in d:
684            d[name] = {}
685        d[name][field] = value
686
687
688    # Parse the enum.h file
689    re_enum_begin = re.compile(r'^typedef enum (?P<name>\w+) {\n')
690    re_enum_entry = re.compile(r'\s*(?P<name>\w+)\s*=\s*(?P<value>\w+),?\n')
691    re_enum_end = re.compile(r'^} \w+;\n')
692    inside_enum = False
693    name = None
694    enums = enums_missing[gfx_version] if gfx_version in enums_missing else {}
695
696    for line in files[3]:
697        r = re_enum_begin.match(line)
698        if r is not None:
699            name = r.group('name')
700            if name in enums:
701                continue
702            enums[name] = {'entries': []}
703            inside_enum = True
704            continue
705
706        r = re_enum_end.match(line)
707        if r is not None:
708            inside_enum = False
709            name = None
710            continue
711
712        if inside_enum:
713            r = re_enum_entry.match(line)
714            assert r
715            enums[name]['entries'].append({
716                'name': r.group('name'),
717                'value': int(r.group('value'), 0),
718            })
719
720
721    # Assemble everything
722    reg_types = {}
723    reg_mappings = []
724    missing_fields = fields_missing[gfx_version] if gfx_version in fields_missing else {}
725
726    for (name, reg) in regs.items():
727        type = {'fields': []}
728
729        if name in shifts and name in masks:
730            for (field, shift) in shifts[name].items():
731                if field not in masks[name]:
732                    continue
733
734                new = {
735                    'bits': [shift, shift + bitcount(masks[name][field]) - 1],
736                    'name': field,
737                }
738                if field in enum_map:
739                    type_map = enum_map[field]
740                    type_name = None
741
742                    if len(type_map) == 1:
743                        type_name = type_map[0];
744                    else:
745                        reg_index = type_map.index(name) if name in type_map else -1
746                        if reg_index >= 1 and reg_index % 2 == 1:
747                            type_name = type_map[reg_index - 1]
748
749                    if type_name is not None:
750                        if type_name not in enums:
751                            print('{0}: {1} type not found for {2}.{3}'
752                                  .format(gfx_version, type_name, name, field), file=sys.stderr)
753                        else:
754                            new['enum_ref'] = type_name
755
756                type['fields'].append(new)
757
758        if name in missing_fields:
759            fields = missing_fields[name]
760            for f in fields:
761                field = {
762                    'bits': [f[1], f[2]],
763                    'name': f[0],
764                }
765                if len(f) >= 4 and f[3] is not None and f[3] in enums:
766                    field['enum_ref'] = f[3]
767                # missing_fields should replace overlapping fields if requested
768                if len(f) >= 5 and f[4]:
769                    for f2 in type['fields']:
770                        if f2['bits'] == field['bits']:
771                            type['fields'].remove(f2)
772
773                type['fields'].append(field)
774
775        if len(type['fields']) > 0:
776            reg_types[name] = type
777            reg['type_ref'] = name
778            reg_mappings.append(reg)
779
780
781    # Generate and canonicalize json
782    all = {
783        'enums': enums,
784        'register_mappings': reg_mappings,
785        'register_types': reg_types,
786    }
787
788    return json_canonicalize(io.StringIO(json.dumps(all, indent=1)))
789
790
791if __name__ == '__main__':
792    if len(sys.argv) <= 1 or (sys.argv[1] not in gfx_versions and sys.argv[1] != 'all'):
793        print('First parameter should be one of: all, ' + ', '.join(gfx_versions.keys()), file=sys.stderr)
794        sys.exit(1)
795
796    if len(sys.argv) <= 2:
797        print('Second parameter should be the path to the amd/include directory.', file=sys.stderr)
798        sys.exit(1)
799
800    if sys.argv[1] == 'all':
801        for gfx_version in gfx_versions.keys():
802            print(generate_json(gfx_version, sys.argv[2]), file=open(gfx_version + '.json', 'w'))
803        sys.exit(0)
804
805    print(generate_json(sys.argv[1], sys.argv[2]))
806