From: Marek Olšák Date: Thu, 20 Aug 2020 09:07:35 +0000 (-0400) Subject: amd/registers: add a script that generates json from kernel headers X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=48a7a24a69f324641f49d9c5e66cf2114745861b amd/registers: add a script that generates json from kernel headers Acked-by: Samuel Pitoiset Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- diff --git a/src/amd/registers/parse_kernel_headers.py b/src/amd/registers/parse_kernel_headers.py new file mode 100644 index 00000000000..adb0bfa3402 --- /dev/null +++ b/src/amd/registers/parse_kernel_headers.py @@ -0,0 +1,805 @@ +#!/usr/bin/env python3 + +import sys, io, re, json +from canonicalize import json_canonicalize + +######### BEGIN HARDCODED CONFIGURATION + +gfx_versions = { + 'gfx6': [ + None, + 'asic_reg/gca/gfx_6_0_d.h', + 'asic_reg/gca/gfx_6_0_sh_mask.h', + 'asic_reg/gca/gfx_7_2_enum.h' # the file for gfx6 doesn't exist + ], + 'gfx7': [ + None, + 'asic_reg/gca/gfx_7_2_d.h', + 'asic_reg/gca/gfx_7_2_sh_mask.h', + 'asic_reg/gca/gfx_7_2_enum.h' + ], + 'gfx8': [ + None, + 'asic_reg/gca/gfx_8_0_d.h', + 'asic_reg/gca/gfx_8_0_sh_mask.h', + 'asic_reg/gca/gfx_8_0_enum.h', + ], + 'gfx81': [ + None, + 'asic_reg/gca/gfx_8_1_d.h', + 'asic_reg/gca/gfx_8_1_sh_mask.h', + 'asic_reg/gca/gfx_8_1_enum.h', + ], + 'gfx9': [ + 'vega10_ip_offset.h', + 'asic_reg/gc/gc_9_2_1_offset.h', + 'asic_reg/gc/gc_9_2_1_sh_mask.h', + 'vega10_enum.h', + ], + 'gfx10': [ + 'navi14_ip_offset.h', + 'asic_reg/gc/gc_10_1_0_offset.h', + 'asic_reg/gc/gc_10_1_0_sh_mask.h', + 'navi10_enum.h', + ], + 'gfx103': [ + 'sienna_cichlid_ip_offset.h', + 'asic_reg/gc/gc_10_3_0_offset.h', + 'asic_reg/gc/gc_10_3_0_sh_mask.h', + 'navi10_enum.h', # the file for gfx10.3 doesn't exist + ], +} + +# match: static const struct IP_BASE GC_BASE ={ { { { 0x00001260, 0x0000A000, 0x02402C00, 0, 0 } }, +re_base = re.compile(r'^static const struct IP_BASE GC_BASE\s*=\s*{ { { { (\w+), (\w+), (\w+), (\w+), (\w+) } },\n') + +# match: #define mmSDMA0_DEC_START 0x0000 +# match: #define ixSDMA0_DEC_START 0x0000 +re_offset = re.compile(r'^#define (?P[mi][mx])(?P\w+)\s+(?P\w+)\n') + +# match: #define SDMA0_DEC_START__START__SHIFT 0x0 +re_shift = re.compile(r'^#define (?P\w+)__(?P\w+)__SHIFT\s+(?P\w+)\n') + +# match: #define SDMA0_DEC_START__START_MASK 0xFFFFFFFFL +# match: #define SDMA0_DEC_START__START_MASK 0xFFFFFFFF +re_mask = re.compile(r'^#define (?P\w+)__(?P\w+)_MASK\s+(?P[0-9a-fA-Fx]+)L?\n') + +def register_filter(gfx_version, name, offset, already_added): + # Only accept writeable registers and debug registers + return ((offset // 0x1000 in [0xB, 0x28, 0x30, 0x31, 0x34, 0x35, 0x36, 0x37] or + # Add SQ_WAVE registers for trap handlers + name.startswith('SQ_WAVE_') or + # Add registers in the 0x8000 range used by all generations + (offset // 0x1000 == 0x8 and + (name.startswith('SQ_IMG_') or + name.startswith('SQ_BUF_') or + name.startswith('SQ_THREAD') or + name.startswith('GRBM_STATUS') or + name.startswith('CP_CP'))) or + # Add all registers in the 0x8000 range for gfx6 + (gfx_version == 'gfx6' and offset // 0x1000 == 0x8) or + # Add registers in the 0x9000 range + (offset // 0x1000 == 0x9 and + (name in ['TA_CS_BC_BASE_ADDR', 'GB_ADDR_CONFIG', 'SPI_CONFIG_CNTL'] or + (name.startswith('GB') and 'TILE_MODE' in name)))) and + # Remove SQ compiler definitions + offset // 4 not in (0x23B0, 0x23B1, 0x237F) and + # Remove conflicts (multiple definitions for the same offset) + not already_added and + 'PREF_PRI_ACCUM' not in name) + +# Mapping from field names to enum types +enum_map = { + # Format: + # field: [type1] - all registers use the same enum + # OR: + # field: [type1, reg1, type2, reg2, ...] - apply different enums to different registers + "ALPHA_COMB_FCN": ["CombFunc", "CB_BLEND0_CONTROL", "SX_OPT_COMB_FCN", "SX_MRT0_BLEND_OPT"], + "ALPHA_DESTBLEND": ["BlendOp"], + "ALPHA_DST_OPT": ["SX_BLEND_OPT"], + "ALPHA_SRCBLEND": ["BlendOp"], + "ALPHA_SRC_OPT": ["SX_BLEND_OPT"], + "ARRAY_MODE": ["ArrayMode"], + "BANK_HEIGHT": ["BankHeight"], + "BANK_WIDTH": ["BankWidth"], + "BC_SWIZZLE": ["SQ_IMG_RSRC_WORD4__BC_SWIZZLE"], + "BIN_MAPPING_MODE": ["BinMapMode"], + "BINNING_MODE": ["BinningMode"], + "BIN_SIZE_X_EXTEND": ["BinSizeExtend"], + "BIN_SIZE_Y_EXTEND": ["BinSizeExtend"], + "BLEND_OPT_DISCARD_PIXEL": ["BlendOpt"], + "BLEND_OPT_DONT_RD_DST": ["BlendOpt"], + "BORDER_COLOR_TYPE": ["SQ_TEX_BORDER_COLOR"], + "BUF_TYPE": ["VGT_DMA_BUF_TYPE"], + "CLAMP_X": ["SQ_TEX_CLAMP"], + "CLAMP_Y": ["SQ_TEX_CLAMP"], + "CLAMP_Z": ["SQ_TEX_CLAMP"], + "CLEAR_FILTER_SEL": ["CBPerfClearFilterSel"], + "CLIP_RULE": ["CLIP_RULE"], + "CMASK_ADDR_TYPE": ["CmaskAddr"], + "CMASK_RD_POLICY": ["ReadPolicy"], + "CMASK_WR_POLICY": ["WritePolicy"], + "COL0_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COL1_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COL2_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COL3_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COL4_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COL5_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COL6_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COL7_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "COLOR_COMB_FCN": ["CombFunc", "CB_BLEND0_CONTROL", "SX_OPT_COMB_FCN", "SX_MRT0_BLEND_OPT"], + "COLOR_DESTBLEND": ["BlendOp"], + "COLOR_DST_OPT": ["SX_BLEND_OPT"], + "COLOR_RD_POLICY": ["ReadPolicy"], + "COLOR_SRCBLEND": ["BlendOp"], + "COLOR_SRC_OPT": ["SX_BLEND_OPT"], + "COLOR_WR_POLICY": ["WritePolicy"], + "COMPAREFUNC0": ["CompareFrag"], + "COMPAREFUNC1": ["CompareFrag"], + "COMP_SWAP": ["SurfaceSwap"], + "CONSERVATIVE_Z_EXPORT": ["ConservativeZExport"], + "COVERAGE_TO_SHADER_SELECT": ["CovToShaderSel"], + "CUT_MODE": ["VGT_GS_CUT_MODE"], + "DATA_FORMAT": ["BUF_DATA_FORMAT", "SQ_BUF_RSRC_WORD3", "IMG_DATA_FORMAT", "SQ_IMG_RSRC_WORD1"], + "DCC_RD_POLICY": ["ReadPolicy"], + "DCC_WR_POLICY": ["WritePolicy"], + "DEPTH_COMPARE_FUNC": ["SQ_TEX_DEPTH_COMPARE"], + "DETECT_ONE": ["VGT_DETECT_ONE"], + "DETECT_ZERO": ["VGT_DETECT_ZERO"], + "DISTRIBUTION_MODE": ["VGT_DIST_MODE"], + "DST_SEL_W": ["SQ_SEL_XYZW01"], + "DST_SEL_X": ["SQ_SEL_XYZW01"], + "DST_SEL_Y": ["SQ_SEL_XYZW01"], + "DST_SEL_Z": ["SQ_SEL_XYZW01"], + "ENDIAN": ["SurfaceEndian"], + "ES_EN": ["VGT_STAGES_ES_EN"], + "EVENT_TYPE": ["VGT_EVENT_TYPE"], + "EXCP": ["EXCP_EN"], + "EXCP_EN": ["EXCP_EN"], + "FAULT_BEHAVIOR": ["DbPRTFaultBehavior"], + "FILTER_MODE": ["SQ_IMG_FILTER_TYPE"], + "FLOAT_MODE": ["FLOAT_MODE"], + "FMASK_RD_POLICY": ["ReadPolicy"], + "FMASK_WR_POLICY": ["WritePolicy"], + "FORCE_FULL_Z_RANGE": ["ForceControl"], + "FORCE_HIS_ENABLE0": ["ForceControl"], + "FORCE_HIS_ENABLE1": ["ForceControl"], + "FORCE_HIZ_ENABLE": ["ForceControl"], + "FORCE_Z_LIMIT_SUMM": ["ZLimitSumm"], + "FORMAT": ["ColorFormat", "CB_COLOR0_INFO", "StencilFormat", "DB_STENCIL_INFO", "ZFormat", "DB_Z_INFO"], + "GS_EN": ["VGT_STAGES_GS_EN"], + "HIZ_ZFUNC": ["CompareFrag"], + "HS_EN": ["VGT_STAGES_HS_EN"], + "HTILE_RD_POLICY": ["ReadPolicy"], + "HTILE_WR_POLICY": ["WritePolicy"], + "IDX0_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"], + "INDEX_TYPE": ["VGT_INDEX_TYPE_MODE"], + "LS_EN": ["VGT_STAGES_LS_EN"], + "MACRO_TILE_ASPECT": ["MacroTileAspect"], + "MAJOR_MODE": ["VGT_DI_MAJOR_MODE_SELECT"], + "MAX_UNCOMPRESSED_BLOCK_SIZE": ["CB_COLOR_DCC_CONTROL__MAX_UNCOMPRESSED_BLOCK_SIZE"], + "MICRO_TILE_MODE": ["GB_TILE_MODE0__MICRO_TILE_MODE"], + "MICRO_TILE_MODE_NEW": ["MicroTileMode"], + "MIN_COMPRESSED_BLOCK_SIZE": ["CB_COLOR_DCC_CONTROL__MIN_COMPRESSED_BLOCK_SIZE"], + "MIP_FILTER": ["SQ_TEX_MIP_FILTER"], + "MODE": ["CBMode", "CB_COLOR_CONTROL", "VGT_GS_MODE_TYPE", "VGT_GS_MODE"], + "MRT0_EPSILON": ["SX_BLEND_OPT_EPSILON__MRT0_EPSILON"], + "MRT0": ["SX_DOWNCONVERT_FORMAT"], + "MRT1": ["SX_DOWNCONVERT_FORMAT"], + "MRT2": ["SX_DOWNCONVERT_FORMAT"], + "MRT3": ["SX_DOWNCONVERT_FORMAT"], + "MRT4": ["SX_DOWNCONVERT_FORMAT"], + "MRT5": ["SX_DOWNCONVERT_FORMAT"], + "MRT6": ["SX_DOWNCONVERT_FORMAT"], + "MRT7": ["SX_DOWNCONVERT_FORMAT"], + "NUM_BANKS": ["NumBanks"], + "NUM_FORMAT": ["BUF_NUM_FORMAT", "SQ_BUF_RSRC_WORD3", "IMG_NUM_FORMAT", "SQ_IMG_RSRC_WORD1"], + "NUMBER_TYPE": ["SurfaceNumber"], + "OFFCHIP_GRANULARITY": ["VGT_HS_OFFCHIP_PARAM__OFFCHIP_GRANULARITY"], + "OP_FILTER_SEL": ["CBPerfOpFilterSel"], + "OUTPRIM_TYPE_1": ["VGT_GS_OUTPRIM_TYPE"], + "OUTPRIM_TYPE_2": ["VGT_GS_OUTPRIM_TYPE"], + "OUTPRIM_TYPE_3": ["VGT_GS_OUTPRIM_TYPE"], + "OUTPRIM_TYPE": ["VGT_GS_OUTPRIM_TYPE"], + "PARTIAL_SQUAD_LAUNCH_CONTROL": ["DbPSLControl"], + "PARTITIONING": ["VGT_TESS_PARTITION"], + "PERFMON_ENABLE_MODE": ["CP_PERFMON_ENABLE_MODE"], + "PERFMON_STATE": ["CP_PERFMON_STATE"], + "PIPE_CONFIG": ["PipeConfig"], + "PKR_MAP": ["PkrMap"], + "PKR_XSEL2": ["PkrXsel2"], + "PKR_XSEL": ["PkrXsel"], + "PKR_YSEL": ["PkrYsel"], + "PNT_SPRITE_OVRD_W": ["SPI_PNT_SPRITE_OVERRIDE"], + "PNT_SPRITE_OVRD_X": ["SPI_PNT_SPRITE_OVERRIDE"], + "PNT_SPRITE_OVRD_Y": ["SPI_PNT_SPRITE_OVERRIDE"], + "PNT_SPRITE_OVRD_Z": ["SPI_PNT_SPRITE_OVERRIDE"], + "POLYMODE_BACK_PTYPE": ["PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE"], + "POLYMODE_FRONT_PTYPE": ["PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE"], + "POLY_MODE": ["PA_SU_SC_MODE_CNTL__POLY_MODE"], + "POS0_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"], + "POS1_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"], + "POS2_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"], + "POS3_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"], + "POS4_EXPORT_FORMAT": ["SPI_SHADER_FORMAT"], + "PRIM_TYPE": ["VGT_DI_PRIM_TYPE"], + "PUNCHOUT_MODE": ["DB_DFSM_CONTROL__PUNCHOUT_MODE"], + "QUANT_MODE": ["QUANT_MODE"], + "RB_MAP_PKR0": ["RbMap"], + "RB_MAP_PKR1": ["RbMap"], + "RB_XSEL2": ["RbXsel2"], + "RB_XSEL": ["RbXsel"], + "RB_YSEL": ["RbYsel"], + "ROP3": ["ROP3"], + "RDREQ_POLICY": ["VGT_RDREQ_POLICY"], + "REG_INCLUDE": ["ThreadTraceRegInclude"], + "ROUND_MODE": ["PA_SU_VTX_CNTL__ROUND_MODE", "PA_SU_VTX_CNTL"], + "SC_MAP": ["ScMap"], + "SC_XSEL": ["ScXsel"], + "SC_YSEL": ["ScYsel"], + "SE_MAP": ["SeMap"], + "SE_PAIR_MAP": ["SePairMap"], + "SE_PAIR_XSEL": ["SePairXsel"], + "SE_PAIR_YSEL": ["SePairYsel"], + "SE_XSEL": ["SeXsel"], + "SE_YSEL": ["SeYsel"], + "SOURCE_SELECT": ["VGT_DI_SOURCE_SELECT"], + "SPM_PERFMON_STATE": ["SPM_PERFMON_STATE"], + "S_RD_POLICY": ["ReadPolicy"], + "STENCILFAIL_BF": ["StencilOp"], + "STENCILFAIL": ["StencilOp"], + "STENCILFUNC_BF": ["CompareFrag"], + "STENCILFUNC": ["CompareFrag"], + "STENCILZFAIL_BF": ["StencilOp"], + "STENCILZFAIL": ["StencilOp"], + "STENCILZPASS_BF": ["StencilOp"], + "STENCILZPASS": ["StencilOp"], + "SWAP_MODE": ["VGT_DMA_SWAP_MODE"], + "S_WR_POLICY": ["WritePolicy"], + "TILE_SPLIT": ["TileSplit"], + "TOKEN_EXCLUDE": ["ThreadTraceTokenExclude"], + "TOPOLOGY": ["VGT_TESS_TOPOLOGY"], + "TYPE": ["SQ_RSRC_BUF_TYPE", "SQ_BUF_RSRC_WORD3", "SQ_RSRC_IMG_TYPE", "SQ_IMG_RSRC_WORD3", "VGT_TESS_TYPE", "VGT_TF_PARAM"], + "UNCERTAINTY_REGION_MODE": ["ScUncertaintyRegionMode"], + "VS_EN": ["VGT_STAGES_VS_EN"], + "XY_MAG_FILTER": ["SQ_TEX_XY_FILTER"], + "XY_MIN_FILTER": ["SQ_TEX_XY_FILTER"], + "Z_EXPORT_FORMAT": ["SPI_SHADER_EX_FORMAT"], + "Z_FILTER": ["SQ_TEX_Z_FILTER"], + "ZFUNC": ["CompareFrag"], + "Z_ORDER": ["ZOrder"], + "ZPCPSD_WR_POLICY": ["WritePolicy"], + "Z_RD_POLICY": ["ReadPolicy"], + "Z_WR_POLICY": ["WritePolicy"], +} + +# Enum definitions that are incomplete or missing in kernel headers +DB_DFSM_CONTROL__PUNCHOUT_MODE = { + "entries": [ + {"name": "AUTO", "value": 0}, + {"name": "FORCE_ON", "value": 1}, + {"name": "FORCE_OFF", "value": 2}, + {"name": "RESERVED", "value": 3} + ] +} + +ColorFormat = { + "entries": [ + {"name": "COLOR_INVALID", "value": 0}, + {"name": "COLOR_8", "value": 1}, + {"name": "COLOR_16", "value": 2}, + {"name": "COLOR_8_8", "value": 3}, + {"name": "COLOR_32", "value": 4}, + {"name": "COLOR_16_16", "value": 5}, + {"name": "COLOR_10_11_11", "value": 6}, + {"name": "COLOR_11_11_10", "value": 7}, + {"name": "COLOR_10_10_10_2", "value": 8}, + {"name": "COLOR_2_10_10_10", "value": 9}, + {"name": "COLOR_8_8_8_8", "value": 10}, + {"name": "COLOR_32_32", "value": 11}, + {"name": "COLOR_16_16_16_16", "value": 12}, + {"name": "COLOR_32_32_32_32", "value": 14}, + {"name": "COLOR_5_6_5", "value": 16}, + {"name": "COLOR_1_5_5_5", "value": 17}, + {"name": "COLOR_5_5_5_1", "value": 18}, + {"name": "COLOR_4_4_4_4", "value": 19}, + {"name": "COLOR_8_24", "value": 20}, + {"name": "COLOR_24_8", "value": 21}, + {"name": "COLOR_X24_8_32_FLOAT", "value": 22}, + {"name": "COLOR_5_9_9_9", "value": 24} + ] +} + +SQ_IMG_RSRC_WORD4__BC_SWIZZLE = { + "entries": [ + {"name": "BC_SWIZZLE_XYZW", "value": 0}, + {"name": "BC_SWIZZLE_XWYZ", "value": 1}, + {"name": "BC_SWIZZLE_WZYX", "value": 2}, + {"name": "BC_SWIZZLE_WXYZ", "value": 3}, + {"name": "BC_SWIZZLE_ZYXW", "value": 4}, + {"name": "BC_SWIZZLE_YXWZ", "value": 5} + ] +} + +SX_DOWNCONVERT_FORMAT = { + "entries": [ + {"name": "SX_RT_EXPORT_NO_CONVERSION", "value": 0}, + {"name": "SX_RT_EXPORT_32_R", "value": 1}, + {"name": "SX_RT_EXPORT_32_A", "value": 2}, + {"name": "SX_RT_EXPORT_10_11_11", "value": 3}, + {"name": "SX_RT_EXPORT_2_10_10_10", "value": 4}, + {"name": "SX_RT_EXPORT_8_8_8_8", "value": 5}, + {"name": "SX_RT_EXPORT_5_6_5", "value": 6}, + {"name": "SX_RT_EXPORT_1_5_5_5", "value": 7}, + {"name": "SX_RT_EXPORT_4_4_4_4", "value": 8}, + {"name": "SX_RT_EXPORT_16_16_GR", "value": 9}, + {"name": "SX_RT_EXPORT_16_16_AR", "value": 10}, + {"name": "SX_RT_EXPORT_9_9_9_E5", "value": 11} + ] +} + +ThreadTraceRegInclude = { + "entries": [ + {"name": "REG_INCLUDE_SQDEC", "value": 1}, + {"name": "REG_INCLUDE_SHDEC", "value": 2}, + {"name": "REG_INCLUDE_GFXUDEC", "value": 4}, + {"name": "REG_INCLUDE_COMP", "value": 8}, + {"name": "REG_INCLUDE_CONTEXT", "value": 16}, + {"name": "REG_INCLUDE_CONFIG", "value": 32}, + {"name": "REG_INCLUDE_OTHER", "value": 64}, + {"name": "REG_INCLUDE_READS", "value": 128} + ] +} + +ThreadTraceTokenExclude = { + "entries": [ + {"name": "TOKEN_EXCLUDE_VMEMEXEC", "value": 1}, + {"name": "TOKEN_EXCLUDE_ALUEXEC", "value": 2}, + {"name": "TOKEN_EXCLUDE_VALUINST", "value": 4}, + {"name": "TOKEN_EXCLUDE_WAVERDY", "value": 8}, + {"name": "TOKEN_EXCLUDE_IMMED1", "value": 16}, + {"name": "TOKEN_EXCLUDE_IMMEDIATE", "value": 32}, + {"name": "TOKEN_EXCLUDE_REG", "value": 64}, + {"name": "TOKEN_EXCLUDE_EVENT", "value": 128}, + {"name": "TOKEN_EXCLUDE_INST", "value": 256}, + {"name": "TOKEN_EXCLUDE_UTILCTR", "value": 512}, + {"name": "TOKEN_EXCLUDE_WAVEALLOC", "value": 1024}, + {"name": "TOKEN_EXCLUDE_PERF", "value": 2048} + ] +} + +GB_TILE_MODE0__MICRO_TILE_MODE = { + "entries": [ + {"name": "ADDR_SURF_DISPLAY_MICRO_TILING", "value": 0}, + {"name": "ADDR_SURF_THIN_MICRO_TILING", "value": 1}, + {"name": "ADDR_SURF_DEPTH_MICRO_TILING", "value": 2}, + {"name": "ADDR_SURF_THICK_MICRO_TILING_GFX6", "value": 3} + ] +} + +IMG_DATA_FORMAT_STENCIL = { + "entries": [ + {"name": "IMG_DATA_FORMAT_S8_16", "value": 59}, + {"name": "IMG_DATA_FORMAT_S8_32", "value": 60}, + ] +} + +missing_enums_all = { + 'FLOAT_MODE': { + "entries": [ + {"name": "FP_32_DENORMS", "value": 48}, + {"name": "FP_64_DENORMS", "value": 192}, + {"name": "FP_ALL_DENORMS", "value": 240} + ] + }, + 'QUANT_MODE': { + "entries": [ + {"name": "X_16_8_FIXED_POINT_1_16TH", "value": 0}, + {"name": "X_16_8_FIXED_POINT_1_8TH", "value": 1}, + {"name": "X_16_8_FIXED_POINT_1_4TH", "value": 2}, + {"name": "X_16_8_FIXED_POINT_1_2", "value": 3}, + {"name": "X_16_8_FIXED_POINT_1", "value": 4}, + {"name": "X_16_8_FIXED_POINT_1_256TH", "value": 5}, + {"name": "X_14_10_FIXED_POINT_1_1024TH", "value": 6}, + {"name": "X_12_12_FIXED_POINT_1_4096TH", "value": 7} + ] + }, + "CLIP_RULE": { + "entries": [ + {"name": "OUT", "value": 1}, + {"name": "IN_0", "value": 2}, + {"name": "IN_1", "value": 4}, + {"name": "IN_10", "value": 8}, + {"name": "IN_2", "value": 16}, + {"name": "IN_20", "value": 32}, + {"name": "IN_21", "value": 64}, + {"name": "IN_210", "value": 128}, + {"name": "IN_3", "value": 256}, + {"name": "IN_30", "value": 512}, + {"name": "IN_31", "value": 1024}, + {"name": "IN_310", "value": 2048}, + {"name": "IN_32", "value": 4096}, + {"name": "IN_320", "value": 8192}, + {"name": "IN_321", "value": 16384}, + {"name": "IN_3210", "value": 32768} + ] + }, + 'PA_SU_VTX_CNTL__ROUND_MODE': { + "entries": [ + {"name": "X_TRUNCATE", "value": 0}, + {"name": "X_ROUND", "value": 1}, + {"name": "X_ROUND_TO_EVEN", "value": 2}, + {"name": "X_ROUND_TO_ODD", "value": 3} + ] + }, + "PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE": { + "entries": [ + {"name": "X_DRAW_POINTS", "value": 0}, + {"name": "X_DRAW_LINES", "value": 1}, + {"name": "X_DRAW_TRIANGLES", "value": 2} + ] + }, + "PA_SU_SC_MODE_CNTL__POLY_MODE": { + "entries": [ + {"name": "X_DISABLE_POLY_MODE", "value": 0}, + {"name": "X_DUAL_MODE", "value": 1} + ] + }, + 'VGT_HS_OFFCHIP_PARAM__OFFCHIP_GRANULARITY': { + "entries": [ + {"name": "X_8K_DWORDS", "value": 0}, + {"name": "X_4K_DWORDS", "value": 1}, + {"name": "X_2K_DWORDS", "value": 2}, + {"name": "X_1K_DWORDS", "value": 3} + ] + }, + "ROP3": { + "entries": [ + {"name": "ROP3_CLEAR", "value": 0}, + {"name": "X_0X05", "value": 5}, + {"name": "X_0X0A", "value": 10}, + {"name": "X_0X0F", "value": 15}, + {"name": "ROP3_NOR", "value": 17}, + {"name": "ROP3_AND_INVERTED", "value": 34}, + {"name": "ROP3_COPY_INVERTED", "value": 51}, + {"name": "ROP3_AND_REVERSE", "value": 68}, + {"name": "X_0X50", "value": 80}, + {"name": "ROP3_INVERT", "value": 85}, + {"name": "X_0X5A", "value": 90}, + {"name": "X_0X5F", "value": 95}, + {"name": "ROP3_XOR", "value": 102}, + {"name": "ROP3_NAND", "value": 119}, + {"name": "ROP3_AND", "value": 136}, + {"name": "ROP3_EQUIVALENT", "value": 153}, + {"name": "X_0XA0", "value": 160}, + {"name": "X_0XA5", "value": 165}, + {"name": "ROP3_NO_OP", "value": 170}, + {"name": "X_0XAF", "value": 175}, + {"name": "ROP3_OR_INVERTED", "value": 187}, + {"name": "ROP3_COPY", "value": 204}, + {"name": "ROP3_OR_REVERSE", "value": 221}, + {"name": "ROP3_OR", "value": 238}, + {"name": "X_0XF0", "value": 240}, + {"name": "X_0XF5", "value": 245}, + {"name": "X_0XFA", "value": 250}, + {"name": "ROP3_SET", "value": 255} + ] + }, + "EXCP_EN": { + "entries": [ + {"name": "INVALID", "value": 1}, + {"name": "INPUT_DENORMAL", "value": 2}, + {"name": "DIVIDE_BY_ZERO", "value": 4}, + {"name": "OVERFLOW", "value": 8}, + {"name": "UNDERFLOW", "value": 16}, + {"name": "INEXACT", "value": 32}, + {"name": "INT_DIVIDE_BY_ZERO", "value": 64}, + {"name": "ADDRESS_WATCH", "value": 128}, + {"name": "MEMORY_VIOLATION", "value": 256} + ] + } +} + +missing_enums_gfx8plus = { + **missing_enums_all, + 'CB_COLOR_DCC_CONTROL__MAX_UNCOMPRESSED_BLOCK_SIZE': { + "entries": [ + {"name": "MAX_BLOCK_SIZE_64B", "value": 0}, + {"name": "MAX_BLOCK_SIZE_128B", "value": 1}, + {"name": "MAX_BLOCK_SIZE_256B", "value": 2} + ] + }, + 'CB_COLOR_DCC_CONTROL__MIN_COMPRESSED_BLOCK_SIZE': { + "entries": [ + {"name": "MIN_BLOCK_SIZE_32B", "value": 0}, + {"name": "MIN_BLOCK_SIZE_64B", "value": 1} + ] + }, +} + +missing_enums_gfx81plus = { + **missing_enums_gfx8plus, + "SX_BLEND_OPT_EPSILON__MRT0_EPSILON": { + "entries": [ + {"name": "EXACT", "value": 0}, + {"name": "11BIT_FORMAT", "value": 1}, + {"name": "10BIT_FORMAT", "value": 3}, + {"name": "8BIT_FORMAT", "value": 6}, + {"name": "6BIT_FORMAT", "value": 11}, + {"name": "5BIT_FORMAT", "value": 13}, + {"name": "4BIT_FORMAT", "value": 15} + ] + }, +} + +enums_missing = { + 'gfx6': { + **missing_enums_all, + "GB_TILE_MODE0__MICRO_TILE_MODE": GB_TILE_MODE0__MICRO_TILE_MODE, + }, + 'gfx7': { + **missing_enums_all, + }, + 'gfx8': { + **missing_enums_gfx8plus, + }, + 'gfx81': { + **missing_enums_gfx81plus, + }, + 'gfx9': { + **missing_enums_gfx81plus, + "DB_DFSM_CONTROL__PUNCHOUT_MODE": DB_DFSM_CONTROL__PUNCHOUT_MODE, + "IMG_DATA_FORMAT_STENCIL": IMG_DATA_FORMAT_STENCIL, + "SQ_IMG_RSRC_WORD4__BC_SWIZZLE": SQ_IMG_RSRC_WORD4__BC_SWIZZLE, + }, + 'gfx10': { + **missing_enums_gfx81plus, + "DB_DFSM_CONTROL__PUNCHOUT_MODE": DB_DFSM_CONTROL__PUNCHOUT_MODE, + "ThreadTraceRegInclude": ThreadTraceRegInclude, + "ThreadTraceTokenExclude": ThreadTraceTokenExclude, + }, + 'gfx103': { + **missing_enums_gfx81plus, + "ColorFormat": ColorFormat, + "SX_DOWNCONVERT_FORMAT": SX_DOWNCONVERT_FORMAT, + "DB_DFSM_CONTROL__PUNCHOUT_MODE": DB_DFSM_CONTROL__PUNCHOUT_MODE, + "ThreadTraceRegInclude": ThreadTraceRegInclude, + "ThreadTraceTokenExclude": ThreadTraceTokenExclude, + }, +} + +# Register field definitions that are missing in kernel headers +fields_missing = { + # Format: + # Register: [[Field, StartBit, EndBit, EnumType(optional), ReplaceField=True/False(optional)], ...] + 'gfx6': { + "COMPUTE_RESOURCE_LIMITS": [["WAVES_PER_SH_GFX6", 0, 5]], + "GB_TILE_MODE0": [["MICRO_TILE_MODE", 0, 1, "GB_TILE_MODE0__MICRO_TILE_MODE"]], + "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]], + "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]], + }, + 'gfx7': { + "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]], + "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]], + }, + 'gfx8': { + "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]], + "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]], + }, + 'gfx81': { + "SQ_IMG_SAMP_WORD3": [["UPGRADED_DEPTH", 29, 29]], + "SQ_THREAD_TRACE_MASK": [["RANDOM_SEED", 16, 31]], + }, + 'gfx9': { + "SQ_IMG_RSRC_WORD1": [ + ["DATA_FORMAT_STENCIL", 20, 25, "IMG_DATA_FORMAT_STENCIL"], + ["NUM_FORMAT_FMASK", 26, 29, "IMG_NUM_FORMAT_FMASK"] + ], + }, + 'gfx10': { + "DB_RESERVED_REG_2": [["RESOURCE_LEVEL", 28, 31, None, True]], + }, + 'gfx103': { + "DB_RESERVED_REG_2": [["RESOURCE_LEVEL", 28, 31, None, True]], + }, +} + +######### END HARDCODED CONFIGURATION + +def bitcount(n): + return bin(n).count('1') + +def generate_json(gfx_version, amd_headers_path): + # Add the path to the filenames + filenames = [amd_headers_path + '/' + a if a is not None else None for a in gfx_versions[gfx_version]] + old_gen = filenames[0] is None + + # Open the files + files = [open(a, 'r').readlines() if a is not None else None for a in filenames] + + # Parse the ip_offset.h file + base_offsets = None + if not old_gen: + for line in files[0]: + r = re_base.match(line) + if r is not None: + base_offsets = r.groups() + + if base_offsets is None: + print('Can\'t parse: ' + filenames[0], file=sys.stderr) + sys.exit(1) + + + # Parse the offset.h file + name = None + offset = None + added_offsets = set() + regs = {} + for line in files[1]: + r = re_offset.match(line) + if r is None: + continue + + if '_BASE_IDX' not in r.group('name'): + name = r.group('name') + offset = int(r.group('value'), 0) * 4 + if not old_gen and r.group('mm') == 'mm': + continue + else: + assert name == r.group('name')[:-9] + idx = int(r.group('value')) + assert idx < len(base_offsets) + offset += int(base_offsets[idx], 0) * 4 + + # Only accept writeable registers and debug registers + if register_filter(gfx_version, name, offset, offset in added_offsets): + regs[name] = { + 'chips': [gfx_version], + 'map': {'at': offset, 'to': 'mm'}, + 'name': name, + } + added_offsets.add(offset) + + + # Parse the sh_mask.h file + shifts = {} + masks = {} + for line in files[2]: + r = re_shift.match(line) + is_shift = r is not None + r = re_mask.match(line) if r is None else r + if r is None: + continue + + name = r.group('name') + if name not in regs.keys(): + continue + + field = r.group('field') + value = int(r.group('value'), 0) + assert not is_shift or value < 32 + + d = shifts if is_shift else masks + if name not in d: + d[name] = {} + d[name][field] = value + + + # Parse the enum.h file + re_enum_begin = re.compile(r'^typedef enum (?P\w+) {\n') + re_enum_entry = re.compile(r'\s*(?P\w+)\s*=\s*(?P\w+),?\n') + re_enum_end = re.compile(r'^} \w+;\n') + inside_enum = False + name = None + enums = enums_missing[gfx_version] if gfx_version in enums_missing else {} + + for line in files[3]: + r = re_enum_begin.match(line) + if r is not None: + name = r.group('name') + if name in enums: + continue + enums[name] = {'entries': []} + inside_enum = True + continue + + r = re_enum_end.match(line) + if r is not None: + inside_enum = False + name = None + continue + + if inside_enum: + r = re_enum_entry.match(line) + assert r + enums[name]['entries'].append({ + 'name': r.group('name'), + 'value': int(r.group('value'), 0), + }) + + + # Assemble everything + reg_types = {} + reg_mappings = [] + missing_fields = fields_missing[gfx_version] if gfx_version in fields_missing else {} + + for (name, reg) in regs.items(): + type = {'fields': []} + + if name in shifts and name in masks: + for (field, shift) in shifts[name].items(): + if field not in masks[name]: + continue + + new = { + 'bits': [shift, shift + bitcount(masks[name][field]) - 1], + 'name': field, + } + if field in enum_map: + type_map = enum_map[field] + type_name = None + + if len(type_map) == 1: + type_name = type_map[0]; + else: + reg_index = type_map.index(name) if name in type_map else -1 + if reg_index >= 1 and reg_index % 2 == 1: + type_name = type_map[reg_index - 1] + + if type_name is not None: + if type_name not in enums: + print('{0}: {1} type not found for {2}.{3}' + .format(gfx_version, type_name, name, field), file=sys.stderr) + else: + new['enum_ref'] = type_name + + type['fields'].append(new) + + if name in missing_fields: + fields = missing_fields[name] + for f in fields: + field = { + 'bits': [f[1], f[2]], + 'name': f[0], + } + if len(f) >= 4 and f[3] is not None and f[3] in enums: + field['enum_ref'] = f[3] + # missing_fields should replace overlapping fields if requested + if len(f) >= 5 and f[4]: + for f2 in type['fields']: + if f2['bits'] == field['bits']: + type['fields'].remove(f2) + + type['fields'].append(field) + + if len(type['fields']) > 0: + reg_types[name] = type + reg['type_ref'] = name + reg_mappings.append(reg) + + + # Generate and canonicalize json + all = { + 'enums': enums, + 'register_mappings': reg_mappings, + 'register_types': reg_types, + } + + return json_canonicalize(io.StringIO(json.dumps(all, indent=1))) + + +if __name__ == '__main__': + if len(sys.argv) <= 1 or (sys.argv[1] not in gfx_versions and sys.argv[1] != 'all'): + print('First parameter should be one of: all, ' + ', '.join(gfx_versions.keys()), file=sys.stderr) + sys.exit(1) + + if len(sys.argv) <= 2: + print('Second parameter should be the path to the amd/include directory.', file=sys.stderr) + sys.exit(1) + + if sys.argv[1] == 'all': + for gfx_version in gfx_versions.keys(): + print(generate_json(gfx_version, sys.argv[2]), file=open(gfx_version + '.json', 'w')) + sys.exit(0) + + print(generate_json(sys.argv[1], sys.argv[2]))