intel: gen-decoder: don't decode fields beyond a dword length

For example, a PIPE_CONTROL with DWordLength = 2 should look like
this :

0xffffe374:  0x7a000002:  PIPE_CONTROL
0xffffe374:  0x7a000002 : Dword 0
    DWord Length: 2
0xffffe378:  0x00800000 : Dword 1
    Depth Cache Flush Enable: false
    Stall At Pixel Scoreboard: false
    State Cache Invalidation Enable: false
    Constant Cache Invalidation Enable: false
    VF Cache Invalidation Enable: false
    DC Flush Enable: false
    Pipe Control Flush Enable: false
    Notify Enable: false
    Indirect State Pointers Disable: false
    Texture Cache Invalidation Enable: false
    Instruction Cache Invalidate Enable: false
    Render Target Cache Flush Enable: false
    Depth Stall Enable: false
    Post Sync Operation: 0 (No Write)
    Generic Media State Clear: false
    TLB Invalidate: false
    Global Snapshot Count Reset: false
    Command Streamer Stall Enable: false
    Store Data Index: 0
    LRI Post Sync Operation: 1 (MMIO Write Immediate Data)
    Destination Address Type: 0 (PPGTT)
    Flush LLC: false
0xffffe37c:  0x00000000 : Dword 2
    Address: 0x00000000
0xffffe384:  0x05000000:  MI_BATCH_BUFFER_END

Prior to this change, fields beyond the length of the command would be
decoded (notice the MI_BATCH_BUFFER_END decoded as part of the
previous PIPE_CONTROL) :

0xffffe374:  0x7a000002:  PIPE_CONTROL
0xffffe374:  0x7a000002 : Dword 0
    DWord Length: 2
0xffffe378:  0x00800000 : Dword 1
    Depth Cache Flush Enable: false
    Stall At Pixel Scoreboard: false
    State Cache Invalidation Enable: false
    Constant Cache Invalidation Enable: false
    VF Cache Invalidation Enable: false
    DC Flush Enable: false
    Pipe Control Flush Enable: false
    Notify Enable: false
    Indirect State Pointers Disable: false
    Texture Cache Invalidation Enable: false
    Instruction Cache Invalidate Enable: false
    Render Target Cache Flush Enable: false
    Depth Stall Enable: false
    Post Sync Operation: 0 (No Write)
    Generic Media State Clear: false
    TLB Invalidate: false
    Global Snapshot Count Reset: false
    Command Streamer Stall Enable: false
    Store Data Index: 0
    LRI Post Sync Operation: 1 (MMIO Write Immediate Data)
    Destination Address Type: 0 (PPGTT)
    Flush LLC: false
0xffffe37c:  0x00000000 : Dword 2
    Address: 0x00000000
0xffffe380:  0x00000000 : Dword 3
0xffffe384:  0x05000000 : Dword 4
    Immediate Data: 83886080
0xffffe384:  0x05000000:  MI_BATCH_BUFFER_END

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Scott D Phillips <scott.d.phillips@intel.com>
This commit is contained in:
Lionel Landwerlin 2018-04-03 11:01:56 +01:00
parent 81375516b2
commit 2841af6238

View file

@ -847,35 +847,38 @@ iter_advance_field(struct gen_field_iterator *iter)
return true;
}
static uint64_t
iter_decode_field_raw(struct gen_field_iterator *iter)
static bool
iter_decode_field_raw(struct gen_field_iterator *iter, uint64_t *qw)
{
uint64_t qw = 0;
*qw = 0;
int field_start = iter->p_bit + iter->bit;
int field_end = field_start + (iter->field->end - iter->field->start);
const uint32_t *p = iter->p + (iter->bit / 32);
if ((field_end - field_start) > 32) {
if ((p + 1) < iter->p_end)
qw = ((uint64_t) p[1]) << 32;
qw |= p[0];
} else
qw = p[0];
if (iter->p_end && p >= iter->p_end)
return false;
qw = field_value(qw, field_start, field_end);
if ((field_end - field_start) > 32) {
if (!iter->p_end || (p + 1) < iter->p_end)
*qw = ((uint64_t) p[1]) << 32;
*qw |= p[0];
} else
*qw = p[0];
*qw = field_value(*qw, field_start, field_end);
/* Address & offset types have to be aligned to dwords, their start bit is
* a reminder of the alignment requirement.
*/
if (iter->field->type.kind == GEN_TYPE_ADDRESS ||
iter->field->type.kind == GEN_TYPE_OFFSET)
qw <<= field_start % 32;
*qw <<= field_start % 32;
return qw;
return true;
}
static void
static bool
iter_decode_field(struct gen_field_iterator *iter)
{
union {
@ -890,7 +893,8 @@ iter_decode_field(struct gen_field_iterator *iter)
memset(&v, 0, sizeof(v));
iter->raw_value = iter_decode_field_raw(iter);
if (!iter_decode_field_raw(iter, &iter->raw_value))
return false;
const char *enum_name = NULL;
@ -963,6 +967,8 @@ iter_decode_field(struct gen_field_iterator *iter)
" (%s)", fmt_name);
}
}
return true;
}
void
@ -980,10 +986,14 @@ gen_field_iterator_init(struct gen_field_iterator *iter,
iter->field = group->next->fields;
iter->p = p;
iter->p_bit = p_bit;
iter->p_end = &p[gen_group_get_length(iter->group, iter->p)];
int length = gen_group_get_length(iter->group, iter->p);
iter->p_end = length > 0 ? &p[length] : NULL;
iter->print_colors = print_colors;
iter_decode_field(iter);
bool result = iter_decode_field(iter);
if (length >= 0)
assert(result);
}
bool
@ -992,7 +1002,8 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
if (!iter_advance_field(iter))
return false;
iter_decode_field(iter);
if (!iter_decode_field(iter))
return false;
return true;
}