Compare commits

..

3 Commits

Author SHA1 Message Date
Daniel Lim Wee Soong
8529d84f31 Remove dependency chrono
Earlier chrono was included but after some code changed it was no longer needed

Forgot to remove it so I'm removing it now
2018-03-22 21:53:51 +08:00
Daniel Lim Wee Soong
47f96fe13a Change "yuzu starting..." to be logged with the new macro
Just as a proof that it works
2018-03-22 18:26:43 +08:00
Daniel Lim Wee Soong
3b558eebee Logging: Create logging macros based on fmtlib
Add a new set of logging macros based on fmtlib
Similar but not exactly the same as https://github.com/citra-emu/citra/pull/3533

Citra currently uses a different version of fmt, which does not support FMT_VARIADIC so
make_args is used instead. On the other hand, yuzu uses fmt 4.1.0 which doesn't have make_args yet
so FMT_VARIADIC is used.
2018-03-22 18:21:29 +08:00
146 changed files with 2115 additions and 26855 deletions

2
.gitmodules vendored
View File

@@ -18,7 +18,7 @@
url = https://github.com/fmtlib/fmt.git
[submodule "lz4"]
path = externals/lz4
url = https://github.com/lz4/lz4.git
url = http://github.com/lz4/lz4.git
[submodule "unicorn"]
path = externals/unicorn
url = https://github.com/yuzu-emu/unicorn

View File

@@ -160,9 +160,6 @@ set_property(DIRECTORY APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG> $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
math(EXPR EMU_ARCH_BITS ${CMAKE_SIZEOF_VOID_P}*8)
add_definitions(-DEMU_ARCH_BITS=${EMU_ARCH_BITS})
# System imported libraries
# ======================

View File

@@ -1,5 +1,5 @@
These files were generated by the [glad](https://github.com/Dav1dde/glad) OpenGL loader generator and have been checked in as-is. You can re-generate them using glad with the following command:
```
python -m glad --profile core --out-path glad/ --api gl=3.3 --generator=c
python -m glad --profile core --out-path glad/ --api gl=3.3,gles=3.0
```

View File

@@ -26,7 +26,7 @@
/* Khronos platform-specific types and definitions.
*
* $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
* $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
@@ -101,8 +101,6 @@
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
@@ -225,7 +223,7 @@ typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -58,6 +58,7 @@ add_library(common STATIC
misc.cpp
param_package.cpp
param_package.h
platform.h
quaternion.h
scm_rev.cpp
scm_rev.h
@@ -89,7 +90,7 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC Boost::boost microprofile)
target_link_libraries(common PUBLIC Boost::boost fmt microprofile)
if (ARCHITECTURE_x86_64)
target_link_libraries(common PRIVATE xbyak)
endif()

View File

@@ -11,6 +11,7 @@
#include "common/logging/filter.h"
#include "common/logging/log.h"
#include "common/logging/text_formatter.h"
#include "common/string_util.h"
namespace Log {
@@ -37,7 +38,6 @@ namespace Log {
SUB(Service, AM) \
SUB(Service, AOC) \
SUB(Service, APM) \
SUB(Service, Fatal) \
SUB(Service, Friend) \
SUB(Service, FS) \
SUB(Service, HID) \
@@ -48,7 +48,6 @@ namespace Log {
SUB(Service, PCTL) \
SUB(Service, SET) \
SUB(Service, SM) \
SUB(Service, SPL) \
SUB(Service, Time) \
SUB(Service, VI) \
CLS(HW) \
@@ -104,25 +103,20 @@ const char* GetLevelName(Level log_level) {
}
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
const char* function, const char* format, va_list args) {
const char* function, std::string message) {
using std::chrono::duration_cast;
using std::chrono::steady_clock;
static steady_clock::time_point time_origin = steady_clock::now();
std::array<char, 4 * 1024> formatting_buffer;
Entry entry;
entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin);
entry.log_class = log_class;
entry.log_level = log_level;
snprintf(formatting_buffer.data(), formatting_buffer.size(), "%s:%s:%u", filename, function,
line_nr);
entry.location = std::string(formatting_buffer.data());
vsnprintf(formatting_buffer.data(), formatting_buffer.size(), format, args);
entry.message = std::string(formatting_buffer.data());
entry.filename = Common::TrimSourcePath(filename);
entry.line_num = line_nr;
entry.function = function;
entry.message = std::move(message);
return entry;
}
@@ -133,15 +127,27 @@ void SetFilter(Filter* new_filter) {
filter = new_filter;
}
void LogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
void LogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, const char* format, ...) {
if (filter != nullptr && !filter->CheckMessage(log_class, log_level))
if (filter && !filter->CheckMessage(log_class, log_level))
return;
std::array<char, 4 * 1024> formatting_buffer;
va_list args;
va_start(args, format);
Entry entry = CreateEntry(log_class, log_level, filename, line_nr, function, format, args);
vsnprintf(formatting_buffer.data(), formatting_buffer.size(), format, args);
va_end(args);
Entry entry = CreateEntry(log_class, log_level, filename, line_num, function,
std::string(formatting_buffer.data()));
PrintColoredMessage(entry);
}
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, const char* format, const fmt::ArgList& args) {
if (filter && !filter->CheckMessage(log_class, log_level))
return;
Entry entry =
CreateEntry(log_class, log_level, filename, line_num, function, fmt::format(format, args));
PrintColoredMessage(entry);
}

View File

@@ -22,13 +22,16 @@ struct Entry {
std::chrono::microseconds timestamp;
Class log_class;
Level log_level;
std::string location;
std::string filename;
unsigned int line_num;
std::string function;
std::string message;
Entry() = default;
Entry(Entry&& o) = default;
Entry& operator=(Entry&& o) = default;
Entry& operator=(const Entry& o) = default;
};
/**
@@ -44,7 +47,7 @@ const char* GetLevelName(Level log_level);
/// Creates a log entry by formatting the given source location, and message.
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
const char* function, const char* format, va_list args);
const char* function, std::string message);
void SetFilter(Filter* filter);
} // namespace Log

View File

@@ -65,14 +65,14 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
const std::string::const_iterator end) {
auto level_separator = std::find(begin, end, ':');
if (level_separator == end) {
LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: %s",
std::string(begin, end).c_str());
NGLOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: %s",
std::string(begin, end).c_str());
return false;
}
const Level level = GetLevelByName(level_separator + 1, end);
if (level == Level::Count) {
LOG_ERROR(Log, "Unknown log level in filter: %s", std::string(begin, end).c_str());
NGLOG_ERROR(Log, "Unknown log level in filter: %s", std::string(begin, end).c_str());
return false;
}
@@ -83,7 +83,7 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
const Class log_class = GetClassByName(begin, level_separator);
if (log_class == Class::Count) {
LOG_ERROR(Log, "Unknown log class in filter: %s", std::string(begin, end).c_str());
NGLOG_ERROR(Log, "Unknown log class in filter: %s", std::string(begin, end).c_str());
return false;
}

View File

@@ -19,7 +19,7 @@ namespace Log {
class Filter {
public:
/// Initializes the filter with all classes having `default_level` as the minimum level.
Filter(Level default_level);
Filter(Level default_level = Level::Info);
/// Resets the filter so that all classes have `level` as the minimum displayed level.
void ResetAll(Level level);

View File

@@ -4,6 +4,7 @@
#pragma once
#include <fmt/format.h>
#include "common/common_types.h"
namespace Log {
@@ -54,7 +55,6 @@ enum class Class : ClassType {
Service_AOC, ///< The AOC (AddOn Content) service
Service_APM, ///< The APM (Performance) service
Service_Audio, ///< The Audio (Audio control) service
Service_Fatal, ///< The Fatal service
Service_Friend, ///< The friend service
Service_FS, ///< The FS (Filesystem) service
Service_HID, ///< The HID (Human interface device) service
@@ -65,7 +65,6 @@ enum class Class : ClassType {
Service_PCTL, ///< The PCTL (Parental control) service
Service_SET, ///< The SET (Settings) service
Service_SM, ///< The SM (Service manager) service
Service_SPL, ///< The SPL service
Service_Time, ///< The time service
Service_VI, ///< The VI (Video interface) service
HW, ///< Low-level hardware emulation
@@ -89,7 +88,7 @@ enum class Class : ClassType {
};
/// Logs a message to the global logger.
void LogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
void LogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function,
#ifdef _MSC_VER
_Printf_format_string_
@@ -101,6 +100,10 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
#endif
;
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, const char* format, const fmt::ArgList& args);
FMT_VARIADIC(void, FmtLogMessage, Class, Level, const char*, unsigned int, const char*, const char*)
} // namespace Log
#define LOG_GENERIC(log_class, log_level, ...) \
@@ -123,3 +126,28 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Error, __VA_ARGS__)
#define LOG_CRITICAL(log_class, ...) \
LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Critical, __VA_ARGS__)
// Define the fmt lib macros
#ifdef _DEBUG
#define NGLOG_TRACE(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Trace, __FILE__, __LINE__, \
__func__, __VA_ARGS__)
#else
#define NGLOG_TRACE(log_class, fmt, ...) (void(0))
#endif
#define NGLOG_DEBUG(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Debug, __FILE__, __LINE__, \
__func__, __VA_ARGS__)
#define NGLOG_INFO(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Info, __FILE__, __LINE__, \
__func__, __VA_ARGS__)
#define NGLOG_WARNING(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Warning, __FILE__, __LINE__, \
__func__, __VA_ARGS__)
#define NGLOG_ERROR(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Error, __FILE__, __LINE__, \
__func__, __VA_ARGS__)
#define NGLOG_CRITICAL(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Critical, __FILE__, __LINE__, \
__func__, __VA_ARGS__)

View File

@@ -18,50 +18,29 @@
namespace Log {
// TODO(bunnei): This should be moved to a generic path manipulation library
const char* TrimSourcePath(const char* path, const char* root) {
const char* p = path;
while (*p != '\0') {
const char* next_slash = p;
while (*next_slash != '\0' && *next_slash != '/' && *next_slash != '\\') {
++next_slash;
}
bool is_src = Common::ComparePartialString(p, next_slash, root);
p = next_slash;
if (*p != '\0') {
++p;
}
if (is_src) {
path = p;
}
}
return path;
}
void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len) {
std::string FormatLogMessage(const Entry& entry) {
unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000);
unsigned int time_fractional = static_cast<unsigned int>(entry.timestamp.count() % 1000000);
const char* class_name = GetLogClassName(entry.log_class);
const char* level_name = GetLevelName(entry.log_level);
snprintf(out_text, text_len, "[%4u.%06u] %s <%s> %s: %s", time_seconds, time_fractional,
class_name, level_name, TrimSourcePath(entry.location.c_str()), entry.message.c_str());
return fmt::format("[{:4d}.{:06d}] {} <{}> {}:{}:{}: {}", time_seconds, time_fractional,
class_name, level_name, entry.filename, entry.function, entry.line_num,
entry.message);
}
void PrintMessage(const Entry& entry) {
std::array<char, 4 * 1024> format_buffer;
FormatLogMessage(entry, format_buffer.data(), format_buffer.size());
fputs(format_buffer.data(), stderr);
fputc('\n', stderr);
auto str = FormatLogMessage(entry) + '\n';
fputs(str.c_str(), stderr);
}
void PrintColoredMessage(const Entry& entry) {
#ifdef _WIN32
static HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE);
HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE);
if (console_handle == INVALID_HANDLE_VALUE) {
return;
}
CONSOLE_SCREEN_BUFFER_INFO original_info = {0};
GetConsoleScreenBufferInfo(console_handle, &original_info);

View File

@@ -10,20 +10,8 @@ namespace Log {
struct Entry;
/**
* Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's
* intended to be used to strip a system-specific build directory from the `__FILE__` macro,
* leaving only the path relative to the sources root.
*
* @param path The input file path as a null-terminated string
* @param root The name of the root source directory as a null-terminated string. Path up to and
* including the last occurrence of this name will be stripped
* @return A pointer to the same string passed as `path`, but starting at the trimmed portion
*/
const char* TrimSourcePath(const char* path, const char* root = "src");
/// Formats a log entry into the provided text buffer.
void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len);
std::string FormatLogMessage(const Entry& entry);
/// Formats and prints a log entry to stderr.
void PrintMessage(const Entry& entry);
/// Prints the same message as `PrintMessage`, but colored acoording to the severity level.

34
src/common/platform.h Normal file
View File

@@ -0,0 +1,34 @@
/**
* Copyright (C) 2005-2012 Gekko Emulator
*
* @file platform.h
* @author ShizZy <shizzy247@gmail.com>
* @date 2012-02-11
* @brief Platform detection macros for portable compilation
*
* @section LICENSE
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details at
* http://www.gnu.org/copyleft/gpl.html
*
* Official project repository can be found at:
* http://code.google.com/p/gekko-gc-emu/
*/
#pragma once
////////////////////////////////////////////////////////////////////////////////////////////////////
// Platform detection
#if defined(ARCHITECTURE_x86_64) || defined(__aarch64__)
#define EMU_ARCH_BITS 64
#elif defined(__i386) || defined(_M_IX86) || defined(__arm__) || defined(_M_ARM)
#define EMU_ARCH_BITS 32
#endif

View File

@@ -462,4 +462,27 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_l
return std::string(buffer, len);
}
const char* TrimSourcePath(const char* path, const char* root) {
const char* p = path;
while (*p != '\0') {
const char* next_slash = p;
while (*next_slash != '\0' && *next_slash != '/' && *next_slash != '\\') {
++next_slash;
}
bool is_src = Common::ComparePartialString(p, next_slash, root);
p = next_slash;
if (*p != '\0') {
++p;
}
if (is_src) {
path = p;
}
}
return path;
}
} // namespace Common

