17ec681f3Smrg1. Introduction 27ec681f3Smrg 37ec681f3Smrgrules-ng is a package consisting of a database of nvidia GPU registers in XML 47ec681f3Smrgformat, and tools made to parse this database and do useful work with it. It 57ec681f3Smrgis in mostly usable state, but there are some annoyances that prevent its 67ec681f3Smrgadoption as the home of all nouveau documentation. 77ec681f3Smrg 87ec681f3SmrgNote that this document and rules-ng understands "register" quite liberally as 97ec681f3Smrg"anything that has an address and can have a value in it, written to it, or 107ec681f3Smrgread to it". This includes conventional MMIO registers, as well as fields of 117ec681f3Smrgmemory structures and grobj methods. 127ec681f3Smrg 137ec681f3SmrgIts parsable XML format is supposed to solve three problems: 147ec681f3Smrg 157ec681f3Smrg - serve as actual documentation for the known registers: supports attaching 167ec681f3Smrg arbitrary text in <doc> tags and generating HTML for easy reading. 177ec681f3Smrg - name -> hex translation: supports generating C headers that #define all 187ec681f3Smrg known registers, bitfields and enum values as C constants. 197ec681f3Smrg - hex -> name translation: you tell it the address or address+value of a 207ec681f3Smrg register, and it decodes the address to its symbolic name, and the value to 217ec681f3Smrg its constituting bitfields, if any. Useful for decoding mmio-traces / 227ec681f3Smrg renouveau dumps, as well as standalone use. 237ec681f3Smrg 247ec681f3SmrgWhat's non-trivial about all this [ie. why rules-ng is not a long series of 257ec681f3Smrgplain address - name - documentation tuples]: 267ec681f3Smrg 277ec681f3Smrg - The registers may be split into bitfields, each with a different purpose 287ec681f3Smrg and name [and separate documentation]. 297ec681f3Smrg - The registers/bitfields may accept values from a predefined set [enum], 307ec681f3Smrg each with a different meaning. Each value also has a name and 317ec681f3Smrg documentation. 327ec681f3Smrg - The registers may come in multiple copies, forming arrays. They can also 337ec681f3Smrg form logical groups. And these groups can also come in multiple copies, 347ec681f3Smrg forming larger arrays... and you get a hierarchical structure. 357ec681f3Smrg - There are multiple different GPU chipsets. The available register set 367ec681f3Smrg changed between these chipsets - sometimes only a few registers, sometimes 377ec681f3Smrg half the card was remade from scratch. More annoyingly, sometimes some 387ec681f3Smrg registers move from one place to another, but are otherwise unchanged. 397ec681f3Smrg Also [nvidia-specific], new grobj classes are sometimes really just new 407ec681f3Smrg revisions of a base class with a few methods changed. In both of these 417ec681f3Smrg cases, we want to avoid duplication as much as possible. 427ec681f3Smrg 437ec681f3Smrg2. Proposed new XML format 447ec681f3Smrg 457ec681f3Smrg2.1. General tags 467ec681f3Smrg 477ec681f3SmrgRoot tag is <database>. There is one per the whole file and it should contain 487ec681f3Smrgeverything else. 497ec681f3Smrg 507ec681f3Smrg<brief> and <doc> are tags that can appear inside any other tag, and document 517ec681f3Smrgwhatever it defines. <brief> is supposed to be a short one-line description 527ec681f3Smrggiving a rough idea what a given item is for if no sufficiently descriptive 537ec681f3Smrgname was used. <doc> can be of any length, can contain some html and html-like 547ec681f3Smrgtags, and is supposed to describe a given item in as much detail as needed. 557ec681f3SmrgThere should be at most one <doc> and at most one <brief> tag for any parent. 567ec681f3Smrg 577ec681f3SmrgTags that define top-level entities include: 587ec681f3Smrg 597ec681f3Smrg <domain>: Declares an addressing space containing registers 607ec681f3Smrg <group>: Declares a block of registers, expected to be included by one or 617ec681f3Smrg more <domain>s 627ec681f3Smrg <bitset>: Declares a list of applicable bitfields for some register 637ec681f3Smrg <enum>: Declares a list of related symbolic values. Can describe params to 647ec681f3Smrg a register/bitfield, or discriminate between card variants. 657ec681f3Smrg 667ec681f3SmrgEach of these has an associated global name used to refer to them from other 677ec681f3Smrgparts of database. As a convenience, and to allow related stuff to be kept 687ec681f3Smrgtogether, the top-level entities are allowed to occur pretty much anywhere 697ec681f3Smrginside the XML file except inside <doc> tags. This implies no scoping, 707ec681f3Smrghowever: the effect is the same as putting the entity right below <database>. 717ec681f3SmrgIf two top-level elements of the same type and name are defined, they'll be 727ec681f3Smrgmerged into a single one, as if contents of one were written right after 737ec681f3Smrgcontents of the other. All attributes of the merged tags need to match. 747ec681f3Smrg 757ec681f3SmrgAnother top-level tag that can be used anywhere is the <import> tag. It's used 767ec681f3Smrglike <import file="foo.xml"/> and makes all of foo.xml's definitions available 777ec681f3Smrgto the containing file. If a single file is <import>ed more than one time, all 787ec681f3Smrg<import>s other than the first are ignored. 797ec681f3Smrg 807ec681f3Smrg2.2. Domains 817ec681f3Smrg 827ec681f3SmrgAll register definitions ultimately belong to a <domain>. <domain> is 837ec681f3Smrgbasically just a single address space. So we'll have a domain for the MMIO 847ec681f3SmrgBAR, one for each type of memory structure we need to describe, a domain for 857ec681f3Smrgthe grobj/FIFO methods, and a domain for each indirect index-data pair used to 867ec681f3Smrgaccess something useful. <domain> can have the following attributes: 877ec681f3Smrg 887ec681f3Smrg - name [required]: The name of the domain. 897ec681f3Smrg - width [optional]: the size, in bits, of a single addressable unit. This is 907ec681f3Smrg 8 by default for usual byte-addressable memory, but 32 can be useful 917ec681f3Smrg occasionally for indexed spaces of 32-bit cells. Values sane enough to 927ec681f3Smrg support for now include 8, 16, 32, 64. 937ec681f3Smrg - size [optional]: total number of addressable units it spans. Can be 947ec681f3Smrg undefined if you don't know it or it doesn't make sense. As a special 957ec681f3Smrg exception to the merging rules, size attribute need not be specified on all 967ec681f3Smrg tags that will result in a merged domain: tags with size can be merged with 977ec681f3Smrg tags without size, resulting in merged domain that has size. Error only 987ec681f3Smrg happens when the merged domains both have sizes, and the sizes differ. 997ec681f3Smrg - bare [optional]: if set to "no", all children items will have the domain 1007ec681f3Smrg name prepended to their names. If set to "yes", such prefixing doesn't 1017ec681f3Smrg happen. Default is "no". 1027ec681f3Smrg - prefix [optional]: selects the string that should be prepended to name 1037ec681f3Smrg of every child item. The special value "none" means no prefix, and is the 1047ec681f3Smrg default. All other values are looked up as <enum> names and, for each child 1057ec681f3Smrg item, its name is prefixed with name of the earliest variant in the given 1067ec681f3Smrg enum that supports given item. 1077ec681f3Smrg 1087ec681f3Smrg<domain name="NV_MMIO" size="0x1000000" prefix="chipset" bare="yes"> 1097ec681f3Smrg <reg32 offset="0" name="PMC_BOOT_0" /> 1107ec681f3Smrg <reg32 offset="4" name="PMC_BOOT_1" varset="chipset" variants="NV10-" /> 1117ec681f3Smrg <reg32 offset="0x100" name="PMC_INTR" /> 1127ec681f3Smrg</domain> 1137ec681f3Smrg 1147ec681f3SmrgDescribes a space with 0x1000000 of 8-bit addressable cells. Cells 0-3 belong 1157ec681f3Smrgto NV04_PMC_BOOT_0 register, 4-7 belong to NV10_PMC_BOOT_1 register, 1167ec681f3Smrg0x100-0x103 belong to NV04_PMC_INTR register, and remaining cells are either 1177ec681f3Smrgunused or unknown. The generated .h definitions are: 1187ec681f3Smrg 1197ec681f3Smrg#define NV_MMIO__SIZE 0x1000000 1207ec681f3Smrg#define NV04_PMC_BOOT_0 0 1217ec681f3Smrg#define NV10_PMC_BOOT_1 4 1227ec681f3Smrg#define NV04_PMC_INTR 0x100 1237ec681f3Smrg 1247ec681f3Smrg<domain name="NV50_PFB_VM_TRAP" width="32" size="6"> 1257ec681f3Smrg <reg32 offset="0" name="STATUS" /> 1267ec681f3Smrg <reg32 offset="1" name="CHANNEL" /> 1277ec681f3Smrg <reg32 offset="2" name="UNK2" /> 1287ec681f3Smrg <reg32 offset="3" name="ADDRLOW" /> 1297ec681f3Smrg <reg32 offset="4" name="ADDRMID" /> 1307ec681f3Smrg <reg32 offset="5" name="ADDRHIGH" /> 1317ec681f3Smrg</domain> 1327ec681f3Smrg 1337ec681f3SmrgDefines a 6-cell address space with each cell 32 bits in size and 1347ec681f3Smrgcorresponding to a single register. Definitions are: 1357ec681f3Smrg 1367ec681f3Smrg#define NV50_PFB_VM_TRAP__SIZE 6 1377ec681f3Smrg#define NV50_PFB_VM_TRAP_STATUS 0 1387ec681f3Smrg#define NV50_PFB_VM_TRAP_CHANNEL 1 1397ec681f3Smrg#define NV50_PFB_VM_TRAP_UNK2 2 1407ec681f3Smrg#define NV50_PFB_VM_TRAP_ADDRLOW 3 1417ec681f3Smrg#define NV50_PFB_VM_TRAP_ADDRMID 4 1427ec681f3Smrg#define NV50_PFB_VM_TRAP_ADDRHIGH 5 1437ec681f3Smrg 1447ec681f3Smrg2.3. Registers 1457ec681f3Smrg 1467ec681f3SmrgWhat we really want all the time is defining registers. This is done with 1477ec681f3Smrg<reg8>, <reg16>, <reg32> or <reg64> tags. The register of course takes 1487ec681f3Smrgreg_width / domain_width cells in the domain. It's an error to define a 1497ec681f3Smrgregister with smaller width than the domain it's in. The <reg*> attributes 1507ec681f3Smrgare: 1517ec681f3Smrg 1527ec681f3Smrg - name [required]: the name of the register 1537ec681f3Smrg - offset [required]: the offset of the register 1547ec681f3Smrg - access [optional]: "rw" [default], "r", or "w" to mark the register as 1557ec681f3Smrg read-write, read-only, or write-only. Only makes sense for real MMIO 1567ec681f3Smrg domains. 1577ec681f3Smrg - varset [optional]: the <enum> to choose from by the variant attribute. 1587ec681f3Smrg Defaults to first <enum> used in currently active prefix. 1597ec681f3Smrg - variants [optional]: space-separated list of and variant ranges that this 1607ec681f3Smrg register is present on. The items of this list can be: 1617ec681f3Smrg - var1: a single variant 1627ec681f3Smrg - var1-var2: all variants starting with var1 up to and including var2 1637ec681f3Smrg - var1:var2: all variants starting with var1 up to, but not including var2 1647ec681f3Smrg - :var1: all variants before var1 1657ec681f3Smrg - -var1: all variants up to and including var1 1667ec681f3Smrg - var1-: all variants starting from var1 1677ec681f3Smrg - type [optional]: How to interpret the contents of this register. 1687ec681f3Smrg - "uint": unsigned decimal integer 1697ec681f3Smrg - "int": signed decimal integer 1707ec681f3Smrg - "hex": unsigned hexadecimal integer 1717ec681f3Smrg - "float" IEEE 16-bit, 32-bit or 64-bit floating point format, depending 1727ec681f3Smrg on register/bitfield size 1737ec681f3Smrg - "boolean": a boolean value: 0 is false, 1 is true 1747ec681f3Smrg - any defined enum name: value from that anum 1757ec681f3Smrg - "enum": value from the inline <value> tags in this <reg*> 1767ec681f3Smrg - any defined bitset name: value decoded further according to that bitset 1777ec681f3Smrg - "bitset": value decoded further according to the inline <bitfield> 1787ec681f3Smrg tags 1797ec681f3Smrg - any defined domain name: value decoded as an offset in that domain 1807ec681f3Smrg The default is "bitset" if there are inline <bitfield> tags present, 1817ec681f3Smrg otherwise "enum" if there are inline <value> tags present, otherwise 1827ec681f3Smrg "boolean" if this is a bitfield with width 1, otherwise "hex". 1837ec681f3Smrg - shr [optional]: the value in this register is the real value shifted right 1847ec681f3Smrg by this many bits. Ie. for register with shr="12", register value 0x1234 1857ec681f3Smrg should be interpreted as 0x1234000. May sound too specific, but happens 1867ec681f3Smrg quite often in nvidia hardware. 1877ec681f3Smrg - length [optional]: if specified to be other than 1, the register is treated 1887ec681f3Smrg as if it was enclosed in an anonymous <stripe> with corresponding length 1897ec681f3Smrg and stride attributes, except the __ESIZE and __LEN stripe defines are 1907ec681f3Smrg emitted with the register's name. If not specified, defaults to 1. 1917ec681f3Smrg - stride [optional]: the stride value to use if length is non-1. Defaults to 1927ec681f3Smrg the register's size in cells. 1937ec681f3Smrg 1947ec681f3SmrgThe definitions emitted for a non-stripe register include only its offset and 1957ec681f3Smrgshr value. Other informations are generally expected to be a part of code 1967ec681f3Smrglogic anyway: 1977ec681f3Smrg 1987ec681f3Smrg<reg32 offset="0x400784" name="PGRAPH_CTXCTL_SWAP" shr="12" /> 1997ec681f3Smrg 2007ec681f3Smrgresults in 2017ec681f3Smrg 2027ec681f3Smrg#define PGRAPH_CTXCTL_SWAP 0x400784 2037ec681f3Smrg#define PGRAPH_CTXCTL_SWAP__SHR 12 2047ec681f3Smrg 2057ec681f3SmrgFor striped registers, __LEN and __ESIZE definitions like <stripe> are emitted 2067ec681f3Smrgtoo: 2077ec681f3Smrg 2087ec681f3Smrg<!-- in a 8-bit domain --> 2097ec681f3Smrg<reg32 offset="0x0600" name="NV50_COMPUTE_USER_PARAM" length="64" /> 2107ec681f3Smrg 2117ec681f3Smrgresults in 2127ec681f3Smrg 2137ec681f3Smrg#define NV50_COMPUTE_USER_PARAM(i) (0x600 + (i)*4) 2147ec681f3Smrg#define NV50_COMPUTE_USER_PARAM__LEN 64 2157ec681f3Smrg#define NV50_COMPUTE_USER_PARAM__ESIZE 4 2167ec681f3Smrg 2177ec681f3SmrgThe <reg*> tags can also contain either bitfield definitions, or enum value 2187ec681f3Smrgdefinitions. 2197ec681f3Smrg 2207ec681f3Smrg2.4. Enums and variants 2217ec681f3Smrg 2227ec681f3SmrgEnum is, basically, a set of values. They're defined by <enum> tag with the 2237ec681f3Smrgfollowing attributes: 2247ec681f3Smrg 2257ec681f3Smrg - name [required]: an identifying name. 2267ec681f3Smrg - inline [optional]: "yes" or "no", with "no" being the default. Selects if 2277ec681f3Smrg this enum should emit its own definitions in .h file, or be inlined into 2287ec681f3Smrg any <reg*> / <bitfield> definitions that reference it. 2297ec681f3Smrg - bare [optional]: only for no-inline enums, behaves like bare attribute 2307ec681f3Smrg to <domain> 2317ec681f3Smrg - prefix [optional]: only for no-inline enums, behaves like prefix attribute 2327ec681f3Smrg to <domain>. 2337ec681f3Smrg 2347ec681f3SmrgThe <enum> tag contains <value> tags with the following attributes: 2357ec681f3Smrg 2367ec681f3Smrg - name [required]: the name of the value 2377ec681f3Smrg - value [optional]: the value 2387ec681f3Smrg - varset [optional]: like in <reg*> 2397ec681f3Smrg - variants [optional]: like in <reg*> 2407ec681f3Smrg 2417ec681f3SmrgThe <enum>s are referenced from inside <reg*> and <bitfield> tags by setting 2427ec681f3Smrgthe type attribute to the name of the enum. For single-use enums, the <value> 2437ec681f3Smrgtags can also be written directly inside <reg*> tag. 2447ec681f3Smrg 2457ec681f3Smrg<enum name="SURFACE_FORMAT" prefix="chipset"> 2467ec681f3Smrg <value value="6" name="A8R8G8B8" /> 2477ec681f3Smrg <value value="0x12" name="A8R8G8B8_RECT" variants="NV10-" /> 2487ec681f3Smrg</enum> 2497ec681f3Smrg 2507ec681f3Smrg<enum name="gl_shade_model" inline="yes"> 2517ec681f3Smrg <value value="0x1d00" name="FLAT" /> 2527ec681f3Smrg <value value="0x1d01" name="SMOOTH" /> 2537ec681f3Smrg</enum> 2547ec681f3Smrg 2557ec681f3Smrg<reg32 offset="0x1234" name="TEXTURE_FORMAT" type="SURFACE_FORMAT" /> 2567ec681f3Smrg<reg32 offset="0x1238" name="SHADE_MODEL" type="gl_shade_model" /> 2577ec681f3Smrg<reg32 offset="0x123c" name="PATTERN_SELECT"> 2587ec681f3Smrg <value value="1" name="MONO" /> 2597ec681f3Smrg <value value="2" name="COLOR" /> 2607ec681f3Smrg</reg32> 2617ec681f3Smrg 2627ec681f3SmrgResult: 2637ec681f3Smrg 2647ec681f3Smrg#define NV04_SURFACE_FORMAT_A8R8G8B8 6 2657ec681f3Smrg#define NV04_SURFACE_FORMAT_A8R8G8B8_RECT 0x12 2667ec681f3Smrg#define TEXTURE_FORMAT 0x1234 2677ec681f3Smrg#define SHADE_MODEL 0x1238 2687ec681f3Smrg#define SHADE_MODEL_FLAT 0x1d00 2697ec681f3Smrg#define SHADE_MODEL_SMOOTH 0x1d01 2707ec681f3Smrg#define PATTERN_SELECT 0x123c 2717ec681f3Smrg#define PATTERN_SELECT_MONO 1 2727ec681f3Smrg#define PATTERN_SELECT_COLOR 2 2737ec681f3Smrg 2747ec681f3SmrgAnother use for enums is describing variants: slightly different versions of 2757ec681f3Smrgcards, objects, etc. The varset and variant attributes of most tags allow 2767ec681f3Smrgdefining items that are only present when you're dealing with something of the 2777ec681f3Smrgmatching variant. The variant space is "multidimensional" - so you can have 2787ec681f3Smrga variant "dimension" representing what GPU chipset you're using at the 2797ec681f3Smrgmoment, and another dimension representing what grobj class you're dealing 2807ec681f3Smrgwith [taken from another enum]. Both of these can be independent. 2817ec681f3Smrg 2827ec681f3Smrg<enum name="chipset"> 2837ec681f3Smrg <brief>The chipset of the card</brief> 2847ec681f3Smrg <value name="NV04"> 2857ec681f3Smrg <brief>RIVA TNT</brief> 2867ec681f3Smrg </value> 2877ec681f3Smrg <value name="NV05"> 2887ec681f3Smrg <brief>RIVA TNT2</brief> 2897ec681f3Smrg </value> 2907ec681f3Smrg <value name="NV10"> 2917ec681f3Smrg <brief>GeForce 256</brief> 2927ec681f3Smrg </value> 2937ec681f3Smrg <value name="NV50"> 2947ec681f3Smrg <brief>G80: GeForce 8800 GTX, Tesla *870, ...</brief> 2957ec681f3Smrg </value> 2967ec681f3Smrg <value name="NV84"> 2977ec681f3Smrg <brief>G84: GeForce 8600 GT, ...</brief> 2987ec681f3Smrg </value> 2997ec681f3Smrg <value name="NVA0"> 3007ec681f3Smrg <brief>G200: GeForce 260 GTX, Tesla C1060, ...</brief> 3017ec681f3Smrg </value> 3027ec681f3Smrg <value name="NVA5"> 3037ec681f3Smrg <brief>GT216: GeForce GT 220</brief> 3047ec681f3Smrg </value> 3057ec681f3Smrg</enum> 3067ec681f3Smrg 3077ec681f3SmrgIf enabled for a given domain, the name of the earliest variant to support 3087ec681f3Smrga given register / bitfield / value / whatever will be automatically prepended 3097ec681f3Smrgto its name. For this purpose, "earliest" is defined as "comes first in the 3107ec681f3SmrgXML file". 3117ec681f3Smrg 3127ec681f3Smrg<enum>s used for this purpose can still be used as normal enums. And can even 3137ec681f3Smrghave variant-specific values referencing another <enum>. Example: 3147ec681f3Smrg 3157ec681f3Smrg<enum name="grobj-class" bare="yes" prefix="chipset"> 3167ec681f3Smrg <value name="MEMORY_TO_MEMORY_FORMAT" value="0x0039" variants=":NV50" /> 3177ec681f3Smrg <value name="MEMORY_TO_MEMORY_FORMAT" value="0x5039" variants="NV50-" /> 3187ec681f3Smrg <value name="2D" value="0x502d" variants="NV50-" /> 3197ec681f3Smrg <value name="TCL" value="0x5097" variants="NV50:NVA0" /> 3207ec681f3Smrg <value name="TCL" value="0x8297" variants="NV84" /> 3217ec681f3Smrg <value name="COMPUTE" value="0x50c0" variants="NV50-" /> 3227ec681f3Smrg</enum> 3237ec681f3Smrg 3247ec681f3SmrgIn generated .h file, this will result in: 3257ec681f3Smrg 3267ec681f3Smrg#define NV04_MEMORY_TO_MEMORY_FORMAT 0x0039 3277ec681f3Smrg#define NV50_MEMORY_TO_MEMORY_FORMAT 0x5039 3287ec681f3Smrg#define NV50_2D 0x502d 3297ec681f3Smrg#define NV50_TCL 0x5097 3307ec681f3Smrg#define NV84_TCL 0x8297 3317ec681f3Smrg#define NV50_COMPUTE 0x50c0 3327ec681f3Smrg 3337ec681f3Smrg2.5. Bitfields 3347ec681f3Smrg 3357ec681f3SmrgOften, registers store not a single full-width value, but are split into 3367ec681f3Smrgbitfields. Like values can be grouped in enums, bitfields can be called in 3377ec681f3Smrgbitsets. The <bitset> tag has the same set of attributes as <enum> tag, and 3387ec681f3Smrgcontains <bitfield> tags with the following attributes: 3397ec681f3Smrg 3407ec681f3Smrg - name [required]: name of the bitfield 3417ec681f3Smrg - low [required]: index of the lowest bit belonging to this bitfield. bits 3427ec681f3Smrg are counted from 0, LSB-first. 3437ec681f3Smrg - high [required]: index of the highest bit belonging to this bitfield. 3447ec681f3Smrg - varset [optional]: like in <reg*> 3457ec681f3Smrg - variants [optional]: like in <reg*> 3467ec681f3Smrg - type [optional]: like in <reg*> 3477ec681f3Smrg - shr [optional]: like in <reg*> 3487ec681f3Smrg 3497ec681f3SmrgLike <value>s, <bitfield>s are also allowed to be written directly inside 3507ec681f3Smrg<reg*> tags. 3517ec681f3Smrg 3527ec681f3Smrg<bitfield>s themselves can contain <value>s. The defines generated for 3537ec681f3Smrg<bitfield>s include "name__MASK" equal to the bitmask corresponding to given 3547ec681f3Smrgbitfield, "name__SHIFT" equal to the low attribute, "name__SHR" equal to 3557ec681f3Smrgthe shr attribute [if defined]. Single-bit bitfields with type "boolean" are 3567ec681f3Smrgtreated specially, and get "name" defined to the bitmask instead. If the 3577ec681f3Smrgbitfield contains any <value>s, <bitfield>s, or references an inlined 3587ec681f3Smrgenum/bitset, defines for them are also generated, pre-shifted to the correct 3597ec681f3Smrgposition. Example: 3607ec681f3Smrg 3617ec681f3Smrg<enum name="nv03_operation" inline="yes"> 3627ec681f3Smrg <value value="0" name="SRCCOPY_AND" /> 3637ec681f3Smrg <value value="1" name="ROP_AND" /> 3647ec681f3Smrg <value value="2" name="BLEND_AND" /> 3657ec681f3Smrg <value value="3" name="SRCCOPY" /> 3667ec681f3Smrg <value value="4" name="SRCCOPY_PRE" /> 3677ec681f3Smrg <value value="5" name="BLEND_PRE" /> 3687ec681f3Smrg</enum> 3697ec681f3Smrg 3707ec681f3Smrg<bitset name="NV04_GROBJ_1"> 3717ec681f3Smrg <bitfield high="7" low="0" name="GRCLASS" /> 3727ec681f3Smrg <bitfield high="12" low="12" name="CHROMA_KEY" /> 3737ec681f3Smrg <bitfield high="13" low="13" name="USER_CLIP" /> 3747ec681f3Smrg <bitfield high="14" low="14" name="SWIZZLE" /> 3757ec681f3Smrg <bitfield high="17" low="15" name="PATCH_CONFIG" type="nv03_operation" /> 3767ec681f3Smrg <!-- ... --> 3777ec681f3Smrg</bitset> 3787ec681f3Smrg 3797ec681f3Smrg<bitset name="xy16" inline="yes"> 3807ec681f3Smrg <bitfield high="15" low="0" name="X" /> 3817ec681f3Smrg <bitfield high="31" low="16" name="Y" /> 3827ec681f3Smrg</bitset> 3837ec681f3Smrg 3847ec681f3Smrg<bitset name="nv50_vic" inline="yes"> 3857ec681f3Smrg <bitfield high="0" low="0" name="X"/> 3867ec681f3Smrg <bitfield high="1" low="1" name="Y"/> 3877ec681f3Smrg <bitfield high="2" low="2" name="Z"/> 3887ec681f3Smrg <bitfield high="3" low="3" name="W"/> 3897ec681f3Smrg</bitset> 3907ec681f3Smrg 3917ec681f3Smrg<reg32 offset="0x40014c" name="PGRAPH_CTX_SWITCH_1" type="NV04_GROBJ_1" /> 3927ec681f3Smrg 3937ec681f3Smrg<reg32 offset="0x0404" name="FORMAT"> 3947ec681f3Smrg <bitfield high="15" low="0" name="PITCH" /> 3957ec681f3Smrg <bitfield high="23" low="16" name="ORIGIN" /> 3967ec681f3Smrg <bitfield high="31" low="24" name="FILTER" /> 3977ec681f3Smrg</reg32> 3987ec681f3Smrg 3997ec681f3Smrg<reg32 offset="0x040c" name="POINT" type="xy16" /> 4007ec681f3Smrg 4017ec681f3Smrg<reg32 offset="0x1988" name="FP_INTERPOLANT_CTRL"> 4027ec681f3Smrg <bitfield name="UMASK" high="31" low="24" type="nv50_vic"/> 4037ec681f3Smrg <bitfield name="COUNT_NONFLAT" high="23" low="16" type="int"/> 4047ec681f3Smrg <bitfield name="OFFSET" high="15" low="8" type="int"/> 4057ec681f3Smrg <bitfield name="COUNT" high="7" low="0" type="int"/> 4067ec681f3Smrg</reg32> 4077ec681f3Smrg 4087ec681f3SmrgResult: 4097ec681f3Smrg 4107ec681f3Smrg#define NV04_GROBJ_1_GRCLASS__MASK 0x000000ff 4117ec681f3Smrg#define NV04_GROBJ_1_GRCLASS__SHIFT 0 4127ec681f3Smrg#define NV04_GROBJ_1_CHROMA_KEY 0x00001000 4137ec681f3Smrg#define NV04_GROBJ_1_USER_CLIP 0x00002000 4147ec681f3Smrg#define NV04_GROBJ_1_SWIZZLE 0x00004000 4157ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG__MASK 0x00038000 4167ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG__SHIFT 15 4177ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG_SRCCOPY_AND 0x00000000 4187ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG_ROP_AND 0x00008000 4197ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG_BLEND_AND 0x00010000 4207ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG_SRCCOPY 0x00018000 4217ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG_SRCCOPY_PRE 0x00020000 4227ec681f3Smrg#define NV04_GROBJ_1_PATCH_CONFIG_BLEND_PRE 0x00028000 4237ec681f3Smrg 4247ec681f3Smrg#define PGRAPH_CTX_SWITCH_1 0x40014c 4257ec681f3Smrg 4267ec681f3Smrg#define FORMAT 0x0404 4277ec681f3Smrg#define FORMAT_PITCH__MASK 0x0000ffff 4287ec681f3Smrg#define FORMAT_PITCH__SHIFT 0 4297ec681f3Smrg#define FORMAT_ORIGIN__MASM 0x00ff0000 4307ec681f3Smrg#define FORMAT_ORIGIN__SHIFT 16 4317ec681f3Smrg#define FORMAT_FILTER__MASK 0xff000000 4327ec681f3Smrg#define FORMAT_FILTER__SHIFT 24 4337ec681f3Smrg 4347ec681f3Smrg#define POINT 0x040c 4357ec681f3Smrg#define POINT_X 0x0000ffff 4367ec681f3Smrg#define POINT_X__SHIFT 0 4377ec681f3Smrg#define POINT_Y 0xffff0000 4387ec681f3Smrg#define POINT_Y__SHIFT 16 4397ec681f3Smrg 4407ec681f3Smrg#define FP_INTERPOLANT_CTRL 0x00001988 4417ec681f3Smrg#define FP_INTERPOLANT_CTRL_UMASK__MASK 0xff000000 4427ec681f3Smrg#define FP_INTERPOLANT_CTRL_UMASK__SHIFT 24 4437ec681f3Smrg#define FP_INTERPOLANT_CTRL_UMASK_X 0x01000000 4447ec681f3Smrg#define FP_INTERPOLANT_CTRL_UMASK_Y 0x02000000 4457ec681f3Smrg#define FP_INTERPOLANT_CTRL_UMASK_Z 0x04000000 4467ec681f3Smrg#define FP_INTERPOLANT_CTRL_UMASK_W 0x08000000 4477ec681f3Smrg#define FP_INTERPOLANT_CTRL_COUNT_NONFLAT__MASK 0x00ff0000 4487ec681f3Smrg#define FP_INTERPOLANT_CTRL_COUNT_NONFLAT__SHIFT 16 4497ec681f3Smrg#define FP_INTERPOLANT_CTRL_OFFSET__MASK 0x0000ff00 4507ec681f3Smrg#define FP_INTERPOLANT_CTRL_OFFSET__SHIFT 8 4517ec681f3Smrg#define FP_INTERPOLANT_CTRL_COUNT__MASK 0x000000ff 4527ec681f3Smrg#define FP_INTERPOLANT_CTRL_COUNT__SHIFT 0 4537ec681f3Smrg 4547ec681f3Smrg2.6. Arrays and stripes. 4557ec681f3Smrg 4567ec681f3SmrgSometimes you have multiple copies of a register. Sometimes you actually have 4577ec681f3Smrgmultiple copies of a whole set of registers. And sometimes this set itself 4587ec681f3Smrgcontains multiple copies of something. This is what <array>s are for. The 4597ec681f3Smrg<array> represents "length" units, each of size "stride" packed next to each 4607ec681f3Smrgother starting at "offset". Offsets of everything inside the array are 4617ec681f3Smrgrelative to start of an element of the array. The <array> attributes include: 4627ec681f3Smrg 4637ec681f3Smrg - name [required]: name of the array, also used as prefix for all items 4647ec681f3Smrg inside it 4657ec681f3Smrg - offset [required]: starting offset of the array. 4667ec681f3Smrg - stride [required]: size of a single element of the array, as well as the 4677ec681f3Smrg difference between offsets of two neighboring elements 4687ec681f3Smrg - length [required]: Number of elements in the array 4697ec681f3Smrg - varset [optional]: As in <reg*> 4707ec681f3Smrg - variants [optional]: As in <reg*> 4717ec681f3Smrg 4727ec681f3SmrgThe definitions emitted for an array include: 4737ec681f3Smrg - name(i) defined to be the starting offset of element i, if length > 1 4747ec681f3Smrg - name defined to be the starting offset of arrayi, if length == 1 4757ec681f3Smrg - name__LEN defined to be the length of array 4767ec681f3Smrg - name__ESIZE defined to be the stride of array 4777ec681f3Smrg 4787ec681f3SmrgAlso, if length is not 1, definitions for all items inside the array that 4797ec681f3Smrginvolve offsets become parameter-taking C macros that calculate the offset 4807ec681f3Smrgbased on array index. For nested arrays, this macro takes as many arguments 4817ec681f3Smrgas there are indices involved. 4827ec681f3Smrg 4837ec681f3SmrgIt's an error if an item inside an array doesn't fit inside the array element. 4847ec681f3Smrg 4857ec681f3Smrg<array offset="0x408000" name="PGRAPH_TP" stride="0x1000" length="8"> 4867ec681f3Smrg <array offset="0x200" name="MP" stride="0x80" length="2"> 4877ec681f3Smrg <!-- ... --> 4887ec681f3Smrg <reg64 offset="0x70" name="TRAPPED_OPCODE" /> 4897ec681f3Smrg <!-- ... --> 4907ec681f3Smrg </array> 4917ec681f3Smrg <reg32 offset="0x314" name="MP_TRAP /> 4927ec681f3Smrg <!-- ... --> 4937ec681f3Smrg</array> 4947ec681f3Smrg 4957ec681f3Smrg#define PGRAPH_TP(i) (0x408000+(i)*0x1000) 4967ec681f3Smrg#define PGRAPH_TP__LEN 8 4977ec681f3Smrg#define PGRAPH_TP__ESIZE 0x1000 4987ec681f3Smrg#define PGRAPH_TP_MP(i,j) (0x408200+(i)*0x1000+(j)*0x80) 4997ec681f3Smrg#define PGRAPH_TP__LEN 2 5007ec681f3Smrg#define PGRAPH_TP__ESIZE 0x80 5017ec681f3Smrg#define PGRAPH_TP_MP_TRAPPED_OPCODE(i,j) (0x408270+(i)*0x1000+(j)*0x80) 5027ec681f3Smrg 5037ec681f3Smrg<stripe>s are somewhat similar to arrays, but don't reserve space, merely say 5047ec681f3Smrgthat all items inside come in "length" copies "stride" cells apart. As opposed 5057ec681f3Smrgto <array>s, items can have offsets larger than stride, and offsets aren't 5067ec681f3Smrgautomatically assumed to be a part of <stripe> unless a <reg*> explicitely 5077ec681f3Smrghits that particular offset for some index. Also, <stripe>s of length 1 and 5087ec681f3Smrgstride 0 can be used as generic container, for example to apply a variant set 5097ec681f3Smrgor a prefix to a bigger set of elements. Attributes: 5107ec681f3Smrg 5117ec681f3Smrg - name [optional]: like in <array>. If not given, no prefixing happens, and 5127ec681f3Smrg the defines for <stripe> itself aren't emitted. 5137ec681f3Smrg - offset [optional]: like <array>. Defaults to 0 if unspecified. 5147ec681f3Smrg - stride [optional]: the difference between offsets of items with indices i 5157ec681f3Smrg and i+1. Or size of the <stripe> if it makes sense in that particular 5167ec681f3Smrg context. Defaults to 0. 5177ec681f3Smrg - length [optional]: like in array. Defaults to 1. 5187ec681f3Smrg - varset [optional]: as in <reg*> 5197ec681f3Smrg - variants [optional]: as in <reg*> 5207ec681f3Smrg - prefix [optional]: as in <domain>, overrides parent's prefix option. 5217ec681f3Smrg 5227ec681f3SmrgDefinitions are emitted like for arrays, but: 5237ec681f3Smrg - if no name is given, the definitions for stripe itself won't be emitted 5247ec681f3Smrg - if length is 0, the length is assumed to be unknown or undefined. No __LEN 5257ec681f3Smrg is emitted in this case. 5267ec681f3Smrg - if stride is 0, __ESIZE is not emitted 5277ec681f3Smrg - it's an error to have stride 0 with length different than 1 5287ec681f3Smrg 5297ec681f3Smrg 5307ec681f3SmrgExamples: 5317ec681f3Smrg 5327ec681f3Smrg<stripe name="PGRAPH" offset="0x400000" variants="NV04-NV05"> 5337ec681f3Smrg <reg32 offset="0x100" name="INTR" /> 5347ec681f3Smrg <reg32 offset="0x140" name="INTR_EN" /> 5357ec681f3Smrg</stripe> 5367ec681f3Smrg 5377ec681f3Smrg<stripe name="PGRAPH" offset="0x400000" variants="NV50-"> 5387ec681f3Smrg <reg32 offset="0x100" name="INTR" /> 5397ec681f3Smrg <reg32 offset="0x108" name="TRAP" /> 5407ec681f3Smrg <reg32 offset="0x138" name="TRAP_EN" /> 5417ec681f3Smrg <reg32 offset="0x13c" name="INTR_EN" /> 5427ec681f3Smrg</stripe> 5437ec681f3Smrg 5447ec681f3SmrgResults in: 5457ec681f3Smrg 5467ec681f3Smrg#define NV04_PGRAPH 0x400000 5477ec681f3Smrg#define NV04_PGRAPH_INTR 0x400100 5487ec681f3Smrg#define NV04_PGRAPH_INTR_EN 0x400140 5497ec681f3Smrg#define NV50_PGRAPH 0x400000 5507ec681f3Smrg#define NV50_PGRAPH_INTR 0x400100 5517ec681f3Smrg#define NV50_PGRAPH_TRAP 0x400108 5527ec681f3Smrg#define NV50_PGRAPH_TRAP_EN 0x400138 5537ec681f3Smrg#define NV50_PGRAPH_INTR_EN 0x40013c 5547ec681f3Smrg 5557ec681f3Smrg<stripe name="PVIDEO" offset="0x8000"> 5567ec681f3Smrg <stripe offset="0x900" stride="4" length="2"> 5577ec681f3Smrg <reg32 offset="0" name="BASE" /> 5587ec681f3Smrg <reg32 offset="8" name="LIMIT" /> 5597ec681f3Smrg <reg32 offset="0x10" name="LUMINANCE" /> 5607ec681f3Smrg <reg32 offset="0x18" name="CHROMINANCE" /> 5617ec681f3Smrg <!-- ... --> 5627ec681f3Smrg </stripe> 5637ec681f3Smrg</stripe> 5647ec681f3Smrg 5657ec681f3SmrgResults in: 5667ec681f3Smrg 5677ec681f3Smrg#define PVIDEO_BASE (0x8900+(i)*4) 5687ec681f3Smrg#define PVIDEO_LIMIT (0x8908+(i)*4) 5697ec681f3Smrg#define PVIDEO_LUMINANCE (0x8910+(i)*4) 5707ec681f3Smrg#define PVIDEO_CHROMINANCE (0x8918+(i)*4) 5717ec681f3Smrg 5727ec681f3Smrg<domain name="NV_OBJECT" bare="yes"> 5737ec681f3Smrg <stripe name="OBJECT" prefix="chipset"> 5747ec681f3Smrg <reg32 offset="0x00" name="NAME" /> 5757ec681f3Smrg <reg32 offset="0x10" name="FENCE_ADDRESS_HIGH" variants="NV50-" /> 5767ec681f3Smrg <!-- more PFIFO methods --> 5777ec681f3Smrg </stripe> 5787ec681f3Smrg <stripe prefix="grobj-class"> 5797ec681f3Smrg <stripe variants="NV04_MEMORY_TO_MEMORY_FORMAT-NV05_MEMORY_TO_MEMORY_FORMAT"> 5807ec681f3Smrg <reg32 offset="0x200" name="LINEAR_IN" variants="NV50_MEMORY_TO_MEMORY_FORMAT" /> 5817ec681f3Smrg <reg32 offset="0x328" name="BUFFER_NOTIFY" /> 5827ec681f3Smrg <!-- more m2mf methods --> 5837ec681f3Smrg </stripe> 5847ec681f3Smrg <stripe variants="NV50_COMPUTE"> 5857ec681f3Smrg <reg32 offset="0x368" name="LAUNCH" /> 5867ec681f3Smrg <stripe name="GLOBAL" offset="0x400" stride="0x20" length="16"> 5877ec681f3Smrg <reg32 offset="0" name="ADDRESS_HIGH" /> 5887ec681f3Smrg <reg32 offset="4" name="ADDRESS_LOW" /> 5897ec681f3Smrg <reg32 offset="8" name="PITCH" /> 5907ec681f3Smrg <reg32 offset="0xc" name="LIMIT" /> 5917ec681f3Smrg <reg32 offset="0x10" name="MODE" /> 5927ec681f3Smrg </stripe> 5937ec681f3Smrg <!-- more NV50_COMPUTE methods --> 5947ec681f3Smrg <reg32 offset="0x0600" name="USER_PARAM" length="64" /> 5957ec681f3Smrg </stripe> 5967ec681f3Smrg </stripe> 5977ec681f3Smrg</domain> 5987ec681f3Smrg 5997ec681f3SmrgResults in: 6007ec681f3Smrg 6017ec681f3Smrg#define NV01_OBJECT_NAME 0x00 6027ec681f3Smrg#define NV50_OBJECT_FENCE_ADDRESS_HIGH 0x10 6037ec681f3Smrg#define NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN 0x200 6047ec681f3Smrg#define NV04_MEMORY_TO_MEMORY_FORMAT_BUFFER_NOTIFY 0x328 6057ec681f3Smrg#define NV50_COMPUTE_LAUNCH 0x368 6067ec681f3Smrg#define NV50_COMPUTE_GLOBAL 0x400 6077ec681f3Smrg#define NV50_COMPUTE_GLOBAL__LEN 16 6087ec681f3Smrg#define NV50_COMPUTE_GLOBAL__ESIZE 0x20 6097ec681f3Smrg#define NV50_COMPUTE_GLOBAL_ADDRESS_HIGH (0x400 + (i)*0x20) 6107ec681f3Smrg#define NV50_COMPUTE_GLOBAL_ADDRESS_LOW (0x404 + (i)*0x20) 6117ec681f3Smrg#define NV50_COMPUTE_GLOBAL_PITCH (0x408 + (i)*0x20) 6127ec681f3Smrg#define NV50_COMPUTE_GLOBAL_LIMIT (0x40c + (i)*0x20) 6137ec681f3Smrg#define NV50_COMPUTE_GLOBAL_MODE (0x410 + (i)*0x20) 6147ec681f3Smrg#define NV50_COMPUTE_USER_PARAM(i) (0x600 + (i)*4) 6157ec681f3Smrg#define NV50_COMPUTE_USER_PARAM__LEN 64 6167ec681f3Smrg#define NV50_COMPUTE_USER_PARAM__ESIZE 4 6177ec681f3Smrg 6187ec681f3Smrg2.7. Groups 6197ec681f3Smrg 6207ec681f3SmrgGroups are just sets of registers and/or arrays that can be copied-and-pasted 6217ec681f3Smrgtogether, when they're duplicated in several places in the same <domain>, 6227ec681f3Smrgtwo different <domain>s, or have different offsets for different variants. 6237ec681f3Smrg<group> and <use-group> only have the name attribute. <use-group> can appear 6247ec681f3Smrgwherever <reg*> can, including inside a <group>. 6257ec681f3Smrg 6267ec681f3Smrg<group name="nv50_mp"> 6277ec681f3Smrg <!-- ... --> 6287ec681f3Smrg <reg64 offset="0x70" name="TRAPPED_OPCODE" /> 6297ec681f3Smrg <!-- ... --> 6307ec681f3Smrg</group> 6317ec681f3Smrg 6327ec681f3Smrg<array offset="0x408000" name="PGRAPH_TP" stride="0x1000" length="8" variants="NV50:NVA0"> 6337ec681f3Smrg <array offset="0x200" name="MP" stride="0x80" length="2"> 6347ec681f3Smrg <use-group name="nv50_mp" /> 6357ec681f3Smrg </array> 6367ec681f3Smrg <!-- ... --> 6377ec681f3Smrg</array> 6387ec681f3Smrg<array offset="0x408000" name="PGRAPH_TP" stride="0x800" length="10" variants="NVA0-"> 6397ec681f3Smrg <array offset="0x100" name="MP" stride="0x80" length="4"> 6407ec681f3Smrg <use-group name="nv50_mp" /> 6417ec681f3Smrg </array> 6427ec681f3Smrg <!-- ... --> 6437ec681f3Smrg</array> 6447ec681f3Smrg 6457ec681f3SmrgWill get you: 6467ec681f3Smrg 6477ec681f3Smrg#define NV50_PGRAPH_TP_MP_TRAPPED_OPCODE(i, j) (0x408270 + (i)*0x1000 + (j)*0x80) 6487ec681f3Smrg#define NVA0_PGRAPH_TP_MP_TRAPPED_OPCODE(i, j) (0x408170 + (i)*0x800 + (j)*0x80) 6497ec681f3Smrg 6507ec681f3Smrg3. The utilities. 6517ec681f3Smrg 6527ec681f3SmrgThe header generation utility will take a set of XML files and generate .h 6537ec681f3Smrgfile with all of their definitions, as defined above. 6547ec681f3Smrg 6557ec681f3SmrgThe HTML generation utilty will take an XML file and generate HTML 6567ec681f3Smrgdocumentation out of it. The documentation will include the <brief> and <doc> 6577ec681f3Smrgtags in some way, as well as information from all the attributes, in some easy 6587ec681f3Smrgto read format. Some naming scheme for the HTML files should be decided, so 6597ec681f3Smrgthat cross-refs to HTML documentation generated for <import>ed files will work 6607ec681f3Smrgcorrectly if the generator is run in both. 6617ec681f3Smrg 6627ec681f3SmrgThe lookup utility will perform database lookups of the following types: 6637ec681f3Smrg 6647ec681f3Smrg - domain name, offset, access type, variant type[s] -> register name + array 6657ec681f3Smrg indices if applicable 6667ec681f3Smrg - the above + register value -> same as above + decoded value. For registers 6677ec681f3Smrg with bitfields, print all bitfields, and indicate if any bits not covered 6687ec681f3Smrg by the bitfields are set to 1. For registers/bitfields with enum values, 6697ec681f3Smrg print the matching one if any. For remaining registers/bitfields, print 6707ec681f3Smrg according to type attribute. 6717ec681f3Smrg - bitset name + value -> decoded value, as above 6727ec681f3Smrg - enum name + value -> decoded value, as above 6737ec681f3Smrg 6747ec681f3SmrgThe mmio-parse utility will parse a mmio-trace file and apply the second kind 6757ec681f3Smrgof database lookups to all memory accesses matching a given range. Some 6767ec681f3Smrgnv-specific hacks will be in order to automate the parsing: extract the 6777ec681f3Smrgchipset from PMC_BOOT_0, figure out the mmio base from PCI config, etc. 6787ec681f3Smrg 6797ec681f3SmrgThe renouveau-parse utility will take contents of a PFIFO pushbuffer and 6807ec681f3Smrgdecode them. The splitting to method,data pair will be done by nv-specific 6817ec681f3Smrgcode, then the pair will be handed over to generic rules-ng lookup. 6827ec681f3Smrg 6837ec681f3Smrg4. Issues 6847ec681f3Smrg 6857ec681f3Smrg - Random typing-saving feature for bitfields: make high default to same value 6867ec681f3Smrg as low, to have one less attribute for single-bit bitfields? 6877ec681f3Smrg 6887ec681f3Smrg - What about allowing nameless registers and/or bitfields? These are 6897ec681f3Smrg supported by renouveau.xml and are used commonly to signify an unknown 6907ec681f3Smrg register. 6917ec681f3Smrg 6927ec681f3Smrg - How about cross-ref links in <doc> tags? 6937ec681f3Smrg 6947ec681f3Smrg - <translation>: do we need them? Sounds awesome and useful, but as defined 6957ec681f3Smrg by the old spec, they're quite limited. The only examples of straight 6967ec681f3Smrg translations that I know of are the legacy VGA registers and 6977ec681f3Smrg NV50_PFB_VM_TRAP. And NV01_PDAC, but I doubt anybody gives a damn about it. 6987ec681f3Smrg This list is small enough to be just handled by nv-specific hacks in 6997ec681f3Smrg mmio-trace parser if really needed. 7007ec681f3Smrg 7017ec681f3Smrg - Another thing that renouveau.xml does is disassembling NV20-NV40 shaders. 7027ec681f3Smrg Do we want that in rules-ng? IMO we'd be better off hacking nv50dis to 7037ec681f3Smrg support it... 704