/* * Copyright (C) 2021 Alyssa Rosenzweig * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef __AGX_IO_H #define __AGX_IO_H #include #include "agx_bo.h" #if __APPLE__ #include #include #endif #define AGX_SERVICE_TYPE 0x100005 enum agx_selector { AGX_SELECTOR_GET_GLOBAL_IDS = 0x6, AGX_SELECTOR_SET_API = 0x7, AGX_SELECTOR_CREATE_COMMAND_QUEUE = 0x8, AGX_SELECTOR_FREE_COMMAND_QUEUE = 0x9, AGX_SELECTOR_ALLOCATE_MEM = 0xA, AGX_SELECTOR_FREE_MEM = 0xB, AGX_SELECTOR_CREATE_SHMEM = 0xF, AGX_SELECTOR_FREE_SHMEM = 0x10, AGX_SELECTOR_CREATE_NOTIFICATION_QUEUE = 0x11, AGX_SELECTOR_FREE_NOTIFICATION_QUEUE = 0x12, AGX_SELECTOR_SUBMIT_COMMAND_BUFFERS = 0x1E, AGX_SELECTOR_GET_VERSION = 0x23, AGX_NUM_SELECTORS = 0x30 }; static const char *selector_table[AGX_NUM_SELECTORS] = { "unk0", "unk1", "unk2", "unk3", "unk4", "unk5", "GET_GLOBAL_IDS", "SET_API", "CREATE_COMMAND_QUEUE", "FREE_COMMAND_QUEUE", "ALLOCATE_MEM", "FREE_MEM", "unkC", "unkD", "unkE", "CREATE_SHMEM", "FREE_SHMEM", "CREATE_NOTIFICATION_QUEUE", "FREE_NOTIFICATION_QUEUE", "unk13", "unk14", "unk15", "unk16", "unk17", "unk18", "unk19", "unk1A", "unk1B", "unk1C", "unk1D", "SUBMIT_COMMAND_BUFFERS", "unk1F", "unk20", "unk21", "unk22", "GET_VERSION", "unk24", "unk25", "unk26", "unk27", "unk28", "unk29", "unk2A", "unk2B", "unk2C", "unk2D", "unk2E", "unk2F" }; static inline const char * wrap_selector_name(uint32_t selector) { return (selector < AGX_NUM_SELECTORS) ? selector_table[selector] : "unk??"; } struct agx_create_command_queue_resp { uint64_t id; uint32_t unk2; // 90 0A 08 27 uint32_t unk3; // 0 } __attribute__((packed)); struct agx_create_shmem_resp { void *map; uint32_t size; uint32_t id; } __attribute__((packed)); struct agx_create_notification_queue_resp { #ifdef __APPLE__ IODataQueueMemory *queue; #else void *queue; #endif uint32_t unk2; // 1 uint32_t unk3; // 0 } __attribute__((packed)); struct agx_submit_cmdbuf_req { uint32_t unk0; uint32_t unk1; uint32_t cmdbuf; uint32_t mappings; void *user_0; void *user_1; uint32_t unk2; uint32_t unk3; } __attribute__((packed)); /* Memory allocation isn't really understood yet. By comparing SHADER/CMDBUF_32 * vs everything else, it appears the 0x40000000 bit indicates the GPU VA must * be be in the first 4GiB */ enum agx_memory_type { AGX_MEMORY_TYPE_NORMAL = 0x00000000, /* used for user allocations */ AGX_MEMORY_TYPE_UNK = 0x08000000, /* unknown */ AGX_MEMORY_TYPE_CMDBUF_64 = 0x18000000, /* used for command buffer storage */ AGX_MEMORY_TYPE_SHADER = 0x48000000, /* used for shader memory, with VA = 0 */ AGX_MEMORY_TYPE_CMDBUF_32 = 0x58000000, /* used for command buffers, with VA < 32-bit */ AGX_MEMORY_TYPE_FRAMEBUFFER = 0x00888F00, /* used for framebuffer backing */ }; static inline const char * agx_memory_type_name(uint32_t type) { switch (type) { case AGX_MEMORY_TYPE_NORMAL: return "normal"; case AGX_MEMORY_TYPE_UNK: return "unk"; case AGX_MEMORY_TYPE_CMDBUF_64: return "cmdbuf_64"; case AGX_MEMORY_TYPE_SHADER: return "shader"; case AGX_MEMORY_TYPE_CMDBUF_32: return "cmdbuf_32"; case AGX_MEMORY_TYPE_FRAMEBUFFER: return "framebuffer"; default: return NULL; } } struct agx_notification_queue { #ifdef __APPLE__ mach_port_t port; IODataQueueMemory *queue; #else unsigned port; void *queue; #endif unsigned id; }; struct agx_command_queue { unsigned id; struct agx_notification_queue notif; }; /* Not sure if this is hardware or software defined */ struct agx_map_header { uint64_t cmdbuf_id; // GUID uint32_t unk2; // 01 00 00 00 uint32_t unk3; // 28 05 00 80 uint64_t encoder_id; // GUID uint32_t unk6; // 00 00 00 00 uint32_t cmdbuf_size; uint32_t nr_handles; uint32_t nr_entries; uint32_t indices[6]; } __attribute__((packed)); struct agx_map_entry { uint32_t unkAAA; // 20 00 00 00 uint32_t unk2; // 00 00 00 00 uint32_t unk3; // 00 00 00 00 uint32_t unk4; // 00 00 00 00 uint32_t unk5; // 00 00 00 00 uint32_t unk6; // 00 00 00 00 uint32_t unkBBB; // 01 00 00 00 uint32_t unk8; // 00 00 00 00 uint32_t unk9; // 00 00 00 00 uint32_t unka; // ff ff 01 00 uint32_t indices[6]; } __attribute__((packed)); uint64_t agx_get_global_id(struct agx_device *dev); #endif