View File

@@ -134,4 +134,17 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) {
* NUL-terminated then the string ends at max_len characters.
*/
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len);
/**
* Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's
* intended to be used to strip a system-specific build directory from the `__FILE__` macro,
* leaving only the path relative to the sources root.
*
* @param path The input file path as a null-terminated string
* @param root The name of the root source directory as a null-terminated string. Path up to and
* including the last occurrence of this name will be stripped
* @return A pointer to the same string passed as `path`, but starting at the trimmed portion
*/
const char* TrimSourcePath(const char* path, const char* root = "src");
} // namespace Common

View File

@@ -7,8 +7,6 @@ add_library(core STATIC
core_timing.cpp
core_timing.h
file_sys/directory.h
file_sys/disk_filesystem.cpp
file_sys/disk_filesystem.h
file_sys/errors.h
file_sys/filesystem.cpp
file_sys/filesystem.h
@@ -20,8 +18,6 @@ add_library(core STATIC
file_sys/romfs_factory.h
file_sys/romfs_filesystem.cpp
file_sys/romfs_filesystem.h
file_sys/savedata_factory.cpp
file_sys/savedata_factory.h
file_sys/storage.h
frontend/emu_window.cpp
frontend/emu_window.h
@@ -114,12 +110,6 @@ add_library(core STATIC
hle/service/audio/audren_u.h
hle/service/audio/codecctl.cpp
hle/service/audio/codecctl.h
hle/service/fatal/fatal.cpp
hle/service/fatal/fatal.h
hle/service/fatal/fatal_p.cpp
hle/service/fatal/fatal_p.h
hle/service/fatal/fatal_u.cpp
hle/service/fatal/fatal_u.h
hle/service/filesystem/filesystem.cpp
hle/service/filesystem/filesystem.h
hle/service/filesystem/fsp_srv.cpp
@@ -175,14 +165,6 @@ add_library(core STATIC
hle/service/service.h
hle/service/set/set.cpp
hle/service/set/set.h
hle/service/set/set_cal.cpp
hle/service/set/set_cal.h
hle/service/set/set_fd.cpp
hle/service/set/set_fd.h
hle/service/set/set_sys.cpp
hle/service/set/set_sys.h
hle/service/set/settings.cpp
hle/service/set/settings.h
hle/service/sm/controller.cpp
hle/service/sm/controller.h
hle/service/sm/sm.cpp
@@ -193,12 +175,6 @@ add_library(core STATIC
hle/service/sockets/sfdnsres.h
hle/service/sockets/sockets.cpp
hle/service/sockets/sockets.h
hle/service/spl/csrng.cpp
hle/service/spl/csrng.h
hle/service/spl/module.cpp
hle/service/spl/module.h
hle/service/spl/spl.cpp
hle/service/spl/spl.h
hle/service/time/time.cpp
hle/service/time/time.h
hle/service/time/time_s.cpp

View File

@@ -25,18 +25,22 @@ public:
VAddr tls_address;
};
/// Runs the CPU until an event happens
virtual void Run() = 0;
/**
* Runs the CPU for the given number of instructions
* @param num_instructions Number of instructions to run
*/
void Run(int num_instructions) {
ExecuteInstructions(num_instructions);
this->num_instructions += num_instructions;
}
/// Step CPU by one instruction
virtual void Step() = 0;
void Step() {
Run(1);
}
/// Maps a backing memory region for the CPU
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) = 0;
/// Unmaps a region of memory that was previously mapped using MapBackingMemory
virtual void UnmapMemory(VAddr address, size_t size) = 0;
Kernel::VMAPermission perms) {}
/// Clear all instruction cache
virtual void ClearInstructionCache() = 0;
@@ -118,4 +122,19 @@ public:
/// Prepare core for thread reschedule (if needed to correctly handle state)
virtual void PrepareReschedule() = 0;
/// Getter for num_instructions
u64 GetNumInstructions() const {
return num_instructions;
}
protected:
/**
* Executes the given number of instructions
* @param num_instructions Number of instructions to executes
*/
virtual void ExecuteInstructions(int num_instructions) = 0;
private:
u64 num_instructions = 0; ///< Number of instructions executed
};

View File

@@ -8,7 +8,6 @@
#include <dynarmic/A64/config.h>
#include "common/logging/log.h"
#include "core/arm/dynarmic/arm_dynarmic.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/svc.h"
@@ -107,7 +106,7 @@ public:
};
std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_Callbacks>& cb) {
const auto page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data();
const auto page_table = Kernel::g_current_process->vm_manager.page_table.pointers.data();
Dynarmic::A64::UserConfig config;
config.callbacks = cb.get();
@@ -122,22 +121,11 @@ std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_C
return std::make_unique<Dynarmic::A64::Jit>(config);
}
void ARM_Dynarmic::Run() {
ASSERT(Memory::GetCurrentPageTable() == current_page_table);
jit->Run();
}
void ARM_Dynarmic::Step() {
cb->InterpreterFallback(jit->GetPC(), 1);
}
ARM_Dynarmic::ARM_Dynarmic()
: cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), jit(MakeJit(cb)) {
ARM_Interface::ThreadContext ctx;
inner_unicorn.SaveContext(ctx);
LoadContext(ctx);
PageTableChanged();
}
ARM_Dynarmic::~ARM_Dynarmic() = default;
@@ -147,10 +135,6 @@ void ARM_Dynarmic::MapBackingMemory(u64 address, size_t size, u8* memory,
inner_unicorn.MapBackingMemory(address, size, memory, perms);
}
void ARM_Dynarmic::UnmapMemory(u64 address, size_t size) {
inner_unicorn.UnmapMemory(address, size);
}
void ARM_Dynarmic::SetPC(u64 pc) {
jit->SetPC(pc);
}
@@ -200,6 +184,13 @@ void ARM_Dynarmic::SetTlsAddress(u64 address) {
cb->tpidrro_el0 = address;
}
void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
cb->ticks_remaining = num_instructions;
jit->Run();
CoreTiming::AddTicks(num_instructions - cb->num_interpreted_instructions);
cb->num_interpreted_instructions = 0;
}
void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
ctx.cpu_registers = jit->GetRegisters();
ctx.sp = jit->GetSP();
@@ -232,5 +223,4 @@ void ARM_Dynarmic::ClearInstructionCache() {
void ARM_Dynarmic::PageTableChanged() {
jit = MakeJit(cb);
current_page_table = Memory::GetCurrentPageTable();
}

View File

@@ -19,7 +19,7 @@ public:
void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) override;
void UnmapMemory(u64 address, size_t size) override;
void SetPC(u64 pc) override;
u64 GetPC() const override;
u64 GetReg(int index) const override;
@@ -29,8 +29,6 @@ public:
u32 GetVFPReg(int index) const override;
void SetVFPReg(int index, u32 value) override;
u32 GetCPSR() const override;
void Run() override;
void Step() override;
void SetCPSR(u32 cpsr) override;
VAddr GetTlsAddress() const override;
void SetTlsAddress(VAddr address) override;
@@ -39,6 +37,7 @@ public:
void LoadContext(const ThreadContext& ctx) override;
void PrepareReschedule() override;
void ExecuteInstructions(int num_instructions) override;
void ClearInstructionCache() override;
void PageTableChanged() override;
@@ -48,6 +47,4 @@ private:
std::unique_ptr<ARM_Dynarmic_Callbacks> cb;
std::unique_ptr<Dynarmic::A64::Jit> jit;
ARM_Unicorn inner_unicorn;
Memory::PageTable* current_page_table = nullptr;
};

View File

@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <unicorn/arm64.h>
#include "common/assert.h"
#include "common/microprofile.h"
@@ -53,7 +52,7 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
void* user_data) {
ARM_Interface::ThreadContext ctx{};
Core::CPU().SaveContext(ctx);
ASSERT_MSG(false, "Attempted to read from unmapped memory: 0x%lx, pc=0x%lx, lr=0x%lx", addr,
ASSERT_MSG(false, "Attempted to read from unmapped memory: 0x%llx, pc=0x%llx, lr=0x%llx", addr,
ctx.pc, ctx.cpu_registers[30]);
return {};
}
@@ -78,10 +77,6 @@ void ARM_Unicorn::MapBackingMemory(VAddr address, size_t size, u8* memory,
CHECKED(uc_mem_map_ptr(uc, address, size, static_cast<u32>(perms), memory));
}
void ARM_Unicorn::UnmapMemory(VAddr address, size_t size) {
CHECKED(uc_mem_unmap(uc, address, size));
}
void ARM_Unicorn::SetPC(u64 pc) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &pc));
}
@@ -154,14 +149,6 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base));
}
void ARM_Unicorn::Run() {
ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0));
}
void ARM_Unicorn::Step() {
ExecuteInstructions(1);
}
MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
void ARM_Unicorn::ExecuteInstructions(int num_instructions) {

View File

@@ -14,7 +14,6 @@ public:
~ARM_Unicorn();
void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) override;
void UnmapMemory(VAddr address, size_t size) override;
void SetPC(u64 pc) override;
u64 GetPC() const override;
u64 GetReg(int index) const override;
@@ -30,9 +29,7 @@ public:
void SaveContext(ThreadContext& ctx) override;
void LoadContext(const ThreadContext& ctx) override;
void PrepareReschedule() override;
void ExecuteInstructions(int num_instructions);
void Run() override;
void Step() override;
void ExecuteInstructions(int num_instructions) override;
void ClearInstructionCache() override;
void PageTableChanged() override{};

View File

