Now About Social Code
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2024-07-21 00:12:12 +0100
committerLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2024-07-21 00:12:12 +0100
commit8afcff21ee9d5fb1a17360858a496244ac218c1e (patch)
tree7e29c14310f8130b6f776a96be197cb6045bf450
parent4193a0967c0b1cdc48c30204d442f9c48f1436a6 (diff)
drvemu: Implement device memory allocation
-rw-r--r--src/drvemu.c116
1 files changed, 91 insertions, 25 deletions
diff --git a/src/drvemu.c b/src/drvemu.c
index 3188ec1..1d64b9f 100644
--- a/src/drvemu.c
+++ b/src/drvemu.c
@@ -58,6 +58,7 @@
#define MAX_ALLOCATIONS 1024
+#define ARRAY_SIZE(x) ((sizeof x) / (sizeof *x))
#define STR_DETAIL(x) #x
#define STR(x) STR_DETAIL(x)
#define LOG(msg...) fprintf(stderr, "[DRVEMU] " msg)
@@ -75,30 +76,6 @@ static struct memory_allocation allocations[MAX_ALLOCATIONS];
static int false_fd = 10241024;
-static int alloc_memory(int heap, size_t size) {
- for (size_t i = 0; i < MAX_ALLOCATIONS; i++) {
- if (!allocations[i].allocated) {
- struct memory_allocation *mem = &allocations[i];
- mem->allocated = true;
- // TODO use heaps to get right device addr
- mem->device_ptr = 0;
- mem->cpu_ptr = malloc(size);
- mem->size = size;
- return i+1;
- }
- }
-
- assert(0);
- return -1;
-}
-
-#define create_handle(size, msg) create_handle_helper((size), (msg), __FILE__, __LINE__)
-static void *create_handle_helper(int size, const char *msg, const char *file, int line) {
- int handle = alloc_memory(0, size); // TODO handle heap correctly here;
- LOG("%s:%d Creating handle 0x%x for %s\n", file, line, handle, msg);
- return (void*)handle;
-}
-
#define PROLOG(func) \
static typeof(func) *orig_##func = NULL; \
if(!orig_##func) \
@@ -138,6 +115,21 @@ int fcntl(int fd, int op, int arg) {
return orig_fcntl(fd, op, arg);
}
+static const char *pvr_heap_names[] = {
+ "DRVEMU_INTERNAL",
+ "SGX_GENERAL_HEAP",
+ "SGX_TADATA_HEAP",
+ "SGX_KERNEL_CODE_HEAP",
+ "SGX_KERNEL_DATA_HEAP",
+ "SGX_PIXELSHADER_HEAP",
+ "SGX_VERTEXSHADER_HEAP",
+ "SGX_PDSPIXEL_CODEDATA_HEAP",
+ "SGX_PDSVERTEX_CODEDATA_HEAP",
+ "SGX_SYNCINFO_HEAP",
+ "SGX_SHARED_3DPARAMETERS_HEAP",
+ "SGX_PERCONTEXT_3DPARAMETERS_HEAP"
+};
+
PVRSRV_HEAP_INFO pvr_heaps[] = {
{
.ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID),
@@ -218,6 +210,49 @@ PVRSRV_HEAP_INFO pvr_heaps[] = {
},
};
+static int alloc_memory(int heap_id, size_t size) {
+ for (size_t i = 0; i < MAX_ALLOCATIONS; i++) {
+ if (!allocations[i].allocated) {
+ struct memory_allocation *mem = &allocations[i];
+ mem->allocated = true;
+ // If heap is 0 that is for internal allocs
+ if (heap_id != 0) {
+ assert((heap_id-1) < ARRAY_SIZE(pvr_heaps));
+ PVRSRV_HEAP_INFO *heap = &pvr_heaps[heap_id-1];
+ mem->device_ptr = heap->sDevVAddrBase.uiAddr;
+ heap->sDevVAddrBase.uiAddr += size;
+ } else {
+ mem->device_ptr = 0;
+ }
+ mem->cpu_ptr = malloc(size);
+ mem->size = size;
+ return i+1;
+ }
+ }
+
+ assert(0);
+ return -1;
+}
+
+static struct memory_allocation *alloc_sync(PVRSRV_CLIENT_SYNC_INFO *sync) {
+ int handle = alloc_memory(0, 1024);
+ struct memory_allocation *alloc = &allocations[handle-1];
+ sync->hMappingInfo = (void*)handle;
+ sync->psSyncData = (void*)alloc;
+ sync->sWriteOpsCompleteDevVAddr.uiAddr = handle;
+ sync->sReadOpsCompleteDevVAddr.uiAddr = handle;
+ sync->sReadOps2CompleteDevVAddr.uiAddr = handle;
+ sync->hKernelSyncInfo = sync->hMappingInfo;
+ return alloc;
+}
+
+#define create_handle(size, msg) create_handle_helper((size), (msg), __FILE__, __LINE__)
+static void *create_handle_helper(int size, const char *msg, const char *file, int line) {
+ int handle = alloc_memory(0, size); // TODO handle heap correctly here;
+ LOG("%s:%d Creating handle 0x%x for %s\n", file, line, handle, msg);
+ return (void*)handle;
+}
+
#define DEV_NAME "pvr"
#define DEV_DATE "20110701"
#define DEV_DESC "Imagination Technologies PVR DRM"
@@ -484,6 +519,37 @@ static bool pvrsrv_ioctl(int fd, PVRSRV_BRIDGE_PACKAGE *bridge_package) {
memcpy(out->sHeapInfo, pvr_heaps, sizeof(pvr_heaps));
break;
}
+ case _IOC_NR(PVRSRV_BRIDGE_ALLOC_DEVICEMEM): {
+ PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *in = bridge_package->pvParamIn;
+ PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ int handle = alloc_memory((int)in->hDevMemHeap, in->uSize);
+ struct memory_allocation *alloc = &allocations[handle-1];
+ out->psKernelMemInfo = (void*)alloc;
+ out->sClientMemInfo.pvLinAddr = alloc->cpu_ptr;
+ out->sClientMemInfo.pvLinAddrKM = alloc->cpu_ptr;
+ out->sClientMemInfo.sDevVAddr.uiAddr = alloc->device_ptr;
+ // TODO missing flags
+ out->sClientMemInfo.uAllocSize = alloc->size;
+ // TODO missing sync
+ out->sClientMemInfo.hMappingInfo = (void*)handle;
+ out->sClientMemInfo.hKernelMemInfo = (void*)handle;
+ out->sClientMemInfo.hResItem = (void*)handle;
+ out->sClientMemInfo.psNext = NULL;
+
+
+ if (in->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ) {
+ out->sClientMemInfo.psClientSyncInfo = NULL;
+ } else {
+ struct memory_allocation *sync = alloc_sync(&out->sClientSyncInfo);
+ out->sClientMemInfo.psClientSyncInfo = (void*)sync;
+ }
+
+ LOG("Allocated 0x%x at 0x%x:0x%x from %s\n",
+ alloc->size, (uintptr_t)alloc->cpu_ptr,
+ alloc->device_ptr, pvr_heap_names[(int)in->hDevMemHeap]);
+ break;
+ }
case _IOC_NR(PVRSRV_BRIDGE_DISCONNECT_SERVICES):
case _IOC_NR(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO):
case _IOC_NR(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE):
@@ -587,7 +653,7 @@ int ioctl(int fd, int request, ...) {
va_end(args);
}
- LOG("Got ioctl %d!\n", fd);
+ //LOG("Got ioctl %d!\n", fd);
if (pvr)
return spoof_ioctl(fd, request, ptr);