[Mesa-dev] [PATCH v3] aubinator: Fix the decoding of values that span two Dwords

Anuj Phogat anuj.phogat at gmail.com
Tue Sep 20 23:08:13 UTC 2016


On Tue, Sep 20, 2016 at 3:59 PM, Sirisha Gandikota
<sirisha.gandikota at intel.com> wrote:
> From: Sirisha Gandikota <Sirisha.Gandikota at intel.com>
>
> Fixed the way the values that span two Dwords are decoded.
> Based on the start and end indices of the field, the Dwords
> are fetched and decoded accordingly.
>
> v2: rename dw to qw in gen_field_iterator_next
> and remove extra white space (Anuj)
>
> v3: change all instances of dw to qw (Anuj)
>
> Earlier, 64-bit fields (such as most pointers on Gen8+)
> weren't decoded correctly.  gen_field_iterator_next seemed
> to walk one DWord at a time, sets v.dw, and then passes it
> to field(). So, even though field() takes a uint64_t, we're
> passing it a uint32_t (which gets promoted, so the top 32
> bits will always be zero). This seems pretty bogus... (Ken)
>
> Signed-off-by: Sirisha Gandikota <Sirisha.Gandikota at intel.com>
> ---
>  src/intel/tools/decoder.c | 50 +++++++++++++++++++++++++++++++++++------------
>  1 file changed, 37 insertions(+), 13 deletions(-)
>
> diff --git a/src/intel/tools/decoder.c b/src/intel/tools/decoder.c
> index b5f557c..be3558b 100644
> --- a/src/intel/tools/decoder.c
> +++ b/src/intel/tools/decoder.c
> @@ -191,6 +191,26 @@ get_register_offset(const char **atts, uint32_t *offset)
>     return;
>  }
>
> +static void
> +get_start_end_pos(int *start, int *end)
> +{
> +   /* start value has to be mod with 32 as we need the relative
> +    * start position in the first DWord. For the end position, add
> +    * the length of the field to the start position to get the
> +    * relative postion in the 64 bit address.
> +    */
> +   if (*end - *start > 32) {
> +      int len = *end - *start;
> +      *start = *start % 32;
> +      *end = *start + len;
> +   } else {
> +      *start = *start % 32;
> +      *end = *end % 32;
> +   }
> +
> +   return;
> +}
> +
>  static inline uint64_t
>  mask(int start, int end)
>  {
> @@ -204,18 +224,16 @@ mask(int start, int end)
>  static inline uint64_t
>  field(uint64_t value, int start, int end)
>  {
> -   /* The field values are obtained from the DWord,
> -    * Hence, get the relative start and end positions
> -    * by doing a %32 on the start and end positions
> -    */
> -   return (value & mask(start % 32, end % 32)) >> (start % 32);
> +   get_start_end_pos(&start, &end);
> +   return (value & mask(start, end)) >> (start);
>  }
>
>  static inline uint64_t
>  field_address(uint64_t value, int start, int end)
>  {
>     /* no need to right shift for address/offset */
> -   return (value & mask(start % 32, end % 32));
> +   get_start_end_pos(&start, &end);
> +   return (value & mask(start, end));
>  }
>
>  static struct gen_type
> @@ -491,7 +509,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
>  {
>     struct gen_field *f;
>     union {
> -      uint32_t dw;
> +      uint64_t qw;
>        float f;
>     } v;
>
> @@ -500,20 +518,26 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
>
>     f = iter->group->fields[iter->i++];
>     iter->name = f->name;
> -   v.dw = iter->p[f->start / 32];
> +   int index = f->start / 32;
> +
> +   if ((f->end - f->start) > 32)
> +      v.qw = ((uint64_t) iter->p[index+1] << 32) | iter->p[index];
> +   else
> +      v.qw = iter->p[index];
> +
>     switch (f->type.kind) {
>     case GEN_TYPE_UNKNOWN:
>     case GEN_TYPE_INT:
>        snprintf(iter->value, sizeof(iter->value),
> -               "%ld", field(v.dw, f->start, f->end));
> +               "%ld", field(v.qw, f->start, f->end));
>        break;
>     case GEN_TYPE_UINT:
>        snprintf(iter->value, sizeof(iter->value),
> -               "%lu", field(v.dw, f->start, f->end));
> +               "%lu", field(v.qw, f->start, f->end));
>        break;
>     case GEN_TYPE_BOOL:
>        snprintf(iter->value, sizeof(iter->value),
> -               "%s", field(v.dw, f->start, f->end) ? "true" : "false");
> +               "%s", field(v.qw, f->start, f->end) ? "true" : "false");
>        break;
>     case GEN_TYPE_FLOAT:
>        snprintf(iter->value, sizeof(iter->value), "%f", v.f);
> @@ -521,7 +545,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
>     case GEN_TYPE_ADDRESS:
>     case GEN_TYPE_OFFSET:
>        snprintf(iter->value, sizeof(iter->value),
> -               "0x%08lx", field_address(v.dw, f->start, f->end));
> +               "0x%08lx", field_address(v.qw, f->start, f->end));
>        break;
>     case GEN_TYPE_STRUCT:
>        snprintf(iter->value, sizeof(iter->value),
> @@ -529,7 +553,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
>        break;
>     case GEN_TYPE_UFIXED:
>        snprintf(iter->value, sizeof(iter->value),
> -               "%f", (float) field(v.dw, f->start, f->end) / (1 << f->type.f));
> +               "%f", (float) field(v.qw, f->start, f->end) / (1 << f->type.f));
>        break;
>     case GEN_TYPE_SFIXED:
>        /* FIXME: Sign extend extracted field. */
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>


More information about the mesa-dev mailing list