@@ -26,7 +26,7 @@ namespace Core {
/*static*/ System System::s_instance;
System::ResultStatus System::RunLoop(bool tight_loop) {
System::ResultStatus System::RunLoop(int tight_loop) {
status = ResultStatus::Success;
if (!cpu_core) {
return ResultStatus::ErrorNotInitialized;
@@ -40,7 +40,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
if (GDBStub::GetCpuHaltFlag()) {
if (GDBStub::GetCpuStepFlag()) {
GDBStub::SetCpuStepFlag(false);
tight_loop = false;
tight_loop = 1;
} else {
return ResultStatus::Success;
}
@@ -56,11 +56,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
PrepareReschedule();
} else {
CoreTiming::Advance();
if (tight_loop) {
cpu_core->Run();
} else {
cpu_core->Step();
}
cpu_core->Run(tight_loop);
}
HW::Update();
@@ -70,7 +66,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
}
System::ResultStatus System::SingleStep() {
return RunLoop(false);
return RunLoop(1);
}
System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) {
@@ -99,15 +95,14 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
ResultStatus init_result{Init(emu_window, system_mode.first.get())};
if (init_result != ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error %i)!",
static_cast<int>(init_result));
LOG_CRITICAL(Core, "Failed to initialize system (Error %i)!", init_result);
System::Shutdown();
return init_result;
}
const Loader::ResultStatus load_result{app_loader->Load(current_process)};
const Loader::ResultStatus load_result{app_loader->Load(Kernel::g_current_process)};
if (Loader::ResultStatus::Success != load_result) {
LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", static_cast<int>(load_result));
LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result);
System::Shutdown();
switch (load_result) {
@@ -146,8 +141,6 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
CoreTiming::Init();
current_process = Kernel::Process::Create("main");
switch (Settings::values.cpu_core) {
case Settings::CpuCore::Unicorn:
cpu_core = std::make_shared<ARM_Unicorn>();

View File

@@ -7,7 +7,6 @@
#include <memory>
#include <string>
#include "common/common_types.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/scheduler.h"
#include "core/loader/loader.h"
#include "core/memory.h"
@@ -53,10 +52,10 @@ public:
* 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 If false, the CPU single-steps.
* @param tight_loop Number of instructions to execute.
* @return Result status, indicating whether or not the operation succeeded.
*/
ResultStatus RunLoop(bool tight_loop = true);
ResultStatus RunLoop(int tight_loop = 100000);
/**
* Step the CPU one instruction
@@ -113,10 +112,6 @@ public:
return *scheduler;
}
Kernel::SharedPtr<Kernel::Process>& CurrentProcess() {
return current_process;
}
PerfStats perf_stats;
FrameLimiter frame_limiter;
@@ -154,8 +149,6 @@ private:
std::unique_ptr<Kernel::Scheduler> scheduler;
std::unique_ptr<Tegra::GPU> gpu_core;
Kernel::SharedPtr<Kernel::Process> current_process;
/// When true, signals that a reschedule should happen
bool reschedule_pending{};
@@ -176,8 +169,4 @@ inline TelemetrySession& Telemetry() {
return System::GetInstance().TelemetrySession();
}
inline Kernel::SharedPtr<Kernel::Process>& CurrentProcess() {
return System::GetInstance().CurrentProcess();
}
} // namespace Core

View File

@@ -1,146 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cstring>
#include <memory>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/disk_filesystem.h"
#include "core/file_sys/errors.h"
namespace FileSys {
std::string Disk_FileSystem::GetName() const {
return "Disk";
}
ResultVal<std::unique_ptr<StorageBackend>> Disk_FileSystem::OpenFile(const std::string& path,
Mode mode) const {
ASSERT_MSG(mode == Mode::Read || mode == Mode::Write, "Other file modes are not supported");
std::string full_path = base_directory + path;
auto file = std::make_shared<FileUtil::IOFile>(full_path, mode == Mode::Read ? "rb" : "wb");
if (!file->IsOpen()) {
return ERROR_PATH_NOT_FOUND;
}
return MakeResult<std::unique_ptr<StorageBackend>>(
std::make_unique<Disk_Storage>(std::move(file)));
}
ResultCode Disk_FileSystem::DeleteFile(const Path& path) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
// TODO(bunnei): Use correct error code
return ResultCode(-1);
}
ResultCode Disk_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
std::string full_path = base_directory + path;
if (size == 0) {
FileUtil::CreateEmptyFile(full_path);
return RESULT_SUCCESS;
}
FileUtil::IOFile file(full_path, "wb");
// Creates a sparse file (or a normal file on filesystems without the concept of sparse files)
// We do this by seeking to the right size, then writing a single null byte.
if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1) {
return RESULT_SUCCESS;
}
LOG_ERROR(Service_FS, "Too large file");
// TODO(Subv): Find out the correct error code
return ResultCode(-1);
}
ResultCode Disk_FileSystem::CreateDirectory(const Path& path) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultVal<std::unique_ptr<DirectoryBackend>> Disk_FileSystem::OpenDirectory(
const Path& path) const {
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<Disk_Directory>());
}
u64 Disk_FileSystem::GetFreeSpaceSize() const {
LOG_WARNING(Service_FS, "(STUBBED) called");
return 0;
}
ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& path) const {
std::string full_path = base_directory + path;
if (!FileUtil::Exists(full_path)) {
return ERROR_PATH_NOT_FOUND;
}
// TODO(Subv): Find out the EntryType values
UNIMPLEMENTED_MSG("Unimplemented GetEntryType");
}
ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length);
file->Seek(offset, SEEK_SET);
return MakeResult<size_t>(file->ReadBytes(buffer, length));
}
ResultVal<size_t> Disk_Storage::Write(const u64 offset, const size_t length, const bool flush,
const u8* buffer) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
file->Seek(offset, SEEK_SET);
size_t written = file->WriteBytes(buffer, length);
if (flush) {
file->Flush();
}
return MakeResult<size_t>(written);
}
u64 Disk_Storage::GetSize() const {
return file->GetSize();
}
bool Disk_Storage::SetSize(const u64 size) const {
LOG_WARNING(Service_FS, "(STUBBED) called");
return false;
}
u32 Disk_Directory::Read(const u32 count, Entry* entries) {
LOG_WARNING(Service_FS, "(STUBBED) called");
return 0;
}
bool Disk_Directory::Close() const {
LOG_WARNING(Service_FS, "(STUBBED) called");
return true;
}
} // namespace FileSys

View File

@@ -1,66 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <cstddef>
#include <memory>
#include <string>
#include "common/common_types.h"
#include "common/file_util.h"
#include "core/file_sys/directory.h"
#include "core/file_sys/filesystem.h"
#include "core/file_sys/storage.h"
#include "core/hle/result.h"
namespace FileSys {
class Disk_FileSystem : public FileSystemBackend {
public:
explicit Disk_FileSystem(std::string base_directory)
: base_directory(std::move(base_directory)) {}
std::string GetName() const override;
ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path,
Mode mode) const override;
ResultCode DeleteFile(const Path& path) const override;
ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override;
ResultCode DeleteDirectory(const Path& path) const override;
ResultCode DeleteDirectoryRecursively(const Path& path) const override;
ResultCode CreateFile(const std::string& path, u64 size) const override;
ResultCode CreateDirectory(const Path& path) const override;
ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override;
ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override;
u64 GetFreeSpaceSize() const override;
ResultVal<EntryType> GetEntryType(const std::string& path) const override;
protected:
std::string base_directory;
};
class Disk_Storage : public StorageBackend {
public:
Disk_Storage(std::shared_ptr<FileUtil::IOFile> file) : file(std::move(file)) {}
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override;
u64 GetSize() const override;
bool SetSize(u64 size) const override;
bool Close() const override {
return false;
}
void Flush() const override {}
private:
std::shared_ptr<FileUtil::IOFile> file;
};
class Disk_Directory : public DirectoryBackend {
public:
u32 Read(const u32 count, Entry* entries) override;
bool Close() const override;
};
} // namespace FileSys

View File

@@ -10,17 +10,36 @@ namespace FileSys {
namespace ErrCodes {
enum {
NotFound = 1,
RomFSNotFound = 100,
ArchiveNotMounted = 101,
FileNotFound = 112,
PathNotFound = 113,
GameCardNotInserted = 141,
NotFound = 120,
FileAlreadyExists = 180,
DirectoryAlreadyExists = 185,
AlreadyExists = 190,
InvalidOpenFlags = 230,
DirectoryNotEmpty = 240,
NotAFile = 250,
NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
ExeFSSectionNotFound = 567,
CommandNotAllowed = 630,
InvalidReadFlag = 700,
InvalidPath = 702,
WriteBeyondEnd = 705,
UnsupportedOpenFlags = 760,
IncorrectExeFSReadSize = 761,
UnexpectedFileOrDirectory = 770,
};
}
constexpr ResultCode ERROR_PATH_NOT_FOUND(ErrorModule::FS, ErrCodes::NotFound);
// TODO(bunnei): Replace these with correct errors for Switch OS
constexpr ResultCode ERROR_INVALID_PATH(ResultCode(-1));
constexpr ResultCode ERROR_UNSUPPORTED_OPEN_FLAGS(ResultCode(-1));
constexpr ResultCode ERROR_INVALID_OPEN_FLAGS(ResultCode(-1));
constexpr ResultCode ERROR_FILE_NOT_FOUND(ResultCode(-1));
constexpr ResultCode ERROR_PATH_NOT_FOUND(ResultCode(-1));
constexpr ResultCode ERROR_UNEXPECTED_FILE_OR_DIRECTORY(ResultCode(-1));
constexpr ResultCode ERROR_DIRECTORY_ALREADY_EXISTS(ResultCode(-1));
constexpr ResultCode ERROR_FILE_ALREADY_EXISTS(ResultCode(-1));

View File

@@ -27,14 +27,11 @@ enum LowPathType : u32 {
Wchar = 4,
};
enum EntryType : u32 {
Directory = 0,
File = 1,
};
enum class Mode : u32 {
Read = 1,
Write = 2,
union Mode {
u32 hex;
BitField<0, 1, u32> read_flag;
BitField<1, 1, u32> write_flag;
BitField<2, 1, u32> create_flag;
};
class Path {
@@ -89,7 +86,7 @@ public:
* @param size The size of the new file, filled with zeroes
* @return Result of the operation
*/
virtual ResultCode CreateFile(const std::string& path, u64 size) const = 0;
virtual ResultCode CreateFile(const Path& path, u64 size) const = 0;
/**
* Delete a file specified by its path
@@ -141,8 +138,8 @@ public:
* @param mode Mode to open the file with
* @return Opened file, or error code
*/
virtual ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path,
Mode mode) const = 0;
virtual ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const Path& path,
const Mode& mode) const = 0;
/**
* Open a directory specified by its path
@@ -156,12 +153,6 @@ public:
* @return The number of free bytes in the archive
*/
virtual u64 GetFreeSpaceSize() const = 0;
/**
* Get the type of the specified path
* @return The type of the specified path or error code
*/
virtual ResultVal<EntryType> GetEntryType(const std::string& path) const = 0;
};
class FileSystemFactory : NonCopyable {
@@ -183,9 +174,10 @@ public:
/**
* Deletes the archive contents and then re-creates the base folder
* @param path Path to the archive
* @param format_info Format information for the new archive
* @return ResultCode of the operation, 0 on success
*/
virtual ResultCode Format(const Path& path) = 0;
virtual ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) = 0;
/**
* Retrieves the format info about the archive with the specified path

View File

@@ -23,7 +23,7 @@ ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& pa
return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive));
}
ResultCode RomFS_Factory::Format(const Path& path) {
ResultCode RomFS_Factory::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) {
LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
// TODO(bunnei): Find the right error code for this
return ResultCode(-1);

View File

@@ -23,7 +23,7 @@ public:
return "ArchiveFactory_RomFS";
}
ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override;
ResultCode Format(const Path& path) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
private:

View File

@@ -14,8 +14,8 @@ std::string RomFS_FileSystem::GetName() const {
return "RomFS";
}
ResultVal<std::unique_ptr<StorageBackend>> RomFS_FileSystem::OpenFile(const std::string& path,
Mode mode) const {
ResultVal<std::unique_ptr<StorageBackend>> RomFS_FileSystem::OpenFile(const Path& path,
const Mode& mode) const {
return MakeResult<std::unique_ptr<StorageBackend>>(
std::make_unique<RomFS_Storage>(romfs_file, data_offset, data_size));
}
@@ -48,7 +48,7 @@ ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const
return ResultCode(-1);
}
ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const {
ResultCode RomFS_FileSystem::CreateFile(const Path& path, u64 size) const {
LOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive (%s).",
GetName().c_str());
// TODO(bunnei): Use correct error code
@@ -79,12 +79,6 @@ u64 RomFS_FileSystem::GetFreeSpaceSize() const {
return 0;
}
ResultVal<FileSys::EntryType> RomFS_FileSystem::GetEntryType(const std::string& path) const {
LOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path %s).", path.c_str());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length);
romfs_file->Seek(data_offset + offset, SEEK_SET);

View File

@@ -29,18 +29,17 @@ public:
std::string GetName() const override;
ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path,
Mode mode) const override;
ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const Path& path,
const Mode& mode) const override;
ResultCode DeleteFile(const Path& path) const override;
ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override;
ResultCode DeleteDirectory(const Path& path) const override;
ResultCode DeleteDirectoryRecursively(const Path& path) const override;
ResultCode CreateFile(const std::string& path, u64 size) const override;
ResultCode CreateFile(const Path& path, u64 size) const override;
ResultCode CreateDirectory(const Path& path) const override;
ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override;
ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override;
u64 GetFreeSpaceSize() const override;
ResultVal<EntryType> GetEntryType(const std::string& path) const override;
protected:
std::shared_ptr<FileUtil::IOFile> romfs_file;

View File

@@ -1,57 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cinttypes>
#include <memory>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/file_sys/disk_filesystem.h"
#include "core/file_sys/savedata_factory.h"
#include "core/hle/kernel/process.h"
namespace FileSys {
SaveData_Factory::SaveData_Factory(std::string nand_directory)
: nand_directory(std::move(nand_directory)) {}
ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& path) {
std::string save_directory = GetFullPath();
// Return an error if the save data doesn't actually exist.
if (!FileUtil::IsDirectory(save_directory)) {
// TODO(Subv): Find out correct error code.
return ResultCode(-1);
}
auto archive = std::make_unique<Disk_FileSystem>(save_directory);
return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive));
}
ResultCode SaveData_Factory::Format(const Path& path) {
LOG_WARNING(Service_FS, "Format archive %s", GetName().c_str());
// Create the save data directory.
if (!FileUtil::CreateFullPath(GetFullPath())) {
// TODO(Subv): Find the correct error code.
return ResultCode(-1);
}
return RESULT_SUCCESS;
}
ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const {
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str());
// TODO(bunnei): Find the right error code for this
return ResultCode(-1);
}
std::string SaveData_Factory::GetFullPath() const {
u64 title_id = Core::CurrentProcess()->program_id;
// TODO(Subv): Somehow obtain this value.
u32 user = 0;
return Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X/", nand_directory.c_str(), title_id,
user);
}
} // namespace FileSys

View File

@@ -1,33 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <string>
#include "common/common_types.h"
#include "core/file_sys/filesystem.h"
#include "core/hle/result.h"
namespace FileSys {
/// File system interface to the SaveData archive
class SaveData_Factory final : public FileSystemFactory {
public:
explicit SaveData_Factory(std::string nand_directory);
std::string GetName() const override {
return "SaveData_Factory";
}
ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override;
ResultCode Format(const Path& path) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
private:
std::string nand_directory;
std::string GetFullPath() const;
};
} // namespace FileSys

View File

@@ -693,7 +693,7 @@ static void ReadMemory() {
u64 len =
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
LOG_DEBUG(Debug_GDBStub, "gdb: addr: %016lx len: %016lx\n", addr, len);
LOG_DEBUG(Debug_GDBStub, "gdb: addr: %016llx len: %016llx\n", addr, len);
if (len * 2 > sizeof(reply)) {
SendReply("E01");

View File

@@ -118,8 +118,7 @@ public:
AlignWithPadding();
const bool request_has_domain_header{context.GetDomainMessageHeader() != nullptr};
if (context.Session()->IsDomain() && request_has_domain_header) {
if (context.Session()->IsDomain()) {
IPC::DomainMessageHeader domain_header{};
domain_header.num_objects = num_domain_objects;
PushRaw(domain_header);

View File

@@ -5,7 +5,6 @@
#include <utility>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
@@ -78,7 +77,7 @@ SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
if (handle == CurrentThread) {
return GetCurrentThread();
} else if (handle == CurrentProcess) {
return Core::CurrentProcess();
return g_current_process;
}
if (!IsValid(handle)) {

View File

@@ -7,7 +7,6 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/kernel.h"
@@ -27,32 +26,6 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr<ServerSession> server_s
boost::range::remove_erase(connected_sessions, server_session);
}
SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
const std::string& reason, u64 timeout,
WakeupCallback&& callback) {
// Put the client thread to sleep until the wait event is signaled or the timeout expires.
thread->wakeup_callback =
[context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, size_t index) mutable -> bool {
ASSERT(thread->status == THREADSTATUS_WAIT_HLE_EVENT);
callback(thread, context, reason);
context.WriteToOutgoingCommandBuffer(*thread);
return true;
};
auto event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
thread->status = THREADSTATUS_WAIT_HLE_EVENT;
thread->wait_objects = {event};
event->AddWaitingThread(thread);
if (timeout > 0) {
thread->WakeAfterDelay(timeout);
}
return event;
}
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)
: server_session(std::move(server_session)) {
cmd_buf[0] = 0;
@@ -62,7 +35,7 @@ HLERequestContext::~HLERequestContext() = default;
void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
IPC::RequestParser rp(src_cmdbuf);
command_header = std::make_shared<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>());
command_header = std::make_unique<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>());
if (command_header->type == IPC::CommandType::Close) {
// Close does not populate the rest of the IPC header
@@ -72,7 +45,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
// If handle descriptor is present, add size of it
if (command_header->enable_handle_descriptor) {
handle_descriptor_header =
std::make_shared<IPC::HandleDescriptorHeader>(rp.PopRaw<IPC::HandleDescriptorHeader>());
std::make_unique<IPC::HandleDescriptorHeader>(rp.PopRaw<IPC::HandleDescriptorHeader>());
if (handle_descriptor_header->send_current_pid) {
rp.Skip(2, false);
}
@@ -112,18 +85,13 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
if (Session()->IsDomain() && (command_header->type == IPC::CommandType::Request || !incoming)) {
// If this is an incoming message, only CommandType "Request" has a domain header
// All outgoing domain messages have the domain header, if only incoming has it
if (incoming || domain_message_header) {
domain_message_header =
std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
} else {
if (Session()->IsDomain())
LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
}
// All outgoing domain messages have the domain header
domain_message_header =
std::make_unique<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
}
data_payload_header =
std::make_shared<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
data_payload_offset = rp.GetCurrentOffset();
@@ -186,11 +154,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdb
return RESULT_SUCCESS;
}
ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf;
Memory::ReadBlock(*thread.owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(),
dst_cmdbuf.size() * sizeof(u32));
ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process,
HandleTable& dst_table) {
// The header was already built in the internal command buffer. Attempt to parse it to verify
// the integrity and then copy it over to the target command buffer.
ParseCommandBuffer(cmd_buf.data(), false);
@@ -201,7 +166,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
if (domain_message_header)
size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32);
std::copy_n(cmd_buf.begin(), size, dst_cmdbuf.data());
std::copy_n(cmd_buf.begin(), size, dst_cmdbuf);
if (command_header->enable_handle_descriptor) {
ASSERT_MSG(!move_objects.empty() || !copy_objects.empty(),
@@ -231,7 +196,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
// TODO(Subv): Translate the X/A/B/W buffers.
if (Session()->IsDomain() && domain_message_header) {
if (Session()->IsDomain()) {
ASSERT(domain_message_header->num_objects == domain_objects.size());
// Write the domain objects to the command buffer, these go after the raw untranslated data.
// TODO(Subv): This completely ignores C buffers.
@@ -243,11 +208,6 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
dst_cmdbuf[domain_offset++] = static_cast<u32_le>(request_handlers.size());
}
}
// Copy the translated command buffer back into the thread's command buffer area.
Memory::WriteBlock(*thread.owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(),
dst_cmdbuf.size() * sizeof(u32));
return RESULT_SUCCESS;
}
@@ -269,7 +229,7 @@ std::vector<u8> HLERequestContext::ReadBuffer() const {
size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size) const {
const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
ASSERT_MSG(size <= GetWriteBufferSize(), "Size %lx is too big", size);
ASSERT_MSG(size <= GetWriteBufferSize(), "Size %d is too big", size);
if (is_buffer_b) {
Memory::WriteBlock(BufferDescriptorB()[0].Address(), buffer, size);

View File

@@ -6,7 +6,6 @@
#include <array>
#include <memory>
#include <string>
#include <vector>
#include <boost/container/small_vector.hpp>
#include "common/common_types.h"
@@ -14,7 +13,6 @@
#include "core/hle/ipc.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/thread.h"
namespace Service {
class ServiceFrameworkBase;
@@ -26,7 +24,6 @@ class Domain;
class HandleTable;
class HLERequestContext;
class Process;
class Event;
/**
* Interface implemented by HLE Session handlers.
@@ -105,31 +102,14 @@ public:
return server_session;
}
using WakeupCallback = std::function<void(SharedPtr<Thread> thread, HLERequestContext& context,
ThreadWakeupReason reason)>;
/**
* Puts the specified guest thread to sleep until the returned event is signaled or until the
* specified timeout expires.
* @param thread Thread to be put to sleep.
* @param reason Reason for pausing the thread, to be used for debugging purposes.
* @param timeout Timeout in nanoseconds after which the thread will be awoken and the callback
* invoked with a Timeout reason.
* @param callback Callback to be invoked when the thread is resumed. This callback must write
* the entire command response once again, regardless of the state of it before this function
* was called.
* @returns Event that when signaled will resume the thread and call the callback function.
*/
SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
u64 timeout, WakeupCallback&& callback);
void ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming);
/// Populates this context with data from the requesting process/thread.
ResultCode PopulateFromIncomingCommandBuffer(u32_le* src_cmdbuf, Process& src_process,
HandleTable& src_table);
/// Writes data from this context back to the requesting process/thread.
ResultCode WriteToOutgoingCommandBuffer(Thread& thread);
ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process,
HandleTable& dst_table);
u32_le GetCommand() const {
return command;
@@ -159,7 +139,7 @@ public:
return buffer_c_desciptors;
}
const std::shared_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
const std::unique_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
return domain_message_header;
}
@@ -232,10 +212,10 @@ private:
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
std::shared_ptr<IPC::CommandHeader> command_header;
std::shared_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header;
std::shared_ptr<IPC::DataPayloadHeader> data_payload_header;
std::shared_ptr<IPC::DomainMessageHeader> domain_message_header;
std::unique_ptr<IPC::CommandHeader> command_header;
std::unique_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header;
std::unique_ptr<IPC::DataPayloadHeader> data_payload_header;
std::unique_ptr<IPC::DomainMessageHeader> domain_message_header;
std::vector<IPC::BufferDescriptorX> buffer_x_desciptors;
std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;

