19
#include "etnaviv_compat.h"
20
#include "etnaviv_gem.h"
21
#include "etnaviv_gpu.h"
23
#include <etnaviv_xml/cmdstream.xml.h>
25
#define EXTRACT(val, field) (((val) & field##__MASK) >> field##__SHIFT)
27
struct etna_validation_state {
28
struct etnaviv_gpu *gpu;
29
const struct drm_etnaviv_gem_submit_reloc *relocs;
30
unsigned int num_relocs;
34
#define ETNAVIV_STATES_SIZE (VIV_FE_LOAD_STATE_HEADER_OFFSET__MASK + 1u)
36
static uint8_t cmd_length[32] = {
37
[FE_OPCODE_DRAW_PRIMITIVES] = 4,
38
[FE_OPCODE_DRAW_INDEXED_PRIMITIVES] = 6,
39
[FE_OPCODE_DRAW_INSTANCED] = 4,
41
[FE_OPCODE_STALL] = 2,
44
bool etnaviv_cmd_validate_one(struct etnaviv_gpu *gpu, uint32_t *stream,
46
struct drm_etnaviv_gem_submit_reloc *relocs,
47
unsigned int reloc_size)
49
struct etna_validation_state state;
50
uint32_t *buf = stream;
51
uint32_t *end = buf + size;
54
state.relocs = relocs;
55
state.num_relocs = reloc_size;
58
log_debug("gpu(%p) stream(%p) size(%d) relocs(%p) reloc_size(%d)", gpu,
59
stream, size, relocs, reloc_size);
62
unsigned int len, n = 0, off;
63
unsigned int op = cmd >> 27;
64
log_debug("buf(%p) cmd(%x) op(%x)", buf, cmd, op);
67
case FE_OPCODE_LOAD_STATE:
68
n = EXTRACT(cmd, VIV_FE_LOAD_STATE_HEADER_COUNT);
69
len = ALIGN(1 + n, 2);
70
log_debug("FE_OPCODE_LOAD_STATE: n(%x) len(%x) end(%x)", n, len, end);
74
off = EXTRACT(cmd, VIV_FE_LOAD_STATE_HEADER_OFFSET);
75
log_debug("FE_OPCODE_LOAD_STATE: n(%x) cmd(%x) off(%x)", n, len, off);
78
case FE_OPCODE_DRAW_2D:
79
n = EXTRACT(cmd, VIV_FE_DRAW_2D_HEADER_COUNT);
83
log_debug("FE_OPCODE_DRAW_2D: n(%x) len(%x)", n, len);
88
log_debug("default: n(%x) len(%x) op(%x)", n, len, op);
90
log_error("%s: op %u not permitted at offset %tu\n",
91
__func__, op, buf - state.start);
102
log_error("%s: commands overflow end of buffer: %tu > %u\n",
103
__func__, buf - state.start, size);