embox

Форк
0
/
etnaviv_cmd_parser.c 
108 строк · 2.9 Кб
1
/*
2
 * Copyright (C) 2015 Etnaviv Project
3
 *
4
 * This program is free software; you can redistribute it and/or modify it
5
 * under the terms of the GNU General Public License version 2 as published by
6
 * the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11
 * more details.
12
 *
13
 * You should have received a copy of the GNU General Public License along with
14
 * this program.  If not, see <http://www.gnu.org/licenses/>.
15
 */
16

17
#include <util/log.h>
18

19
#include "etnaviv_compat.h"
20
#include "etnaviv_gem.h"
21
#include "etnaviv_gpu.h"
22

23
#include <etnaviv_xml/cmdstream.xml.h>
24

25
#define EXTRACT(val, field) (((val) & field##__MASK) >> field##__SHIFT)
26

27
struct etna_validation_state {
28
	struct etnaviv_gpu *gpu;
29
	const struct drm_etnaviv_gem_submit_reloc *relocs;
30
	unsigned int num_relocs;
31
	uint32_t *start;
32
};
33

34
#define ETNAVIV_STATES_SIZE (VIV_FE_LOAD_STATE_HEADER_OFFSET__MASK + 1u)
35

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,
40
	[FE_OPCODE_NOP] = 2,
41
	[FE_OPCODE_STALL] = 2,
42
};
43

44
bool etnaviv_cmd_validate_one(struct etnaviv_gpu *gpu, uint32_t *stream,
45
			      unsigned int size,
46
			      struct drm_etnaviv_gem_submit_reloc *relocs,
47
			      unsigned int reloc_size)
48
{
49
	struct etna_validation_state state;
50
	uint32_t *buf = stream;
51
	uint32_t *end = buf + size;
52

53
	state.gpu = gpu;
54
	state.relocs = relocs;
55
	state.num_relocs = reloc_size;
56
	state.start = stream;
57

58
	log_debug("gpu(%p) stream(%p) size(%d) relocs(%p) reloc_size(%d)",  gpu,
59
			stream, size, relocs, reloc_size);
60
	while (buf < end) {
61
		uint32_t cmd = *buf;
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);
65

66
		switch (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);
71
			if (buf + len > end)
72
				break;
73

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);
76
			break;
77

78
		case FE_OPCODE_DRAW_2D:
79
			n = EXTRACT(cmd, VIV_FE_DRAW_2D_HEADER_COUNT);
80
			if (n == 0)
81
				n = 256;
82
			len = 2 + n * 2;
83
			log_debug("FE_OPCODE_DRAW_2D: n(%x) len(%x)", n, len);
84
			break;
85

86
		default:
87
			len = cmd_length[op];
88
			log_debug("default: n(%x) len(%x) op(%x)", n, len, op);
89
			if (len == 0) {
90
				log_error("%s: op %u not permitted at offset %tu\n",
91
					__func__, op, buf - state.start);
92
				len = 0; /* Treat as NOP */
93
				buf = end;
94
			}
95
			break;
96
		}
97

98
		buf += len;
99
	}
100

101
	if (buf > end) {
102
		log_error("%s: commands overflow end of buffer: %tu > %u\n",
103
			__func__, buf - state.start, size);
104
		return false;
105
	}
106

107
	return true;
108
}
109

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.