View File

@@ -41,6 +41,7 @@ void Shutdown() {
g_object_address_table.Clear();
Kernel::ThreadingShutdown();
g_current_process = nullptr;
Kernel::TimersShutdown();
Kernel::ResourceLimitsShutdown();

View File

@@ -33,6 +33,10 @@ enum class HandleType : u32 {
ServerSession,
};
enum {
DEFAULT_STACK_SIZE = 0x10000,
};
enum class ResetType {
OneShot,
Sticky,

View File

@@ -10,12 +10,12 @@ namespace Kernel {
ObjectAddressTable g_object_address_table;
void ObjectAddressTable::Insert(VAddr addr, SharedPtr<Object> obj) {
ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x%lx", addr);
ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x%llx", addr);
objects[addr] = obj;
}
void ObjectAddressTable::Close(VAddr addr) {
ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x%lx", addr);
ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x%llx", addr);
objects.erase(addr);
}

View File

@@ -20,9 +20,12 @@ namespace Kernel {
// Lists all processes that exist in the current session.
static std::vector<SharedPtr<Process>> process_list;
SharedPtr<CodeSet> CodeSet::Create(std::string name) {
SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
SharedPtr<CodeSet> codeset(new CodeSet);
codeset->name = std::move(name);
codeset->program_id = program_id;
return codeset;
}
@@ -38,7 +41,6 @@ SharedPtr<Process> Process::Create(std::string&& name) {
process->flags.raw = 0;
process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
process->status = ProcessStatus::Created;
process->program_id = 0;
process_list.push_back(process);
return process;
@@ -117,12 +119,11 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
}
void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
// Allocate and map the main thread stack
// TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part
// of the user address space.
// Allocate and map stack
vm_manager
.MapMemoryBlock(Memory::STACK_VADDR, std::make_shared<std::vector<u8>>(stack_size, 0), 0,
stack_size, MemoryState::Mapped)
.MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size,
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
MemoryState::Heap)
.Unwrap();
misc_memory_used += stack_size;
memory_region->used += stack_size;
@@ -154,9 +155,9 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
};
// Map CodeSet segments
MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic);
MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable);
MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable);
MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::Code);
MapSegment(module_->rodata, VMAPermission::Read, MemoryState::Static);
MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::Static);
}
VAddr Process::GetLinearHeapAreaAddress() const {
@@ -183,8 +184,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
// Initialize heap
heap_memory = std::make_shared<std::vector<u8>>();
heap_start = heap_end = target;
} else {
vm_manager.UnmapRange(heap_start, heap_end - heap_start);
}
// If necessary, expand backing vector to cover new heap extents.
@@ -204,7 +203,7 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per
size, MemoryState::Heap));
vm_manager.Reprotect(vma, perms);
heap_used = size;
heap_used += size;
memory_region->used += size;
return MakeResult<VAddr>(heap_end - size);
@@ -291,7 +290,7 @@ ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
CASCADE_RESULT(auto new_vma,
vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size,
MemoryState::Mapped));
vma->second.meminfo_state));
// Protect mirror with permissions from old region
vm_manager.Reprotect(new_vma, vma->second.permissions);
// Remove permissions from old region
@@ -322,4 +321,5 @@ SharedPtr<Process> GetProcessById(u32 process_id) {
return *itr;
}
SharedPtr<Process> g_current_process;
} // namespace Kernel

View File

