Result writehax_sharedmem_physmem(u32 *linearaddr) { Result ret=0; u32 chunksize = 0x1000; u32 *tmpbuf; //Allocate memory for the sharedmem page, then copy the sharedmem physmem data into the buf. tmpbuf = linearAlloc(chunksize); if(tmpbuf==NULL) { printf("Failed to allocate mem for tmpbuf.\n"); return -1; } memset(tmpbuf, 0, chunksize); GSPGPU_FlushDataCache(tmpbuf, chunksize); GX_TextureCopy(linearaddr, 0, tmpbuf, 0, chunksize, 0x8); gspWaitForPPF(); ret = init_hax_sharedmem(tmpbuf); if(ret) { linearFree(tmpbuf); return ret; } //Flush dcache for the modified sharedmem, then copy the data back into the sharedmem physmem. GSPGPU_FlushDataCache(tmpbuf, chunksize); GX_TextureCopy(tmpbuf, 0, linearaddr, 0, chunksize, 0x8); gspWaitForPPF(); linearFree(tmpbuf); return 0; }
static void svchax_gspwn(u32 dst, u32 src, u32 size, u8* flush_buffer) { extern Handle gspEvents[GSPEVENT_MAX]; memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); GSPGPU_InvalidateDataCache(dst, size); GSPGPU_FlushDataCache(src, size); memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); svcClearEvent(gspEvents[GSPEVENT_PPF]); GX_TextureCopy(src, 0, dst, 0, size, 8); svcWaitSynchronization(gspEvents[GSPEVENT_PPF], U64_MAX); memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); }
void gxlowcmd_4(u32* inadr, u32* outadr, u32 size, u32 width0, u32 height0, u32 width1, u32 height1, u32 flags) { GX_TextureCopy(inadr, width0 | (height0<<16), outadr, width1 | (height1<<16), size, flags); }
//This searches physmem for the page which starts with the data stored in cmpblock_bin. The first byte in cmpblock is XORed with 0x01 to avoid detecting the cmpblock in physmem. Result locate_sharedmem_linearaddr(u32 **linearaddr) { u8 *tmpbuf; u32 chunksize = 0x100000; u32 linearpos, bufpos, size; u32 i; u32 xorval; int found = 0; *linearaddr = NULL; tmpbuf = linearAlloc(chunksize); if(tmpbuf==NULL) { printf("Failed to allocate mem for tmpbuf.\n"); return -1; } size = osGetMemRegionSize(MEMREGION_APPLICATION); for(linearpos=0; linearpos<size; linearpos+= chunksize) { *linearaddr = (u32*)(0x30000000+linearpos); memset(tmpbuf, 0, chunksize); GSPGPU_FlushDataCache(tmpbuf, chunksize); GX_TextureCopy(*linearaddr, 0, (u32*)tmpbuf, 0, chunksize, 0x8); gspWaitForPPF(); for(bufpos=0; bufpos<chunksize; bufpos+= 0x1000) { found = 1; for(i=0; i<cmpblock_bin_size; i++) { xorval = 0; if(i==0)xorval = 1; if(tmpbuf[bufpos + i] != (cmpblock_bin[i] ^ xorval)) { found = 0; break; } } if(found) { *linearaddr = (u32*)(0x30000000+linearpos+bufpos); break; } } if(found)break; } linearFree(tmpbuf); if(!found)return -1; return 0; }