Now About Social Code
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drvemu.c161
1 files changed, 131 insertions, 30 deletions
diff --git a/drvemu.c b/drvemu.c
index 63c4998..75592f7 100644
--- a/drvemu.c
+++ b/drvemu.c
@@ -39,28 +39,69 @@
#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, ...) {
- printf("Called open64 on %s (%d)\n", pathname, flags);
+ LOG("Called open64 on %s (%d)\n", pathname, flags);
PROLOG(open64);
- int fd = orig_open64(pathname, flags);
if (strcmp(pathname, "/dev/dri/renderD128") == 0) {
- printf("Spoofing FD!\n");
+ 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) {
- printf("Called fcntl on %d\n", fd);
+ LOG("Called fcntl on %d\n", fd);
PROLOG(fcntl);
if (fd == false_fd)
@@ -160,8 +201,17 @@ void get_misc_info(SGX_MISC_INFO *info) {
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:
- printf("Unimplemented misc req %d\n", info->eRequest);
+ LOG("Unimplemented misc req %d\n", info->eRequest);
assert(false);
break;
}
@@ -169,7 +219,7 @@ void get_misc_info(SGX_MISC_INFO *info) {
static bool pvrsrv_ioctl(int fd, PVRSRV_BRIDGE_PACKAGE *bridge_package) {
int ioctl_nr = _IOC_NR(bridge_package->ui32BridgeID);
- printf(">>> pvr_ioctl(%s)(0x%x)\n", pvrsrv_ioctl_names[ioctl_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;
@@ -195,7 +245,7 @@ static bool pvrsrv_ioctl(int fd, PVRSRV_BRIDGE_PACKAGE *bridge_package) {
break;
}
case _IOC_NR(PVRSRV_BRIDGE_SGX_GETMISCINFO): {
- printf("Get misc info!\n");
+ LOG("Get misc info!\n");
PVRSRV_BRIDGE_IN_SGXGETMISCINFO *in = bridge_package->pvParamIn;
PVRSRV_BRIDGE_RETURN *out = bridge_package->pvParamOut;
out->eError = PVRSRV_OK;
@@ -232,6 +282,7 @@ static bool pvrsrv_ioctl(int fd, PVRSRV_BRIDGE_PACKAGE *bridge_package) {
}
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;
}
@@ -266,32 +317,82 @@ static bool pvrsrv_ioctl(int fd, PVRSRV_BRIDGE_PACKAGE *bridge_package) {
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*)0x1234;
+ 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;
- printf("Attempting map 0x%x\n", (uint32_t)in->hDeviceClassBuffer);
+ LOG("Attempting map 0x%x\n", (uint32_t)in->hDeviceClassBuffer);
out->eError = PVRSRV_OK;
- out->sClientMemInfo.hMappingInfo = (void*)0x43214321;
- //out->sClientSyncInfo = 0;
- out->psKernelMemInfo = (void*)0xDEADBEEF;
- out->hMappingInfo = (void*)0x12341234;
+ 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;
- printf("Attempting mhandle map 0x%x\n", (uint32_t)in->hMHandle);
- //out->eError = PVRSRV_OK;
- //out->sClientMemInfo = ;
- //out->sClientSyncInfo = 0;
- //out->psKernelMemInfo = (void*)0xDEADBEEF;
- //out->hMappingInfo = (void*)0x1;
+ 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;
@@ -304,7 +405,7 @@ static bool pvrsrv_ioctl(int fd, PVRSRV_BRIDGE_PACKAGE *bridge_package) {
}
#endif
default:
- printf("Unimplemented pvrsrv ioctl %d, may be %s\n", ioctl_nr, pvrsrv_ioctl_names[ioctl_nr]);
+ LOG("Unimplemented pvrsrv ioctl %d, may be %s\n", ioctl_nr, pvrsrv_ioctl_names[ioctl_nr]);
assert(false);
break;
}
@@ -315,7 +416,7 @@ 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): {
- printf("Spoofing device info\n");
+ LOG("Spoofing device info\n");
drmVersionPtr version = (drmVersionPtr)ptr;
version->version_major = 1;
version->version_minor = 13;
@@ -353,7 +454,7 @@ static bool spoof_ioctl(int fd, int request, void *ptr) {
break;
#endif
case _IOC_NR(DRM_IOCTL_DROP_MASTER):
- printf(">>> ioctl(DRM_IOCTL_DROP_MASTER)\n");
+ LOG(">>> ioctl(DRM_IOCTL_DROP_MASTER)\n");
return 0;
case PVR_DRM_SRVKM_CMD:
//fwrite(ptr, 1, sizeof(PVRSRV_BRIDGE_PACKAGE), log_file);
@@ -361,11 +462,11 @@ static bool spoof_ioctl(int fd, int request, void *ptr) {
return pvrsrv_ioctl(fd, ptr);
break;
case PVR_DRM_IS_MASTER_CMD:
- printf(">>> ioctl(PVR_DRM_IS_MASTER_CMD) 0x%x\n", PVR_DRM_SRVKM_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:
- printf("Unimplemented ioctl 0x%x\n", ioctl_nr);
+ LOG("Unimplemented ioctl 0x%x\n", ioctl_nr);
assert(false);
break;
}
@@ -386,7 +487,7 @@ int ioctl(int fd, int request, ...) {
va_end(args);
}
- printf("Got ioctl %d!\n", fd);
+ LOG("Got ioctl %d!\n", fd);
if (pvr)
return spoof_ioctl(fd, request, ptr);
@@ -395,26 +496,26 @@ int ioctl(int fd, int request, ...) {
}
int open(const char *pathname, int flags, mode_t mode) {
- printf("Called open on %s (%d)\n", pathname, flags);
+ 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, ...) {
- printf("Called openat on %s (%d) (%d)\n", pathname, dirfd, 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, ...) {
- printf("Called openat64 %s\n", path);
+ LOG("Called openat64 %s\n", path);
PROLOG(openat64);
return orig_openat64(fd, path, oflag);
}
DIR *opendir(const char *dirname) {
- printf("Opening dir %s\n", dirname);
+ LOG("Opening dir %s\n", dirname);
PROLOG(opendir);
return orig_opendir(dirname);
}