@@ -56,7 +56,7 @@ class ResourceLimit;
struct MemoryRegionInfo;
struct CodeSet final : public Object {
static SharedPtr<CodeSet> Create(std::string name);
static SharedPtr<CodeSet> Create(std::string name, u64 program_id);
std::string GetTypeName() const override {
return "CodeSet";
@@ -72,6 +72,8 @@ struct CodeSet final : public Object {
/// Name of the process
std::string name;
/// Title ID corresponding to the process
u64 program_id;
std::shared_ptr<std::vector<u8>> memory;
@@ -111,9 +113,6 @@ public:
static u32 next_process_id;
/// Title ID corresponding to the process
u64 program_id;
/// Resource limit descriptor for this process
SharedPtr<ResourceLimit> resource_limit;
@@ -203,4 +202,5 @@ void ClearProcessList();
/// Retrieves a process from the current list of processes.
SharedPtr<Process> GetProcessById(u32 process_id);
extern SharedPtr<Process> g_current_process;
} // namespace Kernel

View File

@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/scheduler.h"
@@ -68,7 +67,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
// Cancel any outstanding wakeup events for this thread
new_thread->CancelWakeupTimer();
auto previous_process = Core::CurrentProcess();
auto previous_process = Kernel::g_current_process;
current_thread = new_thread;
@@ -76,8 +75,8 @@ void Scheduler::SwitchContext(Thread* new_thread) {
new_thread->status = THREADSTATUS_RUNNING;
if (previous_process != current_thread->owner_process) {
Core::CurrentProcess() = current_thread->owner_process;
SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
Kernel::g_current_process = current_thread->owner_process;
SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
}
cpu_core->LoadContext(new_thread->context);

View File

@@ -4,7 +4,6 @@
#include <tuple>
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
@@ -78,8 +77,7 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
}
}
LOG_CRITICAL(IPC, "Unknown domain command=%d",
static_cast<int>(domain_message_header->command.Value()));
LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value());
ASSERT(false);
}
@@ -93,12 +91,12 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
Kernel::HLERequestContext context(this);
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
context.PopulateFromIncomingCommandBuffer(cmd_buf, *Core::CurrentProcess(),
context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process,
Kernel::g_handle_table);
ResultCode result = RESULT_SUCCESS;
// If the session has been converted to a domain, handle the domain request
if (IsDomain() && context.GetDomainMessageHeader()) {
if (IsDomain()) {
result = HandleDomainSyncRequest(context);
// If there is no domain header, the regular session handler is used
} else if (hle_handler != nullptr) {

View File

@@ -4,7 +4,6 @@
#include <cstring>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/shared_memory.h"
@@ -52,8 +51,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
}
// Refresh the address mappings for the current process.
if (Core::CurrentProcess() != nullptr) {
Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
if (Kernel::g_current_process != nullptr) {
Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
}
} else {
auto& vm_manager = shared_memory->owner_process->vm_manager;
@@ -107,7 +106,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
// Error out if the requested permissions don't match what the creator process allows.
if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match",
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
GetObjectId(), address, name.c_str());
return ERR_INVALID_COMBINATION;
}
@@ -115,7 +114,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
// Error out if the provided permissions are not compatible with what the creator process needs.
if (other_permissions != MemoryPermission::DontCare &&
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match",
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
GetObjectId(), address, name.c_str());
return ERR_WRONG_PERMISSION;
}
@@ -126,7 +125,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
if (address != 0) {
// TODO(shinyquagsire23): Check for virtual/mappable memory here too?
if (address >= Memory::HEAP_VADDR && address < Memory::HEAP_VADDR_END) {
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, invalid address",
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, invalid address",
GetObjectId(), address, name.c_str());
return ERR_INVALID_ADDRESS;
}
@@ -143,9 +142,10 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
auto result = target_process->vm_manager.MapMemoryBlock(
target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
if (result.Failed()) {
LOG_ERROR(Kernel,
"cannot map id=%u, target_address=0x%lx name=%s, error mapping to virtual memory",
GetObjectId(), target_address, name.c_str());
LOG_ERROR(
Kernel,
"cannot map id=%u, target_address=0x%llx name=%s, error mapping to virtual memory",
GetObjectId(), target_address, name.c_str());
return result.Code();
}

View File

@@ -8,7 +8,6 @@
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
@@ -32,14 +31,14 @@ namespace Kernel {
/// Set the process heap to a given Size. It can both extend and shrink the heap.
static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
LOG_TRACE(Kernel_SVC, "called, heap_size=0x%llx", heap_size);
auto& process = *Core::CurrentProcess();
auto& process = *g_current_process;
CASCADE_RESULT(*heap_addr,
process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
return RESULT_SUCCESS;
}
static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {
LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x%lx", addr);
LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x%llx", addr);
return RESULT_SUCCESS;
}
@@ -47,14 +46,14 @@ static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state
static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
src_addr, size);
return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size);
return g_current_process->MirrorMemory(dst_addr, src_addr, size);
}
/// Unmaps a region that was previously mapped with svcMapMemory
static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
src_addr, size);
return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size);
return g_current_process->UnmapMemory(dst_addr, src_addr, size);
}
/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -307,23 +306,23 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id,
info_sub_id, handle);
auto& vm_manager = Core::CurrentProcess()->vm_manager;
auto& vm_manager = g_current_process->vm_manager;
switch (static_cast<GetInfoType>(info_id)) {
case GetInfoType::AllowedCpuIdBitmask:
*result = Core::CurrentProcess()->allowed_processor_mask;
*result = g_current_process->allowed_processor_mask;
break;
case GetInfoType::AllowedThreadPrioBitmask:
*result = Core::CurrentProcess()->allowed_thread_priority_mask;
*result = g_current_process->allowed_thread_priority_mask;
break;
case GetInfoType::MapRegionBaseAddr:
*result = Memory::MAP_REGION_VADDR;
*result = vm_manager.GetMapRegionBaseAddr();
break;
case GetInfoType::MapRegionSize:
*result = Memory::MAP_REGION_SIZE;
*result = vm_manager.GetAddressSpaceSize();
break;
case GetInfoType::HeapRegionBaseAddr:
*result = Memory::HEAP_VADDR;
*result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize();
break;
case GetInfoType::HeapRegionSize:
*result = Memory::HEAP_SIZE;
@@ -347,13 +346,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = vm_manager.GetAddressSpaceSize();
break;
case GetInfoType::NewMapRegionBaseAddr:
*result = Memory::NEW_MAP_REGION_VADDR;
*result = vm_manager.GetNewMapRegionBaseAddr();
break;
case GetInfoType::NewMapRegionSize:
*result = Memory::NEW_MAP_REGION_SIZE;
*result = vm_manager.GetNewMapRegionSize();
break;
case GetInfoType::IsVirtualAddressMemoryEnabled:
*result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
*result = g_current_process->is_virtual_address_memory_enabled;
break;
case GetInfoType::TitleId:
LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
@@ -393,7 +392,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
// Note: The kernel uses the current process's resource limit instead of
// the one from the thread owner's resource limit.
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
return ERR_NOT_AUTHORIZED;
}
@@ -436,7 +435,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
case MemoryPermission::WriteExecute:
case MemoryPermission::ReadWriteExecute:
case MemoryPermission::DontCare:
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
return shared_memory->Map(g_current_process.get(), addr, permissions_type,
MemoryPermission::DontCare);
default:
LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
@@ -452,7 +451,7 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
return shared_memory->Unmap(Core::CurrentProcess().get(), addr);
return shared_memory->Unmap(g_current_process.get(), addr);
}
/// Query process memory
@@ -464,11 +463,11 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
}
auto vma = process->vm_manager.FindVMA(addr);
memory_info->attributes = 0;
if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) {
if (vma == g_current_process->vm_manager.vma_map.end()) {
memory_info->base_address = 0;
memory_info->permission = static_cast<u32>(VMAPermission::None);
memory_info->size = 0;
memory_info->type = static_cast<u32>(MemoryState::Unmapped);
memory_info->type = static_cast<u32>(MemoryState::Free);
} else {
memory_info->base_address = vma->second.base;
memory_info->permission = static_cast<u32>(vma->second.permissions);
@@ -488,17 +487,16 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
/// Exits the current process
static void ExitProcess() {
LOG_INFO(Kernel_SVC, "Process %u exiting", Core::CurrentProcess()->process_id);
LOG_INFO(Kernel_SVC, "Process %u exiting", g_current_process->process_id);
ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running,
"Process has already exited");
ASSERT_MSG(g_current_process->status == ProcessStatus::Running, "Process has already exited");
Core::CurrentProcess()->status = ProcessStatus::Exited;
g_current_process->status = ProcessStatus::Exited;
// Stop all the process threads that are currently waiting for objects.
auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList();
for (auto& thread : thread_list) {
if (thread->owner_process != Core::CurrentProcess())
if (thread->owner_process != g_current_process)
continue;
if (thread == GetCurrentThread())
@@ -527,14 +525,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
return ERR_OUT_OF_RANGE;
}
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
SharedPtr<ResourceLimit>& resource_limit = g_current_process->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) {
return ERR_NOT_AUTHORIZED;
}
if (processor_id == THREADPROCESSORID_DEFAULT) {
// Set the target CPU to the one specified in the process' exheader.
processor_id = Core::CurrentProcess()->ideal_processor;
processor_id = g_current_process->ideal_processor;
ASSERT(processor_id != THREADPROCESSORID_DEFAULT);
}
@@ -556,7 +554,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
CASCADE_RESULT(SharedPtr<Thread> thread,
Thread::Create(name, entry_point, priority, arg, processor_id, stack_top,
Core::CurrentProcess()));
g_current_process));
CASCADE_RESULT(thread->guest_handle, g_handle_table.Create(thread));
*out_handle = thread->guest_handle;
@@ -750,7 +748,7 @@ static ResultCode ResetSignal(Handle handle) {
/// Creates a TransferMemory object
static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) {
LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%lx, size=0x%lx, perms=%08X", addr, size,
LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%llx, size=0x%llx, perms=%08X", addr, size,
permissions);
*handle = 0;
return RESULT_SUCCESS;

View File

@@ -55,6 +55,16 @@ inline static u32 const NewThreadId() {
Thread::Thread() {}
Thread::~Thread() {}
/**
* Check if the specified thread is waiting on the specified address to be arbitrated
* @param thread The thread to test
* @param wait_address The address to test against
* @return True if the thread is waiting, false otherwise
*/
static bool CheckWait_AddressArbiter(const Thread* thread, VAddr wait_address) {
return thread->status == THREADSTATUS_WAIT_ARB && wait_address == thread->wait_address;
}
void Thread::Stop() {
// Cancel any outstanding wakeup events for this thread
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle);
@@ -84,7 +94,7 @@ void Thread::Stop() {
u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
u64 tls_slot =
((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot);
Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot);
}
void WaitCurrentThread_Sleep() {
@@ -92,6 +102,12 @@ void WaitCurrentThread_Sleep() {
thread->status = THREADSTATUS_WAIT_SLEEP;
}
void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) {
Thread* thread = GetCurrentThread();
thread->wait_address = wait_address;
thread->status = THREADSTATUS_WAIT_ARB;
}
void ExitCurrentThread() {
Thread* thread = GetCurrentThread();
thread->Stop();
@@ -113,8 +129,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
bool resume = true;
if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
thread->status == THREADSTATUS_WAIT_SYNCH_ALL ||
thread->status == THREADSTATUS_WAIT_HLE_EVENT) {
thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) {
// Remove the thread from each of its waiting objects' waitlists
for (auto& object : thread->wait_objects)
@@ -148,7 +163,7 @@ void Thread::ResumeFromWait() {
switch (status) {
case THREADSTATUS_WAIT_SYNCH_ALL:
case THREADSTATUS_WAIT_SYNCH_ANY:
case THREADSTATUS_WAIT_HLE_EVENT:
case THREADSTATUS_WAIT_ARB:
case THREADSTATUS_WAIT_SLEEP:
case THREADSTATUS_WAIT_IPC:
break;
@@ -299,7 +314,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
// TODO(Subv): Find the correct MemoryState for this region.
vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE,
linheap_memory, offset, Memory::PAGE_SIZE,
MemoryState::ThreadLocal);
MemoryState::ThreadLocalStorage);
}
// Mark the slot as used
@@ -338,11 +353,11 @@ void Thread::BoostPriority(u32 priority) {
SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority,
SharedPtr<Process> owner_process) {
// Setup page table so we can write to memory
SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table);
// Initialize new "main" thread
auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
Memory::STACK_VADDR_END, owner_process);
Memory::HEAP_VADDR_END, owner_process);
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
@@ -391,8 +406,6 @@ void ThreadingInit() {
next_thread_id = 1;
}
void ThreadingShutdown() {
Kernel::ClearProcessList();
}
void ThreadingShutdown() {}
} // namespace Kernel

View File

