From 2d42ff1f62c6a8c4585c768b4d9dcc6a9cd95ea1 Mon Sep 17 00:00:00 2001 From: Lucas Fryzek Date: Tue, 16 Jul 2024 22:16:16 +0100 Subject: repo: Clean up source organization --- src/drvemu.c | 530 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 530 insertions(+) create mode 100644 src/drvemu.c (limited to 'src/drvemu.c') 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} -- cgit