17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2016 Intel Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg#ifndef INTEL_DECODER_H
257ec681f3Smrg#define INTEL_DECODER_H
267ec681f3Smrg
277ec681f3Smrg#include <stdint.h>
287ec681f3Smrg#include <stdbool.h>
297ec681f3Smrg#include <stdio.h>
307ec681f3Smrg
317ec681f3Smrg#include "dev/intel_device_info.h"
327ec681f3Smrg#include "util/hash_table.h"
337ec681f3Smrg#include "util/bitset.h"
347ec681f3Smrg
357ec681f3Smrg#include "drm-uapi/i915_drm.h"
367ec681f3Smrg
377ec681f3Smrg#ifdef __cplusplus
387ec681f3Smrgextern "C" {
397ec681f3Smrg#endif
407ec681f3Smrg
417ec681f3Smrgstruct intel_spec;
427ec681f3Smrgstruct intel_group;
437ec681f3Smrgstruct intel_field;
447ec681f3Smrgunion intel_field_value;
457ec681f3Smrg
467ec681f3Smrg#define I915_ENGINE_CLASS_TO_MASK(x) BITSET_BIT(x)
477ec681f3Smrg
487ec681f3Smrgstatic inline uint32_t intel_make_gen(uint32_t major, uint32_t minor)
497ec681f3Smrg{
507ec681f3Smrg   return (major << 8) | minor;
517ec681f3Smrg}
527ec681f3Smrg
537ec681f3Smrgstruct intel_group *intel_spec_find_struct(struct intel_spec *spec, const char *name);
547ec681f3Smrgstruct intel_spec *intel_spec_load(const struct intel_device_info *devinfo);
557ec681f3Smrgstruct intel_spec *
567ec681f3Smrgintel_spec_load_from_path(const struct intel_device_info *devinfo,
577ec681f3Smrg                          const char *path);
587ec681f3Smrgstruct intel_spec *intel_spec_load_filename(const char *filename);
597ec681f3Smrgvoid intel_spec_destroy(struct intel_spec *spec);
607ec681f3Smrguint32_t intel_spec_get_gen(struct intel_spec *spec);
617ec681f3Smrgstruct intel_group *intel_spec_find_instruction(struct intel_spec *spec,
627ec681f3Smrg                                                enum drm_i915_gem_engine_class engine,
637ec681f3Smrg                                                const uint32_t *p);
647ec681f3Smrgstruct intel_group *intel_spec_find_register(struct intel_spec *spec, uint32_t offset);
657ec681f3Smrgstruct intel_group *intel_spec_find_register_by_name(struct intel_spec *spec, const char *name);
667ec681f3Smrgstruct intel_enum *intel_spec_find_enum(struct intel_spec *spec, const char *name);
677ec681f3Smrg
687ec681f3Smrgint intel_group_get_length(struct intel_group *group, const uint32_t *p);
697ec681f3Smrgconst char *intel_group_get_name(struct intel_group *group);
707ec681f3Smrguint32_t intel_group_get_opcode(struct intel_group *group);
717ec681f3Smrgstruct intel_field *intel_group_find_field(struct intel_group *group, const char *name);
727ec681f3Smrgstruct intel_enum *intel_spec_find_enum(struct intel_spec *spec, const char *name);
737ec681f3Smrg
747ec681f3Smrgbool intel_field_is_header(struct intel_field *field);
757ec681f3Smrg
767ec681f3Smrg/* Only allow 5 levels of subgroup'ing
777ec681f3Smrg */
787ec681f3Smrg#define DECODE_MAX_ARRAY_DEPTH 5
797ec681f3Smrg
807ec681f3Smrgstruct intel_field_iterator {
817ec681f3Smrg   struct intel_group *group;
827ec681f3Smrg   char name[128];
837ec681f3Smrg   char value[128];
847ec681f3Smrg   uint64_t raw_value;
857ec681f3Smrg   struct intel_group *struct_desc;
867ec681f3Smrg   const uint32_t *p;
877ec681f3Smrg   int p_bit; /**< bit offset into p */
887ec681f3Smrg   const uint32_t *p_end;
897ec681f3Smrg   int start_bit; /**< current field starts at this bit offset into p */
907ec681f3Smrg   int end_bit; /**< current field ends at this bit offset into p */
917ec681f3Smrg
927ec681f3Smrg   struct intel_field *fields[DECODE_MAX_ARRAY_DEPTH];
937ec681f3Smrg   struct intel_group *groups[DECODE_MAX_ARRAY_DEPTH];
947ec681f3Smrg   int array_iter[DECODE_MAX_ARRAY_DEPTH];
957ec681f3Smrg   int level;
967ec681f3Smrg
977ec681f3Smrg   struct intel_field *field;
987ec681f3Smrg   bool print_colors;
997ec681f3Smrg};
1007ec681f3Smrg
1017ec681f3Smrgstruct intel_spec {
1027ec681f3Smrg   uint32_t gen;
1037ec681f3Smrg
1047ec681f3Smrg   struct hash_table *commands;
1057ec681f3Smrg   struct hash_table *structs;
1067ec681f3Smrg   struct hash_table *registers_by_name;
1077ec681f3Smrg   struct hash_table *registers_by_offset;
1087ec681f3Smrg   struct hash_table *enums;
1097ec681f3Smrg
1107ec681f3Smrg   struct hash_table *access_cache;
1117ec681f3Smrg};
1127ec681f3Smrg
1137ec681f3Smrgstruct intel_group {
1147ec681f3Smrg   struct intel_spec *spec;
1157ec681f3Smrg   char *name;
1167ec681f3Smrg
1177ec681f3Smrg   struct intel_field *fields; /* linked list of fields */
1187ec681f3Smrg   struct intel_field *dword_length_field; /* <instruction> specific */
1197ec681f3Smrg
1207ec681f3Smrg   uint32_t dw_length;
1217ec681f3Smrg   uint32_t engine_mask; /* <instruction> specific */
1227ec681f3Smrg   uint32_t bias; /* <instruction> specific */
1237ec681f3Smrg   uint32_t array_offset; /* <group> specific */
1247ec681f3Smrg   uint32_t array_count; /* number of elements, <group> specific */
1257ec681f3Smrg   uint32_t array_item_size; /* <group> specific */
1267ec681f3Smrg   bool variable; /* <group> specific */
1277ec681f3Smrg   bool fixed_length; /* True for <struct> & <register> */
1287ec681f3Smrg
1297ec681f3Smrg   struct intel_group *parent;
1307ec681f3Smrg   struct intel_group *next;
1317ec681f3Smrg
1327ec681f3Smrg   uint32_t opcode_mask;
1337ec681f3Smrg   uint32_t opcode;
1347ec681f3Smrg
1357ec681f3Smrg   uint32_t register_offset; /* <register> specific */
1367ec681f3Smrg};
1377ec681f3Smrg
1387ec681f3Smrgstruct intel_value {
1397ec681f3Smrg   char *name;
1407ec681f3Smrg   uint64_t value;
1417ec681f3Smrg};
1427ec681f3Smrg
1437ec681f3Smrgstruct intel_enum {
1447ec681f3Smrg   char *name;
1457ec681f3Smrg   int nvalues;
1467ec681f3Smrg   struct intel_value **values;
1477ec681f3Smrg};
1487ec681f3Smrg
1497ec681f3Smrgstruct intel_type {
1507ec681f3Smrg   enum {
1517ec681f3Smrg      INTEL_TYPE_UNKNOWN,
1527ec681f3Smrg      INTEL_TYPE_INT,
1537ec681f3Smrg      INTEL_TYPE_UINT,
1547ec681f3Smrg      INTEL_TYPE_BOOL,
1557ec681f3Smrg      INTEL_TYPE_FLOAT,
1567ec681f3Smrg      INTEL_TYPE_ADDRESS,
1577ec681f3Smrg      INTEL_TYPE_OFFSET,
1587ec681f3Smrg      INTEL_TYPE_STRUCT,
1597ec681f3Smrg      INTEL_TYPE_UFIXED,
1607ec681f3Smrg      INTEL_TYPE_SFIXED,
1617ec681f3Smrg      INTEL_TYPE_MBO,
1627ec681f3Smrg      INTEL_TYPE_ENUM
1637ec681f3Smrg   } kind;
1647ec681f3Smrg
1657ec681f3Smrg   /* Struct definition for  INTEL_TYPE_STRUCT */
1667ec681f3Smrg   union {
1677ec681f3Smrg      struct intel_group *intel_struct;
1687ec681f3Smrg      struct intel_enum *intel_enum;
1697ec681f3Smrg      struct {
1707ec681f3Smrg         /* Integer and fractional sizes for INTEL_TYPE_UFIXED and INTEL_TYPE_SFIXED */
1717ec681f3Smrg         int i, f;
1727ec681f3Smrg      };
1737ec681f3Smrg   };
1747ec681f3Smrg};
1757ec681f3Smrg
1767ec681f3Smrgunion intel_field_value {
1777ec681f3Smrg   bool b32;
1787ec681f3Smrg   float f32;
1797ec681f3Smrg   uint64_t u64;
1807ec681f3Smrg   int64_t i64;
1817ec681f3Smrg};
1827ec681f3Smrg
1837ec681f3Smrgstruct intel_field {
1847ec681f3Smrg   struct intel_group *parent;
1857ec681f3Smrg   struct intel_field *next;
1867ec681f3Smrg   struct intel_group *array;
1877ec681f3Smrg
1887ec681f3Smrg   char *name;
1897ec681f3Smrg   int start, end;
1907ec681f3Smrg   struct intel_type type;
1917ec681f3Smrg   bool has_default;
1927ec681f3Smrg   uint32_t default_value;
1937ec681f3Smrg
1947ec681f3Smrg   struct intel_enum inline_enum;
1957ec681f3Smrg};
1967ec681f3Smrg
1977ec681f3Smrgvoid intel_field_iterator_init(struct intel_field_iterator *iter,
1987ec681f3Smrg                               struct intel_group *group,
1997ec681f3Smrg                               const uint32_t *p, int p_bit,
2007ec681f3Smrg                               bool print_colors);
2017ec681f3Smrg
2027ec681f3Smrgbool intel_field_iterator_next(struct intel_field_iterator *iter);
2037ec681f3Smrg
2047ec681f3Smrgvoid intel_print_group(FILE *out,
2057ec681f3Smrg                       struct intel_group *group,
2067ec681f3Smrg                       uint64_t offset, const uint32_t *p, int p_bit,
2077ec681f3Smrg                       bool color);
2087ec681f3Smrg
2097ec681f3Smrgenum intel_batch_decode_flags {
2107ec681f3Smrg   /** Print in color! */
2117ec681f3Smrg   INTEL_BATCH_DECODE_IN_COLOR  = (1 << 0),
2127ec681f3Smrg   /** Print everything, not just headers */
2137ec681f3Smrg   INTEL_BATCH_DECODE_FULL      = (1 << 1),
2147ec681f3Smrg   /** Print offsets along with the batch */
2157ec681f3Smrg   INTEL_BATCH_DECODE_OFFSETS   = (1 << 2),
2167ec681f3Smrg   /** Guess when a value is a float and print it as such */
2177ec681f3Smrg   INTEL_BATCH_DECODE_FLOATS    = (1 << 3),
2187ec681f3Smrg};
2197ec681f3Smrg
2207ec681f3Smrgstruct intel_batch_decode_bo {
2217ec681f3Smrg   uint64_t addr;
2227ec681f3Smrg   uint32_t size;
2237ec681f3Smrg   const void *map;
2247ec681f3Smrg};
2257ec681f3Smrg
2267ec681f3Smrgstruct intel_batch_decode_ctx {
2277ec681f3Smrg   /**
2287ec681f3Smrg    * Return information about the buffer containing the given address.
2297ec681f3Smrg    *
2307ec681f3Smrg    * If the given address is inside a buffer, the map pointer should be
2317ec681f3Smrg    * offset accordingly so it points at the data corresponding to address.
2327ec681f3Smrg    */
2337ec681f3Smrg   struct intel_batch_decode_bo (*get_bo)(void *user_data, bool ppgtt, uint64_t address);
2347ec681f3Smrg   unsigned (*get_state_size)(void *user_data,
2357ec681f3Smrg                              uint64_t address,
2367ec681f3Smrg                              uint64_t base_address);
2377ec681f3Smrg   void *user_data;
2387ec681f3Smrg
2397ec681f3Smrg   FILE *fp;
2407ec681f3Smrg   struct intel_device_info devinfo;
2417ec681f3Smrg   struct intel_spec *spec;
2427ec681f3Smrg   enum intel_batch_decode_flags flags;
2437ec681f3Smrg
2447ec681f3Smrg   bool use_256B_binding_tables;
2457ec681f3Smrg   uint64_t surface_base;
2467ec681f3Smrg   uint64_t bt_pool_base;
2477ec681f3Smrg   uint64_t dynamic_base;
2487ec681f3Smrg   uint64_t instruction_base;
2497ec681f3Smrg
2507ec681f3Smrg   int max_vbo_decoded_lines;
2517ec681f3Smrg
2527ec681f3Smrg   enum drm_i915_gem_engine_class engine;
2537ec681f3Smrg
2547ec681f3Smrg   int n_batch_buffer_start;
2557ec681f3Smrg   uint64_t acthd;
2567ec681f3Smrg};
2577ec681f3Smrg
2587ec681f3Smrgvoid intel_batch_decode_ctx_init(struct intel_batch_decode_ctx *ctx,
2597ec681f3Smrg                                 const struct intel_device_info *devinfo,
2607ec681f3Smrg                                 FILE *fp, enum intel_batch_decode_flags flags,
2617ec681f3Smrg                                 const char *xml_path,
2627ec681f3Smrg                                 struct intel_batch_decode_bo (*get_bo)(void *,
2637ec681f3Smrg                                                                        bool,
2647ec681f3Smrg                                                                        uint64_t),
2657ec681f3Smrg                                 unsigned (*get_state_size)(void *, uint64_t,
2667ec681f3Smrg                                                            uint64_t),
2677ec681f3Smrg                                 void *user_data);
2687ec681f3Smrgvoid intel_batch_decode_ctx_finish(struct intel_batch_decode_ctx *ctx);
2697ec681f3Smrg
2707ec681f3Smrg
2717ec681f3Smrgvoid intel_print_batch(struct intel_batch_decode_ctx *ctx,
2727ec681f3Smrg                       const uint32_t *batch, uint32_t batch_size,
2737ec681f3Smrg                       uint64_t batch_addr, bool from_ring);
2747ec681f3Smrg
2757ec681f3Smrg#ifdef __cplusplus
2767ec681f3Smrg}
2777ec681f3Smrg#endif
2787ec681f3Smrg
2797ec681f3Smrg
2807ec681f3Smrg#endif /* INTEL_DECODER_H */
281