diff options
author | Tom St Denis <tom.stdenis@amd.com> | 2019-01-24 10:58:43 -0500 |
---|---|---|
committer | Tom St Denis <tom.stdenis@amd.com> | 2019-01-24 10:59:54 -0500 |
commit | 0c1f34137484a620f5fc2aa6e1dcdd99898f40b5 (patch) | |
tree | acf9bcb7d9ad11f306e5fa39f03f6df246e393db | |
parent | 8e585c8945b10e50cf0f931ece6a2d66d9452bf7 (diff) |
Update and add PM4/SDMA stream opcode decoding documentation
Signed-off-by: Tom St Denis <tom.stdenis@amd.com>
-rw-r--r-- | doc/sphinx/source/libpm4_stream.rst | 71 | ||||
-rw-r--r-- | doc/sphinx/source/libsdma_stream.rst | 129 | ||||
-rw-r--r-- | doc/sphinx/source/libumr_api.rst | 1 | ||||
-rw-r--r-- | src/umr.h | 1 |
4 files changed, 201 insertions, 1 deletions
diff --git a/doc/sphinx/source/libpm4_stream.rst b/doc/sphinx/source/libpm4_stream.rst index 50eceed..7dbd683 100644 --- a/doc/sphinx/source/libpm4_stream.rst +++ b/doc/sphinx/source/libpm4_stream.rst @@ -102,3 +102,74 @@ will not free these copies. } src; }; +--------------- +Packet Decoding +--------------- + +To decode packets the following function is used: + +:: + + struct umr_pm4_stream *umr_pm4_decode_stream_opcodes(struct umr_asic *asic, struct umr_pm4_stream_decode_ui *ui, struct umr_pm4_stream *stream, + uint64_t ib_addr, uint32_t ib_vmid, uint64_t from_addr, uint64_t from_vmid, + unsigned long opcodes, int follow); + +The function takes an already streamed PM4 structure and proceeds to decode the packets and the internal fields. The ib_addr/ib_vmid reference the address of the packets being +decoded while the from_addr/from_vmid point to any stream that pointed to this data (e.g. the ring offset that points to this IB). The 'opcodes' parameter +indicates how many opcodes to decode (set to ~0UL for the entire stream). The 'follow' parameter indicates whether the function should also decode packets from IBs pointed +to by this stream. + +It returns the address of the first undecoded packet in the stream. + +The function uses the following callback structure to pass information back to the caller: + +:: + + struct umr_pm4_stream_decode_ui { + + /** start_ib -- Start a new IB + * ib_addr/ib_vmid: Address of the IB + * from_addr/from_vmid: Where does this reference come from? + * size: size of IB in DWORDs + * type: type of IB (which type of packets + */ + void (*start_ib)(struct umr_pm4_stream_decode_ui *ui, uint64_t ib_addr, uint32_t ib_vmid, uint64_t from_addr, uint32_t from_vmid, uint32_t size, int type); + + /** start_opcode -- Start a new opcode + * ib_addr/ib_vmid: Address of where packet is found + * opcode: The numeric value of the ocpode + * nwords: number of DWORDS in this opcode + * opcode_name: Printable string name of opcode + */ + void (*start_opcode)(struct umr_pm4_stream_decode_ui *ui, uint64_t ib_addr, uint32_t ib_vmid, int pkttype, uint32_t opcode, uint32_t nwords, char *opcode_name); + + /** add_field -- Add a decoded field to a specific DWORD + * ib_addr/ib_vmid: Address of the word from which the field comes + * field_name: printable name of the field + * value: Value of the field + * ideal_radix: (10 decimal, 16 hex) + */ + void (*add_field)(struct umr_pm4_stream_decode_ui *ui, uint64_t ib_addr, uint32_t ib_vmid, const char *field_name, uint64_t value, char *str, int ideal_radix); + + /** add_shader -- Add a reference to a shader found in the IB stream + * ib_addr/ib_vmid: Address of where reference comes from + * asic: The ASIC the IB stream and shader are bound to + * shader: The shader reference + */ + void (*add_shader)(struct umr_pm4_stream_decode_ui *ui, struct umr_asic *asic, uint64_t ib_addr, uint32_t ib_vmid, struct umr_shaders_pgm *shader); + + /** unhandled -- Decoder for unhandled (private) opcodes + * asic: The ASIC the IB stream is bound to + * ib_addr:ib_vmid: The address where the PM4 opcode comes from + * stream: The pointer to the current stream opcode being handled + * + * Can be NULL to drop support for unhandled opcodes. + */ + void (*unhandled)(struct umr_pm4_stream_decode_ui *ui, struct umr_asic *asic, uint64_t ib_addr, uint32_t ib_vmid, struct umr_pm4_stream *stream); + + void (*done)(struct umr_pm4_stream_decode_ui *ui); + + /** data -- opaque pointer that can be used to track state information */ + void *data; + }; + diff --git a/doc/sphinx/source/libsdma_stream.rst b/doc/sphinx/source/libsdma_stream.rst new file mode 100644 index 0000000..d668b8a --- /dev/null +++ b/doc/sphinx/source/libsdma_stream.rst @@ -0,0 +1,129 @@ +==================== +SDMA Stream Decoding +==================== + +The UMR library has the ability to read rings into a linked list +of SDMA packets with pointers to indirect buffers (IBs) and shaders. + +------------------ +SDMA Decode a Ring +------------------ + +To decode a ring into a stream the following function can be used: + +:: + + struct umr_sdma_stream *umr_sdma_decode_ring(struct umr_asic *asic, char *ringname); + +Which will decode the ring named by ringname and return a pointer to +the following structure if successful: + +:: + + /* SDMA decoding */ + struct umr_sdma_stream { + uint32_t + opcode, + sub_opcode, + nwords, + header_dw, + *words; + + struct { + uint32_t vmid, size; + uint64_t addr; + } ib; + + struct umr_sdma_stream *next, *next_ib; + }; + +Adjacent SDMA packets are pointed to by 'next' (NULL terminated) and +any IBs that are found are pointed to by 'next_ib'. + +-------------------- +SDMA Decode a Buffer +-------------------- + +To decode a SDMA stream inside a user buffer the following function +can be used: + +:: + + struct umr_sdma_stream *umr_sdma_decode_stream(struct umr_asic *asic, int vmid, uint32_t *stream, uint32_t nwords); + +This will return a structure pointer if successful. + + +---------------------- +Freeing an SDMA Stream +---------------------- + +An SDMA stream can be freed with the following function: + +:: + + void umr_free_sdma_stream(struct umr_sdma_stream *stream); + +--------------- +Packet Decoding +--------------- + +To decode packets the following function is used: + +:: + + struct umr_sdma_stream *umr_sdma_decode_stream_opcodes(struct umr_asic *asic, struct umr_sdma_stream_decode_ui *ui, struct umr_sdma_stream *stream, + uint64_t ib_addr, uint32_t ib_vmid, uint64_t from_addr, uint64_t from_vmid, + unsigned long opcodes, int follow); + +The function takes an already streamed SDMA structure and proceeds to decode the packets and the internal fields. The ib_addr/ib_vmid reference the address of the packets being +decoded while the from_addr/from_vmid point to any stream that pointed to this data (e.g. the ring offset that points to this IB). The 'opcodes' parameter +indicates how many opcodes to decode (set to ~0UL for the entire stream). The 'follow' parameter indicates whether the function should also decode packets from IBs pointed +to by this stream. + +It returns the address of the first undecoded packet in the stream. + +The function uses the following callback structure to pass information back to the caller: + +:: + + struct umr_sdma_stream_decode_ui { + + /** start_ib -- Start a new IB + * ib_addr/ib_vmid: Address of the IB + * from_addr/from_vmid: Where does this reference come from? + * size: size of IB in DWORDs + */ + void (*start_ib)(struct umr_sdma_stream_decode_ui *ui, uint64_t ib_addr, uint32_t ib_vmid, uint64_t from_addr, uint32_t from_vmid, uint32_t size); + + /** start_opcode -- Start a new opcode + * ib_addr/ib_vmid: Address of where packet is found + * opcode: The numeric value of the ocpode + * nwords: number of DWORDS in this opcode + * opcode_name: Printable string name of opcode + */ + void (*start_opcode)(struct umr_sdma_stream_decode_ui *ui, uint64_t ib_addr, uint32_t ib_vmid, uint32_t opcode, uint32_t sub_opcode, uint32_t nwords, char *opcode_name); + + /** add_field -- Add a decoded field to a specific DWORD + * ib_addr/ib_vmid: Address of the word from which the field comes + * field_name: printable name of the field + * value: Value of the field + * ideal_radix: (10 decimal, 16 hex) + */ + void (*add_field)(struct umr_sdma_stream_decode_ui *ui, uint64_t ib_addr, uint32_t ib_vmid, const char *field_name, uint64_t value, char *str, int ideal_radix); + + /** unhandled -- Decoder for unhandled (private) opcodes + * asic: The ASIC the IB stream is bound to + * ib_addr:ib_vmid: The address where the sdma opcode comes from + * stream: The pointer to the current stream opcode being handled + * + * Can be NULL to drop support for unhandled opcodes. + */ + void (*unhandled)(struct umr_sdma_stream_decode_ui *ui, struct umr_asic *asic, uint64_t ib_addr, uint32_t ib_vmid, struct umr_sdma_stream *stream); + + void (*done)(struct umr_sdma_stream_decode_ui *ui); + + /** data -- opaque pointer that can be used to track state information */ + void *data; + }; + diff --git a/doc/sphinx/source/libumr_api.rst b/doc/sphinx/source/libumr_api.rst index f2a569f..891110e 100644 --- a/doc/sphinx/source/libumr_api.rst +++ b/doc/sphinx/source/libumr_api.rst @@ -14,3 +14,4 @@ libumrcore.a: API Documentation libhalt_waves libwave_status libpm4_stream + libsdma_stream @@ -706,7 +706,6 @@ struct umr_shaders_pgm *umr_find_shader_in_stream(struct umr_pm4_stream *stream, struct umr_shaders_pgm *umr_find_shader_in_ring(struct umr_asic *asic, char *ringname, unsigned vmid, uint64_t addr, int no_halt); int umr_pm4_decode_ring_is_halted(struct umr_asic *asic, char *ringname); - // PM4 decoding library struct umr_pm4_stream_decode_ui { |