• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Alyssa Rosenzweig <alyssa@rosenzweig.io>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #ifndef __AGX_IO_H
25 #define __AGX_IO_H
26 
27 #include <stdbool.h>
28 #include "agx_bo.h"
29 
30 #if __APPLE__
31 #include <mach/mach.h>
32 #include <IOKit/IODataQueueClient.h>
33 #endif
34 
35 #define AGX_SERVICE_TYPE 0x100005
36 
37 enum agx_selector {
38 	AGX_SELECTOR_GET_GLOBAL_IDS = 0x6,
39 	AGX_SELECTOR_SET_API = 0x7,
40 	AGX_SELECTOR_CREATE_COMMAND_QUEUE = 0x8,
41 	AGX_SELECTOR_FREE_COMMAND_QUEUE = 0x9,
42 	AGX_SELECTOR_ALLOCATE_MEM = 0xA,
43 	AGX_SELECTOR_FREE_MEM = 0xB,
44 	AGX_SELECTOR_CREATE_SHMEM = 0xF,
45 	AGX_SELECTOR_FREE_SHMEM = 0x10,
46 	AGX_SELECTOR_CREATE_NOTIFICATION_QUEUE = 0x11,
47 	AGX_SELECTOR_FREE_NOTIFICATION_QUEUE = 0x12,
48 	AGX_SELECTOR_SUBMIT_COMMAND_BUFFERS = 0x1E,
49 	AGX_SELECTOR_GET_VERSION = 0x23,
50 	AGX_NUM_SELECTORS = 0x30
51 };
52 
53 static const char *selector_table[AGX_NUM_SELECTORS] = {
54 	"unk0",
55 	"unk1",
56 	"unk2",
57 	"unk3",
58 	"unk4",
59 	"unk5",
60 	"GET_GLOBAL_IDS",
61 	"SET_API",
62 	"CREATE_COMMAND_QUEUE",
63 	"FREE_COMMAND_QUEUE",
64 	"ALLOCATE_MEM",
65 	"FREE_MEM",
66 	"unkC",
67 	"unkD",
68 	"unkE",
69 	"CREATE_SHMEM",
70 	"FREE_SHMEM",
71 	"CREATE_NOTIFICATION_QUEUE",
72 	"FREE_NOTIFICATION_QUEUE",
73 	"unk13",
74 	"unk14",
75 	"unk15",
76 	"unk16",
77 	"unk17",
78 	"unk18",
79 	"unk19",
80 	"unk1A",
81 	"unk1B",
82 	"unk1C",
83 	"unk1D",
84 	"SUBMIT_COMMAND_BUFFERS",
85 	"unk1F",
86 	"unk20",
87 	"unk21",
88 	"unk22",
89 	"GET_VERSION",
90 	"unk24",
91 	"unk25",
92 	"unk26",
93 	"unk27",
94 	"unk28",
95 	"unk29",
96 	"unk2A",
97 	"unk2B",
98 	"unk2C",
99 	"unk2D",
100 	"unk2E",
101 	"unk2F"
102 };
103 
104 static inline const char *
wrap_selector_name(uint32_t selector)105 wrap_selector_name(uint32_t selector)
106 {
107 	return (selector < AGX_NUM_SELECTORS) ? selector_table[selector] : "unk??";
108 }
109 
110 struct agx_create_command_queue_resp {
111 	uint64_t id;
112 	uint32_t unk2; // 90 0A 08 27
113 	uint32_t unk3; // 0
114 } __attribute__((packed));
115 
116 struct agx_create_shmem_resp {
117 	void *map;
118 	uint32_t size;
119 	uint32_t id;
120 } __attribute__((packed));
121 
122 struct agx_create_notification_queue_resp {
123 #ifdef __APPLE__
124 	IODataQueueMemory *queue;
125 #else
126    void *queue;
127 #endif
128 	uint32_t unk2; // 1
129 	uint32_t unk3; // 0
130 } __attribute__((packed));
131 
132 struct agx_submit_cmdbuf_req {
133 	uint32_t unk0;
134 	uint32_t unk1;
135 	uint32_t cmdbuf;
136 	uint32_t mappings;
137 	void *user_0;
138 	void *user_1;
139 	uint32_t unk2;
140 	uint32_t unk3;
141 } __attribute__((packed));
142 
143 /* Memory allocation isn't really understood yet. By comparing SHADER/CMDBUF_32
144  * vs everything else, it appears the 0x40000000 bit indicates the GPU VA must
145  * be be in the first 4GiB */
146 
147 enum agx_memory_type {
148 	AGX_MEMORY_TYPE_NORMAL      = 0x00000000, /* used for user allocations */
149 	AGX_MEMORY_TYPE_UNK         = 0x08000000, /* unknown */
150 	AGX_MEMORY_TYPE_CMDBUF_64   = 0x18000000, /* used for command buffer storage */
151 	AGX_MEMORY_TYPE_SHADER      = 0x48000000, /* used for shader memory, with VA = 0 */
152 	AGX_MEMORY_TYPE_CMDBUF_32   = 0x58000000, /* used for command buffers, with VA < 32-bit */
153 	AGX_MEMORY_TYPE_FRAMEBUFFER = 0x00888F00, /* used for framebuffer backing */
154 };
155 
156 static inline const char *
agx_memory_type_name(uint32_t type)157 agx_memory_type_name(uint32_t type)
158 {
159 	switch (type) {
160 	case AGX_MEMORY_TYPE_NORMAL: return "normal";
161 	case AGX_MEMORY_TYPE_UNK: return "unk";
162 	case AGX_MEMORY_TYPE_CMDBUF_64: return "cmdbuf_64";
163 	case AGX_MEMORY_TYPE_SHADER: return "shader";
164 	case AGX_MEMORY_TYPE_CMDBUF_32: return "cmdbuf_32";
165 	case AGX_MEMORY_TYPE_FRAMEBUFFER: return "framebuffer";
166 	default: return NULL;
167 	}
168 }
169 
170 struct agx_notification_queue {
171 #ifdef __APPLE__
172    mach_port_t port;
173    IODataQueueMemory *queue;
174 #else
175    unsigned port;
176    void *queue;
177 #endif
178    unsigned id;
179 };
180 
181 struct agx_command_queue {
182    unsigned id;
183    struct agx_notification_queue notif;
184 };
185 
186 /* Not sure if this is hardware or software defined */
187 
188 struct agx_map_header {
189 	uint64_t cmdbuf_id; // GUID
190 	uint32_t unk2; // 01 00 00 00
191 	uint32_t unk3; // 28 05 00 80
192 	uint64_t encoder_id; // GUID
193 	uint32_t unk6; // 00 00 00 00
194 	uint32_t cmdbuf_size;
195 	uint32_t nr_handles;
196 	uint32_t nr_entries;
197 	uint32_t indices[6];
198 } __attribute__((packed));
199 
200 struct agx_map_entry {
201 	uint32_t unkAAA; // 20 00 00 00
202 	uint32_t unk2; // 00 00 00 00
203 	uint32_t unk3; // 00 00 00 00
204 	uint32_t unk4; // 00 00 00 00
205 	uint32_t unk5; // 00 00 00 00
206 	uint32_t unk6; // 00 00 00 00
207 	uint32_t unkBBB; // 01 00 00 00
208 	uint32_t unk8; // 00 00 00 00
209 	uint32_t unk9; // 00 00 00 00
210 	uint32_t unka; // ff ff 01 00
211 	uint32_t indices[6];
212 } __attribute__((packed));
213 
214 uint64_t
215 agx_get_global_id(struct agx_device *dev);
216 
217 #endif
218