From 499cc60e728ff7225fd7cac158ff772435c27b62 Mon Sep 17 00:00:00 2001 From: Lucas Fryzek Date: Tue, 6 Aug 2024 22:27:40 +0100 Subject: drv: Attempt to add mapping support Map allocated buffers so we can clear them and then write copied dumps from proprietary driver to them. Currently memory allocations fail with `MAP_FAILED` in mmap. --- src/drv.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 14 deletions(-) (limited to 'src/drv.c') diff --git a/src/drv.c b/src/drv.c index e4d74f5..9733ac3 100644 --- a/src/drv.c +++ b/src/drv.c @@ -33,6 +33,11 @@ #define UNUSED(x) (void)x +struct mem_alloc { + PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM dev_mem; + void *data; +}; + struct driver_state { int fd; IMG_HANDLE kernel_services; @@ -44,11 +49,11 @@ struct driver_state { PVRSRV_HEAP_INFO kernel_heap; PVRSRV_HEAP_INFO perctx_3d_heap; PVRSRV_HEAP_INFO ta_data_heap; - PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM ccb_buffer; - PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM kernel_buffer_2; - PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM kernel_buffer_3; - PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM perctx_3d_buffer; - PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM ta_data_buffer; + struct mem_alloc ccb_buffer; + struct mem_alloc kernel_buffer_2; + struct mem_alloc kernel_buffer_3; + struct mem_alloc perctx_3d_buffer; + struct mem_alloc ta_data_buffer; IMG_HANDLE hw_render_ctx; IMG_DEV_VIRTADDR hw_render_ctx_addr; @@ -295,7 +300,8 @@ static void get_dev_mem_heapinfo(struct driver_state *state) { assert(state->perctx_3d_heap.ui32HeapID != 0); } -static PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM allocate_memobj(struct driver_state *state, PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *alloc) { +static struct mem_alloc allocate_memobj(struct driver_state *state, PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *alloc) { + struct mem_alloc mem; PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM out; PVRSRV_BRIDGE_PACKAGE data = { .ui32BridgeID = PVRSRV_BRIDGE_ALLOC_DEVICEMEM, @@ -309,9 +315,41 @@ static PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM allocate_memobj(struct driver_state *sta printf("Allocating from %p %p 0x%x\n", alloc->hDevCookie, alloc->hDevMemHeap, alloc->uSize); check_ioctl(state->fd, DRM_IOCTL_PVR_SRVKM, &data); - check_pvr_error(out.eError); - return out; + + { + PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA in = { + .hMHandle = out.sClientMemInfo.hKernelMemInfo, + }; + PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA out2; + PVRSRV_BRIDGE_PACKAGE data = { + .ui32BridgeID = PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, + .ui32Size = sizeof(data), + .pvParamIn = &in, + .ui32InBufferSize = sizeof(in), + .pvParamOut = &out2, + .ui32OutBufferSize = sizeof(out2), + .hKernelServices = state->kernel_services + }; + + check_ioctl(state->fd, DRM_IOCTL_PVR_SRVKM, &data); + check_pvr_error(out2.eError); + + PPRINT(stdout, &out2, PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA); + + printf("Attempting map 0x%x, 0x%x\n", out2.uiRealByteSize, out2.uiMMapOffset); + //mem.data = mmap2(NULL, out2.uiRealByteSize, PROT_READ|PROT_WRITE, + // MAP_SHARED, state->fd, out2.uiMMapOffset); + mem.data = syscall(SYS_mmap2, NULL, out2.uiRealByteSize, + PROT_READ | PROT_WRITE, MAP_SHARED, + state->fd, out2.uiRealByteSize); + + assert(mem.data != MAP_FAILED); + memset(mem.data, 0x00, out.sClientMemInfo.uAllocSize); + } + + mem.dev_mem = out; + return mem; } static void allocate_memory(struct driver_state *state) { @@ -370,12 +408,12 @@ static void register_hw_render_ctx(struct driver_state *state) { 0x21, 0x1, 0x0, - state->ccb_buffer.sClientMemInfo.sDevVAddr.uiAddr, // Not all zeros - state->kernel_buffer_2.sClientMemInfo.sDevVAddr.uiAddr, // All zeros + state->ccb_buffer.dev_mem.sClientMemInfo.sDevVAddr.uiAddr, // Needs to be patched + state->kernel_buffer_2.dev_mem.sClientMemInfo.sDevVAddr.uiAddr, // All zeros 0x0, - state->kernel_buffer_3.sClientMemInfo.sDevVAddr.uiAddr, // All zeros - state->perctx_3d_buffer.sClientMemInfo.sDevVAddr.uiAddr, // All zeros - state->ta_data_buffer.sClientMemInfo.sDevVAddr.uiAddr, // All zeros + state->kernel_buffer_3.dev_mem.sClientMemInfo.sDevVAddr.uiAddr, // All zeros + state->perctx_3d_buffer.dev_mem.sClientMemInfo.sDevVAddr.uiAddr, // All zeros + state->ta_data_buffer.dev_mem.sClientMemInfo.sDevVAddr.uiAddr, // All zeros 0x0, 0x0, 0x0, @@ -384,7 +422,7 @@ static void register_hw_render_ctx(struct driver_state *state) { 0x0, 0x0, 0x0, - 0x50f, // This value seems to change but I'm not sure why + 0x0, // This value seems to change when dumping, but overriding to zero doesn't break anything }; PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT in = { .hDevCookie = state->dev_cookie, -- cgit