From 9877e681935c72e575448d51b1730daac1f6aa9a Mon Sep 17 00:00:00 2001 From: Lucas Fryzek Date: Tue, 16 Jul 2024 17:09:06 +0100 Subject: drvemu: Get `sgx_init_info` to run successfully --- drvemu.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 131 insertions(+), 30 deletions(-) (limited to 'drvemu.c') 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); } -- cgit