@@ -38,7 +38,7 @@ enum ThreadProcessorId : s32 {
enum ThreadStatus {
THREADSTATUS_RUNNING, ///< Currently running
THREADSTATUS_READY, ///< Ready to run
THREADSTATUS_WAIT_HLE_EVENT, ///< Waiting for hle event to finish
THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter
THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC
THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request
THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false

View File

@@ -18,26 +18,8 @@ namespace Kernel {
static const char* GetMemoryStateName(MemoryState state) {
static const char* names[] = {
"Unmapped",
"Io",
"Normal",
"CodeStatic",
"CodeMutable",
"Heap",
"Shared",
"Unknown1"
"ModuleCodeStatic",
"ModuleCodeMutable",
"IpcBuffer0",
"Mapped",
"ThreadLocal",
"TransferMemoryIsolated",
"TransferMemory",
"ProcessMemory",
"Unknown2"
"IpcBuffer1",
"IpcBuffer3",
"KernelStack",
"Free", "Reserved", "IO", "Static", "Code", "Private",
"Shared", "Continuous", "Aliased", "Alias", "AliasCode", "Locked",
};
return names[(int)state];
@@ -160,7 +142,7 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) {
VirtualMemoryArea& vma = vma_handle->second;
vma.type = VMAType::Free;
vma.permissions = VMAPermission::None;
vma.meminfo_state = MemoryState::Unmapped;
vma.meminfo_state = MemoryState::Free;
vma.backing_block = nullptr;
vma.offset = 0;
@@ -184,9 +166,6 @@ ResultCode VMManager::UnmapRange(VAddr target, u64 size) {
}
ASSERT(FindVMA(target)->second.size >= size);
Core::CPU().UnmapMemory(target, size);
return RESULT_SUCCESS;
}
@@ -398,4 +377,19 @@ u64 VMManager::GetAddressSpaceSize() {
return MAX_ADDRESS;
}
VAddr VMManager::GetMapRegionBaseAddr() {
LOG_WARNING(Kernel, "(STUBBED) called");
return Memory::HEAP_VADDR;
}
VAddr VMManager::GetNewMapRegionBaseAddr() {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x8000000;
}
u64 VMManager::GetNewMapRegionSize() {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x8000000;
}
} // namespace Kernel

View File

@@ -41,24 +41,15 @@ enum class VMAPermission : u8 {
/// Set of values returned in MemoryInfo.state by svcQueryMemory.
enum class MemoryState : u32 {
Unmapped = 0x0,
Io = 0x1,
Normal = 0x2,
CodeStatic = 0x3,
CodeMutable = 0x4,
Heap = 0x5,
Shared = 0x6,
ModuleCodeStatic = 0x8,
ModuleCodeMutable = 0x9,
IpcBuffer0 = 0xA,
Mapped = 0xB,
ThreadLocal = 0xC,
TransferMemoryIsolated = 0xD,
TransferMemory = 0xE,
ProcessMemory = 0xF,
IpcBuffer1 = 0x11,
IpcBuffer3 = 0x12,
KernelStack = 0x13,
Free = 0,
IO = 1,
Normal = 2,
Code = 3,
Static = 4,
Heap = 5,
Shared = 6,
Mapped = 6,
ThreadLocalStorage = 12,
};
/**
@@ -75,7 +66,7 @@ struct VirtualMemoryArea {
VMAType type = VMAType::Free;
VMAPermission permissions = VMAPermission::None;
/// Tag returned by svcQueryMemory. Not otherwise used.
MemoryState meminfo_state = MemoryState::Unmapped;
MemoryState meminfo_state = MemoryState::Free;
// Settings for type = AllocatedMemoryBlock
/// Memory block backing this VMA.
@@ -201,6 +192,15 @@ public:
/// Gets the total address space address size, used by svcGetInfo
u64 GetAddressSpaceSize();
/// Gets the map region base address, used by svcGetInfo
VAddr GetMapRegionBaseAddr();
/// Gets the base address for a new memory region, used by svcGetInfo
VAddr GetNewMapRegionBaseAddr();
/// Gets the size for a new memory region, used by svcGetInfo
u64 GetNewMapRegionSize();
/// Each VMManager has its own page table, which is set as the main one when the owning process
/// is scheduled.
Memory::PageTable page_table;

View File

@@ -39,8 +39,7 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
for (const auto& thread : waiting_threads) {
// The list of waiting threads must not contain threads that are not waiting to be awakened.
ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
thread->status == THREADSTATUS_WAIT_SYNCH_ALL ||
thread->status == THREADSTATUS_WAIT_HLE_EVENT,
thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
"Inconsistent thread statuses in waiting_threads");
if (thread->current_priority >= candidate_priority)

View File

@@ -108,11 +108,11 @@ union ResultCode {
}
constexpr bool IsSuccess() const {
return raw == 0;
return is_error.ExtractValue(raw) == 0;
}
constexpr bool IsError() const {
return raw != 0;
return is_error.ExtractValue(raw) == 1;
}
};

View File

@@ -2,15 +2,12 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cinttypes>
#include "core/file_sys/filesystem.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/nvflinger/nvflinger.h"
namespace Service {
@@ -419,24 +416,9 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
}
void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u128 uid = rp.PopRaw<u128>();
LOG_WARNING(Service, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]);
LOG_WARNING(Service, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
FileSys::Path unused;
auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData, unused);
if (savedata.Failed()) {
// Create the save data and return an error indicating that the operation was performed.
FileSystem::FormatFileSystem(FileSystem::Type::SaveData);
// TODO(Subv): Find out the correct error code for this.
rb.Push(ResultCode(ErrorModule::FS, 40));
} else {
rb.Push(RESULT_SUCCESS);
}
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
}

View File

@@ -52,9 +52,7 @@ public:
CoreTiming::ScheduleEvent(audio_ticks, audio_event);
}
~IAudioOut() {
CoreTiming::UnscheduleEvent(audio_event, 0);
}
~IAudioOut() = default;
private:
void StartAudioOut(Kernel::HLERequestContext& ctx) {

View File

@@ -45,9 +45,7 @@ public:
// Start the audio event
CoreTiming::ScheduleEvent(audio_ticks, audio_event);
}
~IAudioRenderer() {
CoreTiming::UnscheduleEvent(audio_event, 0);
}
~IAudioRenderer() = default;
private:
void UpdateAudioCallback() {

View File

@@ -1,38 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/fatal/fatal.h"
#include "core/hle/service/fatal/fatal_p.h"
#include "core/hle/service/fatal/fatal_u.h"
namespace Service {
namespace Fatal {
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
: ServiceFramework(name), module(std::move(module)) {}
void Module::Interface::FatalSimple(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u32 error_code = rp.Pop<u32>();
LOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x%X", error_code);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::TransitionToFatalError(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Fatal, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void InstallInterfaces(SM::ServiceManager& service_manager) {
auto module = std::make_shared<Module>();
std::make_shared<Fatal_P>(module)->InstallAsService(service_manager);
std::make_shared<Fatal_U>(module)->InstallAsService(service_manager);
}
} // namespace Fatal
} // namespace Service

View File

@@ -1,29 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace Fatal {
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
void FatalSimple(Kernel::HLERequestContext& ctx);
void TransitionToFatalError(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
};
};
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace Fatal
} // namespace Service

View File

@@ -1,14 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/fatal/fatal_p.h"
namespace Service {
namespace Fatal {
Fatal_P::Fatal_P(std::shared_ptr<Module> module)
: Module::Interface(std::move(module), "fatal:p") {}
} // namespace Fatal
} // namespace Service

View File

@@ -1,18 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/fatal/fatal.h"
namespace Service {
namespace Fatal {
class Fatal_P final : public Module::Interface {
public:
explicit Fatal_P(std::shared_ptr<Module> module);
};
} // namespace Fatal
} // namespace Service

View File

@@ -1,19 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/fatal/fatal_u.h"
namespace Service {
namespace Fatal {
Fatal_U::Fatal_U(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "fatal:u") {
static const FunctionInfo functions[] = {
{1, &Fatal_U::FatalSimple, "FatalSimple"},
{2, &Fatal_U::TransitionToFatalError, "TransitionToFatalError"},
};
RegisterHandlers(functions);
}
} // namespace Fatal
} // namespace Service

View File

@@ -1,18 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/fatal/fatal.h"
namespace Service {
namespace Fatal {
class Fatal_U final : public Module::Interface {
public:
explicit Fatal_U(std::shared_ptr<Module> module);
};
} // namespace Fatal
} // namespace Service

View File

@@ -3,9 +3,7 @@
// Refer to the license.txt file included.
#include <boost/container/flat_map.hpp>
#include "common/file_util.h"
#include "core/file_sys/filesystem.h"
#include "core/file_sys/savedata_factory.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/filesystem/fsp_srv.h"
@@ -43,30 +41,12 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
return itr->second->Open(path);
}
ResultCode FormatFileSystem(Type type) {
LOG_TRACE(Service_FS, "Formatting FileSystem with type=%d", type);
auto itr = filesystem_map.find(type);
if (itr == filesystem_map.end()) {
// TODO(bunnei): Find a better error code for this
return ResultCode(-1);
}
FileSys::Path unused;
return itr->second->Format(unused);
}
void RegisterFileSystems() {
void UnregisterFileSystems() {
filesystem_map.clear();
std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);
auto savedata = std::make_unique<FileSys::SaveData_Factory>(std::move(nand_directory));
RegisterFileSystem(std::move(savedata), Type::SaveData);
}
void InstallInterfaces(SM::ServiceManager& service_manager) {
RegisterFileSystems();
UnregisterFileSystems();
std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
}

View File

@@ -25,7 +25,6 @@ namespace FileSystem {
/// Supported FileSystem types
enum class Type {
RomFS = 1,
SaveData = 2,
};
/**
@@ -44,13 +43,6 @@ ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& fact
ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
FileSys::Path& path);
/**
* Formats a file system
* @param type Type of the file system to format
* @return ResultCode of the operation
*/
ResultCode FormatFileSystem(Type type);
/// Registers all Filesystem services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);

View File

@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cinttypes>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/file_sys/filesystem.h"
@@ -35,7 +34,7 @@ private:
const s64 offset = rp.Pop<s64>();
const s64 length = rp.Pop<s64>();
LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length);
LOG_DEBUG(Service_FS, "called, offset=0x%llx, length=0x%llx", offset, length);
// Error checking
if (length < 0) {
@@ -66,187 +65,10 @@ private:
}
};
class IFile final : public ServiceFramework<IFile> {
public:
explicit IFile(std::unique_ptr<FileSys::StorageBackend>&& backend)
: ServiceFramework("IFile"), backend(std::move(backend)) {
static const FunctionInfo functions[] = {
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, {2, nullptr, "Flush"},
{3, nullptr, "SetSize"}, {4, nullptr, "GetSize"},
};
RegisterHandlers(functions);
}
private:
std::unique_ptr<FileSys::StorageBackend> backend;
void Read(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u64 unk = rp.Pop<u64>();
const s64 offset = rp.Pop<s64>();
const s64 length = rp.Pop<s64>();
LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length);
// Error checking
if (length < 0) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidLength));
return;
}
if (offset < 0) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidOffset));
return;
}
// Read the data from the Storage backend
std::vector<u8> output(length);
ResultVal<size_t> res = backend->Read(offset, length, output.data());
if (res.Failed()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res.Code());
return;
}
// Write the data to memory
ctx.WriteBuffer(output);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u64>(*res));
}
void Write(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u64 unk = rp.Pop<u64>();
const s64 offset = rp.Pop<s64>();
const s64 length = rp.Pop<s64>();
LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length);
// Error checking
if (length < 0) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidLength));
return;
}
if (offset < 0) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidOffset));
return;
}
// Write the data to the Storage backend
std::vector<u8> data = ctx.ReadBuffer();
ResultVal<size_t> res = backend->Write(offset, length, true, data.data());
if (res.Failed()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res.Code());
return;
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
};
class IFileSystem final : public ServiceFramework<IFileSystem> {
public:
explicit IFileSystem(std::unique_ptr<FileSys::FileSystemBackend>&& backend)
: ServiceFramework("IFileSystem"), backend(std::move(backend)) {
static const FunctionInfo functions[] = {
{0, &IFileSystem::CreateFile, "CreateFile"},
{7, &IFileSystem::GetEntryType, "GetEntryType"},
{8, &IFileSystem::OpenFile, "OpenFile"},
{10, &IFileSystem::Commit, "Commit"},
};
RegisterHandlers(functions);
}
void CreateFile(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto file_buffer = ctx.ReadBuffer();
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
std::string name(file_buffer.begin(), end);
u64 mode = rp.Pop<u64>();
u32 size = rp.Pop<u32>();
LOG_DEBUG(Service_FS, "called file %s mode 0x%" PRIX64 " size 0x%08X", name.c_str(), mode,
size);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(backend->CreateFile(name, size));
}
void OpenFile(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto file_buffer = ctx.ReadBuffer();
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
std::string name(file_buffer.begin(), end);
auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>());
LOG_DEBUG(Service_FS, "called file %s mode %u", name.c_str(), static_cast<u32>(mode));
auto result = backend->OpenFile(name, mode);
if (result.Failed()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result.Code());
return;
}
auto file = std::move(result.Unwrap());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IFile>(std::move(file));
}
void GetEntryType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto file_buffer = ctx.ReadBuffer();
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
std::string name(file_buffer.begin(), end);
LOG_DEBUG(Service_FS, "called file %s", name.c_str());
auto result = backend->GetEntryType(name);
if (result.Failed()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result.Code());
return;
}
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(static_cast<u32>(*result));
}
void Commit(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
private:
std::unique_ptr<FileSys::FileSystemBackend> backend;
};
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
static const FunctionInfo functions[] = {
{1, &FSP_SRV::Initalize, "Initalize"},
{18, &FSP_SRV::MountSdCard, "MountSdCard"},
{22, &FSP_SRV::CreateSaveData, "CreateSaveData"},
{51, &FSP_SRV::MountSaveData, "MountSaveData"},
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
{202, nullptr, "OpenDataStorageByDataId"},
{203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"},
@@ -280,30 +102,6 @@ void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto save_struct = rp.PopRaw<std::array<u8, 0x40>>();
auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
u128 uid = rp.PopRaw<u128>();
LOG_WARNING(Service_FS, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");
FileSys::Path unused;
auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap();
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
}
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");

View File

@@ -24,8 +24,6 @@ private:
void Initalize(Kernel::HLERequestContext& ctx);
void MountSdCard(Kernel::HLERequestContext& ctx);
void CreateSaveData(Kernel::HLERequestContext& ctx);
void MountSaveData(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenRomStorage(Kernel::HLERequestContext& ctx);

View File

@@ -45,10 +45,6 @@ public:
CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
}
~IAppletResource() {
CoreTiming::UnscheduleEvent(pad_update_event, 0);
}
private:
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 1};

View File

@@ -32,7 +32,7 @@ public:
{0, &IRequest::GetRequestState, "GetRequestState"},
{1, &IRequest::GetResult, "GetResult"},
{2, &IRequest::GetSystemEventReadableHandles, "GetSystemEventReadableHandles"},
{3, &IRequest::Cancel, "Cancel"},
{3, nullptr, "Cancel"},
{4, nullptr, "Submit"},
{5, nullptr, "SetRequirement"},
{6, nullptr, "SetRequirementPreset"},
@@ -80,11 +80,6 @@ private:
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event1, event2);
}
void Cancel(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
Kernel::SharedPtr<Kernel::Event> event1, event2;
};
@@ -101,56 +96,13 @@ public:
}
};
class IGeneralService final : public ServiceFramework<IGeneralService> {
public:
IGeneralService();
private:
void GetClientId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
}
void CreateScanRequest(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IScanRequest>();
LOG_DEBUG(Service_NIFM, "called");
}
void CreateRequest(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IRequest>();
LOG_DEBUG(Service_NIFM, "called");
}
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<INetworkProfile>();
LOG_DEBUG(Service_NIFM, "called");
}
};
IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
static const FunctionInfo functions[] = {
{1, &IGeneralService::GetClientId, "GetClientId"},
{2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
{4, &IGeneralService::CreateRequest, "CreateRequest"},
{5, nullptr, "GetCurrentNetworkProfile"},
{6, nullptr, "EnumerateNetworkInterfaces"},
{7, nullptr, "EnumerateNetworkProfiles"},
{6, nullptr, "GetCurrentNetworkProfile"},
{7, nullptr, "EnumerateNetworkInterfaces"},
{8, nullptr, "GetNetworkProfile"},
{9, nullptr, "SetNetworkProfile"},
{10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
@@ -185,28 +137,50 @@ IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
RegisterHandlers(functions);
}
void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
void IGeneralService::GetClientId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
rb.Push<u64>(0);
}
void IGeneralService::CreateScanRequest(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IScanRequest>();
LOG_DEBUG(Service_NIFM, "called");
}
void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) {
void IGeneralService::CreateRequest(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
rb.PushIpcInterface<IRequest>();
LOG_DEBUG(Service_NIFM, "called");
}
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
: ServiceFramework(name), module(std::move(module)) {}
void IGeneralService::RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void IGeneralService::CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<INetworkProfile>();
LOG_DEBUG(Service_NIFM, "called");
}
void InstallInterfaces(SM::ServiceManager& service_manager) {
auto module = std::make_shared<Module>();
std::make_shared<NIFM_A>(module)->InstallAsService(service_manager);
std::make_shared<NIFM_S>(module)->InstallAsService(service_manager);
std::make_shared<NIFM_U>(module)->InstallAsService(service_manager);
std::make_shared<NIFM_A>()->InstallAsService(service_manager);
std::make_shared<NIFM_S>()->InstallAsService(service_manager);
std::make_shared<NIFM_U>()->InstallAsService(service_manager);
}
} // namespace NIFM

