diff --git a/src/asahi/lib/io.h b/src/asahi/lib/io.h new file mode 100644 index 00000000000..e5915b05654 --- /dev/null +++ b/src/asahi/lib/io.h @@ -0,0 +1,216 @@ +/* + * 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 unk7; // 80 07 00 00 + uint32_t nr_entries_1; + uint32_t nr_entries_2; + uint32_t unka; // 0b 00 00 00 + uint32_t padding[5]; +} __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 index; + uint32_t padding[5]; +} __attribute__((packed)); + +#endif