panwrap-mmap.h 4.39 KB
Newer Older
1
/*
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
2
 * © Copyright 2017-2018 The Panfrost Community
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */

#ifndef __MMAP_TRACE_H__
#define __MMAP_TRACE_H__

#include <mali-ioctl.h>
#include <list.h>
#include <stdlib.h>
21
#include <stddef.h>
22
#include "panwrap.h"
23 24

struct panwrap_allocated_memory {
25
	mali_ptr gpu_va;
26
	int flags;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
27
	int allocation_number;
28

29 30 31 32 33 34 35
	struct list node;
};

struct panwrap_mapped_memory {
	size_t length;

	void *addr;
36
	mali_ptr gpu_va;
37 38
	int prot;
        int flags;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
39

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
40
	int allocation_number;
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
41
	char name[32];
42

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
43
	bool* touched;
44

45 46 47
	struct list node;
};

48
#define TOUCH_MEMSET(mem, addr, sz, offset) \
49
	memset(mem->touched + ((addr - mem->gpu_va) / sizeof(uint32_t)), 1, (sz - offset) / sizeof(uint32_t)); \
50
	panwrap_log("\n");
51

52
#define TOUCH_LEN(mem, addr, sz, ename, number, dyn) \
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
	TOUCH_MEMSET(mem, addr, sz, 0) \
	panwrap_log("mali_ptr %s_%d_p = pandev_upload(%d, alloc_gpu_va_%d, %s, &%s_%d, sizeof(%s_%d), false);\n\n", ename, number, dyn ? -1 : (int) ((addr - mem->gpu_va)), mem->allocation_number, mem->name, ename, number, ename, number);

/* Job payloads are touched somewhat different than other structures, due to the
 * variable lengths and odd packing requirements */

#define TOUCH_JOB_HEADER(mem, addr, sz, offset, number) \
	TOUCH_MEMSET(mem, addr, sz, offset) \
	panwrap_log("mali_ptr job_%d_p = pandev_upload(-1, alloc_gpu_va_%d, %s, &job_%d, sizeof(job_%d) - %d, true);\n\n", number, mem->allocation_number, mem->name, number, number, offset);

#define TOUCH_SEQUENTIAL(mem, addr, sz, ename, number) \
	TOUCH_MEMSET(mem, addr, sz, 0) \
	panwrap_log("mali_ptr %s_%d_p = pandev_upload_sequential(alloc_gpu_va_%d, %s, &%s_%d, sizeof(%s_%d));\n\n", ename, number, mem->allocation_number, mem->name, ename, number, ename, number);

/* Syntax sugar for sanely sized objects */
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
68

69 70
#define TOUCH(mem, addr, obj, ename, number, dyn) \
	TOUCH_LEN(mem, addr, sizeof(typeof(obj)), ename, number, dyn)
71

72
void replay_memory();
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
73
void replay_memory_specific(struct panwrap_mapped_memory *pos, int offset, int len);
74
char *pointer_as_memory_reference(mali_ptr ptr);
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
75

Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
76
void panwrap_track_allocation(mali_ptr gpu_va, int flags, int number, size_t length);
77
void panwrap_track_mmap(mali_ptr gpu_va, void *addr, size_t length,
78 79 80 81 82
                        int prot, int flags);
void panwrap_track_munmap(void *addr);

struct panwrap_mapped_memory *panwrap_find_mapped_mem(void *addr);
struct panwrap_mapped_memory *panwrap_find_mapped_mem_containing(void *addr);
83 84
struct panwrap_mapped_memory *panwrap_find_mapped_gpu_mem(mali_ptr addr);
struct panwrap_mapped_memory *panwrap_find_mapped_gpu_mem_containing(mali_ptr addr);
85

86 87 88 89 90 91
void panwrap_assert_gpu_same(const struct panwrap_mapped_memory *mem,
			     mali_ptr gpu_va, size_t size,
			     const unsigned char *data);
void panwrap_assert_gpu_mem_zero(const struct panwrap_mapped_memory *mem,
				 mali_ptr gpu_va, size_t size);

92
void __attribute__((noreturn))
93
__panwrap_fetch_mem_err(const struct panwrap_mapped_memory *mem,
94
			mali_ptr gpu_va, size_t size,
95 96
			int line, const char *filename);

97
static inline void *
98
__panwrap_fetch_gpu_mem(const struct panwrap_mapped_memory *mem,
99
			mali_ptr gpu_va, size_t size,
100
			int line, const char *filename)
101
{
102 103 104
	if (!mem)
		mem = panwrap_find_mapped_gpu_mem_containing(gpu_va);

105 106 107
	if (!mem ||
	    size + (gpu_va - mem->gpu_va) > mem->length ||
	    !(mem->prot & MALI_MEM_PROT_CPU_RD))
108
		__panwrap_fetch_mem_err(mem, gpu_va, size, line, filename);
109

110
	return mem->addr + gpu_va - mem->gpu_va;
111
}
112

113 114
#define panwrap_fetch_gpu_mem(mem, gpu_va, size) \
	__panwrap_fetch_gpu_mem(mem, gpu_va, size, __LINE__, __FILE__)
115

116 117 118
/* Returns a validated pointer to mapped GPU memory with the given pointer type,
 * size automatically determined from the pointer type
 */
119
#define PANWRAP_PTR(mem, gpu_va, type) \
120
	((type*)(__panwrap_fetch_gpu_mem(mem, gpu_va, sizeof(type), \
121 122
					 __LINE__, __FILE__)))

123 124 125 126 127
/* Usage: <variable type> PANWRAP_PTR_VAR(name, mem, gpu_va) */
#define PANWRAP_PTR_VAR(name, mem, gpu_va) \
	name = __panwrap_fetch_gpu_mem(mem, gpu_va, sizeof(*name), \
				       __LINE__, __FILE__)

128
#endif /* __MMAP_TRACE_H__ */