Merge pull request #2343 from bunnei/core-cleanup
Core: Top-level consolidate & misc cleanup
This commit is contained in:
commit
aa47af7fb6
45 changed files with 439 additions and 595 deletions
|
@ -31,7 +31,6 @@ set(SRCS
|
|||
file_sys/savedata_archive.cpp
|
||||
gdbstub/gdbstub.cpp
|
||||
hle/config_mem.cpp
|
||||
hle/hle.cpp
|
||||
hle/applets/applet.cpp
|
||||
hle/applets/erreula.cpp
|
||||
hle/applets/mii_selector.cpp
|
||||
|
@ -155,7 +154,6 @@ set(SRCS
|
|||
tracer/recorder.cpp
|
||||
memory.cpp
|
||||
settings.cpp
|
||||
system.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
|
@ -196,7 +194,6 @@ set(HEADERS
|
|||
gdbstub/gdbstub.h
|
||||
hle/config_mem.h
|
||||
hle/function_wrappers.h
|
||||
hle/hle.h
|
||||
hle/ipc.h
|
||||
hle/applets/applet.h
|
||||
hle/applets/erreula.h
|
||||
|
@ -325,7 +322,6 @@ set(HEADERS
|
|||
memory_setup.h
|
||||
mmio.h
|
||||
settings.h
|
||||
system.h
|
||||
)
|
||||
|
||||
include_directories(../../externals/dynarmic/include)
|
||||
|
|
|
@ -8,15 +8,22 @@
|
|||
#include "core/arm/skyeye_common/arm_regformat.h"
|
||||
#include "core/arm/skyeye_common/vfp/asm_vfp.h"
|
||||
|
||||
namespace Core {
|
||||
struct ThreadContext;
|
||||
}
|
||||
|
||||
/// Generic ARM11 CPU interface
|
||||
class ARM_Interface : NonCopyable {
|
||||
public:
|
||||
virtual ~ARM_Interface() {}
|
||||
|
||||
struct ThreadContext {
|
||||
u32 cpu_registers[13];
|
||||
u32 sp;
|
||||
u32 lr;
|
||||
u32 pc;
|
||||
u32 cpsr;
|
||||
u32 fpu_registers[64];
|
||||
u32 fpscr;
|
||||
u32 fpexc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs the CPU for the given number of instructions
|
||||
* @param num_instructions Number of instructions to run
|
||||
|
@ -124,13 +131,13 @@ public:
|
|||
* Saves the current CPU context
|
||||
* @param ctx Thread context to save
|
||||
*/
|
||||
virtual void SaveContext(Core::ThreadContext& ctx) = 0;
|
||||
virtual void SaveContext(ThreadContext& ctx) = 0;
|
||||
|
||||
/**
|
||||
* Loads a CPU context
|
||||
* @param ctx Thread context to load
|
||||
*/
|
||||
virtual void LoadContext(const Core::ThreadContext& ctx) = 0;
|
||||
virtual void LoadContext(const ThreadContext& ctx) = 0;
|
||||
|
||||
/// Prepare core for thread reschedule (if needed to correctly handle state)
|
||||
virtual void PrepareReschedule() = 0;
|
||||
|
|
|
@ -137,7 +137,7 @@ void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
|
|||
AddTicks(ticks_executed);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic::SaveContext(Core::ThreadContext& ctx) {
|
||||
void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
|
||||
memcpy(ctx.cpu_registers, jit->Regs().data(), sizeof(ctx.cpu_registers));
|
||||
memcpy(ctx.fpu_registers, jit->ExtRegs().data(), sizeof(ctx.fpu_registers));
|
||||
|
||||
|
@ -150,7 +150,7 @@ void ARM_Dynarmic::SaveContext(Core::ThreadContext& ctx) {
|
|||
ctx.fpexc = interpreter_state->VFP[VFP_FPEXC];
|
||||
}
|
||||
|
||||
void ARM_Dynarmic::LoadContext(const Core::ThreadContext& ctx) {
|
||||
void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
|
||||
memcpy(jit->Regs().data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
|
||||
memcpy(jit->ExtRegs().data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
|
||||
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/skyeye_common/armstate.h"
|
||||
|
||||
namespace Core {
|
||||
struct ThreadContext;
|
||||
}
|
||||
|
||||
class ARM_Dynarmic final : public ARM_Interface {
|
||||
public:
|
||||
ARM_Dynarmic(PrivilegeMode initial_mode);
|
||||
|
@ -33,8 +29,8 @@ public:
|
|||
|
||||
void AddTicks(u64 ticks) override;
|
||||
|
||||
void SaveContext(Core::ThreadContext& ctx) override;
|
||||
void LoadContext(const Core::ThreadContext& ctx) override;
|
||||
void SaveContext(ThreadContext& ctx) override;
|
||||
void LoadContext(const ThreadContext& ctx) override;
|
||||
|
||||
void PrepareReschedule() override;
|
||||
void ExecuteInstructions(int num_instructions) override;
|
||||
|
|
|
@ -89,7 +89,7 @@ void ARM_DynCom::ExecuteInstructions(int num_instructions) {
|
|||
AddTicks(ticks_executed);
|
||||
}
|
||||
|
||||
void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
|
||||
void ARM_DynCom::SaveContext(ThreadContext& ctx) {
|
||||
memcpy(ctx.cpu_registers, state->Reg.data(), sizeof(ctx.cpu_registers));
|
||||
memcpy(ctx.fpu_registers, state->ExtReg.data(), sizeof(ctx.fpu_registers));
|
||||
|
||||
|
@ -102,7 +102,7 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
|
|||
ctx.fpexc = state->VFP[VFP_FPEXC];
|
||||
}
|
||||
|
||||
void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) {
|
||||
void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
|
||||
memcpy(state->Reg.data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
|
||||
memcpy(state->ExtReg.data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
|
||||
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
#include "core/arm/skyeye_common/arm_regformat.h"
|
||||
#include "core/arm/skyeye_common/armstate.h"
|
||||
|
||||
namespace Core {
|
||||
struct ThreadContext;
|
||||
}
|
||||
|
||||
class ARM_DynCom final : public ARM_Interface {
|
||||
public:
|
||||
ARM_DynCom(PrivilegeMode initial_mode);
|
||||
|
@ -36,8 +32,8 @@ public:
|
|||
|
||||
void AddTicks(u64 ticks) override;
|
||||
|
||||
void SaveContext(Core::ThreadContext& ctx) override;
|
||||
void LoadContext(const Core::ThreadContext& ctx) override;
|
||||
void SaveContext(ThreadContext& ctx) override;
|
||||
void LoadContext(const ThreadContext& ctx) override;
|
||||
|
||||
void PrepareReschedule() override;
|
||||
void ExecuteInstructions(int num_instructions) override;
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "audio_core/audio_core.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/dynarmic/arm_dynarmic.h"
|
||||
|
@ -10,18 +12,24 @@
|
|||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hw/hw.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/settings.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
std::unique_ptr<ARM_Interface> g_app_core; ///< ARM11 application core
|
||||
std::unique_ptr<ARM_Interface> g_sys_core; ///< ARM11 system (OS) core
|
||||
/*static*/ System System::s_instance;
|
||||
|
||||
System::ResultStatus System::RunLoop(int tight_loop) {
|
||||
if (!cpu_core) {
|
||||
return ResultStatus::ErrorNotInitialized;
|
||||
}
|
||||
|
||||
/// Run the core CPU loop
|
||||
void RunLoop(int tight_loop) {
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
GDBStub::HandlePacket();
|
||||
|
||||
|
@ -32,7 +40,7 @@ void RunLoop(int tight_loop) {
|
|||
GDBStub::SetCpuStepFlag(false);
|
||||
tight_loop = 1;
|
||||
} else {
|
||||
return;
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,48 +51,114 @@ void RunLoop(int tight_loop) {
|
|||
LOG_TRACE(Core_ARM11, "Idling");
|
||||
CoreTiming::Idle();
|
||||
CoreTiming::Advance();
|
||||
HLE::Reschedule(__func__);
|
||||
PrepareReschedule();
|
||||
} else {
|
||||
g_app_core->Run(tight_loop);
|
||||
cpu_core->Run(tight_loop);
|
||||
}
|
||||
|
||||
HW::Update();
|
||||
if (HLE::IsReschedulePending()) {
|
||||
Kernel::Reschedule();
|
||||
Reschedule();
|
||||
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
System::ResultStatus System::SingleStep() {
|
||||
return RunLoop(1);
|
||||
}
|
||||
|
||||
System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) {
|
||||
if (app_loader) {
|
||||
app_loader.reset();
|
||||
}
|
||||
|
||||
app_loader = Loader::GetLoader(filepath);
|
||||
|
||||
if (!app_loader) {
|
||||
LOG_CRITICAL(Core, "Failed to obtain loader for %s!", filepath.c_str());
|
||||
return ResultStatus::ErrorGetLoader;
|
||||
}
|
||||
|
||||
boost::optional<u32> system_mode{app_loader->LoadKernelSystemMode()};
|
||||
if (!system_mode) {
|
||||
LOG_CRITICAL(Core, "Failed to determine system mode!");
|
||||
return ResultStatus::ErrorSystemMode;
|
||||
}
|
||||
|
||||
ResultStatus init_result{Init(emu_window, system_mode.get())};
|
||||
if (init_result != ResultStatus::Success) {
|
||||
LOG_CRITICAL(Core, "Failed to initialize system (Error %i)!", init_result);
|
||||
System::Shutdown();
|
||||
return init_result;
|
||||
}
|
||||
|
||||
const Loader::ResultStatus load_result{app_loader->Load()};
|
||||
if (Loader::ResultStatus::Success != load_result) {
|
||||
LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result);
|
||||
System::Shutdown();
|
||||
|
||||
switch (load_result) {
|
||||
case Loader::ResultStatus::ErrorEncrypted:
|
||||
return ResultStatus::ErrorLoader_ErrorEncrypted;
|
||||
case Loader::ResultStatus::ErrorInvalidFormat:
|
||||
return ResultStatus::ErrorLoader_ErrorInvalidFormat;
|
||||
default:
|
||||
return ResultStatus::ErrorLoader;
|
||||
}
|
||||
}
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
/// Step the CPU one instruction
|
||||
void SingleStep() {
|
||||
RunLoop(1);
|
||||
void System::PrepareReschedule() {
|
||||
cpu_core->PrepareReschedule();
|
||||
reschedule_pending = true;
|
||||
}
|
||||
|
||||
/// Halt the core
|
||||
void Halt(const char* msg) {
|
||||
// TODO(ShizZy): ImplementMe
|
||||
void System::Reschedule() {
|
||||
if (!reschedule_pending) {
|
||||
return;
|
||||
}
|
||||
|
||||
reschedule_pending = false;
|
||||
Kernel::Reschedule();
|
||||
}
|
||||
|
||||
/// Kill the core
|
||||
void Stop() {
|
||||
// TODO(ShizZy): ImplementMe
|
||||
}
|
||||
System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||
if (cpu_core) {
|
||||
cpu_core.reset();
|
||||
}
|
||||
|
||||
Memory::Init();
|
||||
|
||||
/// Initialize the core
|
||||
void Init() {
|
||||
if (Settings::values.use_cpu_jit) {
|
||||
g_sys_core = std::make_unique<ARM_Dynarmic>(USER32MODE);
|
||||
g_app_core = std::make_unique<ARM_Dynarmic>(USER32MODE);
|
||||
cpu_core = std::make_unique<ARM_Dynarmic>(USER32MODE);
|
||||
} else {
|
||||
g_sys_core = std::make_unique<ARM_DynCom>(USER32MODE);
|
||||
g_app_core = std::make_unique<ARM_DynCom>(USER32MODE);
|
||||
cpu_core = std::make_unique<ARM_DynCom>(USER32MODE);
|
||||
}
|
||||
|
||||
CoreTiming::Init();
|
||||
HW::Init();
|
||||
Kernel::Init(system_mode);
|
||||
Service::Init();
|
||||
AudioCore::Init();
|
||||
GDBStub::Init();
|
||||
|
||||
if (!VideoCore::Init(emu_window)) {
|
||||
return ResultStatus::ErrorVideoCore;
|
||||
}
|
||||
|
||||
LOG_DEBUG(Core, "Initialized OK");
|
||||
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
g_app_core.reset();
|
||||
g_sys_core.reset();
|
||||
void System::Shutdown() {
|
||||
GDBStub::Shutdown();
|
||||
AudioCore::Shutdown();
|
||||
VideoCore::Shutdown();
|
||||
Service::Shutdown();
|
||||
Kernel::Shutdown();
|
||||
HW::Shutdown();
|
||||
CoreTiming::Shutdown();
|
||||
|
||||
LOG_DEBUG(Core, "Shutdown OK");
|
||||
}
|
||||
|
|
150
src/core/core.h
150
src/core/core.h
|
@ -5,56 +5,118 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
#include <string>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
class EmuWindow;
|
||||
class ARM_Interface;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
namespace Loader {
|
||||
class AppLoader;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
|
||||
struct ThreadContext {
|
||||
u32 cpu_registers[13];
|
||||
u32 sp;
|
||||
u32 lr;
|
||||
u32 pc;
|
||||
u32 cpsr;
|
||||
u32 fpu_registers[64];
|
||||
u32 fpscr;
|
||||
u32 fpexc;
|
||||
class System {
|
||||
public:
|
||||
/**
|
||||
* Gets the instance of the System singleton class.
|
||||
* @returns Reference to the instance of the System singleton class.
|
||||
*/
|
||||
static System& GetInstance() {
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
/// Enumeration representing the return values of the System Initialize and Load process.
|
||||
enum class ResultStatus : u32 {
|
||||
Success, ///< Succeeded
|
||||
ErrorNotInitialized, ///< Error trying to use core prior to initialization
|
||||
ErrorGetLoader, ///< Error finding the correct application loader
|
||||
ErrorSystemMode, ///< Error determining the system mode
|
||||
ErrorLoader, ///< Error loading the specified application
|
||||
ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
|
||||
ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an
|
||||
/// invalid format
|
||||
ErrorVideoCore, ///< Error in the video core
|
||||
};
|
||||
|
||||
/**
|
||||
* Run the core CPU loop
|
||||
* This function runs the core for the specified number of CPU instructions before trying to
|
||||
* update hardware. This is much faster than SingleStep (and should be equivalent), as the CPU
|
||||
* is not required to do a full dispatch with each instruction. NOTE: the number of instructions
|
||||
* requested is not guaranteed to run, as this will be interrupted preemptively if a hardware
|
||||
* update is requested (e.g. on a thread switch).
|
||||
* @param tight_loop Number of instructions to execute.
|
||||
* @return Result status, indicating whethor or not the operation succeeded.
|
||||
*/
|
||||
ResultStatus RunLoop(int tight_loop = 1000);
|
||||
|
||||
/**
|
||||
* Step the CPU one instruction
|
||||
* @return Result status, indicating whethor or not the operation succeeded.
|
||||
*/
|
||||
ResultStatus SingleStep();
|
||||
|
||||
/// Shutdown the emulated system.
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* Load an executable application.
|
||||
* @param emu_window Pointer to the host-system window used for video output and keyboard input.
|
||||
* @param filepath String path to the executable application to load on the host file system.
|
||||
* @returns ResultStatus code, indicating if the operation succeeded.
|
||||
*/
|
||||
ResultStatus Load(EmuWindow* emu_window, const std::string& filepath);
|
||||
|
||||
/**
|
||||
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
|
||||
* application).
|
||||
* @returns True if the emulated system is powered on, otherwise false.
|
||||
*/
|
||||
bool IsPoweredOn() const {
|
||||
return cpu_core != nullptr;
|
||||
}
|
||||
|
||||
/// Prepare the core emulation for a reschedule
|
||||
void PrepareReschedule();
|
||||
|
||||
/**
|
||||
* Gets a reference to the emulated CPU.
|
||||
* @returns A reference to the emulated CPU.
|
||||
*/
|
||||
ARM_Interface& CPU() {
|
||||
return *cpu_core;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initialize the emulated system.
|
||||
* @param emu_window Pointer to the host-system window used for video output and keyboard input.
|
||||
* @param system_mode The system mode.
|
||||
* @return ResultStatus code, indicating if the operation succeeded.
|
||||
*/
|
||||
ResultStatus Init(EmuWindow* emu_window, u32 system_mode);
|
||||
|
||||
/// Reschedule the core emulation
|
||||
void Reschedule();
|
||||
|
||||
/// AppLoader used to load the current executing application
|
||||
std::unique_ptr<Loader::AppLoader> app_loader;
|
||||
|
||||
///< ARM11 CPU core
|
||||
std::unique_ptr<ARM_Interface> cpu_core;
|
||||
|
||||
/// When true, signals that a reschedule should happen
|
||||
bool reschedule_pending{};
|
||||
|
||||
static System s_instance;
|
||||
};
|
||||
|
||||
extern std::unique_ptr<ARM_Interface> g_app_core; ///< ARM11 application core
|
||||
extern std::unique_ptr<ARM_Interface> g_sys_core; ///< ARM11 system (OS) core
|
||||
static ARM_Interface& CPU() {
|
||||
return System::GetInstance().CPU();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Start the core
|
||||
void Start();
|
||||
|
||||
/**
|
||||
* Run the core CPU loop
|
||||
* This function runs the core for the specified number of CPU instructions before trying to update
|
||||
* hardware. This is much faster than SingleStep (and should be equivalent), as the CPU is not
|
||||
* required to do a full dispatch with each instruction. NOTE: the number of instructions requested
|
||||
* is not guaranteed to run, as this will be interrupted preemptively if a hardware update is
|
||||
* requested (e.g. on a thread switch).
|
||||
*/
|
||||
void RunLoop(int tight_loop = 1000);
|
||||
|
||||
/// Step the CPU one instruction
|
||||
void SingleStep();
|
||||
|
||||
/// Halt the core
|
||||
void Halt(const char* msg);
|
||||
|
||||
/// Kill the core
|
||||
void Stop();
|
||||
|
||||
/// Initialize the core
|
||||
void Init();
|
||||
|
||||
/// Shutdown the core
|
||||
void Shutdown();
|
||||
|
||||
} // namespace
|
||||
} // namespace Core
|
||||
|
|
|
@ -130,7 +130,6 @@ int RegisterEvent(const char* name, TimedCallback callback) {
|
|||
|
||||
static void AntiCrashCallback(u64 userdata, int cycles_late) {
|
||||
LOG_CRITICAL(Core_Timing, "Savestate broken: an unregistered event was called.");
|
||||
Core::Halt("invalid timing events");
|
||||
}
|
||||
|
||||
void RestoreRegisterEvent(int event_type, const char* name, TimedCallback callback) {
|
||||
|
@ -147,7 +146,7 @@ void UnregisterAllEvents() {
|
|||
}
|
||||
|
||||
void Init() {
|
||||
Core::g_app_core->down_count = INITIAL_SLICE_LENGTH;
|
||||
Core::CPU().down_count = INITIAL_SLICE_LENGTH;
|
||||
g_slice_length = INITIAL_SLICE_LENGTH;
|
||||
global_timer = 0;
|
||||
idled_cycles = 0;
|
||||
|
@ -187,7 +186,7 @@ void Shutdown() {
|
|||
}
|
||||
|
||||
u64 GetTicks() {
|
||||
return (u64)global_timer + g_slice_length - Core::g_app_core->down_count;
|
||||
return (u64)global_timer + g_slice_length - Core::CPU().down_count;
|
||||
}
|
||||
|
||||
u64 GetIdleTicks() {
|
||||
|
@ -461,18 +460,18 @@ void MoveEvents() {
|
|||
}
|
||||
|
||||
void ForceCheck() {
|
||||
s64 cycles_executed = g_slice_length - Core::g_app_core->down_count;
|
||||
s64 cycles_executed = g_slice_length - Core::CPU().down_count;
|
||||
global_timer += cycles_executed;
|
||||
// This will cause us to check for new events immediately.
|
||||
Core::g_app_core->down_count = 0;
|
||||
Core::CPU().down_count = 0;
|
||||
// But let's not eat a bunch more time in Advance() because of this.
|
||||
g_slice_length = 0;
|
||||
}
|
||||
|
||||
void Advance() {
|
||||
s64 cycles_executed = g_slice_length - Core::g_app_core->down_count;
|
||||
s64 cycles_executed = g_slice_length - Core::CPU().down_count;
|
||||
global_timer += cycles_executed;
|
||||
Core::g_app_core->down_count = g_slice_length;
|
||||
Core::CPU().down_count = g_slice_length;
|
||||
|
||||
if (has_ts_events)
|
||||
MoveEvents();
|
||||
|
@ -481,7 +480,7 @@ void Advance() {
|
|||
if (!first) {
|
||||
if (g_slice_length < 10000) {
|
||||
g_slice_length += 10000;
|
||||
Core::g_app_core->down_count += g_slice_length;
|
||||
Core::CPU().down_count += g_slice_length;
|
||||
}
|
||||
} else {
|
||||
// Note that events can eat cycles as well.
|
||||
|
@ -491,7 +490,7 @@ void Advance() {
|
|||
|
||||
const int diff = target - g_slice_length;
|
||||
g_slice_length += diff;
|
||||
Core::g_app_core->down_count += diff;
|
||||
Core::CPU().down_count += diff;
|
||||
}
|
||||
if (advance_callback)
|
||||
advance_callback(static_cast<int>(cycles_executed));
|
||||
|
@ -507,12 +506,12 @@ void LogPendingEvents() {
|
|||
}
|
||||
|
||||
void Idle(int max_idle) {
|
||||
s64 cycles_down = Core::g_app_core->down_count;
|
||||
s64 cycles_down = Core::CPU().down_count;
|
||||
if (max_idle != 0 && cycles_down > max_idle)
|
||||
cycles_down = max_idle;
|
||||
|
||||
if (first && cycles_down > 0) {
|
||||
s64 cycles_executed = g_slice_length - Core::g_app_core->down_count;
|
||||
s64 cycles_executed = g_slice_length - Core::CPU().down_count;
|
||||
s64 cycles_next_event = first->time - global_timer;
|
||||
|
||||
if (cycles_next_event < cycles_executed + cycles_down) {
|
||||
|
@ -527,9 +526,9 @@ void Idle(int max_idle) {
|
|||
cycles_down / (float)(g_clock_rate_arm11 * 0.001f));
|
||||
|
||||
idled_cycles += cycles_down;
|
||||
Core::g_app_core->down_count -= cycles_down;
|
||||
if (Core::g_app_core->down_count == 0)
|
||||
Core::g_app_core->down_count = -1;
|
||||
Core::CPU().down_count -= cycles_down;
|
||||
if (Core::CPU().down_count == 0)
|
||||
Core::CPU().down_count = -1;
|
||||
}
|
||||
|
||||
std::string GetScheduledEventsSummary() {
|
||||
|
|
|
@ -141,11 +141,10 @@ std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path)
|
|||
|
||||
std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) {
|
||||
if (shared)
|
||||
return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(),
|
||||
SYSTEM_ID.c_str());
|
||||
return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), SYSTEM_ID);
|
||||
|
||||
return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(),
|
||||
SYSTEM_ID.c_str(), SDCARD_ID.c_str());
|
||||
return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(), SYSTEM_ID,
|
||||
SDCARD_ID);
|
||||
}
|
||||
|
||||
Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
namespace FileSys {
|
||||
|
||||
static std::string GetNCCHContainerPath(const std::string& nand_directory) {
|
||||
return Common::StringFromFormat("%s%s/title/", nand_directory.c_str(), SYSTEM_ID.c_str());
|
||||
return Common::StringFromFormat("%s%s/title/", nand_directory.c_str(), SYSTEM_ID);
|
||||
}
|
||||
|
||||
static std::string GetNCCHPath(const std::string& mount_point, u32 high, u32 low) {
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace {
|
|||
|
||||
std::string GetSaveDataContainerPath(const std::string& sdmc_directory) {
|
||||
return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(),
|
||||
SYSTEM_ID.c_str(), SDCARD_ID.c_str());
|
||||
SYSTEM_ID, SDCARD_ID);
|
||||
}
|
||||
|
||||
std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) {
|
||||
|
|
|
@ -26,7 +26,7 @@ std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& pa
|
|||
}
|
||||
|
||||
std::string GetSystemSaveDataContainerPath(const std::string& mount_point) {
|
||||
return Common::StringFromFormat("%sdata/%s/sysdata/", mount_point.c_str(), SYSTEM_ID.c_str());
|
||||
return Common::StringFromFormat("%sdata/%s/sysdata/", mount_point.c_str(), SYSTEM_ID);
|
||||
}
|
||||
|
||||
Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low) {
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
const int GDB_BUFFER_SIZE = 10000;
|
||||
|
@ -449,9 +450,9 @@ static void SendSignal(u32 signal) {
|
|||
|
||||
latest_signal = signal;
|
||||
|
||||
std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15,
|
||||
htonl(Core::g_app_core->GetPC()), 13,
|
||||
htonl(Core::g_app_core->GetReg(13)));
|
||||
std::string buffer =
|
||||
Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15,
|
||||
htonl(Core::CPU().GetPC()), 13, htonl(Core::CPU().GetReg(13)));
|
||||
LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str());
|
||||
SendReply(buffer.c_str());
|
||||
}
|
||||
|
@ -538,15 +539,15 @@ static void ReadRegister() {
|
|||
}
|
||||
|
||||
if (id <= R15_REGISTER) {
|
||||
IntToGdbHex(reply, Core::g_app_core->GetReg(id));
|
||||
IntToGdbHex(reply, Core::CPU().GetReg(id));
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
IntToGdbHex(reply, Core::g_app_core->GetCPSR());
|
||||
IntToGdbHex(reply, Core::CPU().GetCPSR());
|
||||
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
|
||||
IntToGdbHex(reply, Core::g_app_core->GetVFPReg(
|
||||
IntToGdbHex(reply, Core::CPU().GetVFPReg(
|
||||
id - CPSR_REGISTER -
|
||||
1)); // VFP registers should start at 26, so one after CSPR_REGISTER
|
||||
} else if (id == FPSCR_REGISTER) {
|
||||
IntToGdbHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR
|
||||
IntToGdbHex(reply, Core::CPU().GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR
|
||||
IntToGdbHex(reply + 8, 0);
|
||||
} else {
|
||||
return SendReply("E01");
|
||||
|
@ -563,22 +564,22 @@ static void ReadRegisters() {
|
|||
u8* bufptr = buffer;
|
||||
|
||||
for (int reg = 0; reg <= R15_REGISTER; reg++) {
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetReg(reg));
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetReg(reg));
|
||||
}
|
||||
|
||||
bufptr += (16 * CHAR_BIT);
|
||||
|
||||
IntToGdbHex(bufptr, Core::g_app_core->GetCPSR());
|
||||
IntToGdbHex(bufptr, Core::CPU().GetCPSR());
|
||||
|
||||
bufptr += CHAR_BIT;
|
||||
|
||||
for (int reg = 0; reg <= 31; reg++) {
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetVFPReg(reg));
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetVFPReg(reg));
|
||||
}
|
||||
|
||||
bufptr += (32 * CHAR_BIT);
|
||||
|
||||
IntToGdbHex(bufptr, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR));
|
||||
IntToGdbHex(bufptr, Core::CPU().GetVFPSystemReg(VFP_FPSCR));
|
||||
|
||||
SendReply(reinterpret_cast<char*>(buffer));
|
||||
}
|
||||
|
@ -595,13 +596,13 @@ static void WriteRegister() {
|
|||
}
|
||||
|
||||
if (id <= R15_REGISTER) {
|
||||
Core::g_app_core->SetReg(id, GdbHexToInt(buffer_ptr));
|
||||
Core::CPU().SetReg(id, GdbHexToInt(buffer_ptr));
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr));
|
||||
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr));
|
||||
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
|
||||
Core::g_app_core->SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr));
|
||||
Core::CPU().SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr));
|
||||
} else if (id == FPSCR_REGISTER) {
|
||||
Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr));
|
||||
Core::CPU().SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr));
|
||||
} else {
|
||||
return SendReply("E01");
|
||||
}
|
||||
|
@ -618,20 +619,19 @@ static void WriteRegisters() {
|
|||
|
||||
for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
|
||||
if (reg <= R15_REGISTER) {
|
||||
Core::g_app_core->SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
Core::CPU().SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
} else if (reg == CPSR_REGISTER) {
|
||||
Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
} else if (reg == CPSR_REGISTER - 1) {
|
||||
// Dummy FPA register, ignore
|
||||
} else if (reg < CPSR_REGISTER) {
|
||||
// Dummy FPA registers, ignore
|
||||
i += 2;
|
||||
} else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
|
||||
Core::g_app_core->SetVFPReg(reg - CPSR_REGISTER - 1,
|
||||
GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
Core::CPU().SetVFPReg(reg - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
i++; // Skip padding
|
||||
} else if (reg == FPSCR_REGISTER) {
|
||||
Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
Core::CPU().SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -908,7 +908,7 @@ void ToggleServer(bool status) {
|
|||
server_enabled = status;
|
||||
|
||||
// Start server
|
||||
if (!IsConnected() && Core::g_sys_core != nullptr) {
|
||||
if (!IsConnected() && Core::System().GetInstance().IsPoweredOn()) {
|
||||
Init();
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
#include "common/common_types.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/svc.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace HLE {
|
||||
|
||||
#define PARAM(n) Core::g_app_core->GetReg(n)
|
||||
#define PARAM(n) Core::CPU().GetReg(n)
|
||||
|
||||
/// An invalid result code that is meant to be overwritten when a thread resumes from waiting
|
||||
static const ResultCode RESULT_INVALID(0xDEADC0DE);
|
||||
|
@ -24,7 +24,7 @@ static const ResultCode RESULT_INVALID(0xDEADC0DE);
|
|||
* @param res Result to return
|
||||
*/
|
||||
static inline void FuncReturn(u32 res) {
|
||||
Core::g_app_core->SetReg(0, res);
|
||||
Core::CPU().SetReg(0, res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,8 +33,8 @@ static inline void FuncReturn(u32 res) {
|
|||
* @todo Verify that this function is correct
|
||||
*/
|
||||
static inline void FuncReturn64(u64 res) {
|
||||
Core::g_app_core->SetReg(0, (u32)(res & 0xFFFFFFFF));
|
||||
Core::g_app_core->SetReg(1, (u32)((res >> 32) & 0xFFFFFFFF));
|
||||
Core::CPU().SetReg(0, (u32)(res & 0xFFFFFFFF));
|
||||
Core::CPU().SetReg(1, (u32)((res >> 32) & 0xFFFFFFFF));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -49,7 +49,7 @@ template <ResultCode func(u32*, u32, u32, u32, u32, u32)>
|
|||
void Wrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -57,19 +57,19 @@ template <ResultCode func(u32*, s32, u32, u32, u32, s32)>
|
|||
void Wrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
template <ResultCode func(s32*, u32*, s32, bool, s64)>
|
||||
void Wrap() {
|
||||
s32 param_1 = 0;
|
||||
s32 retval = func(¶m_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2),
|
||||
s32 retval = func(¶m_1, (Kernel::Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2),
|
||||
(PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0)))
|
||||
.raw;
|
||||
|
||||
if (retval != RESULT_INVALID.raw) {
|
||||
Core::g_app_core->SetReg(1, (u32)param_1);
|
||||
Core::CPU().SetReg(1, (u32)param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ template <ResultCode func(u32*)>
|
|||
void Wrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval = func(¶m_1).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -102,24 +102,24 @@ void Wrap() {
|
|||
MemoryInfo memory_info = {};
|
||||
PageInfo page_info = {};
|
||||
u32 retval = func(&memory_info, &page_info, PARAM(2)).raw;
|
||||
Core::g_app_core->SetReg(1, memory_info.base_address);
|
||||
Core::g_app_core->SetReg(2, memory_info.size);
|
||||
Core::g_app_core->SetReg(3, memory_info.permission);
|
||||
Core::g_app_core->SetReg(4, memory_info.state);
|
||||
Core::g_app_core->SetReg(5, page_info.flags);
|
||||
Core::CPU().SetReg(1, memory_info.base_address);
|
||||
Core::CPU().SetReg(2, memory_info.size);
|
||||
Core::CPU().SetReg(3, memory_info.permission);
|
||||
Core::CPU().SetReg(4, memory_info.state);
|
||||
Core::CPU().SetReg(5, page_info.flags);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
template <ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)>
|
||||
template <ResultCode func(MemoryInfo*, PageInfo*, Kernel::Handle, u32)>
|
||||
void Wrap() {
|
||||
MemoryInfo memory_info = {};
|
||||
PageInfo page_info = {};
|
||||
u32 retval = func(&memory_info, &page_info, PARAM(2), PARAM(3)).raw;
|
||||
Core::g_app_core->SetReg(1, memory_info.base_address);
|
||||
Core::g_app_core->SetReg(2, memory_info.size);
|
||||
Core::g_app_core->SetReg(3, memory_info.permission);
|
||||
Core::g_app_core->SetReg(4, memory_info.state);
|
||||
Core::g_app_core->SetReg(5, page_info.flags);
|
||||
Core::CPU().SetReg(1, memory_info.base_address);
|
||||
Core::CPU().SetReg(2, memory_info.size);
|
||||
Core::CPU().SetReg(3, memory_info.permission);
|
||||
Core::CPU().SetReg(4, memory_info.state);
|
||||
Core::CPU().SetReg(5, page_info.flags);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ template <ResultCode func(s32*, u32)>
|
|||
void Wrap() {
|
||||
s32 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(1)).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ template <ResultCode func(u32*, u32)>
|
|||
void Wrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(1)).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ template <ResultCode func(u32*, const char*)>
|
|||
void Wrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval = func(¶m_1, (char*)Memory::GetPointer(PARAM(1))).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ template <ResultCode func(u32*, s32, s32)>
|
|||
void Wrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ template <ResultCode func(s32*, u32, s32)>
|
|||
void Wrap() {
|
||||
s32 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -184,8 +184,8 @@ template <ResultCode func(s64*, u32, s32)>
|
|||
void Wrap() {
|
||||
s64 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw;
|
||||
Core::g_app_core->SetReg(1, (u32)param_1);
|
||||
Core::g_app_core->SetReg(2, (u32)(param_1 >> 32));
|
||||
Core::CPU().SetReg(1, (u32)param_1);
|
||||
Core::CPU().SetReg(2, (u32)(param_1 >> 32));
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ void Wrap() {
|
|||
u32 param_1 = 0;
|
||||
// The last parameter is passed in R0 instead of R4
|
||||
u32 retval = func(¶m_1, PARAM(1), PARAM(2), PARAM(3), PARAM(0)).raw;
|
||||
Core::g_app_core->SetReg(1, param_1);
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
@ -205,30 +205,30 @@ void Wrap() {
|
|||
FuncReturn(func(PARAM(0), param1, param2).raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(s64*, Handle, u32)>
|
||||
template <ResultCode func(s64*, Kernel::Handle, u32)>
|
||||
void Wrap() {
|
||||
s64 param_1 = 0;
|
||||
u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw;
|
||||
Core::g_app_core->SetReg(1, (u32)param_1);
|
||||
Core::g_app_core->SetReg(2, (u32)(param_1 >> 32));
|
||||
Core::CPU().SetReg(1, (u32)param_1);
|
||||
Core::CPU().SetReg(2, (u32)(param_1 >> 32));
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
template <ResultCode func(Handle, u32)>
|
||||
template <ResultCode func(Kernel::Handle, u32)>
|
||||
void Wrap() {
|
||||
FuncReturn(func(PARAM(0), PARAM(1)).raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(Handle*, Handle*, const char*, u32)>
|
||||
template <ResultCode func(Kernel::Handle*, Kernel::Handle*, const char*, u32)>
|
||||
void Wrap() {
|
||||
Handle param_1 = 0;
|
||||
Handle param_2 = 0;
|
||||
Kernel::Handle param_1 = 0;
|
||||
Kernel::Handle param_2 = 0;
|
||||
u32 retval = func(¶m_1, ¶m_2,
|
||||
reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3))
|
||||
.raw;
|
||||
// The first out parameter is moved into R2 and the second is moved into R1.
|
||||
Core::g_app_core->SetReg(1, param_2);
|
||||
Core::g_app_core->SetReg(2, param_1);
|
||||
Core::CPU().SetReg(1, param_2);
|
||||
Core::CPU().SetReg(2, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ void Reschedule(const char* reason) {
|
|||
// routines. This simulates that time by artificially advancing the number of CPU "ticks".
|
||||
// The value was chosen empirically, it seems to work well enough for everything tested, but
|
||||
// is likely not ideal. We should find a more accurate way to simulate timing with HLE.
|
||||
Core::g_app_core->AddTicks(4000);
|
||||
Core::AppCore().AddTicks(4000);
|
||||
|
||||
Core::g_app_core->PrepareReschedule();
|
||||
Core::AppCore().PrepareReschedule();
|
||||
|
||||
reschedule = true;
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
typedef u32 Handle;
|
||||
typedef s32 Result;
|
||||
|
||||
const Handle INVALID_HANDLE = 0;
|
||||
|
||||
namespace HLE {
|
||||
|
||||
void Reschedule(const char* reason);
|
||||
bool IsReschedulePending();
|
||||
void DoneRescheduling();
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
|
||||
} // namespace
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/kernel/address_arbiter.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
#include "core/memory.h"
|
||||
|
|
|
@ -11,11 +11,12 @@
|
|||
#include <vector>
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
using Handle = u32;
|
||||
|
||||
class Thread;
|
||||
|
||||
// TODO: Verify code
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "core/arm/skyeye_common/armstate.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/kernel/mutex.h"
|
||||
|
@ -188,7 +187,7 @@ static void SwitchContext(Thread* new_thread) {
|
|||
// Save context for previous thread
|
||||
if (previous_thread) {
|
||||
previous_thread->last_running_ticks = CoreTiming::GetTicks();
|
||||
Core::g_app_core->SaveContext(previous_thread->context);
|
||||
Core::CPU().SaveContext(previous_thread->context);
|
||||
|
||||
if (previous_thread->status == THREADSTATUS_RUNNING) {
|
||||
// This is only the case when a reschedule is triggered without the current thread
|
||||
|
@ -214,8 +213,8 @@ static void SwitchContext(Thread* new_thread) {
|
|||
// Restores thread to its nominal priority if it has been temporarily changed
|
||||
new_thread->current_priority = new_thread->nominal_priority;
|
||||
|
||||
Core::g_app_core->LoadContext(new_thread->context);
|
||||
Core::g_app_core->SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
|
||||
Core::CPU().LoadContext(new_thread->context);
|
||||
Core::CPU().SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
|
||||
} else {
|
||||
current_thread = nullptr;
|
||||
}
|
||||
|
@ -330,7 +329,7 @@ void Thread::ResumeFromWait() {
|
|||
|
||||
ready_queue.push_back(current_priority, this);
|
||||
status = THREADSTATUS_READY;
|
||||
HLE::Reschedule(__func__);
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -385,9 +384,9 @@ std::tuple<u32, u32, bool> GetFreeThreadLocalSlot(std::vector<std::bitset<8>>& t
|
|||
* @param entry_point Address of entry point for execution
|
||||
* @param arg User argument for thread
|
||||
*/
|
||||
static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point,
|
||||
u32 arg) {
|
||||
memset(&context, 0, sizeof(Core::ThreadContext));
|
||||
static void ResetThreadContext(ARM_Interface::ThreadContext& context, u32 stack_top,
|
||||
u32 entry_point, u32 arg) {
|
||||
memset(&context, 0, sizeof(ARM_Interface::ThreadContext));
|
||||
|
||||
context.cpu_registers[0] = arg;
|
||||
context.pc = entry_point;
|
||||
|
@ -545,8 +544,6 @@ void Reschedule() {
|
|||
Thread* cur = GetCurrentThread();
|
||||
Thread* next = PopNextReadyThread();
|
||||
|
||||
HLE::DoneRescheduling();
|
||||
|
||||
if (cur && next) {
|
||||
LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId());
|
||||
} else if (cur) {
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include "common/common_types.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
|
@ -158,7 +158,7 @@ public:
|
|||
return !wait_objects.empty();
|
||||
}
|
||||
|
||||
Core::ThreadContext context;
|
||||
ARM_Interface::ThreadContext context;
|
||||
|
||||
u32 thread_id;
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "core/file_sys/archive_systemsavedata.h"
|
||||
#include "core/file_sys/directory_backend.h"
|
||||
#include "core/file_sys/file_backend.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/fs/archive.h"
|
||||
|
@ -46,9 +45,7 @@ struct hash<Service::FS::ArchiveIdCode> {
|
|||
};
|
||||
}
|
||||
|
||||
/// TODO(Subv): Confirm length of these strings
|
||||
const std::string SYSTEM_ID = "00000000000000000000000000000000";
|
||||
const std::string SDCARD_ID = "00000000000000000000000000000000";
|
||||
static constexpr Kernel::Handle INVALID_HANDLE{};
|
||||
|
||||
namespace Service {
|
||||
namespace FS {
|
||||
|
|
|
@ -17,9 +17,9 @@ class FileBackend;
|
|||
}
|
||||
|
||||
/// The unique system identifier hash, also known as ID0
|
||||
extern const std::string SYSTEM_ID;
|
||||
static constexpr char SYSTEM_ID[]{"00000000000000000000000000000000"};
|
||||
/// The scrambled SD card CID, also known as ID1
|
||||
extern const std::string SDCARD_ID;
|
||||
static constexpr char SDCARD_ID[]{"00000000000000000000000000000000"};
|
||||
|
||||
namespace Service {
|
||||
namespace FS {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/service/ir/ir.h"
|
||||
#include "core/hle/service/ir/ir_rst.h"
|
||||
|
@ -36,7 +37,7 @@ void InitializeIrNopShared(Interface* self) {
|
|||
u32 send_buff_size = cmd_buff[4];
|
||||
u32 unk2 = cmd_buff[5];
|
||||
u8 baud_rate = cmd_buff[6] & 0xFF;
|
||||
Handle handle = cmd_buff[8];
|
||||
Kernel::Handle handle = cmd_buff[8];
|
||||
|
||||
if (Kernel::g_handle_table.IsValid(handle)) {
|
||||
transfer_shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(handle);
|
||||
|
|
|
@ -457,7 +457,7 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
|
|||
}
|
||||
}
|
||||
|
||||
Core::g_app_core->ClearInstructionCache();
|
||||
Core::CPU().ClearInstructionCache();
|
||||
|
||||
LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(),
|
||||
cro_address, cro_address + fix_size);
|
||||
|
@ -562,7 +562,7 @@ static void UnloadCRO(Interface* self) {
|
|||
memory_synchronizer.RemoveMemoryBlock(cro_address, cro_buffer_ptr);
|
||||
}
|
||||
|
||||
Core::g_app_core->ClearInstructionCache();
|
||||
Core::CPU().ClearInstructionCache();
|
||||
|
||||
cmd_buff[1] = result.raw;
|
||||
}
|
||||
|
@ -624,7 +624,7 @@ static void LinkCRO(Interface* self) {
|
|||
}
|
||||
|
||||
memory_synchronizer.SynchronizeOriginalMemory();
|
||||
Core::g_app_core->ClearInstructionCache();
|
||||
Core::CPU().ClearInstructionCache();
|
||||
|
||||
cmd_buff[1] = result.raw;
|
||||
}
|
||||
|
@ -686,7 +686,7 @@ static void UnlinkCRO(Interface* self) {
|
|||
}
|
||||
|
||||
memory_synchronizer.SynchronizeOriginalMemory();
|
||||
Core::g_app_core->ClearInstructionCache();
|
||||
Core::CPU().ClearInstructionCache();
|
||||
|
||||
cmd_buff[1] = result.raw;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/service/mic_u.h"
|
||||
|
||||
|
@ -50,7 +51,7 @@ static bool audio_buffer_loop;
|
|||
static void MapSharedMem(Interface* self) {
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 size = cmd_buff[1];
|
||||
Handle mem_handle = cmd_buff[3];
|
||||
Kernel::Handle mem_handle = cmd_buff[3];
|
||||
shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(mem_handle);
|
||||
if (shared_memory) {
|
||||
shared_memory->name = "MIC_U:shared_memory";
|
||||
|
|
|
@ -166,7 +166,8 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
|
|||
}
|
||||
|
||||
/// Maps a memory block to specified address
|
||||
static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) {
|
||||
static ResultCode MapMemoryBlock(Kernel::Handle handle, u32 addr, u32 permissions,
|
||||
u32 other_permissions) {
|
||||
using Kernel::SharedMemory;
|
||||
using Kernel::MemoryPermission;
|
||||
|
||||
|
@ -198,7 +199,7 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
|
|||
ErrorSummary::InvalidArgument, ErrorLevel::Usage);
|
||||
}
|
||||
|
||||
static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
|
||||
static ResultCode UnmapMemoryBlock(Kernel::Handle handle, u32 addr) {
|
||||
using Kernel::SharedMemory;
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X", handle, addr);
|
||||
|
@ -213,7 +214,7 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
|
|||
}
|
||||
|
||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||
static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) {
|
||||
static ResultCode ConnectToPort(Kernel::Handle* out_handle, const char* port_name) {
|
||||
if (port_name == nullptr)
|
||||
return ERR_NOT_FOUND;
|
||||
if (std::strlen(port_name) > 11)
|
||||
|
@ -238,7 +239,7 @@ static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) {
|
|||
}
|
||||
|
||||
/// Makes a blocking IPC call to an OS service.
|
||||
static ResultCode SendSyncRequest(Handle handle) {
|
||||
static ResultCode SendSyncRequest(Kernel::Handle handle) {
|
||||
SharedPtr<Kernel::ClientSession> session =
|
||||
Kernel::g_handle_table.Get<Kernel::ClientSession>(handle);
|
||||
if (session == nullptr) {
|
||||
|
@ -253,13 +254,13 @@ static ResultCode SendSyncRequest(Handle handle) {
|
|||
}
|
||||
|
||||
/// Close a handle
|
||||
static ResultCode CloseHandle(Handle handle) {
|
||||
static ResultCode CloseHandle(Kernel::Handle handle) {
|
||||
LOG_TRACE(Kernel_SVC, "Closing handle 0x%08X", handle);
|
||||
return Kernel::g_handle_table.Close(handle);
|
||||
}
|
||||
|
||||
/// Wait for a handle to synchronize, timeout after the specified nanoseconds
|
||||
static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
|
||||
static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds) {
|
||||
auto object = Kernel::g_handle_table.GetWaitObject(handle);
|
||||
Kernel::Thread* thread = Kernel::GetCurrentThread();
|
||||
|
||||
|
@ -295,8 +296,8 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
|
|||
}
|
||||
|
||||
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
||||
static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all,
|
||||
s64 nano_seconds) {
|
||||
static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 handle_count,
|
||||
bool wait_all, s64 nano_seconds) {
|
||||
Kernel::Thread* thread = Kernel::GetCurrentThread();
|
||||
|
||||
// Check if 'handles' is invalid
|
||||
|
@ -423,7 +424,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
|
|||
}
|
||||
|
||||
/// Create an address arbiter (to allocate access to shared resources)
|
||||
static ResultCode CreateAddressArbiter(Handle* out_handle) {
|
||||
static ResultCode CreateAddressArbiter(Kernel::Handle* out_handle) {
|
||||
using Kernel::AddressArbiter;
|
||||
|
||||
SharedPtr<AddressArbiter> arbiter = AddressArbiter::Create();
|
||||
|
@ -433,7 +434,7 @@ static ResultCode CreateAddressArbiter(Handle* out_handle) {
|
|||
}
|
||||
|
||||
/// Arbitrate address
|
||||
static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value,
|
||||
static ResultCode ArbitrateAddress(Kernel::Handle handle, u32 address, u32 type, u32 value,
|
||||
s64 nanoseconds) {
|
||||
using Kernel::AddressArbiter;
|
||||
|
||||
|
@ -476,7 +477,7 @@ static void OutputDebugString(const char* string) {
|
|||
}
|
||||
|
||||
/// Get resource limit
|
||||
static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) {
|
||||
static ResultCode GetResourceLimit(Kernel::Handle* resource_limit, Kernel::Handle process_handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle);
|
||||
|
||||
SharedPtr<Kernel::Process> process =
|
||||
|
@ -490,7 +491,7 @@ static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle
|
|||
}
|
||||
|
||||
/// Get resource limit current values
|
||||
static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle,
|
||||
static ResultCode GetResourceLimitCurrentValues(s64* values, Kernel::Handle resource_limit_handle,
|
||||
u32* names, u32 name_count) {
|
||||
LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
|
||||
resource_limit_handle, names, name_count);
|
||||
|
@ -507,8 +508,8 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_lim
|
|||
}
|
||||
|
||||
/// Get resource limit max values
|
||||
static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names,
|
||||
u32 name_count) {
|
||||
static ResultCode GetResourceLimitLimitValues(s64* values, Kernel::Handle resource_limit_handle,
|
||||
u32* names, u32 name_count) {
|
||||
LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
|
||||
resource_limit_handle, names, name_count);
|
||||
|
||||
|
@ -524,7 +525,7 @@ static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit
|
|||
}
|
||||
|
||||
/// Creates a new thread
|
||||
static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point, u32 arg,
|
||||
static ResultCode CreateThread(Kernel::Handle* out_handle, s32 priority, u32 entry_point, u32 arg,
|
||||
u32 stack_top, s32 processor_id) {
|
||||
using Kernel::Thread;
|
||||
|
||||
|
@ -582,13 +583,13 @@ static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point
|
|||
|
||||
/// Called when a thread exits
|
||||
static void ExitThread() {
|
||||
LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::g_app_core->GetPC());
|
||||
LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC());
|
||||
|
||||
Kernel::ExitCurrentThread();
|
||||
}
|
||||
|
||||
/// Gets the priority for the specified thread
|
||||
static ResultCode GetThreadPriority(s32* priority, Handle handle) {
|
||||
static ResultCode GetThreadPriority(s32* priority, Kernel::Handle handle) {
|
||||
const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
|
||||
if (thread == nullptr)
|
||||
return ERR_INVALID_HANDLE;
|
||||
|
@ -598,7 +599,7 @@ static ResultCode GetThreadPriority(s32* priority, Handle handle) {
|
|||
}
|
||||
|
||||
/// Sets the priority for the specified thread
|
||||
static ResultCode SetThreadPriority(Handle handle, s32 priority) {
|
||||
static ResultCode SetThreadPriority(Kernel::Handle handle, s32 priority) {
|
||||
SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
|
||||
if (thread == nullptr)
|
||||
return ERR_INVALID_HANDLE;
|
||||
|
@ -608,11 +609,11 @@ static ResultCode SetThreadPriority(Handle handle, s32 priority) {
|
|||
}
|
||||
|
||||
/// Create a mutex
|
||||
static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
|
||||
static ResultCode CreateMutex(Kernel::Handle* out_handle, u32 initial_locked) {
|
||||
using Kernel::Mutex;
|
||||
|
||||
SharedPtr<Mutex> mutex = Mutex::Create(initial_locked != 0);
|
||||
mutex->name = Common::StringFromFormat("mutex-%08x", Core::g_app_core->GetReg(14));
|
||||
mutex->name = Common::StringFromFormat("mutex-%08x", Core::CPU().GetReg(14));
|
||||
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex)));
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X",
|
||||
|
@ -622,7 +623,7 @@ static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
|
|||
}
|
||||
|
||||
/// Release a mutex
|
||||
static ResultCode ReleaseMutex(Handle handle) {
|
||||
static ResultCode ReleaseMutex(Kernel::Handle handle) {
|
||||
using Kernel::Mutex;
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called handle=0x%08X", handle);
|
||||
|
@ -637,7 +638,7 @@ static ResultCode ReleaseMutex(Handle handle) {
|
|||
}
|
||||
|
||||
/// Get the ID of the specified process
|
||||
static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
|
||||
static ResultCode GetProcessId(u32* process_id, Kernel::Handle process_handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle);
|
||||
|
||||
const SharedPtr<Kernel::Process> process =
|
||||
|
@ -650,7 +651,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
|
|||
}
|
||||
|
||||
/// Get the ID of the process that owns the specified thread
|
||||
static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
|
||||
static ResultCode GetProcessIdOfThread(u32* process_id, Kernel::Handle thread_handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
|
||||
|
||||
const SharedPtr<Kernel::Thread> thread =
|
||||
|
@ -667,7 +668,7 @@ static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
|
|||
}
|
||||
|
||||
/// Get the ID for the specified thread.
|
||||
static ResultCode GetThreadId(u32* thread_id, Handle handle) {
|
||||
static ResultCode GetThreadId(u32* thread_id, Kernel::Handle handle) {
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle);
|
||||
|
||||
const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
|
||||
|
@ -679,11 +680,11 @@ static ResultCode GetThreadId(u32* thread_id, Handle handle) {
|
|||
}
|
||||
|
||||
/// Creates a semaphore
|
||||
static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) {
|
||||
static ResultCode CreateSemaphore(Kernel::Handle* out_handle, s32 initial_count, s32 max_count) {
|
||||
using Kernel::Semaphore;
|
||||
|
||||
CASCADE_RESULT(SharedPtr<Semaphore> semaphore, Semaphore::Create(initial_count, max_count));
|
||||
semaphore->name = Common::StringFromFormat("semaphore-%08x", Core::g_app_core->GetReg(14));
|
||||
semaphore->name = Common::StringFromFormat("semaphore-%08x", Core::CPU().GetReg(14));
|
||||
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(semaphore)));
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called initial_count=%d, max_count=%d, created handle=0x%08X",
|
||||
|
@ -692,7 +693,7 @@ static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max
|
|||
}
|
||||
|
||||
/// Releases a certain number of slots in a semaphore
|
||||
static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
|
||||
static ResultCode ReleaseSemaphore(s32* count, Kernel::Handle handle, s32 release_count) {
|
||||
using Kernel::Semaphore;
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called release_count=%d, handle=0x%08X", release_count, handle);
|
||||
|
@ -708,7 +709,7 @@ static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count)
|
|||
|
||||
/// Query process memory
|
||||
static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info,
|
||||
Handle process_handle, u32 addr) {
|
||||
Kernel::Handle process_handle, u32 addr) {
|
||||
using Kernel::Process;
|
||||
Kernel::SharedPtr<Process> process = Kernel::g_handle_table.Get<Process>(process_handle);
|
||||
if (process == nullptr)
|
||||
|
@ -736,11 +737,11 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32
|
|||
}
|
||||
|
||||
/// Create an event
|
||||
static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
|
||||
static ResultCode CreateEvent(Kernel::Handle* out_handle, u32 reset_type) {
|
||||
using Kernel::Event;
|
||||
|
||||
SharedPtr<Event> evt = Event::Create(static_cast<Kernel::ResetType>(reset_type));
|
||||
evt->name = Common::StringFromFormat("event-%08x", Core::g_app_core->GetReg(14));
|
||||
evt->name = Common::StringFromFormat("event-%08x", Core::CPU().GetReg(14));
|
||||
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt)));
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type,
|
||||
|
@ -749,14 +750,14 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
|
|||
}
|
||||
|
||||
/// Duplicates a kernel handle
|
||||
static ResultCode DuplicateHandle(Handle* out, Handle handle) {
|
||||
static ResultCode DuplicateHandle(Kernel::Handle* out, Kernel::Handle handle) {
|
||||
CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle));
|
||||
LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Signals an event
|
||||
static ResultCode SignalEvent(Handle handle) {
|
||||
static ResultCode SignalEvent(Kernel::Handle handle) {
|
||||
using Kernel::Event;
|
||||
LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
|
||||
|
||||
|
@ -770,7 +771,7 @@ static ResultCode SignalEvent(Handle handle) {
|
|||
}
|
||||
|
||||
/// Clears an event
|
||||
static ResultCode ClearEvent(Handle handle) {
|
||||
static ResultCode ClearEvent(Kernel::Handle handle) {
|
||||
using Kernel::Event;
|
||||
LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
|
||||
|
||||
|
@ -783,11 +784,11 @@ static ResultCode ClearEvent(Handle handle) {
|
|||
}
|
||||
|
||||
/// Creates a timer
|
||||
static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
|
||||
static ResultCode CreateTimer(Kernel::Handle* out_handle, u32 reset_type) {
|
||||
using Kernel::Timer;
|
||||
|
||||
SharedPtr<Timer> timer = Timer::Create(static_cast<Kernel::ResetType>(reset_type));
|
||||
timer->name = Common::StringFromFormat("timer-%08x", Core::g_app_core->GetReg(14));
|
||||
timer->name = Common::StringFromFormat("timer-%08x", Core::CPU().GetReg(14));
|
||||
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer)));
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type,
|
||||
|
@ -796,7 +797,7 @@ static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
|
|||
}
|
||||
|
||||
/// Clears a timer
|
||||
static ResultCode ClearTimer(Handle handle) {
|
||||
static ResultCode ClearTimer(Kernel::Handle handle) {
|
||||
using Kernel::Timer;
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
|
||||
|
@ -810,7 +811,7 @@ static ResultCode ClearTimer(Handle handle) {
|
|||
}
|
||||
|
||||
/// Starts a timer
|
||||
static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) {
|
||||
static ResultCode SetTimer(Kernel::Handle handle, s64 initial, s64 interval) {
|
||||
using Kernel::Timer;
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
|
||||
|
@ -825,7 +826,7 @@ static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) {
|
|||
}
|
||||
|
||||
/// Cancels a timer
|
||||
static ResultCode CancelTimer(Handle handle) {
|
||||
static ResultCode CancelTimer(Kernel::Handle handle) {
|
||||
using Kernel::Timer;
|
||||
|
||||
LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
|
||||
|
@ -854,14 +855,13 @@ static void SleepThread(s64 nanoseconds) {
|
|||
static s64 GetSystemTick() {
|
||||
s64 result = CoreTiming::GetTicks();
|
||||
// Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end.
|
||||
Core::g_app_core->AddTicks(
|
||||
150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
|
||||
Core::CPU().AddTicks(150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Creates a memory block at the specified address with the specified permissions and size
|
||||
static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission,
|
||||
u32 other_permission) {
|
||||
static ResultCode CreateMemoryBlock(Kernel::Handle* out_handle, u32 addr, u32 size,
|
||||
u32 my_permission, u32 other_permission) {
|
||||
using Kernel::SharedMemory;
|
||||
|
||||
if (size % Memory::PAGE_SIZE != 0)
|
||||
|
@ -912,8 +912,8 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
|
|||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode CreatePort(Handle* server_port, Handle* client_port, const char* name,
|
||||
u32 max_sessions) {
|
||||
static ResultCode CreatePort(Kernel::Handle* server_port, Kernel::Handle* client_port,
|
||||
const char* name, u32 max_sessions) {
|
||||
// TODO(Subv): Implement named ports.
|
||||
ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented");
|
||||
|
||||
|
@ -978,7 +978,7 @@ static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
|
|||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
|
||||
static ResultCode GetProcessInfo(s64* out, Kernel::Handle process_handle, u32 type) {
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x%08X type=%u", process_handle, type);
|
||||
|
||||
using Kernel::Process;
|
||||
|
@ -1185,7 +1185,7 @@ void CallSVC(u32 immediate) {
|
|||
if (info->func) {
|
||||
info->func();
|
||||
// TODO(Subv): Not all service functions should cause a reschedule in all cases.
|
||||
HLE::Reschedule(__func__);
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
} else {
|
||||
LOG_ERROR(Kernel_SVC, "unimplemented SVC function %s(..)", info->name);
|
||||
}
|
||||
|
|
|
@ -27,34 +27,14 @@ public:
|
|||
*/
|
||||
static FileType IdentifyType(FileUtil::IOFile& file);
|
||||
|
||||
/**
|
||||
* Returns the type of this file
|
||||
* @return FileType corresponding to the loaded file
|
||||
*/
|
||||
FileType GetFileType() override {
|
||||
return IdentifyType(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the bootable file
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus Load() override;
|
||||
|
||||
/**
|
||||
* Get the icon (typically icon section) of the application
|
||||
* @param buffer Reference to buffer to store data
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus ReadIcon(std::vector<u8>& buffer) override;
|
||||
|
||||
/**
|
||||
* Get the RomFS of the application
|
||||
* @param romfs_file Reference to buffer to store data
|
||||
* @param offset Offset in the file to the RomFS
|
||||
* @param size Size of the RomFS in bytes
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
|
||||
u64& size) override;
|
||||
|
||||
|
|
|
@ -26,18 +26,10 @@ public:
|
|||
*/
|
||||
static FileType IdentifyType(FileUtil::IOFile& file);
|
||||
|
||||
/**
|
||||
* Returns the type of this file
|
||||
* @return FileType corresponding to the loaded file
|
||||
*/
|
||||
FileType GetFileType() override {
|
||||
return IdentifyType(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the bootable file
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus Load() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -171,18 +171,10 @@ public:
|
|||
*/
|
||||
static FileType IdentifyType(FileUtil::IOFile& file);
|
||||
|
||||
/**
|
||||
* Returns the type of this file
|
||||
* @return FileType corresponding to the loaded file
|
||||
*/
|
||||
FileType GetFileType() override {
|
||||
return IdentifyType(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the application
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus Load() override;
|
||||
|
||||
/**
|
||||
|
@ -191,32 +183,12 @@ public:
|
|||
*/
|
||||
boost::optional<u32> LoadKernelSystemMode();
|
||||
|
||||
/**
|
||||
* Get the code (typically .code section) of the application
|
||||
* @param buffer Reference to buffer to store data
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus ReadCode(std::vector<u8>& buffer) override;
|
||||
|
||||
/**
|
||||
* Get the icon (typically icon section) of the application
|
||||
* @param buffer Reference to buffer to store data
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus ReadIcon(std::vector<u8>& buffer) override;
|
||||
|
||||
/**
|
||||
* Get the banner (typically banner section) of the application
|
||||
* @param buffer Reference to buffer to store data
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus ReadBanner(std::vector<u8>& buffer) override;
|
||||
|
||||
/**
|
||||
* Get the logo (typically logo section) of the application
|
||||
* @param buffer Reference to buffer to store data
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
ResultStatus ReadLogo(std::vector<u8>& buffer) override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "audio_core/audio_core.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hle/hle.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hw/hw.h"
|
||||
#include "core/system.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
namespace System {
|
||||
|
||||
static bool is_powered_on{false};
|
||||
|
||||
Result Init(EmuWindow* emu_window, u32 system_mode) {
|
||||
Core::Init();
|
||||
CoreTiming::Init();
|
||||
Memory::Init();
|
||||
HW::Init();
|
||||
Kernel::Init(system_mode);
|
||||
HLE::Init();
|
||||
if (!VideoCore::Init(emu_window)) {
|
||||
return Result::ErrorInitVideoCore;
|
||||
}
|
||||
AudioCore::Init();
|
||||
GDBStub::Init();
|
||||
|
||||
is_powered_on = true;
|
||||
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
bool IsPoweredOn() {
|
||||
return is_powered_on;
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
GDBStub::Shutdown();
|
||||
AudioCore::Shutdown();
|
||||
VideoCore::Shutdown();
|
||||
HLE::Shutdown();
|
||||
Kernel::Shutdown();
|
||||
HW::Shutdown();
|
||||
CoreTiming::Shutdown();
|
||||
Core::Shutdown();
|
||||
|
||||
is_powered_on = false;
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
class EmuWindow;
|
||||
|
||||
namespace System {
|
||||
|
||||
enum class Result {
|
||||
Success, ///< Everything is fine
|
||||
Error, ///< Something went wrong (no module specified)
|
||||
ErrorInitCore, ///< Something went wrong during core init
|
||||
ErrorInitVideoCore, ///< Something went wrong during video core init
|
||||
};
|
||||
|
||||
Result Init(EmuWindow* emu_window, u32 system_mode);
|
||||
bool IsPoweredOn();
|
||||
void Shutdown();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue