1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
|
/*
* GSP 570.144W RPC Client Header
* Auto-generated from firmware decompilation
*/
#ifndef _GSP_RPC_CLIENT_H_
#define _GSP_RPC_CLIENT_H_
#include <linux/types.h>
#include <linux/device.h>
/* ============================================================
* FIRMWARE BASE ADDRESS
* ============================================================ */
#define GSP_FW_BASE 0x04000000UL
/* ============================================================
* RPC DISPATCHER ADDRESSES
* ============================================================ */
/* Primary Dispatcher - Jump table switch for 6 RPC types */
#define GSP_RPC_DISPATCH_PRIMARY (GSP_FW_BASE + 0x17A1AC0) /* 0x057a1ac0 */
#define GSP_RPC_JUMP_TABLE (GSP_FW_BASE + 0x17A3AD8) /* 0x057a3ad8 - 32 sub-commands */
/* Secondary Dispatcher - Full implementation for all 11 RPC types */
#define GSP_RPC_DISPATCH_SECONDARY (GSP_FW_BASE + 0x0ED39DC) /* 0x04ed39dc */
/* Tertiary Dispatcher - Stack=160 bytes */
#define GSP_RPC_DISPATCH_TERTIARY (GSP_FW_BASE + 0x0CC58F8) /* 0x04cc58f8 */
/* Quaternary Dispatcher - Stack=96 bytes */
#define GSP_RPC_DISPATCH_QUATERNARY (GSP_FW_BASE + 0x1723EF4) /* 0x05723ef4 */
/* ============================================================
* SPECIALIZED HANDLER ADDRESSES
* ============================================================ */
#define GSP_ALLOC_MAIN (GSP_FW_BASE + 0x17E94EC) /* 0x057e94ec */
#define GSP_SCHEDULE_MAIN (GSP_FW_BASE + 0x11EFBF4) /* 0x051efbf4 */
#define GSP_BAR_TRAP_HANDLER_JT (GSP_FW_BASE + 0x17675B7) /* 0x057675b7 */
#define GSP_BAR_TRAP_HANDLER_PRIM (GSP_FW_BASE + 0x0CB8189) /* 0x04cb8189 */
#define GSP_PIN_HANDLER_SEC (GSP_FW_BASE + 0x0ED34B8) /* 0x04ed34b8 */
/* Jump Table Handlers (from decoded table at 0x059bfeb0) */
#define GSP_MAP_HANDLER_A (GSP_FW_BASE + 0x1766AB7) /* 0x05766ab7 */
#define GSP_MAP_HANDLER_B (GSP_FW_BASE + 0x1778A37) /* 0x05778a37 */
#define GSP_UNMAP_HANDLER_A (GSP_FW_BASE + 0x17669B7) /* 0x057669b7 */
#define GSP_UNMAP_HANDLER_B (GSP_FW_BASE + 0x1779937) /* 0x05779937 */
#define GSP_PIN_HANDLER_A (GSP_FW_BASE + 0x17664B7) /* 0x057664b7 */
#define GSP_PIN_HANDLER_B (GSP_FW_BASE + 0x177A3B7) /* 0x0577a3b7 */
#define GSP_UNPIN_HANDLER_A (GSP_FW_BASE + 0x17682B7) /* 0x057682b7 */
#define GSP_UNPIN_HANDLER_B (GSP_FW_BASE + 0x1779FB7) /* 0x05779fb7 */
#define GSP_SCHEDULE_HANDLER_A (GSP_FW_BASE + 0x1767F37) /* 0x05767f37 */
#define GSP_SCHEDULE_HANDLER_B (GSP_FW_BASE + 0x175AEB7) /* 0x0575aeb7 */
#define GSP_YIELD_HANDLER_A (GSP_FW_BASE + 0x175AE37) /* 0x0575ae37 */
#define GSP_YIELD_HANDLER_B (GSP_FW_BASE + 0x1767337) /* 0x05767337 */
#define GSP_NOTIFY_HANDLER_A (GSP_FW_BASE + 0x177C8B7) /* 0x0577c8b7 */
#define GSP_NOTIFY_HANDLER_B (GSP_FW_BASE + 0x1767837) /* 0x05767837 */
/* Entry Point */
#define GSP_ENTRY_POINT (GSP_FW_BASE + 0x0009000) /* 0x04009000 */
/* ============================================================
* RPC TYPE DEFINITIONS
* ============================================================ */
enum gsp_rpc_type {
GSP_RPC_ALLOC = 0x01,
GSP_RPC_FREE = 0x02,
GSP_RPC_MAP = 0x03,
GSP_RPC_UNMAP = 0x04,
GSP_RPC_PIN = 0x05,
GSP_RPC_UNPIN = 0x06,
GSP_RPC_SCHEDULE = 0x07,
GSP_RPC_YIELD = 0x08,
GSP_RPC_NOTIFY = 0x09,
GSP_RPC_BAR_TRAP = 0x0A,
GSP_RPC_MIGRATE = 0x0B,
GSP_RPC_DEBUG = 0xFF,
};
/* ============================================================
* ALLOC SUB-COMMANDS (Primary Dispatcher Jump Table Indices)
* ============================================================ */
enum gsp_alloc_subcmd {
GSP_ALLOC_SUBCMD_DEFAULT = 0,
GSP_ALLOC_SUBCMD_TYPE1 = 1,
GSP_ALLOC_SUBCMD_TYPE2 = 3,
GSP_ALLOC_SUBCMD_TYPE3 = 4,
GSP_ALLOC_SUBCMD_TYPE4 = 5,
GSP_ALLOC_SUBCMD_TYPE5 = 8,
GSP_ALLOC_SUBCMD_TYPE6 = 10,
GSP_ALLOC_SUBCMD_TYPE7 = 12,
GSP_ALLOC_SUBCMD_TYPE8 = 17,
GSP_ALLOC_SUBCMD_TYPE9 = 19,
GSP_ALLOC_SUBCMD_TYPE10 = 20,
GSP_ALLOC_SUBCMD_TYPE11 = 21,
GSP_ALLOC_SUBCMD_TYPE12 = 22,
GSP_ALLOC_SUBCMD_TYPE13 = 23,
GSP_ALLOC_SUBCMD_TYPE14 = 24,
GSP_ALLOC_SUBCMD_TYPE15 = 25,
GSP_ALLOC_SUBCMD_TYPE16 = 26,
GSP_ALLOC_SUBCMD_TYPE17 = 27,
GSP_ALLOC_SUBCMD_TYPE18 = 28,
GSP_ALLOC_SUBCMD_TYPE19 = 29,
GSP_ALLOC_SUBCMD_TYPE20 = 30,
GSP_ALLOC_SUBCMD_TYPE21 = 31,
};
/* ============================================================
* MIGRATE SUB-COMMANDS
* ============================================================ */
enum gsp_migrate_subcmd {
GSP_MIGRATE_SUBCMD_SAVE = 0x04,
GSP_MIGRATE_SUBCMD_RESTORE = 0x05,
};
/* ============================================================
* PIN SUB-COMMANDS
* ============================================================ */
enum gsp_pin_subcmd {
GSP_PIN_SUBCMD_DEFAULT = 0x05,
};
/* ============================================================
* SCHEDULE SUB-COMMANDS
* ============================================================ */
enum gsp_sched_subcmd {
GSP_SCHED_SUBCMD_DEFAULT = 0x07,
};
/* ============================================================
* BAR TRAP SUB-COMMANDS
* ============================================================ */
enum gsp_bar_trap_subcmd {
GSP_BAR_TRAP_SUBCMD_DEFAULT = 0x0A,
};
/* ============================================================
* RPC MESSAGE STRUCTURES
* ============================================================ */
struct gsp_rpc_msg {
__le32 type;
__le32 subcmd;
__le64 payload[6];
__le32 seq_id;
__le32 flags;
__le32 reserved[2];
} __packed;
struct gsp_rpc_response {
__le32 status;
__le32 type;
__le64 result[6];
__le32 seq_id;
} __packed;
/* ALLOC request/response */
struct gsp_alloc_req {
__le64 size;
__le64 alignment;
__le32 mem_type;
__le32 flags;
__le64 addr_hint;
__le32 pid;
__le32 reserved;
} __packed;
struct gsp_alloc_rsp {
__le64 gpu_va;
__le64 handle;
__le64 size;
} __packed;
/* MAP request/response */
struct gsp_map_req {
__le64 handle;
__le64 gpu_va;
__le64 size;
__le32 prot;
__le32 flags;
__le64 offset;
__le32 reserved[2];
} __packed;
struct gsp_map_rsp {
__le64 gpu_va;
} __packed;
/* PIN/UNPIN request/response */
struct gsp_pin_req {
__le64 handle;
__le64 offset;
__le64 size;
__le32 flags;
__le32 reserved[3];
} __packed;
struct gsp_pin_rsp {
__le64 dma_addr;
__le32 num_pages;
__le32 reserved;
} __packed;
/* SCHEDULE request */
struct gsp_sched_req {
__le64 work_handle;
__le64 callback;
__le64 arg;
__le32 priority;
__le32 flags;
__le32 reserved[2];
} __packed;
/* BAR TRAP request/response */
struct gsp_bar_trap_req {
__le64 bar_addr;
__le32 access_type;
__le32 size;
__le64 value;
__le32 bar_num;
__le32 reserved;
} __packed;
struct gsp_bar_trap_rsp {
__le64 value;
__le32 handled;
__le32 reserved;
} __packed;
/* MIGRATE request/response */
struct gsp_migrate_req {
__le64 src_gpu_id;
__le64 dst_gpu_id;
__le64 memory_bitmap;
__le64 page_table_ptr;
__le32 state;
__le32 flags;
__le64 context;
__le32 reserved;
} __packed;
struct gsp_migrate_rsp {
__le32 status;
__le32 progress;
__le64 checkpoint;
} __packed;
/* ============================================================
* CLIENT OPAQUE STRUCT
* ============================================================ */
struct gsp_client;
/* ============================================================
* PUBLIC API
* ============================================================ */
/* Client lifecycle */
struct gsp_client *gsp_client_init(struct device *dev, phys_addr_t fw_base, phys_addr_t doorbell);
void gsp_client_fini(struct gsp_client *client);
/* Memory management */
int gsp_rpc_alloc(struct gsp_client *client,
u64 size, u64 alignment, u32 mem_type,
u32 flags, u64 addr_hint, u32 pid,
u64 *gpu_va, u64 *handle, u64 *actual_size);
int gsp_rpc_free(struct gsp_client *client, u64 handle);
int gsp_rpc_map(struct gsp_client *client,
u64 handle, u64 gpu_va, u64 size,
u32 prot, u32 flags, u64 offset,
u64 *mapped_va);
int gsp_rpc_unmap(struct gsp_client *client, u64 handle, u64 gpu_va, u64 size);
/* Page pinning */
int gsp_rpc_pin(struct gsp_client *client,
u64 handle, u64 offset, u64 size,
u32 flags, u64 *dma_addr, u32 *num_pages);
int gsp_rpc_unpin(struct gsp_client *client, u64 handle, u64 offset, u64 size);
/* Scheduling */
int gsp_rpc_schedule(struct gsp_client *client,
u64 work_handle, u64 callback, u64 arg,
u32 priority, u32 flags);
int gsp_rpc_yield(struct gsp_client *client);
/* BAR trap emulation */
int gsp_rpc_bar_trap(struct gsp_client *client,
u64 bar_addr, u32 access_type, u32 size,
u64 value, u32 bar_num, u64 *ret_value);
/* Migration */
int gsp_rpc_migrate_save(struct gsp_client *client,
u64 src_gpu_id, u64 dst_gpu_id,
u64 memory_bitmap, u64 page_table_ptr,
u64 *checkpoint);
int gsp_rpc_migrate_restore(struct gsp_client *client,
u64 src_gpu_id, u64 dst_gpu_id,
u64 memory_bitmap, u64 page_table_ptr,
u64 checkpoint);
/* WPR Management */
int gsp_wpr_write_mutex_acquire(struct gsp_client *client, u32 wpr_id);
int gsp_wpr_write_mutex_release(struct gsp_client *client, u32 wpr_id);
int gsp_wpr_scratch_mutex_acquire(struct gsp_client *client, u32 wpr_id);
int gsp_wpr_scratch_mutex_release(struct gsp_client *client, u32 wpr_id);
/* Emulation control */
void gsp_rpc_emulation_set(bool enable);
bool gsp_rpc_emulation_is_enabled(void);
/* Emulation implementations */
int gsp_rpc_alloc_emul(struct gsp_client *client,
u64 size, u64 alignment, u32 mem_type,
u32 flags, u64 addr_hint, u32 pid,
u64 *gpu_va, u64 *handle, u64 *actual_size);
int gsp_rpc_free_emul(struct gsp_client *client, u64 handle);
int gsp_rpc_map_emul(struct gsp_client *client,
u64 handle, u64 gpu_va, u64 size,
u32 prot, u32 flags, u64 offset,
u64 *mapped_va);
int gsp_rpc_unmap_emul(struct gsp_client *client, u64 handle, u64 gpu_va, u64 size);
int gsp_rpc_pin_emul(struct gsp_client *client,
u64 handle, u64 offset, u64 size,
u32 flags, u64 *dma_addr, u32 *num_pages);
int gsp_rpc_unpin_emul(struct gsp_client *client, u64 handle, u64 offset, u64 size);
/* Notification */
int gsp_rpc_notify_register(struct gsp_client *client,
u32 type,
void (*callback)(struct gsp_client *,
struct gsp_rpc_response *,
void *),
void *ctx);
void gsp_rpc_notify_unregister(struct gsp_client *client, u32 type);
void gsp_handle_notification(struct gsp_client *client, struct gsp_rpc_msg *msg);
/* Client lifecycle */
struct gsp_client *gsp_client_init(struct device *dev, phys_addr_t fw_base, phys_addr_t doorbell);
void gsp_client_fini(struct gsp_client *client);
/* WPR Management */
int gsp_wpr_write_mutex_acquire(struct gsp_client *client, u32 wpr_id);
int gsp_wpr_write_mutex_release(struct gsp_client *client, u32 wpr_id);
int gsp_wpr_scratch_mutex_acquire(struct gsp_client *client, u32 wpr_id);
int gsp_wpr_scratch_mutex_release(struct gsp_client *client, u32 wpr_id);
#endif /* _GSP_RPC_CLIENT_H_ */
|