From 29da6e9ab57a37abafc9c91e00bb01daf451b3ad Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 30 Apr 2014 23:46:06 -0400 Subject: [PATCH 01/22] added a module to load symbol map files for debugging --- src/core/CMakeLists.txt | 1 + src/core/arm/disassembler/load_symbol_map.cpp | 33 +++++++++++++++++++ src/core/arm/disassembler/load_symbol_map.h | 13 ++++++++ src/core/core.vcxproj | 2 ++ src/core/core.vcxproj.filters | 6 ++++ 5 files changed, 55 insertions(+) create mode 100644 src/core/arm/disassembler/load_symbol_map.cpp create mode 100644 src/core/arm/disassembler/load_symbol_map.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 314f6e64c..3308f3c25 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -5,6 +5,7 @@ set(SRCS core.cpp mem_map_funcs.cpp system.cpp arm/disassembler/arm_disasm.cpp + arm/disassembler/load_symbol_map.cpp arm/interpreter/arm_interpreter.cpp arm/interpreter/armemu.cpp arm/interpreter/arminit.cpp diff --git a/src/core/arm/disassembler/load_symbol_map.cpp b/src/core/arm/disassembler/load_symbol_map.cpp new file mode 100644 index 000000000..d7fc0a042 --- /dev/null +++ b/src/core/arm/disassembler/load_symbol_map.cpp @@ -0,0 +1,33 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include +#include + +#include "common/symbols.h" +#include "common/common_types.h" +#include "common/file_util.h" + +#include "core/arm/disassembler/load_symbol_map.h" + +/* + * Loads a symbol map file for use with the disassembler + * @param filename String filename path of symbol map file + */ +void LoadSymbolMap(std::string filename) { + std::ifstream infile(filename); + + std::string address_str, function_name, line; + u32 size, address; + + while (std::getline(infile, line)) { + std::istringstream iss(line); + if (!(iss >> address_str >> size >> function_name)) { + break; // Error parsing + } + u32 address = std::stoul(address_str, nullptr, 16); + + Symbols::Add(address, function_name, size, 2); + } +} diff --git a/src/core/arm/disassembler/load_symbol_map.h b/src/core/arm/disassembler/load_symbol_map.h new file mode 100644 index 000000000..837cca99b --- /dev/null +++ b/src/core/arm/disassembler/load_symbol_map.h @@ -0,0 +1,13 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include + +/* + * Loads a symbol map file for use with the disassembler + * @param filename String filename path of symbol map file + */ +void LoadSymbolMap(std::string filename); diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index be8448969..a5043ea4b 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -138,6 +138,7 @@ + @@ -171,6 +172,7 @@ + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index b5473bc41..9c53f9eff 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -108,6 +108,9 @@ hle + + arm\disassembler + @@ -211,6 +214,9 @@ hle + + arm\disassembler + From 08fb71108abe2862bf02a44cc6e103b86a24f43f Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 30 Apr 2014 23:46:57 -0400 Subject: [PATCH 02/22] added symbol map load function to Qt GUI --- src/citra_qt/main.cpp | 10 +++++++++- src/citra_qt/main.hxx | 9 +++++---- src/citra_qt/main.ui | 18 ++++++++++++------ src/citra_qt/ui_main.h | 5 +++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 89aae7ce6..76e0c68c3 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -23,6 +23,7 @@ #include "core/system.h" #include "core/loader.h" #include "core/core.h" +#include "core/arm/disassembler/load_symbol_map.h" #include "version.h" @@ -74,6 +75,7 @@ GMainWindow::GMainWindow() // Setup connections connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile())); + connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap())); connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame())); connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame())); connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame())); @@ -140,11 +142,17 @@ void GMainWindow::BootGame(const char* filename) void GMainWindow::OnMenuLoadFile() { - QString filename = QFileDialog::getOpenFileName(this, tr("Load file"), QString(), tr("3DS homebrew (*.elf *.dat)")); + QString filename = QFileDialog::getOpenFileName(this, tr("Load file"), QString(), tr("3DS homebrew (*.elf *.dat *.bin)")); if (filename.size()) BootGame(filename.toLatin1().data()); } +void GMainWindow::OnMenuLoadSymbolMap() { + QString filename = QFileDialog::getOpenFileName(this, tr("Load symbol map"), QString(), tr("Symbol map (*)")); + if (filename.size()) + LoadSymbolMap(filename.toLatin1().data()); +} + void GMainWindow::OnStartGame() { render_window->GetEmuThread().SetCpuRunning(true); diff --git a/src/citra_qt/main.hxx b/src/citra_qt/main.hxx index b4b1c533c..fa122f76e 100644 --- a/src/citra_qt/main.hxx +++ b/src/citra_qt/main.hxx @@ -33,10 +33,11 @@ private: void closeEvent(QCloseEvent* event); private slots: - void OnStartGame(); - void OnPauseGame(); - void OnStopGame(); - void OnMenuLoadFile(); + void OnStartGame(); + void OnPauseGame(); + void OnStopGame(); + void OnMenuLoadFile(); + void OnMenuLoadSymbolMap(); void OnOpenHotkeysDialog(); void OnConfigure(); void ToggleWindowMode(); diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index c0cb11a10..f3596716f 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -40,6 +40,7 @@ &File + @@ -72,12 +73,17 @@ - - - Load file... - - - + + + Load file... + + + + + Load symbol map... + + + E&xit diff --git a/src/citra_qt/ui_main.h b/src/citra_qt/ui_main.h index cd3906ecc..04979e5ab 100644 --- a/src/citra_qt/ui_main.h +++ b/src/citra_qt/ui_main.h @@ -27,6 +27,7 @@ class Ui_MainWindow { public: QAction *action_Load_File; + QAction *action_Load_Symbol_Map; QAction *action_Exit; QAction *action_Start; QAction *action_Pause; @@ -56,6 +57,8 @@ public: MainWindow->setDockNestingEnabled(true); action_Load_File = new QAction(MainWindow); action_Load_File->setObjectName(QString::fromUtf8("action_Load_File")); + action_Load_Symbol_Map = new QAction(MainWindow); + action_Load_Symbol_Map->setObjectName(QString::fromUtf8("action_Load_Symbol_Map")); action_Exit = new QAction(MainWindow); action_Exit->setObjectName(QString::fromUtf8("action_Exit")); action_Start = new QAction(MainWindow); @@ -101,6 +104,7 @@ public: menubar->addAction(menu_View->menuAction()); menubar->addAction(menu_Help->menuAction()); menu_File->addAction(action_Load_File); + menu_File->addAction(action_Load_Symbol_Map); menu_File->addSeparator(); menu_File->addAction(action_Exit); menu_Emulation->addAction(action_Start); @@ -123,6 +127,7 @@ public: { MainWindow->setWindowTitle(QApplication::translate("MainWindow", "Citra", 0, QApplication::UnicodeUTF8)); action_Load_File->setText(QApplication::translate("MainWindow", "Load file...", 0, QApplication::UnicodeUTF8)); + action_Load_Symbol_Map->setText(QApplication::translate("MainWindow", "Load symbol map...", 0, QApplication::UnicodeUTF8)); action_Exit->setText(QApplication::translate("MainWindow", "E&xit", 0, QApplication::UnicodeUTF8)); action_Start->setText(QApplication::translate("MainWindow", "&Start", 0, QApplication::UnicodeUTF8)); action_Pause->setText(QApplication::translate("MainWindow", "&Pause", 0, QApplication::UnicodeUTF8)); From bb7fcf79fe4a768eb4e6d26c55c2b1eb8cd4fa07 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 30 Apr 2014 23:50:14 -0400 Subject: [PATCH 03/22] - added option to load a code.bin file extracted from a CXI file - updated load launcher.dat function to use ARM11 format hack --- src/core/loader.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++--- src/core/loader.h | 24 ++++++++++---------- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/core/loader.cpp b/src/core/loader.cpp index 7c1dfef61..8756588ae 100644 --- a/src/core/loader.cpp +++ b/src/core/loader.cpp @@ -89,8 +89,8 @@ bool Load_DAT(std::string &filename) { * but for the sake of making it easier... we'll temporarily/hackishly * allow it. No sense in making a proper reader for this. */ - u32 entrypoint = 0x080c3ee0; // write to same entrypoint as elf - u32 payload_offset = 0x6F4; + u32 entrypoint = 0x00100000; // write to same entrypoint as elf + u32 payload_offset = 0xA150; const u8 *src = &buffer[payload_offset]; u8 *dst = Memory::GetPointer(entrypoint); @@ -114,6 +114,47 @@ bool Load_DAT(std::string &filename) { return true; } + +/// Loads a CTR BIN file extracted from an ExeFS +bool Load_BIN(std::string &filename) { + std::string full_path = filename; + std::string path, file, extension; + SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); +#if EMU_PLATFORM == PLATFORM_WINDOWS + path = ReplaceAll(path, "/", "\\"); +#endif + File::IOFile f(filename, "rb"); + + if (f.IsOpen()) { + u64 size = f.GetSize(); + u8* buffer = new u8[size]; + + f.ReadBytes(buffer, size); + + u32 entrypoint = 0x00100000; // Hardcoded, read from exheader + + const u8 *src = buffer; + u8 *dst = Memory::GetPointer(entrypoint); + u32 srcSize = size; + u32 *s = (u32*)src; + u32 *d = (u32*)dst; + for (int j = 0; j < (int)(srcSize + 3) / 4; j++) + { + *d++ = (*s++); + } + + Core::g_app_core->SetPC(entrypoint); + + delete[] buffer; + } + else { + return false; + } + f.Close(); + + return true; +} + namespace Loader { bool IsBootableDirectory() { @@ -145,6 +186,9 @@ FileType IdentifyFile(std::string &filename) { else if (!strcasecmp(extension.c_str(), ".elf")) { return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p } + else if (!strcasecmp(extension.c_str(), ".bin")) { + return FILETYPE_CTR_BIN; + } else if (!strcasecmp(extension.c_str(), ".dat")) { return FILETYPE_LAUNCHER_DAT; } @@ -178,6 +222,9 @@ bool LoadFile(std::string &filename, std::string *error_string) { case FILETYPE_CTR_ELF: return Load_ELF(filename); + case FILETYPE_CTR_BIN: + return Load_BIN(filename); + case FILETYPE_LAUNCHER_DAT: return Load_DAT(filename); @@ -215,7 +262,7 @@ bool LoadFile(std::string &filename, std::string *error_string) { case FILETYPE_UNKNOWN: default: ERROR_LOG(LOADER, "Failed to identify file"); - *error_string = "Failed to identify file"; + *error_string = " Failed to identify file"; break; } return false; diff --git a/src/core/loader.h b/src/core/loader.h index df30f16c7..9d4aaa874 100644 --- a/src/core/loader.h +++ b/src/core/loader.h @@ -17,19 +17,21 @@ enum FileType { FILETYPE_CTR_CIA, FILETYPE_CTR_CXI, FILETYPE_CTR_ELF, + FILETYPE_CTR_BIN, + FILETYPE_LAUNCHER_DAT, - FILETYPE_DIRECTORY_CXI, - - FILETYPE_UNKNOWN_BIN, - FILETYPE_UNKNOWN_ELF, - - FILETYPE_ARCHIVE_RAR, - FILETYPE_ARCHIVE_ZIP, - - FILETYPE_NORMAL_DIRECTORY, - - FILETYPE_UNKNOWN + FILETYPE_DIRECTORY_CXI, + + FILETYPE_UNKNOWN_BIN, + FILETYPE_UNKNOWN_ELF, + + FILETYPE_ARCHIVE_RAR, + FILETYPE_ARCHIVE_ZIP, + + FILETYPE_NORMAL_DIRECTORY, + + FILETYPE_UNKNOWN }; //////////////////////////////////////////////////////////////////////////////////////////////////// From 4ee72869cce3625f25fb516a8980460510df6041 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 May 2014 18:50:36 -0400 Subject: [PATCH 04/22] - added some function wrappers for HLE - added stub for SVC CreateAddressArbiter - added OutputDebugString SVC --- src/core/hle/function_wrappers.h | 20 ++++++++++++-------- src/core/hle/syscall.cpp | 19 +++++++++++++++++-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h index 4897d3f28..53bfafa78 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h @@ -158,8 +158,8 @@ template void WrapI_UUUUU() { RETURN(retval); } -template void WrapI_V() { - int retval = func(); +template void WrapI_V() { + u32 retval = func(Memory::GetPointer(PARAM(0))); RETURN(retval); } @@ -638,6 +638,10 @@ template void WrapU_CC() { RETURN(retval); } +template void WrapV_C() { + func(Memory::GetCharPointer(PARAM(0))); +} + template void WrapV_CI() { func(Memory::GetCharPointer(PARAM(0)), PARAM(1)); } @@ -716,18 +720,18 @@ template void WrapI_ICI() { } template void WrapI_IVVVVUI(){ - u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1)), Memory::GetPointer(PARAM(2)), Memory::GetPointer(PARAM(3)), Memory::GetPointer(PARAM(4)), PARAM(5), PARAM(6) ); - RETURN(retval); + u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1)), Memory::GetPointer(PARAM(2)), Memory::GetPointer(PARAM(3)), Memory::GetPointer(PARAM(4)), PARAM(5), PARAM(6) ); + RETURN(retval); } template void WrapI_ICUVIII(){ - u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointer(PARAM(3)), PARAM(4), PARAM(5), PARAM(6)); - RETURN(retval); + u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointer(PARAM(3)), PARAM(4), PARAM(5), PARAM(6)); + RETURN(retval); } template void WrapI_VUUUUU(){ - u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); - RETURN(retval); + u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); + RETURN(retval); } template void WrapI_US64() { diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp index df6412743..cc5b561b5 100644 --- a/src/core/hle/syscall.cpp +++ b/src/core/hle/syscall.cpp @@ -82,15 +82,30 @@ Result SendSyncRequest(Handle session) { /// Close a handle Result CloseHandle(Handle handle) { // ImplementMe + NOTICE_LOG(OSHLE, "stubbed function CloseHandle"); return 0; } /// Wait for a handle to synchronize, timeout after the specified nanoseconds Result WaitSynchronization1(Handle handle, s64 nanoseconds) { // ImplementMe + NOTICE_LOG(OSHLE, "stubbed function WaitSynchronization1"); return 0; } +/// Create an address arbiter (to allocate access to shared resources) +Result CreateAddressArbiter(void* arbiter) { + // ImplementMe + NOTICE_LOG(OSHLE, "stubbed function CreateAddressArbiter"); + Core::g_app_core->SetReg(1, 0xDEADBEEF); + return 0; +} + +/// Used to output a message on a debug hardware unit - does nothing on a retail unit +void OutputDebugString(const char* string) { + NOTICE_LOG(OSHLE, "## OSDEBUG: %s", string); +} + const HLE::FunctionDef Syscall_Table[] = { {0x00, NULL, "Unknown"}, {0x01, WrapI_UUUUU, "ControlMemory"}, @@ -125,7 +140,7 @@ const HLE::FunctionDef Syscall_Table[] = { {0x1E, NULL, "CreateMemoryBlock"}, {0x1F, WrapI_UUUU, "MapMemoryBlock"}, {0x20, NULL, "UnmapMemoryBlock"}, - {0x21, NULL, "CreateAddressArbiter"}, + {0x21, WrapI_V, "CreateAddressArbiter"}, {0x22, NULL, "ArbitrateAddress"}, {0x23, WrapI_U, "CloseHandle"}, {0x24, WrapI_US64, "WaitSynchronization1"}, @@ -153,7 +168,7 @@ const HLE::FunctionDef Syscall_Table[] = { {0x3A, NULL, "GetResourceLimitCurrentValues"}, {0x3B, NULL, "GetThreadContext"}, {0x3C, NULL, "Break"}, - {0x3D, NULL, "OutputDebugString"}, + {0x3D, WrapV_C, "OutputDebugString"}, {0x3E, NULL, "ControlPerformanceCounter"}, {0x3F, NULL, "Unknown"}, {0x40, NULL, "Unknown"}, From f0434249150f27d7921a57f70d6af11c12c4e08f Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 May 2014 19:20:44 -0400 Subject: [PATCH 05/22] renamed hle "mrc" module to "coprocessor" --- src/core/CMakeLists.txt | 2 +- src/core/arm/interpreter/armsupp.cpp | 16 ++++++++-------- src/core/core.vcxproj | 4 ++-- src/core/core.vcxproj.filters | 12 ++++++------ src/core/hle/{mrc.cpp => coprocessor.cpp} | 0 src/core/hle/{mrc.h => coprocessor.h} | 0 6 files changed, 17 insertions(+), 17 deletions(-) rename src/core/hle/{mrc.cpp => coprocessor.cpp} (100%) rename src/core/hle/{mrc.h => coprocessor.h} (100%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3308f3c25..88cbabade 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -19,7 +19,7 @@ set(SRCS core.cpp file_sys/directory_file_system.cpp file_sys/meta_file_system.cpp hle/hle.cpp - hle/mrc.cpp + hle/coprocessor.cpp hle/syscall.cpp hle/service/apt.cpp hle/service/gsp.cpp diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index b2bbedc18..d913c179c 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp @@ -20,7 +20,7 @@ //#include "ansidecl.h" #include "skyeye_defs.h" -#include "core/hle/mrc.h" +#include "core/hle/coprocessor.h" #include "core/arm/disassembler/arm_disasm.h" unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg, @@ -663,13 +663,13 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) { unsigned cpab; - //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source); - if (!CP_ACCESS_ALLOWED (state, CPNum)) { - //chy 2004-07-19 should fix in the future ????!!!! - //printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source); - ARMul_UndefInstr (state, instr); - return; - } + ////printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source); + //if (!CP_ACCESS_ALLOWED (state, CPNum)) { + // //chy 2004-07-19 should fix in the future ????!!!! + // //printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source); + // ARMul_UndefInstr (state, instr); + // return; + //} cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index a5043ea4b..7b8953327 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -153,8 +153,8 @@ + - @@ -193,9 +193,9 @@ + - diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index 9c53f9eff..fabe253ed 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -105,12 +105,12 @@ hw - - hle - arm\disassembler + + hle + @@ -211,12 +211,12 @@ hw - - hle - arm\disassembler + + hle + diff --git a/src/core/hle/mrc.cpp b/src/core/hle/coprocessor.cpp similarity index 100% rename from src/core/hle/mrc.cpp rename to src/core/hle/coprocessor.cpp diff --git a/src/core/hle/mrc.h b/src/core/hle/coprocessor.h similarity index 100% rename from src/core/hle/mrc.h rename to src/core/hle/coprocessor.h From c1e71ae1ac6700e2e849c59e55baeacda7a20ae6 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 May 2014 19:21:04 -0400 Subject: [PATCH 06/22] fixed include in coprocessor.cpp --- src/core/hle/coprocessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/coprocessor.cpp b/src/core/hle/coprocessor.cpp index 5223be7c9..5b412c586 100644 --- a/src/core/hle/coprocessor.cpp +++ b/src/core/hle/coprocessor.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include "core/hle/mrc.h" +#include "core/hle/coprocessor.h" #include "core/hle/hle.h" #include "core/mem_map.h" #include "core/core.h" From f7c6302009aa2453c37a6a7a3b1af4843f620078 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 May 2014 23:03:50 -0400 Subject: [PATCH 07/22] - added CallMCR function to coprocessor HLE module - moved instruction decoding to coprocessor HLE module --- src/core/arm/interpreter/armsupp.cpp | 45 ++++++++++++++-------------- src/core/hle/coprocessor.cpp | 16 ++++++++-- src/core/hle/coprocessor.h | 11 ++++--- 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index d913c179c..e531dceda 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp @@ -661,7 +661,8 @@ ARMul_STC (ARMul_State * state, ARMword instr, ARMword address) void ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) { - unsigned cpab; + HLE::CallMCR(instr, source); + //unsigned cpab; ////printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source); //if (!CP_ACCESS_ALLOWED (state, CPNum)) { @@ -671,29 +672,29 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) // return; //} - cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); + //cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); + //while (cpab == ARMul_BUSY) { + // ARMul_Icycles (state, 1, 0); - if (IntPending (state)) { - cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, - instr, 0); - return; - } - else - cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, - source); - } + // if (IntPending (state)) { + // cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, + // instr, 0); + // return; + // } + // else + // cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, + // source); + //} - if (cpab == ARMul_CANT) { - printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source); - ARMul_Abort (state, ARMul_UndefinedInstrV); - } - else { - BUSUSEDINCPCN; - ARMul_Ccycles (state, 1, 0); - } + //if (cpab == ARMul_CANT) { + // printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source); + // ARMul_Abort (state, ARMul_UndefinedInstrV); + //} + //else { + // BUSUSEDINCPCN; + // ARMul_Ccycles (state, 1, 0); + //} } /* This function does the Busy-Waiting for an MCRR instruction. */ @@ -739,7 +740,7 @@ ARMul_MRC (ARMul_State * state, ARMword instr) { unsigned cpab; - ARMword result = HLE::CallMRC((HLE::ARM11_MRC_OPERATION)BITS(20, 27)); + ARMword result = HLE::CallMRC(instr); ////printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr); //if (!CP_ACCESS_ALLOWED (state, CPNum)) { diff --git a/src/core/hle/coprocessor.cpp b/src/core/hle/coprocessor.cpp index 5b412c586..df1362176 100644 --- a/src/core/hle/coprocessor.cpp +++ b/src/core/hle/coprocessor.cpp @@ -44,8 +44,18 @@ Addr GetThreadCommandBuffer() { return CMD_BUFFER_ADDR; } -/// Call an MRC operation in HLE -u32 CallMRC(ARM11_MRC_OPERATION operation) { +/// Call an MCR (move to coprocessor from ARM register) instruction in HLE +s32 CallMCR(u32 instruction, u32 value) { + CoprocessorOperation operation = (CoprocessorOperation)((instruction >> 20) & 0xFF); + ERROR_LOG(OSHLE, "unimplemented MCR instruction=0x%08X, operation=%02X, value=%08X", + instruction, operation, value); + return -1; +} + +/// Call an MRC (move to ARM register from coprocessor) instruction in HLE +s32 CallMRC(u32 instruction) { + CoprocessorOperation operation = (CoprocessorOperation)((instruction >> 20) & 0xFF); + switch (operation) { case DATA_SYNCHRONIZATION_BARRIER: @@ -55,7 +65,7 @@ u32 CallMRC(ARM11_MRC_OPERATION operation) { return GetThreadCommandBuffer(); default: - ERROR_LOG(OSHLE, "unimplemented MRC operation 0x%02X", operation); + ERROR_LOG(OSHLE, "unimplemented MRC instruction 0x%08X", instruction); break; } return -1; diff --git a/src/core/hle/coprocessor.h b/src/core/hle/coprocessor.h index d6b9f162f..03822af13 100644 --- a/src/core/hle/coprocessor.h +++ b/src/core/hle/coprocessor.h @@ -8,13 +8,16 @@ namespace HLE { -/// MRC operations (ARM register from coprocessor), decoded as instr[20:27] -enum ARM11_MRC_OPERATION { +/// Coprocessor operations +enum CoprocessorOperation { DATA_SYNCHRONIZATION_BARRIER = 0xE0, CALL_GET_THREAD_COMMAND_BUFFER = 0xE1, }; -/// Call an MRC operation in HLE -u32 CallMRC(ARM11_MRC_OPERATION operation); +/// Call an MCR (move to coprocessor from ARM register) instruction in HLE +s32 CallMCR(u32 instruction, u32 value); + +/// Call an MRC (move to ARM register from coprocessor) instruction in HLE +s32 CallMRC(u32 instruction); } // namespace From e3ee3e441b271a4d2b4df8a318275ce1dcc82fa0 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 6 May 2014 17:17:00 -0400 Subject: [PATCH 08/22] commented out useless debug logs that just spammed console --- src/core/arm/mmu/arm1176jzf_s_mmu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/arm/mmu/arm1176jzf_s_mmu.cpp b/src/core/arm/mmu/arm1176jzf_s_mmu.cpp index 7e7fbfbfa..a32f076b9 100644 --- a/src/core/arm/mmu/arm1176jzf_s_mmu.cpp +++ b/src/core/arm/mmu/arm1176jzf_s_mmu.cpp @@ -355,7 +355,7 @@ arm1176jzf_s_mmu_load_instr (ARMul_State *state, ARMword va, ARMword *instr) static int debug_count = 0; /* used for debug */ - DEBUG_LOG(ARM11, "va = %x\n", va); + //DEBUG_LOG(ARM11, "va = %x\n", va); va = mmu_pid_va_map (va); if (MMU_Enabled) { @@ -444,7 +444,7 @@ arm1176jzf_s_mmu_read (ARMul_State *state, ARMword va, ARMword *data, ARMword perm; /* physical addr access permissions */ int ap, sop; - DEBUG_LOG(ARM11, "va = %x\n", va); + //DEBUG_LOG(ARM11, "va = %x\n", va); va = mmu_pid_va_map (va); real_va = va; @@ -629,7 +629,7 @@ arm1176jzf_s_mmu_write (ARMul_State *state, ARMword va, ARMword data, } #endif - DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data); + //DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data); va = mmu_pid_va_map (va); real_va = va; From 9db26df05fddd08575be459a12842a96e9f2ddc9 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 6 May 2014 17:18:20 -0400 Subject: [PATCH 09/22] - added better SVC logging - added stubs for GetResourceLimit and GetResourceLimitCurrentValues SVCs --- src/common/log.h | 6 +++--- src/common/log_manager.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/log.h b/src/common/log.h index 02db8bd55..ffc727a27 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -54,7 +54,7 @@ enum LOG_TYPE { WII_IPC_FILEIO, WII_IPC_HID, WII_IPC_HLE, - WII_IPC_NET, + SVC, NDMA, HLE, RENDER, @@ -88,10 +88,10 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, ; #if defined LOGGING || defined _DEBUG || defined DEBUGFAST -#define MAX_LOGLEVEL DEBUG_LEVEL +#define MAX_LOGLEVEL LogTypes::LDEBUG #else #ifndef MAX_LOGLEVEL -#define MAX_LOGLEVEL WARNING_LEVEL +#define MAX_LOGLEVEL LogTypes::LWARNING #endif // loglevel #endif // logging diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp index 8e56deb8f..6f4e10c9a 100644 --- a/src/common/log_manager.cpp +++ b/src/common/log_manager.cpp @@ -66,7 +66,7 @@ LogManager::LogManager() m_Log[LogTypes::WII_IPC_FILEIO] = new LogContainer("WII_IPC_FILEIO", "WII IPC FILEIO"); m_Log[LogTypes::RENDER] = new LogContainer("RENDER", "RENDER"); m_Log[LogTypes::LCD] = new LogContainer("LCD", "LCD"); - m_Log[LogTypes::WII_IPC_NET] = new LogContainer("WII_IPC_NET", "WII IPC NET"); + m_Log[LogTypes::SVC] = new LogContainer("SVC", "Supervisor Call"); m_Log[LogTypes::NDMA] = new LogContainer("NDMA", "NDMA"); m_Log[LogTypes::HLE] = new LogContainer("HLE", "High Level Emulation"); m_Log[LogTypes::HW] = new LogContainer("HW", "Hardware"); @@ -147,7 +147,7 @@ LogContainer::LogContainer(const char* shortName, const char* fullName, bool ena { strncpy(m_fullName, fullName, 128); strncpy(m_shortName, shortName, 32); - m_level = LogTypes::LWARNING; + m_level = MAX_LOGLEVEL; } // LogContainer From d1472b816fdd98a5e2cd2d414a23c133a9c3819d Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 6 May 2014 21:34:00 -0400 Subject: [PATCH 10/22] - disable strict alignment on LDRD/STRD - handle RD in STREX/STREXB --- src/core/arm/interpreter/armemu.cpp | 39 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index a35c5c8dc..1af684fe3 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp @@ -5536,14 +5536,15 @@ Handle_Load_Double (ARMul_State * state, ARMword instr) addr = base; /* The address must be aligned on a 8 byte boundary. */ - if (addr & 0x7) { -#ifdef ABORTS - ARMul_DATAABORT (addr); -#else - ARMul_UndefInstr (state, instr); -#endif - return; - } + // FIX(Normatt): Disable strict alignment on LDRD/STRD +// if (addr & 0x7) { +//#ifdef ABORTS +// ARMul_DATAABORT (addr); +//#else +// ARMul_UndefInstr (state, instr); +//#endif +// return; +// } /* For pre indexed or post indexed addressing modes, check that the destination registers do not overlap @@ -5640,14 +5641,15 @@ Handle_Store_Double (ARMul_State * state, ARMword instr) addr = base; /* The address must be aligned on a 8 byte boundary. */ - if (addr & 0x7) { -#ifdef ABORTS - ARMul_DATAABORT (addr); -#else - ARMul_UndefInstr (state, instr); -#endif - return; - } + // FIX(Normatt): Disable strict alignment on LDRD/STRD +// if (addr & 0x7) { +//#ifdef ABORTS +// ARMul_DATAABORT (addr); +//#else +// ARMul_UndefInstr (state, instr); +//#endif +// return; +// } /* For pre indexed or post indexed addressing modes, check that the destination registers do not overlap @@ -6405,6 +6407,8 @@ handle_v6_insn (ARMul_State * state, ARMword instr) if (state->Aborted) { TAKEABORT; } + // FIX(Normmatt): Handle RD in STREX/STREXB + state->Reg[DESTReg] = 0; //Always succeed return 1; } @@ -6432,7 +6436,8 @@ handle_v6_insn (ARMul_State * state, ARMword instr) if (state->Aborted) { TAKEABORT; } - + // FIX(Normmatt): Handle RD in STREX/STREXB + state->Reg[DESTReg] = 0; //Always succeed //printf("In %s, strexb not implemented\n", __FUNCTION__); UNDEF_LSRBPC; /* WRITESDEST (dest); */ From 34dc0a9b0750321d9556ac2e9c57007526096caf Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 6 May 2014 23:29:39 -0400 Subject: [PATCH 11/22] added config_mem module for HLE of firmware configuration memory settings --- src/core/CMakeLists.txt | 1 + src/core/core.vcxproj | 2 + src/core/core.vcxproj.filters | 6 +++ src/core/hle/config_mem.cpp | 70 +++++++++++++++++++++++++++++++++++ src/core/hle/config_mem.h | 21 +++++++++++ 5 files changed, 100 insertions(+) create mode 100644 src/core/hle/config_mem.cpp create mode 100644 src/core/hle/config_mem.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 88cbabade..eb4fef381 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -19,6 +19,7 @@ set(SRCS core.cpp file_sys/directory_file_system.cpp file_sys/meta_file_system.cpp hle/hle.cpp + hle/config_mem.cpp hle/coprocessor.cpp hle/syscall.cpp hle/service/apt.cpp diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index 7b8953327..b56661e48 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -153,6 +153,7 @@ + @@ -193,6 +194,7 @@ + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index fabe253ed..5c947ec23 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -111,6 +111,9 @@ hle + + hle + @@ -217,6 +220,9 @@ hle + + hle + diff --git a/src/core/hle/config_mem.cpp b/src/core/hle/config_mem.cpp new file mode 100644 index 000000000..48aa878cc --- /dev/null +++ b/src/core/hle/config_mem.cpp @@ -0,0 +1,70 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/common_types.h" +#include "common/log.h" + +#include "core/hle/config_mem.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace ConfigMem { + +enum { + KERNEL_VERSIONREVISION = 0x1FF80001, + KERNEL_VERSIONMINOR = 0x1FF80002, + KERNEL_VERSIONMAJOR = 0x1FF80003, + UPDATEFLAG = 0x1FF80004, + NSTID = 0x1FF80008, + SYSCOREVER = 0x1FF80010, + UNITINFO = 0x1FF80014, + KERNEL_CTRSDKVERSION = 0x1FF80018, + APPMEMTYPE = 0x1FF80030, + APPMEMALLOC = 0x1FF80040, + FIRM_VERSIONREVISION = 0x1FF80061, + FIRM_VERSIONMINOR = 0x1FF80062, + FIRM_VERSIONMAJOR = 0x1FF80063, + FIRM_SYSCOREVER = 0x1FF80064, + FIRM_CTRSDKVERSION = 0x1FF80068, +}; + +template +inline void Read(T &var, const u32 addr) { + switch (addr) { + + // Bit 0 set for Retail + case UNITINFO: + var = 0x00000001; + break; + + // Set app memory size to 64MB? + case APPMEMALLOC: + var = 0x04000000; + break; + + // Unknown - normally set to: 0x08000000 - (APPMEMALLOC + *0x1FF80048) + // (Total FCRAM size - APPMEMALLOC - *0x1FF80048) + case 0x1FF80044: + var = 0x08000000 - (0x04000000 + 0x1400000); + break; + + // Unknown - normally set to: 0x1400000 (20MB) + case 0x1FF80048: + var = 0x1400000; + break; + + default: + ERROR_LOG(HLE, "unknown ConfigMem::Read%d @ 0x%08X", sizeof(var) * 8, addr); + } +} + +// Explicitly instantiate template functions because we aren't defining this in the header: + +template void Read(u64 &var, const u32 addr); +template void Read(u32 &var, const u32 addr); +template void Read(u16 &var, const u32 addr); +template void Read(u8 &var, const u32 addr); + + +} // namespace diff --git a/src/core/hle/config_mem.h b/src/core/hle/config_mem.h new file mode 100644 index 000000000..da396a3e6 --- /dev/null +++ b/src/core/hle/config_mem.h @@ -0,0 +1,21 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +// Configuration memory stores various hardware/kernel configuration settings. This memory page is +// read-only for ARM11 processes. I'm guessing this would normally be written to by the firmware/ +// bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm +// putting this as a subset of HLE for now. + +#include "common/common_types.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace ConfigMem { + +template +inline void Read(T &var, const u32 addr); + +} // namespace From a3a383cb7a9b8e83c1201fd38d08b2932e3d58df Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 6 May 2014 23:32:04 -0400 Subject: [PATCH 12/22] added mem_map read for config_mem --- src/core/mem_map.h | 5 +++++ src/core/mem_map_funcs.cpp | 19 ++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/mem_map.h b/src/core/mem_map.h index 62a8b82a8..83c251ac9 100644 --- a/src/core/mem_map.h +++ b/src/core/mem_map.h @@ -32,6 +32,11 @@ enum { SHARED_MEMORY_VADDR_END = (SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE), SHARED_MEMORY_MASK = (SHARED_MEMORY_SIZE - 1), + CONFIG_MEMORY_SIZE = 0x00001000, ///< Configuration memory size + CONFIG_MEMORY_VADDR = 0x1FF80000, ///< Configuration memory virtual address + CONFIG_MEMORY_VADDR_END = (CONFIG_MEMORY_VADDR + CONFIG_MEMORY_SIZE), + CONFIG_MEMORY_MASK = (CONFIG_MEMORY_SIZE - 1), + EXEFS_CODE_SIZE = 0x03F00000, EXEFS_CODE_VADDR = 0x00100000, ///< ExeFS:/.code is loaded here EXEFS_CODE_VADDR_END = (EXEFS_CODE_VADDR + EXEFS_CODE_SIZE), diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp index 2284b535c..4812a8d22 100644 --- a/src/core/mem_map_funcs.cpp +++ b/src/core/mem_map_funcs.cpp @@ -9,6 +9,7 @@ #include "core/mem_map.h" #include "core/hw/hw.h" #include "hle/hle.h" +#include "hle/config_mem.h" namespace Memory { @@ -46,7 +47,7 @@ inline void _Read(T &var, const u32 addr) { // Could just do a base-relative read, too.... TODO const u32 vaddr = _VirtualAddress(addr); - + // Memory allocated for HLE use that can be addressed from the emulated application // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE // core running the user application (appcore) @@ -74,6 +75,10 @@ inline void _Read(T &var, const u32 addr) { } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { var = *((const T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK]); + // Config memory + } else if ((vaddr >= CONFIG_MEMORY_VADDR) && (vaddr < CONFIG_MEMORY_VADDR_END)) { + ConfigMem::Read(var, vaddr); + // VRAM } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { var = *((const T*)&g_vram[vaddr & VRAM_MASK]); @@ -118,12 +123,12 @@ inline void _Write(u32 addr, const T data) { } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { *(T*)&g_vram[vaddr & VRAM_MASK] = data; - } else if ((vaddr & 0xFFF00000) == 0x1FF00000) { - _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory"); - } else if ((vaddr & 0xFFFF0000) == 0x1FF80000) { - _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory"); - } else if ((vaddr & 0xFFFFF000) == 0x1FF81000) { - _assert_msg_(MEMMAP, false, "umimplemented write to shared page"); + //} else if ((vaddr & 0xFFF00000) == 0x1FF00000) { + // _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory"); + //} else if ((vaddr & 0xFFFF0000) == 0x1FF80000) { + // _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory"); + //} else if ((vaddr & 0xFFFFF000) == 0x1FF81000) { + // _assert_msg_(MEMMAP, false, "umimplemented write to shared page"); // Error out... } else { From de36d82ddec86eb0aa3384af935a47fe2879935e Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 6 May 2014 23:34:20 -0400 Subject: [PATCH 13/22] - added debug logging to syscall.cpp - added stubbed HLE syscall functions for svc_GetResourceLimit and svc_GetResourceLimitCurrentValues --- src/core/hle/function_wrappers.h | 12 +- src/core/hle/syscall.cpp | 296 +++++++++++++++++-------------- 2 files changed, 173 insertions(+), 135 deletions(-) diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h index 53bfafa78..18b01b14b 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h @@ -729,7 +729,17 @@ template void WrapI_ICU RETURN(retval); } -template void WrapI_VUUUUU(){ +template void WrapI_VU(){ + u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1)); + RETURN(retval); +} + +template void WrapI_VUVI(){ + u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), Memory::GetPointer(PARAM(2)), PARAM(3)); + RETURN(retval); +} + +template void WrapI_VUUUUU(){ u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp index cc5b561b5..5b4d47485 100644 --- a/src/core/hle/syscall.cpp +++ b/src/core/hle/syscall.cpp @@ -29,6 +29,9 @@ enum MapMemoryPermission { Result ControlMemory(u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { u32 virtual_address = 0x00000000; + DEBUG_LOG(SVC, "ControlMemory called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X", + operation, addr0, addr1, size, permissions); + switch (operation) { // Map normal heap memory @@ -43,16 +46,18 @@ Result ControlMemory(u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissi // Unknown ControlMemory operation default: - ERROR_LOG(OSHLE, "Unknown ControlMemory operation %08X", operation); + ERROR_LOG(SVC, "ControlMemory unknown operation=0x%08X", operation); } - + DEBUG_LOG(SVC, "...returned virtual_address=0x%08X", virtual_address); Core::g_app_core->SetReg(1, virtual_address); + return 0; } /// Maps a memory block to specified address Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) { - int x = 0; + DEBUG_LOG(SVC, "MapMemoryBlock called memblock=0x08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", + memblock, addr, mypermissions, otherpermission); switch (mypermissions) { case MEMORY_PERMISSION_NORMAL: case MEMORY_PERMISSION_NORMAL + 1: @@ -60,20 +65,23 @@ Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherper Memory::MapBlock_Shared(memblock, addr, mypermissions); break; default: - ERROR_LOG(OSHLE, "Unknown MapMemoryBlock permissions %08X", mypermissions); + ERROR_LOG(OSHLE, "MapMemoryBlock unknown permissions=0x%08X", mypermissions); } return 0; } /// Connect to an OS service given the port name, returns the handle to the port to out Result ConnectToPort(void* out, const char* port_name) { + Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); Core::g_app_core->SetReg(1, service->GetUID()); + DEBUG_LOG(SVC, "ConnectToPort called port_name=%s", port_name); return 0; } /// Synchronize to an OS service Result SendSyncRequest(Handle session) { + DEBUG_LOG(SVC, "SendSyncRequest called session=0x%08X"); Service::Interface* service = Service::g_manager->FetchFromUID(session); service->Sync(); return 0; @@ -82,157 +90,177 @@ Result SendSyncRequest(Handle session) { /// Close a handle Result CloseHandle(Handle handle) { // ImplementMe - NOTICE_LOG(OSHLE, "stubbed function CloseHandle"); + DEBUG_LOG(SVC, "(UNIMPLEMENTED) CloseHandle called handle=0x%08X", handle); return 0; } /// Wait for a handle to synchronize, timeout after the specified nanoseconds Result WaitSynchronization1(Handle handle, s64 nanoseconds) { // ImplementMe - NOTICE_LOG(OSHLE, "stubbed function WaitSynchronization1"); + DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", + handle, nanoseconds); return 0; } /// Create an address arbiter (to allocate access to shared resources) Result CreateAddressArbiter(void* arbiter) { // ImplementMe - NOTICE_LOG(OSHLE, "stubbed function CreateAddressArbiter"); + DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateAddressArbiter called"); Core::g_app_core->SetReg(1, 0xDEADBEEF); return 0; } /// Used to output a message on a debug hardware unit - does nothing on a retail unit void OutputDebugString(const char* string) { - NOTICE_LOG(OSHLE, "## OSDEBUG: %s", string); + NOTICE_LOG(SVC, "## OSDEBUG: %08X %s", Core::g_app_core->GetPC(), string); +} + +/// Get resource limit +Result GetResourceLimit(void* resource_limit, Handle process) { + // With regards to proceess values: + // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for + // the current KThread. + DEBUG_LOG(SVC, "(UNIMPLEMENTED) GetResourceLimit called process=0x%08X", process); + Core::g_app_core->SetReg(1, 0xDEADBEEF); + return 0; +} + +/// Get resource limit current values +Result GetResourceLimitCurrentValues(void* _values, Handle resource_limit, void* names, s32 name_count) { + //s64* values = (s64*)_values; + DEBUG_LOG(SVC, "(UNIMPLEMENTED) GetResourceLimitCurrentValues called resource_limit=%08X, names=%s, name_count=%d", + resource_limit, names, name_count); + Memory::Write32(Core::g_app_core->GetReg(0), 0); // Normmatt: Set used memory to 0 for now + return 0; } const HLE::FunctionDef Syscall_Table[] = { - {0x00, NULL, "Unknown"}, - {0x01, WrapI_UUUUU, "ControlMemory"}, - {0x02, NULL, "QueryMemory"}, - {0x03, NULL, "ExitProcess"}, - {0x04, NULL, "GetProcessAffinityMask"}, - {0x05, NULL, "SetProcessAffinityMask"}, - {0x06, NULL, "GetProcessIdealProcessor"}, - {0x07, NULL, "SetProcessIdealProcessor"}, - {0x08, NULL, "CreateThread"}, - {0x09, NULL, "ExitThread"}, - {0x0A, NULL, "SleepThread"}, - {0x0B, NULL, "GetThreadPriority"}, - {0x0C, NULL, "SetThreadPriority"}, - {0x0D, NULL, "GetThreadAffinityMask"}, - {0x0E, NULL, "SetThreadAffinityMask"}, - {0x0F, NULL, "GetThreadIdealProcessor"}, - {0x10, NULL, "SetThreadIdealProcessor"}, - {0x11, NULL, "GetCurrentProcessorNumber"}, - {0x12, NULL, "Run"}, - {0x13, NULL, "CreateMutex"}, - {0x14, NULL, "ReleaseMutex"}, - {0x15, NULL, "CreateSemaphore"}, - {0x16, NULL, "ReleaseSemaphore"}, - {0x17, NULL, "CreateEvent"}, - {0x18, NULL, "SignalEvent"}, - {0x19, NULL, "ClearEvent"}, - {0x1A, NULL, "CreateTimer"}, - {0x1B, NULL, "SetTimer"}, - {0x1C, NULL, "CancelTimer"}, - {0x1D, NULL, "ClearTimer"}, - {0x1E, NULL, "CreateMemoryBlock"}, - {0x1F, WrapI_UUUU, "MapMemoryBlock"}, - {0x20, NULL, "UnmapMemoryBlock"}, - {0x21, WrapI_V, "CreateAddressArbiter"}, - {0x22, NULL, "ArbitrateAddress"}, - {0x23, WrapI_U, "CloseHandle"}, - {0x24, WrapI_US64, "WaitSynchronization1"}, - {0x25, NULL, "WaitSynchronizationN"}, - {0x26, NULL, "SignalAndWait"}, - {0x27, NULL, "DuplicateHandle"}, - {0x28, NULL, "GetSystemTick"}, - {0x29, NULL, "GetHandleInfo"}, - {0x2A, NULL, "GetSystemInfo"}, - {0x2B, NULL, "GetProcessInfo"}, - {0x2C, NULL, "GetThreadInfo"}, - {0x2D, WrapI_VC, "ConnectToPort"}, - {0x2E, NULL, "SendSyncRequest1"}, - {0x2F, NULL, "SendSyncRequest2"}, - {0x30, NULL, "SendSyncRequest3"}, - {0x31, NULL, "SendSyncRequest4"}, - {0x32, WrapI_U, "SendSyncRequest"}, - {0x33, NULL, "OpenProcess"}, - {0x34, NULL, "OpenThread"}, - {0x35, NULL, "GetProcessId"}, - {0x36, NULL, "GetProcessIdOfThread"}, - {0x37, NULL, "GetThreadId"}, - {0x38, NULL, "GetResourceLimit"}, - {0x39, NULL, "GetResourceLimitLimitValues"}, - {0x3A, NULL, "GetResourceLimitCurrentValues"}, - {0x3B, NULL, "GetThreadContext"}, - {0x3C, NULL, "Break"}, - {0x3D, WrapV_C, "OutputDebugString"}, - {0x3E, NULL, "ControlPerformanceCounter"}, - {0x3F, NULL, "Unknown"}, - {0x40, NULL, "Unknown"}, - {0x41, NULL, "Unknown"}, - {0x42, NULL, "Unknown"}, - {0x43, NULL, "Unknown"}, - {0x44, NULL, "Unknown"}, - {0x45, NULL, "Unknown"}, - {0x46, NULL, "Unknown"}, - {0x47, NULL, "CreatePort"}, - {0x48, NULL, "CreateSessionToPort"}, - {0x49, NULL, "CreateSession"}, - {0x4A, NULL, "AcceptSession"}, - {0x4B, NULL, "ReplyAndReceive1"}, - {0x4C, NULL, "ReplyAndReceive2"}, - {0x4D, NULL, "ReplyAndReceive3"}, - {0x4E, NULL, "ReplyAndReceive4"}, - {0x4F, NULL, "ReplyAndReceive"}, - {0x50, NULL, "BindInterrupt"}, - {0x51, NULL, "UnbindInterrupt"}, - {0x52, NULL, "InvalidateProcessDataCache"}, - {0x53, NULL, "StoreProcessDataCache"}, - {0x54, NULL, "FlushProcessDataCache"}, - {0x55, NULL, "StartInterProcessDma"}, - {0x56, NULL, "StopDma"}, - {0x57, NULL, "GetDmaState"}, - {0x58, NULL, "RestartDma"}, - {0x59, NULL, "Unknown"}, - {0x5A, NULL, "Unknown"}, - {0x5B, NULL, "Unknown"}, - {0x5C, NULL, "Unknown"}, - {0x5D, NULL, "Unknown"}, - {0x5E, NULL, "Unknown"}, - {0x5F, NULL, "Unknown"}, - {0x60, NULL, "DebugActiveProcess"}, - {0x61, NULL, "BreakDebugProcess"}, - {0x62, NULL, "TerminateDebugProcess"}, - {0x63, NULL, "GetProcessDebugEvent"}, - {0x64, NULL, "ContinueDebugEvent"}, - {0x65, NULL, "GetProcessList"}, - {0x66, NULL, "GetThreadList"}, - {0x67, NULL, "GetDebugThreadContext"}, - {0x68, NULL, "SetDebugThreadContext"}, - {0x69, NULL, "QueryDebugProcessMemory"}, - {0x6A, NULL, "ReadProcessMemory"}, - {0x6B, NULL, "WriteProcessMemory"}, - {0x6C, NULL, "SetHardwareBreakPoint"}, - {0x6D, NULL, "GetDebugThreadParam"}, - {0x6E, NULL, "Unknown"}, - {0x6F, NULL, "Unknown"}, - {0x70, NULL, "ControlProcessMemory"}, - {0x71, NULL, "MapProcessMemory"}, - {0x72, NULL, "UnmapProcessMemory"}, - {0x73, NULL, "Unknown"}, - {0x74, NULL, "Unknown"}, - {0x75, NULL, "Unknown"}, - {0x76, NULL, "TerminateProcess"}, - {0x77, NULL, "Unknown"}, - {0x78, NULL, "CreateResourceLimit"}, - {0x79, NULL, "Unknown"}, - {0x7A, NULL, "Unknown"}, - {0x7B, NULL, "Unknown"}, - {0x7C, NULL, "KernelSetState"}, - {0x7D, NULL, "QueryProcessMemory"}, + {0x00, NULL, "Unknown"}, + {0x01, WrapI_UUUUU, "ControlMemory"}, + {0x02, NULL, "QueryMemory"}, + {0x03, NULL, "ExitProcess"}, + {0x04, NULL, "GetProcessAffinityMask"}, + {0x05, NULL, "SetProcessAffinityMask"}, + {0x06, NULL, "GetProcessIdealProcessor"}, + {0x07, NULL, "SetProcessIdealProcessor"}, + {0x08, NULL, "CreateThread"}, + {0x09, NULL, "ExitThread"}, + {0x0A, NULL, "SleepThread"}, + {0x0B, NULL, "GetThreadPriority"}, + {0x0C, NULL, "SetThreadPriority"}, + {0x0D, NULL, "GetThreadAffinityMask"}, + {0x0E, NULL, "SetThreadAffinityMask"}, + {0x0F, NULL, "GetThreadIdealProcessor"}, + {0x10, NULL, "SetThreadIdealProcessor"}, + {0x11, NULL, "GetCurrentProcessorNumber"}, + {0x12, NULL, "Run"}, + {0x13, NULL, "CreateMutex"}, + {0x14, NULL, "ReleaseMutex"}, + {0x15, NULL, "CreateSemaphore"}, + {0x16, NULL, "ReleaseSemaphore"}, + {0x17, NULL, "CreateEvent"}, + {0x18, NULL, "SignalEvent"}, + {0x19, NULL, "ClearEvent"}, + {0x1A, NULL, "CreateTimer"}, + {0x1B, NULL, "SetTimer"}, + {0x1C, NULL, "CancelTimer"}, + {0x1D, NULL, "ClearTimer"}, + {0x1E, NULL, "CreateMemoryBlock"}, + {0x1F, WrapI_UUUU, "MapMemoryBlock"}, + {0x20, NULL, "UnmapMemoryBlock"}, + {0x21, WrapI_V, "CreateAddressArbiter"}, + {0x22, NULL, "ArbitrateAddress"}, + {0x23, WrapI_U, "CloseHandle"}, + {0x24, WrapI_US64, "WaitSynchronization1"}, + {0x25, NULL, "WaitSynchronizationN"}, + {0x26, NULL, "SignalAndWait"}, + {0x27, NULL, "DuplicateHandle"}, + {0x28, NULL, "GetSystemTick"}, + {0x29, NULL, "GetHandleInfo"}, + {0x2A, NULL, "GetSystemInfo"}, + {0x2B, NULL, "GetProcessInfo"}, + {0x2C, NULL, "GetThreadInfo"}, + {0x2D, WrapI_VC, "ConnectToPort"}, + {0x2E, NULL, "SendSyncRequest1"}, + {0x2F, NULL, "SendSyncRequest2"}, + {0x30, NULL, "SendSyncRequest3"}, + {0x31, NULL, "SendSyncRequest4"}, + {0x32, WrapI_U, "SendSyncRequest"}, + {0x33, NULL, "OpenProcess"}, + {0x34, NULL, "OpenThread"}, + {0x35, NULL, "GetProcessId"}, + {0x36, NULL, "GetProcessIdOfThread"}, + {0x37, NULL, "GetThreadId"}, + {0x38, WrapI_VU, "GetResourceLimit"}, + {0x39, NULL, "GetResourceLimitLimitValues"}, + {0x3A, WrapI_VUVI, "GetResourceLimitCurrentValues"}, + {0x3B, NULL, "GetThreadContext"}, + {0x3C, NULL, "Break"}, + {0x3D, WrapV_C, "OutputDebugString"}, + {0x3E, NULL, "ControlPerformanceCounter"}, + {0x3F, NULL, "Unknown"}, + {0x40, NULL, "Unknown"}, + {0x41, NULL, "Unknown"}, + {0x42, NULL, "Unknown"}, + {0x43, NULL, "Unknown"}, + {0x44, NULL, "Unknown"}, + {0x45, NULL, "Unknown"}, + {0x46, NULL, "Unknown"}, + {0x47, NULL, "CreatePort"}, + {0x48, NULL, "CreateSessionToPort"}, + {0x49, NULL, "CreateSession"}, + {0x4A, NULL, "AcceptSession"}, + {0x4B, NULL, "ReplyAndReceive1"}, + {0x4C, NULL, "ReplyAndReceive2"}, + {0x4D, NULL, "ReplyAndReceive3"}, + {0x4E, NULL, "ReplyAndReceive4"}, + {0x4F, NULL, "ReplyAndReceive"}, + {0x50, NULL, "BindInterrupt"}, + {0x51, NULL, "UnbindInterrupt"}, + {0x52, NULL, "InvalidateProcessDataCache"}, + {0x53, NULL, "StoreProcessDataCache"}, + {0x54, NULL, "FlushProcessDataCache"}, + {0x55, NULL, "StartInterProcessDma"}, + {0x56, NULL, "StopDma"}, + {0x57, NULL, "GetDmaState"}, + {0x58, NULL, "RestartDma"}, + {0x59, NULL, "Unknown"}, + {0x5A, NULL, "Unknown"}, + {0x5B, NULL, "Unknown"}, + {0x5C, NULL, "Unknown"}, + {0x5D, NULL, "Unknown"}, + {0x5E, NULL, "Unknown"}, + {0x5F, NULL, "Unknown"}, + {0x60, NULL, "DebugActiveProcess"}, + {0x61, NULL, "BreakDebugProcess"}, + {0x62, NULL, "TerminateDebugProcess"}, + {0x63, NULL, "GetProcessDebugEvent"}, + {0x64, NULL, "ContinueDebugEvent"}, + {0x65, NULL, "GetProcessList"}, + {0x66, NULL, "GetThreadList"}, + {0x67, NULL, "GetDebugThreadContext"}, + {0x68, NULL, "SetDebugThreadContext"}, + {0x69, NULL, "QueryDebugProcessMemory"}, + {0x6A, NULL, "ReadProcessMemory"}, + {0x6B, NULL, "WriteProcessMemory"}, + {0x6C, NULL, "SetHardwareBreakPoint"}, + {0x6D, NULL, "GetDebugThreadParam"}, + {0x6E, NULL, "Unknown"}, + {0x6F, NULL, "Unknown"}, + {0x70, NULL, "ControlProcessMemory"}, + {0x71, NULL, "MapProcessMemory"}, + {0x72, NULL, "UnmapProcessMemory"}, + {0x73, NULL, "Unknown"}, + {0x74, NULL, "Unknown"}, + {0x75, NULL, "Unknown"}, + {0x76, NULL, "TerminateProcess"}, + {0x77, NULL, "Unknown"}, + {0x78, NULL, "CreateResourceLimit"}, + {0x79, NULL, "Unknown"}, + {0x7A, NULL, "Unknown"}, + {0x7B, NULL, "Unknown"}, + {0x7C, NULL, "KernelSetState"}, + {0x7D, NULL, "QueryProcessMemory"}, }; void Register() { From e7a0283625a4d05a9dcf5f9ec4ef8158ce34cf05 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 7 May 2014 18:14:42 -0400 Subject: [PATCH 14/22] added BitField to common --- src/common/bit_field.h | 173 ++++++++++++++++++++++++++++++ src/common/common.vcxproj | 1 + src/common/common.vcxproj.filters | 1 + 3 files changed, 175 insertions(+) create mode 100644 src/common/bit_field.h diff --git a/src/common/bit_field.h b/src/common/bit_field.h new file mode 100644 index 000000000..f5322b25b --- /dev/null +++ b/src/common/bit_field.h @@ -0,0 +1,173 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + + +// Copyright 2014 Tony Wasserka +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the owner nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#pragma once + +#include +#include + +#include "Common.h" + +/* + * Abstract bitfield class + * + * Allows endianness-independent access to individual bitfields within some raw + * integer value. The assembly generated by this class is identical to the + * usage of raw bitfields, so it's a perfectly fine replacement. + * + * For BitField, X is the distance of the bitfield to the LSB of the + * raw value, Y is the length in bits of the bitfield. Z is an integer type + * which determines the sign of the bitfield. Z must have the same size as the + * raw integer. + * + * + * General usage: + * + * Create a new union with the raw integer value as a member. + * Then for each bitfield you want to expose, add a BitField member + * in the union. The template parameters are the bit offset and the number + * of desired bits. + * + * Changes in the bitfield members will then get reflected in the raw integer + * value and vice-versa. + * + * + * Sample usage: + * + * union SomeRegister + * { + * u32 hex; + * + * BitField<0,7,u32> first_seven_bits; // unsigned + * BitField<7,8,32> next_eight_bits; // unsigned + * BitField<3,15,s32> some_signed_fields; // signed + * }; + * + * This is equivalent to the little-endian specific code: + * + * union SomeRegister + * { + * u32 hex; + * + * struct + * { + * u32 first_seven_bits : 7; + * u32 next_eight_bits : 8; + * }; + * struct + * { + * u32 : 3; // padding + * s32 some_signed_fields : 15; + * }; + * }; + * + * + * Caveats: + * + * 1) + * BitField provides automatic casting from and to the storage type where + * appropriate. However, when using non-typesafe functions like printf, an + * explicit cast must be performed on the BitField object to make sure it gets + * passed correctly, e.g.: + * printf("Value: %d", (s32)some_register.some_signed_fields); + * + * 2) + * Not really a caveat, but potentially irritating: This class is used in some + * packed structures that do not guarantee proper alignment. Therefore we have + * to use #pragma pack here not to pack the members of the class, but instead + * to break GCC's assumption that the members of the class are aligned on + * sizeof(StorageType). + * TODO(neobrain): Confirm that this is a proper fix and not just masking + * symptoms. + */ +#pragma pack(1) +template +struct BitField +{ +private: + // This constructor might be considered ambiguous: + // Would it initialize the storage or just the bitfield? + // Hence, delete it. Use the assignment operator to set bitfield values! + BitField(T val) = delete; + +public: + // Force default constructor to be created + // so that we can use this within unions + BitField() = default; + + __forceinline BitField& operator=(T val) + { + storage = (storage & ~GetMask()) | ((val << position) & GetMask()); + return *this; + } + + __forceinline operator T() const + { + if (std::numeric_limits::is_signed) + { + std::size_t shift = 8 * sizeof(T)-bits; + return (T)(((storage & GetMask()) << (shift - position)) >> shift); + } + else + { + return (T)((storage & GetMask()) >> position); + } + } + +private: + // StorageType is T for non-enum types and the underlying type of T if + // T is an enumeration. Note that T is wrapped within an enable_if in the + // former case to workaround compile errors which arise when using + // std::underlying_type::type directly. + typedef typename std::conditional < std::is_enum::value, + std::underlying_type, + std::enable_if < true, T >> ::type::type StorageType; + + // Unsigned version of StorageType + typedef typename std::make_unsigned::type StorageTypeU; + + __forceinline StorageType GetMask() const + { + return ((~(StorageTypeU)0) >> (8 * sizeof(T)-bits)) << position; + } + + StorageType storage; + + static_assert(bits + position <= 8 * sizeof(T), "Bitfield out of range"); + + // And, you know, just in case people specify something stupid like bits=position=0x80000000 + static_assert(position < 8 * sizeof(T), "Invalid position"); + static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); + static_assert(bits > 0, "Invalid number of bits"); +}; +#pragma pack() diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 5048bebff..5dc6ff790 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -157,6 +157,7 @@ + diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters index e9ea40022..268730228 100644 --- a/src/common/common.vcxproj.filters +++ b/src/common/common.vcxproj.filters @@ -39,6 +39,7 @@ + From 92bde183dd5d8665c56a96cb33a78fb8bd5afc61 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 7 May 2014 20:59:21 -0400 Subject: [PATCH 15/22] added GSP to loggers --- src/common/log.h | 2 +- src/common/log_manager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/log.h b/src/common/log.h index ffc727a27..de0629445 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -33,7 +33,7 @@ enum LOG_TYPE { EXPANSIONINTERFACE, GDB_STUB, ARM11, - GPFIFO, + GSP, OSHLE, MASTER_LOG, MEMMAP, diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp index 6f4e10c9a..aec2636ec 100644 --- a/src/common/log_manager.cpp +++ b/src/common/log_manager.cpp @@ -42,7 +42,7 @@ LogManager::LogManager() m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt"); m_Log[LogTypes::DSPINTERFACE] = new LogContainer("DSP", "DSPInterface"); m_Log[LogTypes::DVDINTERFACE] = new LogContainer("DVD", "DVDInterface"); - m_Log[LogTypes::GPFIFO] = new LogContainer("GP", "GPFifo"); + m_Log[LogTypes::GSP] = new LogContainer("GSP", "GSP"); m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI", "ExpansionInt"); m_Log[LogTypes::GDB_STUB] = new LogContainer("GDB_STUB", "GDB Stub"); m_Log[LogTypes::AUDIO_INTERFACE] = new LogContainer("AI", "AudioInt"); From f23e99bb85e7644db78717741cc50f3cc3332aa9 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 7 May 2014 21:01:09 -0400 Subject: [PATCH 16/22] added kernel memory to mem_map --- src/core/mem_map.cpp | 3 +++ src/core/mem_map.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/core/mem_map.cpp b/src/core/mem_map.cpp index af99cbe32..59560b87d 100644 --- a/src/core/mem_map.cpp +++ b/src/core/mem_map.cpp @@ -21,6 +21,7 @@ u8* g_heap = NULL; ///< Application heap (main memo u8* g_heap_gsp = NULL; ///< GSP heap (main memory) u8* g_vram = NULL; ///< Video memory (VRAM) pointer u8* g_shared_mem = NULL; ///< Shared memory +u8* g_kernel_mem; ///< Kernel memory u8* g_physical_bootrom = NULL; ///< Bootrom physical memory u8* g_uncached_bootrom = NULL; @@ -30,6 +31,7 @@ u8* g_physical_fcram = NULL; ///< Main physical memory (FCRAM u8* g_physical_heap_gsp = NULL; ///< GSP heap physical memory u8* g_physical_vram = NULL; ///< Video physical memory (VRAM) u8* g_physical_shared_mem = NULL; ///< Physical shared memory +u8* g_physical_kernel_mem; ///< Kernel memory // We don't declare the IO region in here since its handled by other means. static MemoryView g_views[] = { @@ -37,6 +39,7 @@ static MemoryView g_views[] = { {&g_vram, &g_physical_vram, VRAM_VADDR, VRAM_SIZE, 0}, {&g_heap, &g_physical_fcram, HEAP_VADDR, HEAP_SIZE, MV_IS_PRIMARY_RAM}, {&g_shared_mem, &g_physical_shared_mem, SHARED_MEMORY_VADDR, SHARED_MEMORY_SIZE, 0}, + {&g_kernel_mem, &g_physical_kernel_mem, KERNEL_MEMORY_VADDR, KERNEL_MEMORY_SIZE, 0}, {&g_heap_gsp, &g_physical_heap_gsp, HEAP_GSP_VADDR, HEAP_GSP_SIZE, 0}, }; diff --git a/src/core/mem_map.h b/src/core/mem_map.h index 83c251ac9..af2212a5f 100644 --- a/src/core/mem_map.h +++ b/src/core/mem_map.h @@ -37,6 +37,11 @@ enum { CONFIG_MEMORY_VADDR_END = (CONFIG_MEMORY_VADDR + CONFIG_MEMORY_SIZE), CONFIG_MEMORY_MASK = (CONFIG_MEMORY_SIZE - 1), + KERNEL_MEMORY_SIZE = 0x00001000, ///< Kernel memory size + KERNEL_MEMORY_VADDR = 0xFFFF0000, ///< Kernel memory where the kthread objects etc are + KERNEL_MEMORY_VADDR_END = (KERNEL_MEMORY_VADDR + KERNEL_MEMORY_SIZE), + KERNEL_MEMORY_MASK = (KERNEL_MEMORY_SIZE - 1), + EXEFS_CODE_SIZE = 0x03F00000, EXEFS_CODE_VADDR = 0x00100000, ///< ExeFS:/.code is loaded here EXEFS_CODE_VADDR_END = (EXEFS_CODE_VADDR + EXEFS_CODE_SIZE), @@ -110,6 +115,7 @@ extern u8* g_heap_gsp; ///< GSP heap (main memory) extern u8* g_heap; ///< Application heap (main memory) extern u8* g_vram; ///< Video memory (VRAM) extern u8* g_shared_mem; ///< Shared memory +extern u8* g_kernel_mem; ///< Kernel memory extern u8* g_exefs_code; ///< ExeFS:/.code is loaded here void Init(); From 72622a1b5a13083e1b4eda3d4584bfa2f04dc55c Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 7 May 2014 21:04:55 -0400 Subject: [PATCH 17/22] - removed HLE mem "hack" and replaced with kernel mem region - added a helper function for getting command buffer for services - fixed bug where GSP DMA was incorrectly being done in DataSynchronizationBarrier (instead of gsp_TriggerCmdReqQueue) --- src/core/hle/coprocessor.cpp | 34 +++------------ src/core/hle/hle.cpp | 47 --------------------- src/core/hle/hle.h | 21 ---------- src/core/hle/service/apt.cpp | 2 +- src/core/hle/service/gsp.cpp | 76 +++++++++++++++++++++++++++++++--- src/core/hle/service/service.h | 12 +++++- src/core/hle/service/srv.cpp | 2 +- src/core/mem_map_funcs.cpp | 22 +++++----- 8 files changed, 100 insertions(+), 116 deletions(-) diff --git a/src/core/hle/coprocessor.cpp b/src/core/hle/coprocessor.cpp index df1362176..74305331c 100644 --- a/src/core/hle/coprocessor.cpp +++ b/src/core/hle/coprocessor.cpp @@ -9,39 +9,15 @@ namespace HLE { -enum { - CMD_GX_REQUEST_DMA = 0x00000000, -}; - /// Data synchronization barrier -u32 DataSynchronizationBarrier(u32* command_buffer) { - u32 command = command_buffer[0]; - - switch (command) { - - case CMD_GX_REQUEST_DMA: - { - u32* src = (u32*)Memory::GetPointer(command_buffer[1]); - u32* dst = (u32*)Memory::GetPointer(command_buffer[2]); - u32 size = command_buffer[3]; - memcpy(dst, src, size); - } - break; - - default: - ERROR_LOG(OSHLE, "MRC::DataSynchronizationBarrier unknown command 0x%08X", command); - return -1; - } - +u32 DataSynchronizationBarrier() { return 0; } /// Returns the coprocessor (in this case, syscore) command buffer pointer Addr GetThreadCommandBuffer() { // Called on insruction: mrc p15, 0, r0, c13, c0, 3 - // Returns an address in OSHLE memory for the CPU to read/write to - RETURN(CMD_BUFFER_ADDR); - return CMD_BUFFER_ADDR; + return Memory::KERNEL_MEMORY_VADDR; } /// Call an MCR (move to coprocessor from ARM register) instruction in HLE @@ -49,7 +25,7 @@ s32 CallMCR(u32 instruction, u32 value) { CoprocessorOperation operation = (CoprocessorOperation)((instruction >> 20) & 0xFF); ERROR_LOG(OSHLE, "unimplemented MCR instruction=0x%08X, operation=%02X, value=%08X", instruction, operation, value); - return -1; + return 0; } /// Call an MRC (move to ARM register from coprocessor) instruction in HLE @@ -59,7 +35,7 @@ s32 CallMRC(u32 instruction) { switch (operation) { case DATA_SYNCHRONIZATION_BARRIER: - return DataSynchronizationBarrier((u32*)Memory::GetPointer(PARAM(0))); + return DataSynchronizationBarrier(); case CALL_GET_THREAD_COMMAND_BUFFER: return GetThreadCommandBuffer(); @@ -68,7 +44,7 @@ s32 CallMRC(u32 instruction) { ERROR_LOG(OSHLE, "unimplemented MRC instruction 0x%08X", instruction); break; } - return -1; + return 0; } } // namespace diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp index aae9a3943..be151665b 100644 --- a/src/core/hle/hle.cpp +++ b/src/core/hle/hle.cpp @@ -15,49 +15,6 @@ namespace HLE { static std::vector g_module_db; -u8* g_command_buffer = NULL; ///< Command buffer used for sharing between appcore and syscore - -// Read from memory used by CTROS HLE functions -template -inline void Read(T &var, const u32 addr) { - if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) { - var = *((const T*)&g_command_buffer[addr & CMD_BUFFER_MASK]); - } else { - ERROR_LOG(HLE, "unknown read from address %08X", addr); - } -} - -// Write to memory used by CTROS HLE functions -template -inline void Write(u32 addr, const T data) { - if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) { - *(T*)&g_command_buffer[addr & CMD_BUFFER_MASK] = data; - } else { - ERROR_LOG(HLE, "unknown write to address %08X", addr); - } -} - -u8 *GetPointer(const u32 addr) { - if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) { - return g_command_buffer + (addr & CMD_BUFFER_MASK); - } else { - ERROR_LOG(HLE, "unknown pointer from address %08X", addr); - return 0; - } -} - -// Explicitly instantiate template functions because we aren't defining this in the header: - -template void Read(u64 &var, const u32 addr); -template void Read(u32 &var, const u32 addr); -template void Read(u16 &var, const u32 addr); -template void Read(u8 &var, const u32 addr); - -template void Write(u32 addr, const u64 data); -template void Write(u32 addr, const u32 data); -template void Write(u32 addr, const u16 data); -template void Write(u32 addr, const u8 data); - const FunctionDef* GetSyscallInfo(u32 opcode) { u32 func_num = opcode & 0xFFFFFF; // 8 bits if (func_num > 0xFF) { @@ -91,8 +48,6 @@ void RegisterAllModules() { void Init() { Service::Init(); - - g_command_buffer = new u8[CMD_BUFFER_SIZE]; RegisterAllModules(); @@ -102,8 +57,6 @@ void Init() { void Shutdown() { Service::Shutdown(); - delete g_command_buffer; - g_module_db.clear(); NOTICE_LOG(HLE, "shutdown OK"); diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h index 907e2d741..42f37e29c 100644 --- a/src/core/hle/hle.h +++ b/src/core/hle/hle.h @@ -17,13 +17,6 @@ namespace HLE { -enum { - CMD_BUFFER_ADDR = 0xA0010000, ///< Totally arbitrary unused address space - CMD_BUFFER_SIZE = 0x10000, - CMD_BUFFER_MASK = (CMD_BUFFER_SIZE - 1), - CMD_BUFFER_ADDR_END = (CMD_BUFFER_ADDR + CMD_BUFFER_SIZE), -}; - typedef u32 Addr; typedef void (*Func)(); @@ -39,20 +32,6 @@ struct ModuleDef { const FunctionDef* func_table; }; -// Read from memory used by CTROS HLE functions -template -inline void Read(T &var, const u32 addr); - -// Write to memory used by CTROS HLE functions -template -inline void Write(u32 addr, const T data); - -u8* GetPointer(const u32 Address); - -inline const char* GetCharPointer(const u32 address) { - return (const char *)GetPointer(address); -} - void RegisterModule(std::string name, int num_functions, const FunctionDef *func_table); void CallSyscall(u32 opcode); diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp index 4a1e8c992..709ac5493 100644 --- a/src/core/hle/service/apt.cpp +++ b/src/core/hle/service/apt.cpp @@ -18,7 +18,7 @@ void Initialize(Service::Interface* self) { } void GetLockHandle(Service::Interface* self) { - u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); + u32* cmd_buff = Service::GetCommandBuffer(); cmd_buff[5] = 0x00000000; // TODO: This should be an actual mutex handle } diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp index 88c1f1a0f..58df970c4 100644 --- a/src/core/hle/service/gsp.cpp +++ b/src/core/hle/service/gsp.cpp @@ -4,6 +4,7 @@ #include "common/log.h" +#include "common/bit_field.h" #include "core/mem_map.h" #include "core/hle/hle.h" @@ -11,11 +12,57 @@ #include "core/hw/lcd.h" +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/// GSP shared memory GX command buffer header +union GX_CmdBufferHeader { + u32 hex; + + // Current command index. This index is updated by GSP module after loading the command data, + // right before the command is processed. When this index is updated by GSP module, the total + // commands field is decreased by one as well. + BitField<0,8,u32> index; + + // Total commands to process, must not be value 0 when GSP module handles commands. This must be + // <=15 when writing a command to shared memory. This is incremented by the application when + // writing a command to shared memory, after increasing this value TriggerCmdReqQueue is only + // used if this field is value 1. + BitField<8,8,u32> number_commands; + + // Must not be value 1. When the error-code u32 is set, this u8 is set to value 0x80. + BitField<16,8,u32> unk_0; + + // Bit 0 must not be set + BitField<24,8,u32> unk_1; +}; + +/// Gets the address of the start (header) of a command buffer in GSP shared memory +static inline u32 GX_GetCmdBufferAddress(u32 thread_id) { + return (0x10002000 + 0x800 + (thread_id * 0x200)); +} + +/// Gets a pointer to the start (header) of a command buffer in GSP shared memory +static inline u8* GX_GetCmdBufferPointer(u32 thread_id, u32 offset=0) { + return Memory::GetPointer(GX_GetCmdBufferAddress(thread_id) + offset); +} + +/// Finishes execution of a GSP command +void GX_FinishCommand(u32 thread_id) { + GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(thread_id); + header->number_commands = header->number_commands - 1; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace GSP_GPU namespace GSP_GPU { +u32 g_thread_id = 0; + +enum { + CMD_GX_REQUEST_DMA = 0x00000000, +}; + enum { REG_FRAMEBUFFER_1 = 0x00400468, REG_FRAMEBUFFER_2 = 0x00400494, @@ -26,7 +73,7 @@ void ReadHWRegs(Service::Interface* self) { static const u32 framebuffer_1[] = {LCD::PADDR_VRAM_TOP_LEFT_FRAME1, LCD::PADDR_VRAM_TOP_RIGHT_FRAME1}; static const u32 framebuffer_2[] = {LCD::PADDR_VRAM_TOP_LEFT_FRAME2, LCD::PADDR_VRAM_TOP_RIGHT_FRAME2}; - u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); + u32* cmd_buff = Service::GetCommandBuffer(); u32 reg_addr = cmd_buff[1]; u32 size = cmd_buff[2]; u32* dst = (u32*)Memory::GetPointer(cmd_buff[0x41]); @@ -50,18 +97,37 @@ void ReadHWRegs(Service::Interface* self) { break; default: - ERROR_LOG(OSHLE, "GSP_GPU::ReadHWRegs unknown register read at address %08X", reg_addr); + ERROR_LOG(GSP, "ReadHWRegs unknown register read at address %08X", reg_addr); } } void RegisterInterruptRelayQueue(Service::Interface* self) { - u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); + u32* cmd_buff = Service::GetCommandBuffer(); u32 flags = cmd_buff[1]; u32 event_handle = cmd_buff[3]; // TODO(bunnei): Implement event handling + + cmd_buff[2] = g_thread_id; // ThreadID cmd_buff[4] = self->NewHandle(); +} - return; +/// This triggers handling of the GX command written to the command buffer in shared memory. +void TriggerCmdReqQueue(Service::Interface* self) { + GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(g_thread_id); + u32* cmd_buff = (u32*)GX_GetCmdBufferPointer(g_thread_id, 0x20 + (header->index * 0x20)); + + switch (cmd_buff[0]) { + + // GX request DMA - typically used for copying memory from GSP heap to VRAM + case CMD_GX_REQUEST_DMA: + memcpy(Memory::GetPointer(cmd_buff[2]), Memory::GetPointer(cmd_buff[1]), cmd_buff[3]); + break; + + default: + ERROR_LOG(GSP, "TriggerCmdReqQueue unknown command 0x%08X", cmd_buff[0]); + } + + GX_FinishCommand(g_thread_id); } const Interface::FunctionInfo FunctionTable[] = { @@ -76,7 +142,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00090082, NULL, "InvalidateDataCache"}, {0x000A0044, NULL, "RegisterInterruptEvents"}, {0x000B0040, NULL, "SetLcdForceBlack"}, - {0x000C0000, NULL, "TriggerCmdReqQueue"}, + {0x000C0000, TriggerCmdReqQueue, "TriggerCmdReqQueue"}, {0x000D0140, NULL, "SetDisplayTransfer"}, {0x000E0180, NULL, "SetTextureCopy"}, {0x000F0200, NULL, "SetMemoryFill"}, diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index b79dc9458..b260a290a 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -10,6 +10,7 @@ #include "common/common.h" #include "common/common_types.h" +#include "core/mem_map.h" #include "core/hle/syscall.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -22,6 +23,15 @@ typedef s32 NativeUID; ///< Native handle for a service static const int kMaxPortSize = 0x08; ///< Maximum size of a port name (8 characters) static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header +/** + * Returns a pointer to the command buffer in kernel memory + * @param offset Optional offset into command buffer + * @return Pointer to command buffer + */ +inline static u32* GetCommandBuffer(const int offset=0) { + return (u32*)Memory::GetPointer(Memory::KERNEL_MEMORY_VADDR + kCommandHeaderOffset + offset); +} + class Manager; /// Interface to a CTROS service @@ -81,7 +91,7 @@ public: * @return Return result of svcSendSyncRequest passed back to user app */ Syscall::Result Sync() { - u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + kCommandHeaderOffset); + u32* cmd_buff = GetCommandBuffer(); auto itr = m_functions.find(cmd_buff[0]); if (itr == m_functions.end()) { diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 9437868c5..071741444 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -18,7 +18,7 @@ void Initialize(Service::Interface* self) { void GetServiceHandle(Service::Interface* self) { Syscall::Result res = 0; - u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); + u32* cmd_buff = Service::GetCommandBuffer(); std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp index 4812a8d22..8ab647714 100644 --- a/src/core/mem_map_funcs.cpp +++ b/src/core/mem_map_funcs.cpp @@ -48,11 +48,9 @@ inline void _Read(T &var, const u32 addr) { const u32 vaddr = _VirtualAddress(addr); - // Memory allocated for HLE use that can be addressed from the emulated application - // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE - // core running the user application (appcore) - if (vaddr >= HLE::CMD_BUFFER_ADDR && vaddr < HLE::CMD_BUFFER_ADDR_END) { - HLE::Read(var, vaddr); + // Kernel memory command buffer + if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { + var = *((const T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK]); // Hardware I/O register reads // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space @@ -92,11 +90,9 @@ template inline void _Write(u32 addr, const T data) { u32 vaddr = _VirtualAddress(addr); - // Memory allocated for HLE use that can be addressed from the emulated application - // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE - // core running the user application (appcore) - if (vaddr >= HLE::CMD_BUFFER_ADDR && vaddr < HLE::CMD_BUFFER_ADDR_END) { - HLE::Write(vaddr, data); + // Kernel memory command buffer + if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { + *(T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK] = data; // Hardware I/O register writes // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space @@ -140,8 +136,12 @@ inline void _Write(u32 addr, const T data) { u8 *GetPointer(const u32 addr) { const u32 vaddr = _VirtualAddress(addr); + // Kernel memory command buffer + if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { + return g_kernel_mem + (vaddr & KERNEL_MEMORY_MASK); + // ExeFS:/.code is loaded here - if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { + } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { return g_exefs_code + (vaddr & EXEFS_CODE_MASK); // FCRAM - GSP heap From 4de763f462abb986a58052a69127d50789ffeb06 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 7 May 2014 21:19:03 -0400 Subject: [PATCH 18/22] removed unnecessary log message --- src/core/hle/syscall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp index 5b4d47485..d47df6038 100644 --- a/src/core/hle/syscall.cpp +++ b/src/core/hle/syscall.cpp @@ -48,7 +48,7 @@ Result ControlMemory(u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissi default: ERROR_LOG(SVC, "ControlMemory unknown operation=0x%08X", operation); } - DEBUG_LOG(SVC, "...returned virtual_address=0x%08X", virtual_address); + Core::g_app_core->SetReg(1, virtual_address); return 0; From 505d984f163d3bce9254e7e5fdb949c8e764ec49 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 7 May 2014 21:34:04 -0400 Subject: [PATCH 19/22] logger fix for linux --- src/common/log.h | 4 ++-- src/common/log_manager.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/log.h b/src/common/log.h index de0629445..d95f51f56 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -88,10 +88,10 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, ; #if defined LOGGING || defined _DEBUG || defined DEBUGFAST -#define MAX_LOGLEVEL LogTypes::LDEBUG +#define MAX_LOGLEVEL DEBUG_LEVEL #else #ifndef MAX_LOGLEVEL -#define MAX_LOGLEVEL LogTypes::LWARNING +#define MAX_LOGLEVEL WARNING_LEVEL #endif // loglevel #endif // logging diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp index aec2636ec..80fd473b9 100644 --- a/src/common/log_manager.cpp +++ b/src/common/log_manager.cpp @@ -147,7 +147,7 @@ LogContainer::LogContainer(const char* shortName, const char* fullName, bool ena { strncpy(m_fullName, fullName, 128); strncpy(m_shortName, shortName, 32); - m_level = MAX_LOGLEVEL; + m_level = (LogTypes::LOG_LEVELS)MAX_LOGLEVEL; } // LogContainer From a713bd1bad76f6ec6af1418a3b5a7d550916c157 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 7 May 2014 21:44:16 -0400 Subject: [PATCH 20/22] fixed include of common in bit_field.h --- src/common/bit_field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/bit_field.h b/src/common/bit_field.h index f5322b25b..a59ff0ba8 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -36,7 +36,7 @@ #include #include -#include "Common.h" +#include "common/common.h" /* * Abstract bitfield class From a6b047ec3bf3e7c11438cf11f60f0a94b3e2a005 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 8 May 2014 17:11:41 -0400 Subject: [PATCH 21/22] removed incorrect dolphin copyright line --- src/common/bit_field.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/bit_field.h b/src/common/bit_field.h index a59ff0ba8..dfd00d198 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -1,4 +1,3 @@ -// Copyright 2014 Dolphin Emulator Project // Licensed under GPLv2 // Refer to the license.txt file included. From b39cd3a64c69792ffd720ffa6e0f5fe35740a087 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 8 May 2014 17:12:07 -0400 Subject: [PATCH 22/22] removed unknown fields from GX_CmdBufferHeader --- src/core/hle/service/gsp.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp index 58df970c4..12c7dabcd 100644 --- a/src/core/hle/service/gsp.cpp +++ b/src/core/hle/service/gsp.cpp @@ -28,12 +28,7 @@ union GX_CmdBufferHeader { // writing a command to shared memory, after increasing this value TriggerCmdReqQueue is only // used if this field is value 1. BitField<8,8,u32> number_commands; - - // Must not be value 1. When the error-code u32 is set, this u8 is set to value 0x80. - BitField<16,8,u32> unk_0; - // Bit 0 must not be set - BitField<24,8,u32> unk_1; }; /// Gets the address of the start (header) of a command buffer in GSP shared memory