Now About Social Code
summaryrefslogtreecommitdiff
path: root/src/drvemu.c
diff options
context:
space:
mode:
authorLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2024-07-16 22:16:16 +0100
committerLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2024-07-16 22:16:16 +0100
commit2d42ff1f62c6a8c4585c768b4d9dcc6a9cd95ea1 (patch)
tree6219eb7674505dae63d23cd646f8eb73eaacc473 /src/drvemu.c
parentba5fcc8b96a68e35ce52848bb6f482ebf8c584f5 (diff)
repo: Clean up source organization
Diffstat (limited to 'src/drvemu.c')
-rw-r--r--src/drvemu.c530
1 files changed, 530 insertions, 0 deletions
diff --git a/src/drvemu.c b/src/drvemu.c
new file mode 100644
index 0000000..75592f7
--- /dev/null
+++ b/src/drvemu.c
@@ -0,0 +1,530 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include <dlfcn.h>
+
+#include <dirent.h>
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+#include <asm-generic/ioctl.h>
+
+#include "xf86drm.h"
+
+#define DRM_PVR_RESERVED1 (DRM_COMMAND_BASE + 0)
+#define DRM_PVR_RESERVED2 (DRM_COMMAND_BASE + 1)
+#define DRM_PVR_RESERVED3 (DRM_COMMAND_BASE + 2)
+#define DRM_PVR_RESERVED4 (DRM_COMMAND_BASE + 3)
+#define DRM_PVR_RESERVED5 (DRM_COMMAND_BASE + 4)
+#define DRM_PVR_RESERVED6 (DRM_COMMAND_BASE + 5)
+
+/* PVR includes */
+#define SUPPORT_MEMINFO_IDS
+#define SUPPORT_DRI_DRM_EXT
+#include <config_kernel.h>
+#include <sgxfeaturedefs.h>
+#include <pvr_bridge.h>
+#include <sgx_bridge.h>
+#include <pvr_drm_shared.h>
+#include <sgxconfig.h>
+#include <sgx_mkif_km.h>
+#include <sgx_options.h>
+#include <sgxapi_km.h>
+
+#define DRM_IOCTL_PVR_SRVKM DRM_IOWR(PVR_DRM_SRVKM_CMD, PVRSRV_BRIDGE_PACKAGE)
+#include "pvr_ioctl.h"
+
+#define MAX_ALLOCATIONS 1024
+
+#define LOG(msg...) fprintf(stderr, "[DRVEMU] " msg)
+
+struct memory_allocation {
+ bool allocated;
+ uint32_t device_ptr;
+ void *cpu_ptr;
+ size_t size;
+};
+
+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 PROLOG(func) \
+ static typeof(func) *orig_##func = NULL; \
+ if(!orig_##func) \
+ orig_##func = dlsym(RTLD_NEXT, #func);
+
+
+int open64(const char *pathname, int flags, ...) {
+ LOG("Called open64 on %s (%d)\n", pathname, flags);
+ PROLOG(open64);
+
+ if (strcmp(pathname, "/dev/dri/renderD128") == 0) {
+ LOG("Spoofing FD!\n");
+ return false_fd;
+ }
+
+ int fd = orig_open64(pathname, flags);
+ return fd;
+}
+
+int close(int fd) {
+ LOG("Close called on %d\n", fd);
+ PROLOG(close);
+
+ if (fd != false_fd)
+ return orig_close(fd);
+
+ return 0;
+}
+
+int fcntl(int fd, int op, int arg) {
+ LOG("Called fcntl on %d\n", fd);
+ PROLOG(fcntl);
+
+ if (fd == false_fd)
+ return 0;
+
+ return orig_fcntl(fd, op, arg);
+}
+
+PVRSRV_HEAP_INFO pvr_heaps[] = {
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID),
+ .hDevMemHeap = (void*)1,
+ .sDevVAddrBase = {SGX_GENERAL_HEAP_BASE},
+ .ui32HeapByteSize = SGX_GENERAL_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID),
+ .hDevMemHeap = (void*)2,
+ .sDevVAddrBase = {SGX_TADATA_HEAP_BASE},
+ .ui32HeapByteSize = SGX_TADATA_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_MULTI_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID),
+ .hDevMemHeap = (void*)3,
+ .sDevVAddrBase = {SGX_KERNEL_CODE_HEAP_BASE},
+ .ui32HeapByteSize = SGX_KERNEL_CODE_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_MULTI_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID),
+ .hDevMemHeap = (void*)4,
+ .sDevVAddrBase = {SGX_KERNEL_DATA_HEAP_BASE},
+ .ui32HeapByteSize = SGX_KERNEL_DATA_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_MULTI_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID),
+ .hDevMemHeap = (void*)5,
+ .sDevVAddrBase = {SGX_PIXELSHADER_HEAP_BASE},
+ .ui32HeapByteSize = SGX_PIXELSHADER_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_SINGLE_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID),
+ .hDevMemHeap = (void*)6,
+ .sDevVAddrBase = {SGX_VERTEXSHADER_HEAP_BASE},
+ .ui32HeapByteSize = SGX_VERTEXSHADER_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_SINGLE_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID),
+ .hDevMemHeap = (void*)7,
+ .sDevVAddrBase = {SGX_PDSPIXEL_CODEDATA_HEAP_BASE},
+ .ui32HeapByteSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_SINGLE_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID),
+ .hDevMemHeap = (void*)8,
+ .sDevVAddrBase = {SGX_PDSVERTEX_CODEDATA_HEAP_BASE},
+ .ui32HeapByteSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_SINGLE_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID),
+ .hDevMemHeap = (void*)9,
+ .sDevVAddrBase = {SGX_SYNCINFO_HEAP_BASE},
+ .ui32HeapByteSize = SGX_SYNCINFO_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_MULTI_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SHARED_3DPARAMETERS_HEAP_ID),
+ .hDevMemHeap = (void*)10,
+ .sDevVAddrBase = {SGX_SHARED_3DPARAMETERS_HEAP_BASE},
+ .ui32HeapByteSize = SGX_SHARED_3DPARAMETERS_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_MULTI_PROCESS,
+ },
+ {
+ .ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID),
+ .hDevMemHeap = (void*)11,
+ .sDevVAddrBase = {SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE},
+ .ui32HeapByteSize = SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE,
+ .ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_MEM_RAM_BACKED_ALLOCATION | PVRSRV_HAP_SINGLE_PROCESS,
+ },
+};
+
+#define DEV_NAME "pvr"
+#define DEV_DATE "20110701"
+#define DEV_DESC "Imagination Technologies PVR DRM"
+
+void get_misc_info(SGX_MISC_INFO *info) {
+ switch(info->eRequest) {
+ case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:
+ info->uData.sSGXFeatures.ui32BuildOptions = SGX_BUILD_OPTIONS;
+ info->uData.sSGXFeatures.ui32DDKBuild = 3759903;
+ info->uData.sSGXFeatures.ui32DDKVersion = (1 << 16) | (14 << 8);
+ break;
+ case SGX_MISC_INFO_REQUEST_SGXREV:
+ // TODO need to get this from real hardware
+ info->uData.sSGXFeatures.ui32BuildOptions = SGX_BUILD_OPTIONS;
+ info->uData.sSGXFeatures.ui32DDKBuild = 3759903;
+ info->uData.sSGXFeatures.ui32DDKVersion = (1 << 16) | (14 << 8);
+ break;
+ case SGX_MISC_INFO_REQUEST_CLOCKSPEED_SLCSIZE:
+ info->uData.sQueryClockSpeedSLCSize.ui32SGXClockSpeed = SYS_SGX_CLOCK_SPEED;
+ break;
+ default:
+ LOG("Unimplemented misc req %d\n", info->eRequest);
+ assert(false);
+ break;
+ }
+}
+
+static bool pvrsrv_ioctl(int fd, PVRSRV_BRIDGE_PACKAGE *bridge_package) {
+ int ioctl_nr = _IOC_NR(bridge_package->ui32BridgeID);
+ LOG(">>> pvr_ioctl(%s)(0x%x)\n", pvrsrv_ioctl_names[ioctl_nr], bridge_package->ui32BridgeID);
+ switch(ioctl_nr) {
+ case _IOC_NR(PVRSRV_BRIDGE_CONNECT_SERVICES): {
+ PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *data = bridge_package->pvParamOut;
+ data->eError = PVRSRV_OK;
+ data->hKernelServices = (void*)0x2;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_ENUM_DEVICES): {
+ PVRSRV_BRIDGE_OUT_ENUMDEVICE *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->ui32NumDevices = 1;
+ out->asDeviceIdentifier[0].eDeviceType = PVRSRV_DEVICE_TYPE_SGX;
+ out->asDeviceIdentifier[0].eDeviceClass = PVRSRV_DEVICE_CLASS_3D;
+ out->asDeviceIdentifier[0].ui32DeviceIndex = 0;
+ out->asDeviceIdentifier[0].pszPDumpDevName = NULL;
+ out->asDeviceIdentifier[0].pszPDumpRegName = NULL;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO): {
+ PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->hDevCookie = (void*)0x1;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_SGX_GETMISCINFO): {
+ LOG("Get misc info!\n");
+ PVRSRV_BRIDGE_IN_SGXGETMISCINFO *in = bridge_package->pvParamIn;
+ PVRSRV_BRIDGE_RETURN *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ get_misc_info(in->psMiscInfo);
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_SGX_GETCLIENTINFO): {
+ PVRSRV_BRIDGE_OUT_GETCLIENTINFO *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->sClientInfo.ui32ProcessID = getpid();;
+ out->sClientInfo.pvProcess = NULL;
+ PVRSRV_MISC_INFO *misc = &out->sClientInfo.sMiscInfo;
+ misc->ui32StatePresent = 0;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_ENUM_CLASS): {
+ PVRSRV_BRIDGE_OUT_ENUMDEVICE *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->ui32NumDevices = 1;
+ out->asDeviceIdentifier[0].eDeviceType = PVRSRV_DEVICE_TYPE_SGX;
+ out->asDeviceIdentifier[0].eDeviceClass = PVRSRV_DEVICE_CLASS_3D;
+ out->asDeviceIdentifier[0].ui32DeviceIndex = 0;
+ out->asDeviceIdentifier[0].pszPDumpDevName = "";
+ out->asDeviceIdentifier[0].pszPDumpRegName = "";
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT): {
+ PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->hDevMemContext = (void*)0x2;
+ out->ui32ClientHeapCount = sizeof(pvr_heaps)/sizeof(*pvr_heaps);
+ memcpy(out->sHeapInfo, pvr_heaps, sizeof(pvr_heaps));
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE): {
+ PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->hDeviceKM = (void*)0x1;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_GET_DISPCLASS_INFO): {
+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->sDisplayInfo.ui32MaxSwapChains = 3;
+ out->sDisplayInfo.ui32MaxSwapChainBuffers = 3;
+ out->sDisplayInfo.ui32MinSwapInterval = 0;
+ out->sDisplayInfo.ui32MaxSwapInterval = 1;
+ out->sDisplayInfo.ui32PhysicalWidthmm = 256;
+ out->sDisplayInfo.ui32PhysicalHeightmm = 256;
+ strcpy(out->sDisplayInfo.szDisplayName, "Display");
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS): {
+ PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->ui32Count = 1;
+ out->asFormat[0].pixelformat = PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS): {
+ PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->ui32Count = 1;
+ out->asDim[0].ui32ByteStride = 256;
+ out->asDim[0].ui32Width = 256;
+ out->asDim[0].ui32Height = 256;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER): {
+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->hBuffer = (void*)alloc_memory(0, 256*256*4);
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY): {
+ PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *in = bridge_package->pvParamIn;
+ PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *out = bridge_package->pvParamOut;
+ LOG("Attempting map 0x%x\n", (uint32_t)in->hDeviceClassBuffer);
+ out->eError = PVRSRV_OK;
+ out->sClientMemInfo.hMappingInfo = (void*)alloc_memory(0, 256*256*4);
+ struct memory_allocation *mem = &allocations[((size_t)out->sClientMemInfo.hMappingInfo) - 1];
+ out->sClientMemInfo.pvLinAddr = mem->cpu_ptr;
+ out->sClientMemInfo.pvLinAddrKM = mem->cpu_ptr;
+ out->sClientMemInfo.uAllocSize = mem->size;
+ out->sClientMemInfo.hKernelMemInfo = out->sClientMemInfo.hMappingInfo;
+ out->sClientMemInfo.hResItem = out->sClientMemInfo.hMappingInfo;
+ out->sClientMemInfo.psNext = NULL;
+
+ out->sClientSyncInfo.hMappingInfo = (void*)alloc_memory(0, 1024);
+ out->sClientSyncInfo.psSyncData = NULL;
+ out->sClientSyncInfo.sWriteOpsCompleteDevVAddr.uiAddr = 0xDEADBEEF;
+ out->sClientSyncInfo.sReadOpsCompleteDevVAddr.uiAddr = (uintptr_t)out->sClientSyncInfo.hMappingInfo;
+ out->sClientSyncInfo.sReadOps2CompleteDevVAddr.uiAddr = 0xDEADBEF1;
+ out->sClientSyncInfo.hKernelSyncInfo = out->sClientSyncInfo.hMappingInfo;
+
+ out->psKernelMemInfo = NULL;
+ out->hMappingInfo = out->sClientMemInfo.hMappingInfo;
+ LOG("Allocated 0x%x\n", (uint32_t)out->sClientMemInfo.hMappingInfo);
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA): {
+ PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *in = bridge_package->pvParamIn;
+ PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *out = bridge_package->pvParamOut;
+ size_t handle = (size_t)in->hMHandle;
+ LOG("Attempting mhandle map 0x%x\n", handle);
+ if (handle - 1 < MAX_ALLOCATIONS) {
+ struct memory_allocation *mem = &allocations[handle - 1];
+ out->eError = PVRSRV_OK;
+ out->uiMMapOffset = (uintptr_t)mem->cpu_ptr;
+ out->uiByteOffset = 0;
+ out->uiRealByteSize = mem->size;
+ out->uiUserVAddr = (uintptr_t)mem->cpu_ptr;
+ } else {
+ out->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN): {
+ PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ // TODO figure out what this is
+ out->ui32ReadOpsPending = 0;
+ out->ui32WriteOpsPending = 0;
+ out->ui32ReadOps2Pending = 0;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN): {
+ PVRSRV_BRIDGE_RETURN *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_RELEASE_MMAP_DATA): {
+ PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ // TODO figure out what this is
+ out->bMUnmap = false;
+ break;
+ }
+ case _IOC_NR(PVRSRV_BRIDGE_DISCONNECT_SERVICES):
+ case _IOC_NR(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO):
+ case _IOC_NR(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE):
+ case _IOC_NR(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY):
+ case _IOC_NR(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT): {
+ PVRSRV_BRIDGE_RETURN *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ break;
+ }
+#if 0
+ case _IOC_NR(PVRSRV_BRIDGE_SGX_DEVINITPART2): {
+ PVRSRV_BRIDGE_OUT_SGXDEVINITPART2 *out = bridge_package->pvParamOut;
+ out->eError = PVRSRV_OK;
+ out->ui32KMBuildOptions = SGX_BUILD_OPTIONS;
+ printf("Input size is 0x%x\n", bridge_package->ui32InBufferSize);
+ printf("Build options 0x%x\n", SGX_BUILD_OPTIONS);
+ //out->ui32KMBuildOptions = 0x36a118;
+ break;
+ }
+#endif
+ default:
+ LOG("Unimplemented pvrsrv ioctl %d, may be %s\n", ioctl_nr, pvrsrv_ioctl_names[ioctl_nr]);
+ assert(false);
+ break;
+ }
+ return false;
+}
+
+static bool spoof_ioctl(int fd, int request, void *ptr) {
+ int ioctl_nr = _IOC_NR(request);
+ switch(ioctl_nr) {
+ case _IOC_NR(DRM_IOCTL_VERSION): {
+ LOG("Spoofing device info\n");
+ drmVersionPtr version = (drmVersionPtr)ptr;
+ version->version_major = 1;
+ version->version_minor = 13;
+ version->version_patchlevel = 3341330;
+ version->name_len = sizeof(DEV_NAME);
+ version->date_len = sizeof(DEV_DATE);
+ version->desc_len = sizeof(DEV_DESC);
+
+ if (version->name)
+ strcpy(version->name, DEV_NAME);
+ if (version->date)
+ strcpy(version->date, DEV_DATE);
+ if (version->desc)
+ strcpy(version->desc, DEV_DESC);
+
+ break;
+ }
+
+#if 0
+ case _IOC_NR(DRM_IOCTL_GET_MAGIC):
+ printf(">>> ioctl(DRM_IOCTL_GET_MAGIC)\n");
+ break;
+ case _IOC_NR(DRM_IOCTL_GET_UNIQUE):
+ printf(">>> ioctl(DRM_IOCTL_GET_UNIQUE)\n");
+ break;
+ case _IOC_NR(DRM_IOCTL_SET_VERSION):
+ printf(">>> ioctl(DRM_IOCTL_SET_VERSION)\n");
+ {
+ struct drm_set_version *data = ptr;
+ printf("\t%d %d %d %d\n", data->drm_di_major,
+ data->drm_di_minor,
+ data->drm_dd_major,
+ data->drm_dd_minor);
+ }
+ break;
+#endif
+ case _IOC_NR(DRM_IOCTL_DROP_MASTER):
+ LOG(">>> ioctl(DRM_IOCTL_DROP_MASTER)\n");
+ return 0;
+ case PVR_DRM_SRVKM_CMD:
+ //fwrite(ptr, 1, sizeof(PVRSRV_BRIDGE_PACKAGE), log_file);
+ //PPRINT(stdout, ptr, PVRSRV_BRIDGE_PACKAGE);
+ return pvrsrv_ioctl(fd, ptr);
+ break;
+ case PVR_DRM_IS_MASTER_CMD:
+ LOG(">>> ioctl(PVR_DRM_IS_MASTER_CMD) 0x%x\n", PVR_DRM_SRVKM_CMD);
+ /* From KMD source code this seems to always return 0 */
+ break;
+ default:
+ LOG("Unimplemented ioctl 0x%x\n", ioctl_nr);
+ assert(false);
+ break;
+ }
+ return 0;
+}
+
+int ioctl(int fd, int request, ...) {
+ PROLOG(ioctl);
+ int ioc_size = _IOC_SIZE(request);
+ bool pvr = fd == false_fd;
+
+ //printf("Size is %d\n", ioc_size);
+ void *ptr = NULL;
+ if(ioc_size) {
+ va_list args;
+ va_start(args, request);
+ ptr = va_arg(args, void *);
+ va_end(args);
+ }
+
+ LOG("Got ioctl %d!\n", fd);
+
+ if (pvr)
+ return spoof_ioctl(fd, request, ptr);
+ else
+ return orig_ioctl(fd, request, ptr);
+}
+
+int open(const char *pathname, int flags, mode_t mode) {
+ LOG("Called open on %s (%d)\n", pathname, flags);
+ PROLOG(open);
+ return orig_open(pathname, flags, mode);
+}
+
+int openat(int dirfd, const char *pathname, int flags, ...) {
+ LOG("Called openat on %s (%d) (%d)\n", pathname, dirfd, flags);
+ PROLOG(openat);
+
+ return orig_openat(dirfd, pathname, flags);
+}
+
+int openat64(int fd, const char * path, int oflag, ...) {
+ LOG("Called openat64 %s\n", path);
+ PROLOG(openat64);
+ return orig_openat64(fd, path, oflag);
+}
+
+DIR *opendir(const char *dirname) {
+ LOG("Opening dir %s\n", dirname);
+ PROLOG(opendir);
+ return orig_opendir(dirname);
+}
+
+struct dirent *readdir(DIR *dirp) {
+ PROLOG(readdir);
+ struct dirent *out = orig_readdir(dirp);
+ if (out) {
+ //printf("Reading %d %d %s\n", (int)out->d_type, (int)out->d_reclen, (char*)out->d_name);
+ }
+ return out;
+}