From 9e2938dff48ca2c771585e8417168125d56b5742 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 17 Mar 2019 23:46:39 +0100 Subject: [PATCH] mmu: state change wasn't detected. WinCE syscalls tracing --- core/hw/sh4/modules/ccn.cpp | 14 +- core/hw/sh4/modules/mmu.cpp | 27 ++++ core/hw/sh4/modules/wince.h | 291 ++++++++++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 core/hw/sh4/modules/wince.h diff --git a/core/hw/sh4/modules/ccn.cpp b/core/hw/sh4/modules/ccn.cpp index 0d34c4f2b..49b7c574f 100644 --- a/core/hw/sh4/modules/ccn.cpp +++ b/core/hw/sh4/modules/ccn.cpp @@ -46,12 +46,8 @@ void CCN_MMUCR_write(u32 addr, u32 value) CCN_MMUCR_type temp; temp.reg_data=value; - if (temp.AT != CCN_MMUCR.AT) - { - //printf("<*******>MMU Enabled , ONLY SQ remaps work<*******>\n"); - mmu_set_state(); - } - + bool mmu_changed_state = temp.AT != CCN_MMUCR.AT; + if (temp.TI != 0) { for (u32 i = 0; i < 4; i++) @@ -63,6 +59,12 @@ void CCN_MMUCR_write(u32 addr, u32 value) temp.TI = 0; } CCN_MMUCR=temp; + + if (mmu_changed_state) + { + //printf("<*******>MMU Enabled , ONLY SQ remaps work<*******>\n"); + mmu_set_state(); + } } void CCN_CCR_write(u32 addr, u32 value) { diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 063065f60..67f04775b 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -78,6 +78,10 @@ defining NO_MMU disables the full mmu emulation #include "hw/mem/_vmem.h" +#ifdef TRACE_WINCE_SYSCALLS +#include "wince.h" +#endif + #define printf_mmu(...) #define printf_win32(...) @@ -229,8 +233,20 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) RaiseException(0xE0, 0x100); else //IADDERR - Instruction Address Error { +#ifdef TRACE_WINCE_SYSCALLS + bool skip_exception = false; + if (!print_wince_syscall(address, skip_exception)) + printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); + //if (!skip_exception) + RaiseException(0xE0, 0x100); + //else { + // SH4ThrownException ex = { 0, 0, 0 }; + // throw ex; + //} +#else printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); RaiseException(0xE0, 0x100); +#endif return; } printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled\n", address); @@ -414,6 +430,17 @@ u32 mmu_data_translation(u32 va, u32& rv) if (lookup != MMU_ERROR_NONE) return lookup; +#ifdef TRACE_WINCE_SYSCALLS + if (unresolved_unicode_string != 0) + { + if (va == unresolved_unicode_string) + { + unresolved_unicode_string = 0; + printf("RESOLVED %s\n", get_unicode_string(va).c_str()); + } + } +#endif + u32 md = UTLB[entry].Data.PR >> 1; //0X & User mode-> protection violation diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h new file mode 100644 index 000000000..0c0b854af --- /dev/null +++ b/core/hw/sh4/modules/wince.h @@ -0,0 +1,291 @@ +#include "hw/sh4/sh4_sched.h" + +#define PUserKData 0x00005800 +#define SYSHANDLE_OFFSET 0x004 +#define SYS_HANDLE_BASE 64 +#define SH_WIN32 0 +#define SH_CURTHREAD 1 +#define SH_CURPROC 2 + +static inline u32 GetCurrentThreadId() +{ + u32 addr = PUserKData + SYSHANDLE_OFFSET + SH_CURTHREAD * 4; + return mmu_ReadMem32(addr); +} + +static inline u32 GetCurrentProcessId() +{ + u32 addr = PUserKData + SYSHANDLE_OFFSET + SH_CURPROC * 4; + return mmu_ReadMem32(addr); +} + +#define FIRST_METHOD 0xFFFFFE01 +#define APICALL_SCALE 2 + +static const char *wince_apis[] = { + // SH_* + "WIN32", "CURTHREAD", "CURPROC", "WDMAPI", + // HT_* + "EVENT", "MUTEX", "APISET", "FILE", "FIND", "DBFILE", "DBFIND", "SOCKET", "INTERFACE", "SEMAPHORE", "FSMAP", "WNETENUM", + // SH_* + "GDI", "WMGR", "INIT", "COMM", "FILESYS", "SHELL", "DEVMGR", "TAPI", "PATCHER", "IMM", "WNET", "?", "?", "?", "?", "USER" +}; + +static const char *wince_methods[][256] = { + // WIN32 + { + "Nop", "N/S", "CreateAPISet", "VirtualAlloc", "VirtualFree", "VirtualProtect", "VirtualQuery", "VirtualCopy", + "LoadLibraryW", "FreeLibrary", "GetProcAddressW", "ThreadAttachAllDLLs", "ThreadDetachAllDLLs", "GetTickCount", "OutputDebugStringW", "TlsCall", + "GetSystemInfo", "(ropen)", "(rread)", "(rwrite)", "(rlseek)", "(rclose)", "RegisterDbgZones", "NKvDbgPrintfW", + "ProfileSyscall", "FindResource", "LoadResource", "SizeofResource", "GetRealTime", "SetRealTime", "ProcessDetachAllDLLs", "ExtractResource", + // 32 + "GetRomFileInfo", "GetRomFileBytes", "CacheRangeFlush", "AddTrackedItem", "DeleteTrackedItem", "PrintTrackedItem", "GetKPhys", "GiveKPhys", + "SetExceptionHandler", "RegisterTrackedItem", "FilterTrackedItem", "SetKernelAlarm", "RefreshKernelAlarm", "CeGetRandomSeed", "CloseProcOE", "SetGwesOOMEvent", + "StringCompress", "StringDecompress", "BinaryCompress", "BinaryDecompress", "CreateEvent", "CreateProc", "CreateThread", "InputDebugCharW", + "TakeCritSec", "LeaveCritSec", "WaitForMultiple", "MapPtrToProcess", "MapPtrUnsecure", "GetProcFromPtr", "IsBadPtr", "GetProcAddrBits", + // 64 + "GetFSHeapInfo", "OtherThreadsRunning", "KillAllOtherThreads", "GetOwnerProcess", "GetCallerProcess", "GetIdleTime", "SetLowestScheduledPriority", "IsPrimaryThread", + "SetProcPermissions", "GetCurrentPermissions", "(74?)", "SetDaylightTime", "SetTimeZoneBias", "SetCleanRebootFlag", "CreateCrit", "PowerOffSystem", + "CreateMutex", "SetDbgZone", "Sleep", "TurnOnProfiling", "TurnOffProfiling", "CeGetCurrentTrust", "CeGetCallerTrust", "NKTerminateThread", + "SetLastError", "GetLastError", "GetProcName", "TerminateSelf", "CloseAllHandles", "SetHandleOwner", "LoadDriver", "CreateFileMapping", + // 96 + "UnmapViewOfFile", "FlushViewOfFile", "CreateFileForMappingW", "KernelIoControl", "GetThreadCallStack", "PPSHRestart", "(102?)", "UpdateNLSInfo", + "ConnectDebugger", "InterruptInitialize", "InterruptDone", "InterruptDisable", "SetKMode", "SetPowerOffHandler", "SetGwesPowerHandler", "SetHardwareWatch", + "QueryAPISetID", "PerformCallBack", "CaptureContext", "GetCallerProcessIndex", "WaitForDebugEvent", "ContinueDebugEvent", "DebugNotify", "OpenProcess", + "THCreateSnapshot", "THGrow", "NotifyForceCleanboot", "DumpKCallProfile", "GetProcessVersion", "GetModuleFileNameW", "QueryPerformanceCounter", "QueryPerformanceFrequency", + // 128 + "KernExtractIcons", "ForcePageout", "GetThreadTimes", "GetModuleHandleW", "SetWDevicePowerHandler", "SetStdioPathW", "GetStdioPathW", "ReadRegistryFromOEM", + "WriteRegistryToOEM", "WriteDebugLED", "LockPages", "UnlockPages", "VirtualSetAttributes", "SetRAMMode", "SetStoreQueueBase", "FlushViewOfFileMaybe", + }, + // CURTHREAD + { + "CloseHandle", "(AllHandle_Wait)", "Suspend", "Resume", "SetThreadPrio", "GetThreadPrio", "GetRetCode", "GetContext", + "SetContext", "Terminate", "CeGetPrio", "CeSetPrio", "CeGetQuant", "CeSetQuant" + }, + // CURPROC + { + "CloseHandle", "(AllHandle_Wait)", "Terminate", "GetRetCode", "FlushICache", "ReadMemory", "WriteMemory", "DebugActive", "GetModInfo", "SetVer" + }, + // unused + { + }, + // EVENT + { + "CloseHandle", "(AllHandle_Wait)", "Modify", "AddAccess", "GetData", "SetData" + }, + // MUTEX + { + "CloseHandle", "(AllHandle_Wait)", "ReleaseMutex" + }, + // APISET + { + "CloseHandle", "(AllHandle_Wait)", "Register", "CreateHandle", "Verify" + }, + // FILE + { + "CloseFileHandle", "(NULL)", "ReadFile", "WriteFile", "GetFileSize", "SetFilePointer", "GetFileInformationByHandle", "FlushFileBuffers", + "GetFileTime", "SetFileTime", "SetEndOfFile", "DeviceIoControl", "ReadFileWithSeek", "WriteFileWithSeek" + }, + // FIND + { + "FindClose", "(NULL)", "FindNextFile" + }, + // DBFILE + { + }, + // DBFIND + { + }, + // SOCKET + { + }, + // INTERFACE + { + }, + // SEMAPHORE + { + }, + // FSMAP + { + }, + // WNETENUM + { + }, + // GDI + { + }, + // WMGR + { + }, + // INIT + { + }, + // COMM + { + }, + // FILESYS + { + "ProcNotify", "(AllHandle_Wait)", "CreateDirectory", "RemoveDirectory", "MoveFile", "CopyFile", "DeleteFile", "GetFileAttibutes", + "FindFirstFile", "CreateFile", "CeRegisterFileSystemNotification", "CeRegisterReplNotification", "CeOidGetInfoEx", "CeFindFirstDatabaseEx", "CeCreateDatabaseEx", "CeSetDatabaseInfoEx", + "CeOpenDatabaseEx", "RegCloseKey", "RegCreateKeyExW", "RegDeleteKeyW", "RegDeleteValueW", "RegEnumValueW", "RegEnumKeyExW", "RegOpenKeyExW", + "RegQueryInfoKeyW", "RegQueryValueExW", "RegSetValueExW", "GetTempPathW", "CeDeleteDatabaseEx", "CheckPassword", "SetPassword", "SetFileAttributesW", + "GetStoreInformation", "CeGetReplChangeMask", "CeSetReplChangeMask", "CeGetReplChangeBitsEx", "CeClearReplChangeBitsEx", "CeGetReplOtherBitsEx", "CeSetReplOtherBitsEx", "GetSystemMemoryDivision", + "SetSystemMemoryDivision", "RegCopyFile", "CloseAllFileHandles", "PrestoChangoFileName", "RegRestoreFile", "RegisterAFS", "DeregisterAFS", "GetPasswordActive", + "SetPasswordActive", "RegFlushKey", "NotifyMountedFS", "CeSetReplChangeBitsEx", "RegisterAFSName", "DeregisterAFSName", "GetDiskFreeSpaceExW", "RegisterHiddenAFS", + "CeChangeDatabaseLCID", "DumpHeap", "CeMountDBVol", "CeEnumDBVolumes", "CeUnmountDBVol", "CeFlushDBVol", "CeFreeNotification" + }, + // SHELL + { + }, + // DEVMGR + { + }, + // TAPI + { + }, + // PATCHER + { + }, + // IMM + { + }, + // WNET + { + }, + { + }, + { + }, + { + }, + { + }, + // USER + { + "NotifyCallback", "(unused)", "RegisterClass", "UnregisterClass", "CreateWindowEx", "PostMessage", "PostQuitMessage", "SendMessage", + "GetMessage", "TranslateMessage", "DispatchMessage", "GetCapture", "SetCapture", "ReleaseCapture", "(ununsed)", "(ununsed)", + "(ununsed)", "(ununsed)", "(ununsed)", "GetSystemMetrics", "ImageList_GetDragImage", "ImageList_GetIconSize", "ImageList_SetIconSize", "ImageList_GetImageInfo", + "ImageList_Merge", "ShowCursor", "SetCursorPos", "ImageList_CopyDitherImage", "ImageList_DrawIndirect", "ImageList_DragShowNolock", "CWindowManager::WindowFromPoint(tagPOINT)", "(unused)", + }, +}; + +u32 unresolved_ascii_string; +u32 unresolved_unicode_string; + +std::string get_unicode_string(u32 addr) +{ + try { + std::string str; + while (true) + { + int c = mmu_ReadMem16(addr); + if (c == 0) + break; + str += (char)c; + addr += 2; + } + return str; + } catch (SH4ThrownException& ex) { + unresolved_unicode_string = addr; + return "(page fault)"; + } +} +std::string get_ascii_string(u32 addr) +{ + try { + std::string str; + while (true) + { + int c = mmu_ReadMem8(addr++); + if (c == 0) + break; + str += (char)c; + } + return str; + } catch (SH4ThrownException& ex) { + unresolved_ascii_string = addr; + return "(page fault)"; + } +} + +static bool print_wince_syscall(u32 address, bool &skip_exception) +{ + skip_exception = false; + if (address & 1) + { + if (address == 0xfffffd5d || address == 0xfffffd05) // Sleep, QueryPerformanceCounter + return true; + if (address == 0xfffffde7) // GetTickCount + { + // This should make this syscall faster + //r[0] = sh4_sched_now64() * 1000 / SH4_MAIN_CLOCK; + //next_pc = pr; + //skip_exception = true; + return true; + } + + u32 api_id; + if (address <= FIRST_METHOD) + api_id = (((FIRST_METHOD - address) / APICALL_SCALE) >> 8) & 0x3F; + else + api_id = 0; + const char *api; + char api_buf[128]; + + if (api_id < ARRAY_SIZE(wince_apis)) + api = wince_apis[api_id]; + else + { + sprintf(api_buf, "[%d]", api_id); + api = api_buf; + } + + u32 meth_id; + if (address <= FIRST_METHOD) + meth_id = ((FIRST_METHOD - address) / APICALL_SCALE) & 0xFF; + else + meth_id = ((address - FIRST_METHOD) / APICALL_SCALE) & 0xFF; + const char *method = NULL; + char method_buf[128]; + + if (api_id < ARRAY_SIZE(wince_methods) && meth_id < ARRAY_SIZE(wince_methods[api_id])) + method = wince_methods[api_id][meth_id]; + if (method == NULL) + { + sprintf(method_buf, "[%d]", meth_id); + method = method_buf; + } + printf("WinCE %08x %04x.%04x %s: %s", address, GetCurrentProcessId() & 0xffff, GetCurrentThreadId() & 0xffff, api, method); + if (address == 0xfffffd51) // SetLastError + printf(" dwErrCode = %x\n", r[4]); + else if (address == 0xffffd5ef) // CreateFile + printf(" lpFileName = %s\n", get_unicode_string(r[4]).c_str()); + else if (address == 0xfffffd97) // CreateProc + printf(" imageName = %s, commandLine = %s\n", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); + else if (!strcmp("DebugNotify", method)) + printf(" %x, %x\n", r[4], r[5]); + else if (address == 0xffffd5d3) // RegOpenKeyExW + printf(" hKey = %x, lpSubKey = %s\n", r[4], get_unicode_string(r[5]).c_str()); + else if (!strcmp("LoadLibraryW", method)) + printf(" fileName = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("GetProcAddressW", method)) + printf(" hModule = %x, procName = %s\n", r[4], get_unicode_string(r[5]).c_str()); + else if (!strcmp("NKvDbgPrintfW", method)) + printf(" fmt = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("OutputDebugStringW", method)) + printf(" str = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("RegisterAFSName", method)) + printf(" name = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("CreateAPISet", method)) + printf(" name = %s\n", get_ascii_string(r[4]).c_str()); + else if (!strcmp("Register", method) && !strcmp("APISET", api)) + printf(" p = %x, id = %x\n", r[4], r[5]); + else + printf("\n"); + + return true; + } + else + return false; + +}