View File

@@ -9,18 +9,16 @@
namespace Service {
namespace NIFM {
class Module final {
class IGeneralService final : public ServiceFramework<IGeneralService> {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
IGeneralService();
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
};
private:
void GetClientId(Kernel::HLERequestContext& ctx);
void CreateScanRequest(Kernel::HLERequestContext& ctx);
void CreateRequest(Kernel::HLERequestContext& ctx);
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx);
void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx);
};
void InstallInterfaces(SM::ServiceManager& service_manager);

View File

@@ -2,12 +2,29 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_a.h"
namespace Service {
namespace NIFM {
NIFM_A::NIFM_A(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:a") {
void NIFM_A::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void NIFM_A::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
NIFM_A::NIFM_A() : ServiceFramework("nifm:a") {
static const FunctionInfo functions[] = {
{4, &NIFM_A::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_A::CreateGeneralService, "CreateGeneralService"},

View File

@@ -4,14 +4,20 @@
#pragma once
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
namespace Service {
namespace NIFM {
class NIFM_A final : public Module::Interface {
class NIFM_A final : public ServiceFramework<NIFM_A> {
public:
explicit NIFM_A(std::shared_ptr<Module> module);
NIFM_A();
~NIFM_A() = default;
private:
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
};
} // namespace NIFM

View File

@@ -2,12 +2,29 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_s.h"
namespace Service {
namespace NIFM {
NIFM_S::NIFM_S(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:s") {
void NIFM_S::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void NIFM_S::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
NIFM_S::NIFM_S() : ServiceFramework("nifm:s") {
static const FunctionInfo functions[] = {
{4, &NIFM_S::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_S::CreateGeneralService, "CreateGeneralService"},

View File

@@ -4,14 +4,20 @@
#pragma once
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
namespace Service {
namespace NIFM {
class NIFM_S final : public Module::Interface {
class NIFM_S final : public ServiceFramework<NIFM_S> {
public:
explicit NIFM_S(std::shared_ptr<Module> module);
NIFM_S();
~NIFM_S() = default;
private:
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
};
} // namespace NIFM

View File

@@ -2,12 +2,29 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_u.h"
namespace Service {
namespace NIFM {
NIFM_U::NIFM_U(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:u") {
void NIFM_U::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void NIFM_U::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
NIFM_U::NIFM_U() : ServiceFramework("nifm:u") {
static const FunctionInfo functions[] = {
{4, &NIFM_U::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_U::CreateGeneralService, "CreateGeneralService"},

View File

@@ -4,14 +4,20 @@
#pragma once
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
namespace Service {
namespace NIFM {
class NIFM_U final : public Module::Interface {
class NIFM_U final : public ServiceFramework<NIFM_U> {
public:
explicit NIFM_U(std::shared_ptr<Module> module);
NIFM_U();
~NIFM_U() = default;
private:
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
};
} // namespace NIFM

View File

@@ -4,7 +4,6 @@
#include "common/common_paths.h"
#include "common/file_util.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/ns/pl_u.h"
@@ -91,13 +90,13 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
// dump. In the future, we need to replace this with a more robust solution.
// Map backing memory for the font data
Core::CurrentProcess()->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, shared_font, 0,
SHARED_FONT_MEM_SIZE,
Kernel::MemoryState::Shared);
Kernel::g_current_process->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, shared_font, 0,
SHARED_FONT_MEM_SIZE,
Kernel::MemoryState::Shared);
// Create shared font memory object
shared_font_mem = Kernel::SharedMemory::Create(
Core::CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite,
Kernel::g_current_process, SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite,
Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE,
"PL_U:shared_font_mem");
}

View File

@@ -23,8 +23,8 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) {
VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle);
LOG_WARNING(Service,
"Drawing from address %lx offset %08X Width %u Height %u Stride %u Format %u", addr,
offset, width, height, stride, format);
"Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u",
addr, offset, width, height, stride, format);
using PixelFormat = RendererBase::FramebufferInfo::PixelFormat;
using Flags = NVFlinger::BufferQueue::BufferTransformFlags;

View File

@@ -26,30 +26,26 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
LOG_WARNING(Service, "Adding graphics buffer %u", slot);
queue.emplace_back(buffer);
if (buffer_wait_event) {
buffer_wait_event->Signal();
}
}
boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
u32 BufferQueue::DequeueBuffer(u32 pixel_format, u32 width, u32 height) {
auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
// Only consider free buffers. Buffers become free once again after they've been Acquired
// and Released by the compositor, see the NVFlinger::Compose method.
if (buffer.status != Buffer::Status::Free) {
if (buffer.status != Buffer::Status::Free)
return false;
}
// Make sure that the parameters match.
return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
auto& igbp_buffer = buffer.igbp_buffer;
return igbp_buffer.format == pixel_format && igbp_buffer.width == width &&
igbp_buffer.height == height;
});
if (itr == queue.end()) {
return boost::none;
LOG_CRITICAL(Service_NVDRV, "no free buffers for pixel_format=%d, width=%d, height=%d",
pixel_format, width, height);
itr = queue.begin();
}
buffer_wait_event = nullptr;
itr->status = Buffer::Status::Dequeued;
return itr->slot;
}
@@ -87,10 +83,6 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
ASSERT(itr != queue.end());
ASSERT(itr->status == Buffer::Status::Acquired);
itr->status = Buffer::Status::Free;
if (buffer_wait_event) {
buffer_wait_event->Signal();
}
}
u32 BufferQueue::Query(QueryType type) {
@@ -106,10 +98,5 @@ u32 BufferQueue::Query(QueryType type) {
return 0;
}
void BufferQueue::SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_event) {
ASSERT_MSG(!buffer_wait_event, "buffer_wait_event only supports a single waiting thread!");
buffer_wait_event = std::move(wait_event);
}
} // namespace NVFlinger
} // namespace Service

View File

@@ -69,13 +69,12 @@ public:
};
void SetPreallocatedBuffer(u32 slot, IGBPBuffer& buffer);
boost::optional<u32> DequeueBuffer(u32 width, u32 height);
u32 DequeueBuffer(u32 pixel_format, u32 width, u32 height);
const IGBPBuffer& RequestBuffer(u32 slot) const;
void QueueBuffer(u32 slot, BufferTransformFlags transform);
boost::optional<const Buffer&> AcquireBuffer();
void ReleaseBuffer(u32 slot);
u32 Query(QueryType type);
void SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_event);
u32 GetId() const {
return id;
@@ -91,9 +90,6 @@ private:
std::vector<Buffer> queue;
Kernel::SharedPtr<Kernel::Event> native_handle;
/// Used to signal waiting thread when no buffers are available
Kernel::SharedPtr<Kernel::Event> buffer_wait_event;
};
} // namespace NVFlinger

View File

@@ -150,9 +150,6 @@ void NVFlinger::Compose() {
igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform);
buffer_queue->ReleaseBuffer(buffer->slot);
// TODO(Subv): Figure out when we should actually signal this event.
buffer_queue->GetNativeHandle()->Signal();
}
}

View File

@@ -7,7 +7,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/hle/ipc.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
@@ -20,7 +19,6 @@
#include "core/hle/service/aoc/aoc_u.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/audio/audio.h"
#include "core/hle/service/fatal/fatal.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/friend/friend.h"
#include "core/hle/service/hid/hid.h"
@@ -30,11 +28,10 @@
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/pctl/pctl.h"
#include "core/hle/service/service.h"
#include "core/hle/service/set/settings.h"
#include "core/hle/service/set/set.h"
#include "core/hle/service/sm/controller.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/sockets/sockets.h"
#include "core/hle/service/spl/module.h"
#include "core/hle/service/time/time.h"
#include "core/hle/service/vi/vi.h"
@@ -151,10 +148,12 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
break;
}
default:
UNIMPLEMENTED_MSG("command_type=%d", static_cast<int>(context.GetCommandType()));
UNIMPLEMENTED_MSG("command_type=%d", context.GetCommandType());
}
context.WriteToOutgoingCommandBuffer(*Kernel::GetCurrentThread());
u32* cmd_buf = (u32*)Memory::GetPointer(Kernel::GetCurrentThread()->GetTLSAddress());
context.WriteToOutgoingCommandBuffer(cmd_buf, *Kernel::g_current_process,
Kernel::g_handle_table);
return RESULT_SUCCESS;
}
@@ -181,7 +180,6 @@ void Init() {
AOC::InstallInterfaces(*SM::g_service_manager);
APM::InstallInterfaces(*SM::g_service_manager);
Audio::InstallInterfaces(*SM::g_service_manager);
Fatal::InstallInterfaces(*SM::g_service_manager);
FileSystem::InstallInterfaces(*SM::g_service_manager);
Friend::InstallInterfaces(*SM::g_service_manager);
HID::InstallInterfaces(*SM::g_service_manager);
@@ -191,7 +189,6 @@ void Init() {
Nvidia::InstallInterfaces(*SM::g_service_manager);
PCTL::InstallInterfaces(*SM::g_service_manager);
Sockets::InstallInterfaces(*SM::g_service_manager);
SPL::InstallInterfaces(*SM::g_service_manager);
Time::InstallInterfaces(*SM::g_service_manager);
VI::InstallInterfaces(*SM::g_service_manager, nv_flinger);
Set::InstallInterfaces(*SM::g_service_manager);

View File

@@ -26,19 +26,16 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
}
SET::SET() : ServiceFramework("set") {
SET::SET(const char* name) : ServiceFramework(name) {
static const FunctionInfo functions[] = {
{0, nullptr, "GetLanguageCode"},
{1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"},
{2, nullptr, "MakeLanguageCode"},
{3, nullptr, "GetAvailableLanguageCodeCount"},
{4, nullptr, "GetRegionCode"},
{5, nullptr, "GetAvailableLanguageCodes2"},
{6, nullptr, "GetAvailableLanguageCodeCount2"},
{7, nullptr, "GetKeyCodeMap"},
};
RegisterHandlers(functions);
}
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<SET>("set")->InstallAsService(service_manager);
}
} // namespace Set
} // namespace Service

View File

@@ -11,12 +11,15 @@ namespace Set {
class SET final : public ServiceFramework<SET> {
public:
explicit SET();
explicit SET(const char* name);
~SET() = default;
private:
void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx);
};
/// Registers all Set services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace Set
} // namespace Service

View File

@@ -1,40 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/set/set_cal.h"
namespace Service {
namespace Set {
SET_CAL::SET_CAL() : ServiceFramework("set:cal") {
static const FunctionInfo functions[] = {
{0, nullptr, "GetBluetoothBdAddress"},
{1, nullptr, "GetConfigurationId1"},
{2, nullptr, "GetAccelerometerOffset"},
{3, nullptr, "GetAccelerometerScale"},
{4, nullptr, "GetGyroscopeOffset"},
{5, nullptr, "GetGyroscopeScale"},
{6, nullptr, "GetWirelessLanMacAddress"},
{7, nullptr, "GetWirelessLanCountryCodeCount"},
{8, nullptr, "GetWirelessLanCountryCodes"},
{9, nullptr, "GetSerialNumber"},
{10, nullptr, "SetInitialSystemAppletProgramId"},
{11, nullptr, "SetOverlayDispProgramId"},
{12, nullptr, "GetBatteryLot"},
{14, nullptr, "GetEciDeviceCertificate"},
{15, nullptr, "GetEticketDeviceCertificate"},
{16, nullptr, "GetSslKey"},
{17, nullptr, "GetSslCertificate"},
{18, nullptr, "GetGameCardKey"},
{19, nullptr, "GetGameCardCertificate"},
{20, nullptr, "GetEciDeviceKey"},
{21, nullptr, "GetEticketDeviceKey"},
{22, nullptr, "GetSpeakerParameter"},
{23, nullptr, "GetLcdVendorId"},
};
RegisterHandlers(functions);
}
} // namespace Set
} // namespace Service

View File

@@ -1,19 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace Set {
class SET_CAL final : public ServiceFramework<SET_CAL> {
public:
explicit SET_CAL();
~SET_CAL() = default;
};
} // namespace Set
} // namespace Service

View File

@@ -1,25 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/set/set_fd.h"
namespace Service {
namespace Set {
SET_FD::SET_FD() : ServiceFramework("set:fd") {
static const FunctionInfo functions[] = {
{2, nullptr, "SetSettingsItemValue"},
{3, nullptr, "ResetSettingsItemValue"},
{4, nullptr, "CreateSettingsItemKeyIterator"},
{10, nullptr, "ReadSettings"},
{11, nullptr, "ResetSettings"},
{20, nullptr, "SetWebInspectorFlag"},
{21, nullptr, "SetAllowedSslHosts"},
{22, nullptr, "SetHostFsMountPoint"},
};
RegisterHandlers(functions);
}
} // namespace Set
} // namespace Service

View File

@@ -1,19 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace Set {
class SET_FD final : public ServiceFramework<SET_FD> {
public:
explicit SET_FD();
~SET_FD() = default;
};
} // namespace Set
} // namespace Service

View File

@@ -1,167 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/service/set/set_sys.h"
namespace Service {
namespace Set {
void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0);
LOG_WARNING(Service_SET, "(STUBBED) called");
}
SET_SYS::SET_SYS() : ServiceFramework("set:sys") {
static const FunctionInfo functions[] = {
{0, nullptr, "SetLanguageCode"},
{1, nullptr, "SetNetworkSettings"},
{2, nullptr, "GetNetworkSettings"},
{3, nullptr, "GetFirmwareVersion"},
{4, nullptr, "GetFirmwareVersion2"},
{7, nullptr, "GetLockScreenFlag"},
{8, nullptr, "SetLockScreenFlag"},
{9, nullptr, "GetBacklightSettings"},
{10, nullptr, "SetBacklightSettings"},
{11, nullptr, "SetBluetoothDevicesSettings"},
{12, nullptr, "GetBluetoothDevicesSettings"},
{13, nullptr, "GetExternalSteadyClockSourceId"},
{14, nullptr, "SetExternalSteadyClockSourceId"},
{15, nullptr, "GetUserSystemClockContext"},
{16, nullptr, "SetUserSystemClockContext"},
{17, nullptr, "GetAccountSettings"},
{18, nullptr, "SetAccountSettings"},
{19, nullptr, "GetAudioVolume"},
{20, nullptr, "SetAudioVolume"},
{21, nullptr, "GetEulaVersions"},
{22, nullptr, "SetEulaVersions"},
{23, &SET_SYS::GetColorSetId, "GetColorSetId"},
{24, nullptr, "SetColorSetId"},
{25, nullptr, "GetConsoleInformationUploadFlag"},
{26, nullptr, "SetConsoleInformationUploadFlag"},
{27, nullptr, "GetAutomaticApplicationDownloadFlag"},
{28, nullptr, "SetAutomaticApplicationDownloadFlag"},
{29, nullptr, "GetNotificationSettings"},
{30, nullptr, "SetNotificationSettings"},
{31, nullptr, "GetAccountNotificationSettings"},
{32, nullptr, "SetAccountNotificationSettings"},
{35, nullptr, "GetVibrationMasterVolume"},
{36, nullptr, "SetVibrationMasterVolume"},
{37, nullptr, "GetSettingsItemValueSize"},
{38, nullptr, "GetSettingsItemValue"},
{39, nullptr, "GetTvSettings"},
{40, nullptr, "SetTvSettings"},
{41, nullptr, "GetEdid"},
{42, nullptr, "SetEdid"},
{43, nullptr, "GetAudioOutputMode"},
{44, nullptr, "SetAudioOutputMode"},
{45, nullptr, "IsForceMuteOnHeadphoneRemoved"},
{46, nullptr, "SetForceMuteOnHeadphoneRemoved"},
{47, nullptr, "GetQuestFlag"},
{48, nullptr, "SetQuestFlag"},
{49, nullptr, "GetDataDeletionSettings"},
{50, nullptr, "SetDataDeletionSettings"},
{51, nullptr, "GetInitialSystemAppletProgramId"},
{52, nullptr, "GetOverlayDispProgramId"},
{53, nullptr, "GetDeviceTimeZoneLocationName"},
{54, nullptr, "SetDeviceTimeZoneLocationName"},
{55, nullptr, "GetWirelessCertificationFileSize"},
{56, nullptr, "GetWirelessCertificationFile"},
{57, nullptr, "SetRegionCode"},
{58, nullptr, "GetNetworkSystemClockContext"},
{59, nullptr, "SetNetworkSystemClockContext"},
{60, nullptr, "IsUserSystemClockAutomaticCorrectionEnabled"},
{61, nullptr, "SetUserSystemClockAutomaticCorrectionEnabled"},
{62, nullptr, "GetDebugModeFlag"},
{63, nullptr, "GetPrimaryAlbumStorage"},
{64, nullptr, "SetPrimaryAlbumStorage"},
{65, nullptr, "GetUsb30EnableFlag"},
{66, nullptr, "SetUsb30EnableFlag"},
{67, nullptr, "GetBatteryLot"},
{68, nullptr, "GetSerialNumber"},
{69, nullptr, "GetNfcEnableFlag"},
{70, nullptr, "SetNfcEnableFlag"},
{71, nullptr, "GetSleepSettings"},
{72, nullptr, "SetSleepSettings"},
{73, nullptr, "GetWirelessLanEnableFlag"},
{74, nullptr, "SetWirelessLanEnableFlag"},
{75, nullptr, "GetInitialLaunchSettings"},
{76, nullptr, "SetInitialLaunchSettings"},
{77, nullptr, "GetDeviceNickName"},
{78, nullptr, "SetDeviceNickName"},
{79, nullptr, "GetProductModel"},
{80, nullptr, "GetLdnChannel"},
{81, nullptr, "SetLdnChannel"},
{82, nullptr, "AcquireTelemetryDirtyFlagEventHandle"},
{83, nullptr, "GetTelemetryDirtyFlags"},
{84, nullptr, "GetPtmBatteryLot"},
{85, nullptr, "SetPtmBatteryLot"},
{86, nullptr, "GetPtmFuelGaugeParameter"},
{87, nullptr, "SetPtmFuelGaugeParameter"},
{88, nullptr, "GetBluetoothEnableFlag"},
{89, nullptr, "SetBluetoothEnableFlag"},
{90, nullptr, "GetMiiAuthorId"},
{91, nullptr, "SetShutdownRtcValue"},
{92, nullptr, "GetShutdownRtcValue"},
{93, nullptr, "AcquireFatalDirtyFlagEventHandle"},
{94, nullptr, "GetFatalDirtyFlags"},
{95, nullptr, "GetAutoUpdateEnableFlag"},
{96, nullptr, "SetAutoUpdateEnableFlag"},
{97, nullptr, "GetNxControllerSettings"},
{98, nullptr, "SetNxControllerSettings"},
{99, nullptr, "GetBatteryPercentageFlag"},
{100, nullptr, "SetBatteryPercentageFlag"},
{101, nullptr, "GetExternalRtcResetFlag"},
{102, nullptr, "SetExternalRtcResetFlag"},
{103, nullptr, "GetUsbFullKeyEnableFlag"},
{104, nullptr, "SetUsbFullKeyEnableFlag"},
{105, nullptr, "SetExternalSteadyClockInternalOffset"},
{106, nullptr, "GetExternalSteadyClockInternalOffset"},
{107, nullptr, "GetBacklightSettingsEx"},
{108, nullptr, "SetBacklightSettingsEx"},
{109, nullptr, "GetHeadphoneVolumeWarningCount"},
{110, nullptr, "SetHeadphoneVolumeWarningCount"},
{111, nullptr, "GetBluetoothAfhEnableFlag"},
{112, nullptr, "SetBluetoothAfhEnableFlag"},
{113, nullptr, "GetBluetoothBoostEnableFlag"},
{114, nullptr, "SetBluetoothBoostEnableFlag"},
{115, nullptr, "GetInRepairProcessEnableFlag"},
{116, nullptr, "SetInRepairProcessEnableFlag"},
{117, nullptr, "GetHeadphoneVolumeUpdateFlag"},
{118, nullptr, "SetHeadphoneVolumeUpdateFlag"},
{119, nullptr, "NeedsToUpdateHeadphoneVolume"},
{120, nullptr, "GetPushNotificationActivityModeOnSleep"},
{121, nullptr, "SetPushNotificationActivityModeOnSleep"},
{122, nullptr, "GetServiceDiscoveryControlSettings"},
{123, nullptr, "SetServiceDiscoveryControlSettings"},
{124, nullptr, "GetErrorReportSharePermission"},
{125, nullptr, "SetErrorReportSharePermission"},
{126, nullptr, "GetAppletLaunchFlags"},
{127, nullptr, "SetAppletLaunchFlags"},
{128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"},
{129, nullptr, "SetConsoleSixAxisSensorAccelerationBias"},
{130, nullptr, "GetConsoleSixAxisSensorAngularVelocityBias"},
{131, nullptr, "SetConsoleSixAxisSensorAngularVelocityBias"},
{132, nullptr, "GetConsoleSixAxisSensorAccelerationGain"},
{133, nullptr, "SetConsoleSixAxisSensorAccelerationGain"},
{134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"},
{135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"},
{136, nullptr, "GetKeyboardLayout"},
{137, nullptr, "SetKeyboardLayout"},
{138, nullptr, "GetWebInspectorFlag"},
{139, nullptr, "GetAllowedSslHosts"},
{140, nullptr, "GetHostFsMountPoint"},
};
RegisterHandlers(functions);
}
} // namespace Set
} // namespace Service

View File

@@ -1,22 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace Set {
class SET_SYS final : public ServiceFramework<SET_SYS> {
public:
explicit SET_SYS();
~SET_SYS() = default;
private:
void GetColorSetId(Kernel::HLERequestContext& ctx);
};
} // namespace Set
} // namespace Service

View File

@@ -1,22 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/set/set.h"
#include "core/hle/service/set/set_cal.h"
#include "core/hle/service/set/set_fd.h"
#include "core/hle/service/set/set_sys.h"
#include "core/hle/service/set/settings.h"
namespace Service {
namespace Set {
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<SET>()->InstallAsService(service_manager);
std::make_shared<SET_CAL>()->InstallAsService(service_manager);
std::make_shared<SET_FD>()->InstallAsService(service_manager);
std::make_shared<SET_SYS>()->InstallAsService(service_manager);
}
} // namespace Set
} // namespace Service

View File

@@ -1,16 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace Set {
/// Registers all Settings services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace Set
} // namespace Service

View File

@@ -1,18 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/spl/csrng.h"
namespace Service {
namespace SPL {
CSRNG::CSRNG(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "csrng") {
static const FunctionInfo functions[] = {
{0, &CSRNG::GetRandomBytes, "GetRandomBytes"},
};
RegisterHandlers(functions);
}
} // namespace SPL
} // namespace Service

View File

@@ -1,18 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/spl/module.h"
namespace Service {
namespace SPL {
class CSRNG final : public Module::Interface {
public:
explicit CSRNG(std::shared_ptr<Module> module);
};
} // namespace SPL
} // namespace Service

View File

@@ -1,42 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <cstdlib>
#include <vector>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/spl/csrng.h"
#include "core/hle/service/spl/module.h"
#include "core/hle/service/spl/spl.h"
namespace Service {
namespace SPL {
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
: ServiceFramework(name), module(std::move(module)) {}
void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
size_t size = ctx.GetWriteBufferSize();
std::vector<u8> data(size);
std::generate(data.begin(), data.end(), std::rand);
ctx.WriteBuffer(data);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_SPL, "called");
}
void InstallInterfaces(SM::ServiceManager& service_manager) {
auto module = std::make_shared<Module>();
std::make_shared<CSRNG>(module)->InstallAsService(service_manager);
std::make_shared<SPL>(module)->InstallAsService(service_manager);
}
} // namespace SPL
} // namespace Service

View File

@@ -1,29 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace SPL {
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
Interface(std::shared_ptr<Module> module, const char* name);
void GetRandomBytes(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
};
};
/// Registers all SPL services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace SPL
} // namespace Service

View File

@@ -1,41 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/spl/spl.h"
namespace Service {
namespace SPL {
SPL::SPL(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "spl:") {
static const FunctionInfo functions[] = {
{0, nullptr, "GetConfig"},
{1, nullptr, "UserExpMod"},
{2, nullptr, "GenerateAesKek"},
{3, nullptr, "LoadAesKey"},
{4, nullptr, "GenerateAesKey"},
{5, nullptr, "SetConfig"},
{7, &SPL::GetRandomBytes, "GetRandomBytes"},
{9, nullptr, "LoadSecureExpModKey"},
{10, nullptr, "SecureExpMod"},
{11, nullptr, "IsDevelopment"},
{12, nullptr, "GenerateSpecificAesKey"},
{13, nullptr, "DecryptPrivk"},
{14, nullptr, "DecryptAesKey"},
{15, nullptr, "DecryptAesCtr"},
{16, nullptr, "ComputeCmac"},
{17, nullptr, "LoadRsaOaepKey"},
{18, nullptr, "UnwrapRsaOaepWrappedTitleKey"},
{19, nullptr, "LoadTitleKey"},
{20, nullptr, "UnwrapAesWrappedTitleKey"},
{21, nullptr, "LockAesEngine"},
{22, nullptr, "UnlockAesEngine"},
{23, nullptr, "GetSplWaitEvent"},
{24, nullptr, "SetSharedData"},
{25, nullptr, "GetSharedData"},
};
RegisterHandlers(functions);
}
} // namespace SPL
} // namespace Service

View File

@@ -1,18 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/spl/module.h"
namespace Service {
namespace SPL {
class SPL final : public Module::Interface {
public:
explicit SPL(std::shared_ptr<Module> module);
};
} // namespace SPL
} // namespace Service

View File

@@ -107,7 +107,7 @@ private:
IPC::RequestParser rp{ctx};
u64 posix_time = rp.Pop<u64>();
LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x%016lX", posix_time);
LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x%016llX", posix_time);
CalendarTime calendar_time{2018, 1, 1, 0, 0, 0};
CalendarAdditionalInfo additional_info{};

Some files were not shown because too many files have changed in this diff Show More