Compare commits

..

34 Commits

Author SHA1 Message Date
bunnei
1d51b25ed1 set: GetAvailableLanguageCodes should not return lang_codes size. 2018-02-04 23:42:43 -05:00
bunnei
fe99052599 nvflinger: Signal BufferQueue native handle event.
- This gets BOTW booting.
2018-02-04 23:00:35 -05:00
bunnei
8e1dbb26bd logger: Add Time service logging category. 2018-02-04 22:59:52 -05:00
bunnei
c689fe8424 logger: Add SET service logging category. 2018-02-04 22:55:45 -05:00
bunnei
fc1359dc03 logger: Add PCTL service logging category. 2018-02-04 22:44:00 -05:00
bunnei
649960b4eb logger: Add LM service logging category. 2018-02-04 22:41:55 -05:00
bunnei
8d2e4c3d39 logger: Add APM service logging category. 2018-02-04 22:39:47 -05:00
bunnei
69697535bf lm: Ensure log string is non-empty before checking back(). 2018-02-04 22:36:57 -05:00
bunnei
485c6541cf logger: Add NIFM service logging category. 2018-02-04 22:35:42 -05:00
bunnei
8a5833f7ad logger: Add VI service logging category. 2018-02-04 22:26:44 -05:00
bunnei
119f02a439 hid: Stub out several functions. 2018-02-04 22:24:20 -05:00
bunnei
ad97414057 hid: Implement CreateActiveVibrationDeviceList. 2018-02-04 17:06:14 -05:00
bunnei
ea615ef5a4 logger: Use Service_HID category where applicable. 2018-02-04 17:02:39 -05:00
bunnei
764bbaa19c logger: Use Service_NVDRV category where applicable. 2018-02-04 17:00:33 -05:00
bunnei
65cfe09b62 logger: Add AM service logging category. 2018-02-04 16:58:12 -05:00
bunnei
a947f16b63 logger: Add "account" service logging category. 2018-02-04 16:40:12 -05:00
bunnei
6674e8e048 acc_u0: Stub out GetLastOpenedUser. 2018-02-04 16:32:01 -05:00
bunnei
1ddc18454e Merge pull request #160 from bunnei/svc-improvements
Several SVC fixes and improvements
2018-02-04 13:25:05 -08:00
bunnei
42fc437268 GetInfo: Implement IsCurrentProcessBeingDebugged. 2018-02-04 12:34:45 -05:00
bunnei
0b6b147939 WaitProcessWideKeyAtomic: Handle case where condition variable was already created. 2018-02-04 12:30:51 -05:00
bunnei
eaf75ea970 Merge pull request #159 from mailwl/acc0-fix
acc:u0 : stub GetAccountId
2018-02-04 09:04:32 -08:00
mailwl
272058d7d9 acc:u0 : stub GetAccountId 2018-02-04 09:55:25 +03:00
bunnei
647364db8f svc: SharedMemory size should be 64-bits and cleanup. 2018-02-03 13:36:54 -05:00
bunnei
f9c9ce2005 ArbitrateLock: Assert that requesting_thread is current_thread. 2018-02-03 13:29:18 -05:00
bunnei
abc4be8e0f Merge pull request #157 from bunnei/fix-duplicate-session
controller: DuplicateSession should return a ClientSession.
2018-02-03 10:25:01 -08:00
bunnei
b5bdaf3441 Merge pull request #156 from mailwl/nifm
Service/nifm: add nifm:a, nifm:s and nifm:u services
2018-02-03 10:20:52 -08:00
bunnei
72c5bfb1fa controller: DuplicateSession should return a ClientSession. 2018-02-03 12:09:33 -05:00
mailwl
f67a8d87a0 Service:nifm: add nifm:a, nifm:s and nifm:u services 2018-02-03 18:09:51 +03:00
mailwl
1a8f5bfb8e Service/am: Add AppletAE service (#153)
* Add AppletAE, step 1: move common interfaces to am.h

* Add AppletAE, step 2
2018-02-02 13:03:40 -08:00
bunnei
5ad9b3e19d Merge pull request #154 from mailwl/vi_create_stray_array
vi::CreateStrayLayer : add padding to request
2018-02-02 09:01:21 -08:00
bunnei
1909802156 Merge pull request #155 from mailwl/vi-services
Services/vi: add vi:s and vi:u services
2018-02-02 09:00:31 -08:00
bunnei
2e6776909b Merge pull request #152 from shinyquagsire23/sharedmem-valid-bounds
shared_memory: Only mark addresses as invalid if they are within the heap
2018-02-02 08:59:45 -08:00
mailwl
524c12a5f8 Services/vi: add vi:s and vi:u services 2018-02-02 12:59:50 +03:00
shinyquagsire23
96c444d1ff shared_memory: Only mark addresses as invalid if they are within the heap 2018-01-29 23:38:56 -07:00
41 changed files with 1296 additions and 489 deletions

View File

@@ -32,14 +32,20 @@ namespace Log {
CLS(Kernel) \
SUB(Kernel, SVC) \
CLS(Service) \
SUB(Service, SM) \
SUB(Service, FS) \
SUB(Service, GSP) \
SUB(Service, CFG) \
SUB(Service, DSP) \
SUB(Service, HID) \
SUB(Service, NVDRV) \
SUB(Service, ACC) \
SUB(Service, Audio) \
SUB(Service, AM) \
SUB(Service, APM) \
SUB(Service, FS) \
SUB(Service, HID) \
SUB(Service, LM) \
SUB(Service, NIFM) \
SUB(Service, NVDRV) \
SUB(Service, PCTL) \
SUB(Service, SET) \
SUB(Service, SM) \
SUB(Service, Time) \
SUB(Service, VI) \
CLS(HW) \
SUB(HW, Memory) \
SUB(HW, LCD) \

View File

@@ -49,14 +49,20 @@ enum class Class : ClassType {
Kernel_SVC, ///< Kernel system calls
Service, ///< HLE implementation of system services. Each major service
/// should have its own subclass.
Service_SM, ///< The SRV (Service Directory) implementation
Service_FS, ///< The FS (Filesystem) service implementation
Service_GSP, ///< The GSP (GPU control) service
Service_CFG, ///< The CFG (Configuration) service
Service_DSP, ///< The DSP (DSP control) service
Service_HID, ///< The HID (Human interface device) service
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
Service_ACC, ///< The ACC (Accounts) service
Service_AM, ///< The AM (Applet manager) service
Service_APM, ///< The APM (Performance) service
Service_Audio, ///< The Audio (Audio control) service
Service_FS, ///< The FS (Filesystem) service
Service_HID, ///< The HID (Human interface device) service
Service_LM, ///< The LM (Logger) service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
Service_PCTL, ///< The PCTL (Parental control) service
Service_SET, ///< The SET (Settings) service
Service_SM, ///< The SM (Service manager) service
Service_Time, ///< The time service
Service_VI, ///< The VI (Video interface) service
HW, ///< Low-level hardware emulation
HW_Memory, ///< Memory-map and address translation
HW_LCD, ///< LCD register emulation

View File

@@ -84,6 +84,8 @@ add_library(core STATIC
hle/service/acc/acc_u0.h
hle/service/am/am.cpp
hle/service/am/am.h
hle/service/am/applet_ae.cpp
hle/service/am/applet_ae.h
hle/service/am/applet_oe.cpp
hle/service/am/applet_oe.h
hle/service/aoc/aoc_u.cpp
@@ -112,6 +114,14 @@ add_library(core STATIC
hle/service/hid/hid.h
hle/service/lm/lm.cpp
hle/service/lm/lm.h
hle/service/nifm/nifm.cpp
hle/service/nifm/nifm.h
hle/service/nifm/nifm_a.cpp
hle/service/nifm/nifm_a.h
hle/service/nifm/nifm_s.cpp
hle/service/nifm/nifm_s.h
hle/service/nifm/nifm_u.cpp
hle/service/nifm/nifm_u.h
hle/service/nvdrv/devices/nvdevice.h
hle/service/nvdrv/devices/nvdisp_disp0.cpp
hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -159,6 +169,10 @@ add_library(core STATIC
hle/service/vi/vi.h
hle/service/vi/vi_m.cpp
hle/service/vi/vi_m.h
hle/service/vi/vi_s.cpp
hle/service/vi/vi_s.h
hle/service/vi/vi_u.cpp
hle/service/vi/vi_u.h
hle/shared_page.cpp
hle/shared_page.h
hw/hw.cpp

View File

@@ -15,13 +15,12 @@ ConditionVariable::ConditionVariable() {}
ConditionVariable::~ConditionVariable() {}
ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr,
VAddr mutex_addr,
std::string name) {
SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);
condition_variable->name = std::move(name);
condition_variable->guest_addr = guest_addr;
condition_variable->mutex_addr = mutex_addr;
condition_variable->mutex_addr = 0;
// Condition variables are referenced by guest address, so track this in the kernel
g_object_address_table.Insert(guest_addr, condition_variable);

View File

@@ -19,12 +19,10 @@ public:
* Creates a condition variable.
* @param guest_addr Address of the object tracking the condition variable in guest memory. If
* specified, this condition variable will update the guest object when its state changes.
* @param mutex_addr Optional address of a guest mutex associated with this condition variable,
* used by the OS for implementing events.
* @param name Optional name of condition variable.
* @return The created condition variable.
*/
static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0,
static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr,
std::string name = "Unknown");
std::string GetTypeName() const override {

View File

@@ -14,7 +14,7 @@ namespace Kernel {
SharedMemory::SharedMemory() {}
SharedMemory::~SharedMemory() {}
SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size,
SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u64 size,
MemoryPermission permissions,
MemoryPermission other_permissions, VAddr address,
MemoryRegion region, std::string name) {
@@ -136,7 +136,8 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
// can not map it in its own address space unless it was created with addr=0, result 0xD900182C.
if (address != 0) {
if (address < Memory::HEAP_VADDR) {
// 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%llx name=%s, invalid address",
GetObjectId(), address, name.c_str());
return ERR_INVALID_ADDRESS;

View File

@@ -39,7 +39,7 @@ public:
* linear heap.
* @param name Optional object name, used for debugging purposes.
*/
static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size,
static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u64 size,
MemoryPermission permissions,
MemoryPermission other_permissions, VAddr address = 0,
MemoryRegion region = MemoryRegion::BASE,
@@ -116,7 +116,7 @@ public:
/// Offset into the backing block for this shared memory.
size_t backing_block_offset;
/// Size of the memory block. Page-aligned.
u32 size;
u64 size;
/// Permission restrictions applied to the process which created the block.
MemoryPermission permissions;
/// Permission restrictions applied to other processes mapping the block.

View File

@@ -263,6 +263,7 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle);
ASSERT(requesting_thread);
ASSERT(requesting_thread == GetCurrentThread());
SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
if (!mutex) {
@@ -331,6 +332,9 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
case GetInfoType::TotalHeapUsage:
*result = vm_manager.GetTotalHeapUsage();
break;
case GetInfoType::IsCurrentProcessBeingDebugged:
*result = 0;
break;
case GetInfoType::RandomEntropy:
*result = 0;
break;
@@ -415,8 +419,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
"called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X",
shared_memory_handle, addr, size, permissions);
SharedPtr<SharedMemory> shared_memory =
Kernel::g_handle_table.Get<SharedMemory>(shared_memory_handle);
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
if (!shared_memory) {
return ERR_INVALID_HANDLE;
}
@@ -431,7 +434,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(Kernel::g_current_process.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);
@@ -612,20 +615,29 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
}
ASSERT(mutex->GetOwnerHandle() == thread_handle);
SharedPtr<ConditionVariable> condition_variable =
g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
if (!condition_variable) {
// Create a new condition_variable for the specified address if one does not already exist
condition_variable =
ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap();
condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap();
condition_variable->name =
Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
}
ASSERT(condition_variable->GetAvailableCount() == 0);
ASSERT(condition_variable->mutex_addr == mutex_addr);
if (condition_variable->mutex_addr) {
// Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify
// everything is correct
ASSERT(condition_variable->mutex_addr == mutex_addr);
} else {
// Previously created the ConditionVariable using SignalProcessWideKey, set the mutex
// associated with it
condition_variable->mutex_addr = mutex_addr;
}
if (mutex->GetOwnerHandle()) {
// Release the mutex if the current thread is holding it
mutex->Release(thread.get());
}
auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
SharedPtr<Thread> thread,
@@ -667,8 +679,6 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
CASCADE_CODE(
WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
mutex->Release(thread.get());
return RESULT_SUCCESS;
}
@@ -738,13 +748,14 @@ static ResultCode SetThreadCoreMask(u64, u64, u64) {
return RESULT_SUCCESS;
}
static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions,
static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions,
u32 remote_permissions) {
LOG_TRACE(Kernel_SVC, "called, sz=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", sz,
LOG_TRACE(Kernel_SVC, "called, size=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", size,
local_permissions, remote_permissions);
auto sharedMemHandle = SharedMemory::Create(
g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz,
(Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions);
auto sharedMemHandle =
SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
static_cast<MemoryPermission>(local_permissions),
static_cast<MemoryPermission>(remote_permissions));
CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));
return RESULT_SUCCESS;

View File

@@ -20,7 +20,7 @@ public:
private:
void GetBase(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_ACC, "(STUBBED) called");
ProfileBase profile_base{};
IPC::ResponseBuilder rb{ctx, 16};
rb.Push(RESULT_SUCCESS);
@@ -30,24 +30,32 @@ private:
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
public:
IManagerForApplication() : ServiceFramework("IProfile") {
IManagerForApplication() : ServiceFramework("IManagerForApplication") {
static const FunctionInfo functions[] = {
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
{1, &IManagerForApplication::GetAccountId, "GetAccountId"},
};
RegisterHandlers(functions);
}
private:
void CheckAvailability(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(true); // TODO: Check when this is supposed to return true and when not
}
void GetAccountId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0x12345678ABCDEF);
}
};
void ACC_U0::GetUserExistence(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(true); // TODO: Check when this is supposed to return true and when not
@@ -57,11 +65,11 @@ void ACC_U0::GetProfile(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IProfile>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_ACC, "called");
}
void ACC_U0::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -70,12 +78,21 @@ void ACC_U0::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx)
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IManagerForApplication>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_ACC, "called");
}
void ACC_U0::GetLastOpenedUser(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0x0);
rb.Push<u64>(0x0);
}
ACC_U0::ACC_U0() : ServiceFramework("acc:u0") {
static const FunctionInfo functions[] = {
{1, &ACC_U0::GetUserExistence, "GetUserExistence"},
{4, &ACC_U0::GetLastOpenedUser, "GetLastOpenedUser"},
{5, &ACC_U0::GetProfile, "GetProfile"},
{100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},

View File

@@ -28,6 +28,7 @@ public:
private:
void GetUserExistence(Kernel::HLERequestContext& ctx);
void GetLastOpenedUser(Kernel::HLERequestContext& ctx);
void GetProfile(Kernel::HLERequestContext& ctx);
void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);

View File

@@ -2,14 +2,347 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#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/nvflinger/nvflinger.h"
namespace Service {
namespace AM {
IWindowController::IWindowController() : ServiceFramework("IWindowController") {
static const FunctionInfo functions[] = {
{1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
{10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
};
RegisterHandlers(functions);
}
void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
}
void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
IAudioController::IAudioController() : ServiceFramework("IAudioController") {}
IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") {}
IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
: ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
static const FunctionInfo functions[] = {
{1, &ISelfController::LockExit, "LockExit"},
{2, &ISelfController::UnlockExit, "UnlockExit"},
{11, &ISelfController::SetOperationModeChangedNotification,
"SetOperationModeChangedNotification"},
{12, &ISelfController::SetPerformanceModeChangedNotification,
"SetPerformanceModeChangedNotification"},
{13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
{14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
{16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
{40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
};
RegisterHandlers(functions);
}
void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
// Takes 3 input u8s with each field located immediately after the previous u8, these are
// bool flags. No output.
IPC::RequestParser rp{ctx};
struct FocusHandlingModeParams {
u8 unknown0;
u8 unknown1;
u8 unknown2;
};
auto flags = rp.PopRaw<FocusHandlingModeParams>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
bool flag = rp.Pop<bool>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast<u32>(flag));
}
void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
bool flag = rp.Pop<bool>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast<u32>(flag));
}
void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
// Takes 3 input u8s with each field located immediately after the previous u8, these are
// bool flags. No output.
IPC::RequestParser rp{ctx};
bool enabled = rp.Pop<bool>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
}
void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
// TODO(Subv): Find out how AM determines the display to use, for now just create the layer
// in the Default display.
u64 display_id = nvflinger->OpenDisplay("Default");
u64 layer_id = nvflinger->CreateLayer(display_id);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push(layer_id);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
static const FunctionInfo functions[] = {
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
{1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
{5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
{6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
{9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
};
RegisterHandlers(functions);
event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
}
void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
event->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(15);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u8>(FocusState::InFocus));
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u8>(OperationMode::Handheld));
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
LOG_WARNING(Service_AM, "(STUBBED) called");
}
ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {}
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
public:
explicit IStorageAccessor(std::vector<u8> buffer)
: ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
static const FunctionInfo functions[] = {
{0, &IStorageAccessor::GetSize, "GetSize"},
{11, &IStorageAccessor::Read, "Read"},
};
RegisterHandlers(functions);
}
private:
std::vector<u8> buffer;
void GetSize(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u64>(buffer.size()));
LOG_DEBUG(Service_AM, "called");
}
void Read(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u64 offset = rp.Pop<u64>();
const auto& output_buffer = ctx.BufferDescriptorC()[0];
ASSERT(offset + output_buffer.Size() <= buffer.size());
Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_AM, "called");
}
};
class IStorage final : public ServiceFramework<IStorage> {
public:
explicit IStorage(std::vector<u8> buffer)
: ServiceFramework("IStorage"), buffer(std::move(buffer)) {
static const FunctionInfo functions[] = {
{0, &IStorage::Open, "Open"},
};
RegisterHandlers(functions);
}
private:
std::vector<u8> buffer;
void Open(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
LOG_DEBUG(Service_AM, "called");
}
};
IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
static const FunctionInfo functions[] = {
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
{21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
{22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
{66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
{67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
};
RegisterHandlers(functions);
}
void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
constexpr u8 data[0x88] = {
0xca, 0x97, 0x94, 0xc7, // Magic
1, 0, 0, 0, // IsAccountSelected (bool)
1, 0, 0, 0, // User Id (word 0)
0, 0, 0, 0, // User Id (word 1)
0, 0, 0, 0, // User Id (word 2)
0, 0, 0, 0 // User Id (word 3)
};
std::vector<u8> buffer(data, data + sizeof(data));
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<AM::IStorage>(buffer);
LOG_DEBUG(Service_AM, "called");
}
void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
// Takes an input u32 Result, no output.
// For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
IPC::RequestParser rp{ctx};
u32 result = rp.Pop<u32>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called, result=0x%08X", result);
}
void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(SystemLanguage::English);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
}

View File

@@ -7,6 +7,10 @@
#include <memory>
#include "core/hle/service/service.h"
namespace Kernel {
class Event;
}
namespace Service {
namespace NVFlinger {
class NVFlinger;
@@ -14,6 +18,95 @@ class NVFlinger;
namespace AM {
// TODO: Add more languages
enum SystemLanguage {
Japanese = 0,
English = 1,
};
class IWindowController final : public ServiceFramework<IWindowController> {
public:
IWindowController();
private:
void GetAppletResourceUserId(Kernel::HLERequestContext& ctx);
void AcquireForegroundRights(Kernel::HLERequestContext& ctx);
};
class IAudioController final : public ServiceFramework<IAudioController> {
public:
IAudioController();
};
class IDisplayController final : public ServiceFramework<IDisplayController> {
public:
IDisplayController();
};
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
public:
IDebugFunctions();
};
class ISelfController final : public ServiceFramework<ISelfController> {
public:
ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
private:
void SetFocusHandlingMode(Kernel::HLERequestContext& ctx);
void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx);
void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx);
void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx);
void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx);
void LockExit(Kernel::HLERequestContext& ctx);
void UnlockExit(Kernel::HLERequestContext& ctx);
void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
};
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
public:
ICommonStateGetter();
private:
enum class FocusState : u8 {
InFocus = 1,
NotInFocus = 2,
};
enum class OperationMode : u8 {
Handheld = 0,
Docked = 1,
};
void GetEventHandle(Kernel::HLERequestContext& ctx);
void ReceiveMessage(Kernel::HLERequestContext& ctx);
void GetCurrentFocusState(Kernel::HLERequestContext& ctx);
void GetOperationMode(Kernel::HLERequestContext& ctx);
void GetPerformanceMode(Kernel::HLERequestContext& ctx);
Kernel::SharedPtr<Kernel::Event> event;
};
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
public:
ILibraryAppletCreator();
};
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
public:
IApplicationFunctions();
private:
void PopLaunchParameter(Kernel::HLERequestContext& ctx);
void SetTerminateResult(Kernel::HLERequestContext& ctx);
void GetDesiredLanguage(Kernel::HLERequestContext& ctx);
void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx);
void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
void NotifyRunning(Kernel::HLERequestContext& ctx);
};
/// Registers all AM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger);

View File

@@ -0,0 +1,112 @@
// 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/am/am.h"
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/nvflinger/nvflinger.h"
namespace Service {
namespace AM {
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
public:
ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
: ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)) {
static const FunctionInfo functions[] = {
{0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
{1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"},
{2, &ILibraryAppletProxy::GetWindowController, "GetWindowController"},
{3, &ILibraryAppletProxy::GetAudioController, "GetAudioController"},
{4, &ILibraryAppletProxy::GetDisplayController, "GetDisplayController"},
{11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
{20, &ILibraryAppletProxy::GetApplicationFunctions, "GetApplicationFunctions"},
{1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
};
RegisterHandlers(functions);
}
private:
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>();
LOG_DEBUG(Service_AM, "called");
}
void GetSelfController(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISelfController>(nvflinger);
LOG_DEBUG(Service_AM, "called");
}
void GetWindowController(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IWindowController>();
LOG_DEBUG(Service_AM, "called");
}
void GetAudioController(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IAudioController>();
LOG_DEBUG(Service_AM, "called");
}
void GetDisplayController(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IDisplayController>();
LOG_DEBUG(Service_AM, "called");
}
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IDebugFunctions>();
LOG_DEBUG(Service_AM, "called");
}
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ILibraryAppletCreator>();
LOG_DEBUG(Service_AM, "called");
}
void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationFunctions>();
LOG_DEBUG(Service_AM, "called");
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
};
void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
LOG_DEBUG(Service_AM, "called");
}
AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
: ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) {
static const FunctionInfo functions[] = {
{100, nullptr, "OpenSystemAppletProxy"},
{200, &AppletAE::OpenLibraryAppletProxyOld, "OpenLibraryAppletProxyOld"},
{201, nullptr, "OpenLibraryAppletProxy"},
{300, nullptr, "OpenOverlayAppletProxy"},
{350, nullptr, "OpenSystemApplicationProxy"},
{400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
};
RegisterHandlers(functions);
}
} // namespace AM
} // namespace Service

View File

@@ -0,0 +1,30 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
namespace Service {
namespace NVFlinger {
class NVFlinger;
}
namespace AM {
class AppletAE final : public ServiceFramework<AppletAE> {
public:
AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
~AppletAE() = default;
private:
void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
};
} // namespace AM
} // namespace Service

View File

@@ -4,385 +4,13 @@
#include "common/logging/log.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_oe.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/nvflinger/nvflinger.h"
namespace Service {
namespace AM {
class IWindowController final : public ServiceFramework<IWindowController> {
public:
IWindowController() : ServiceFramework("IWindowController") {
static const FunctionInfo functions[] = {
{1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
{10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
};
RegisterHandlers(functions);
}
private:
void GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
}
void AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
};
class IAudioController final : public ServiceFramework<IAudioController> {
public:
IAudioController() : ServiceFramework("IAudioController") {}
};
class IDisplayController final : public ServiceFramework<IDisplayController> {
public:
IDisplayController() : ServiceFramework("IDisplayController") {}
};
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
public:
IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
};
class ISelfController final : public ServiceFramework<ISelfController> {
public:
ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
: ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
static const FunctionInfo functions[] = {
{1, &ISelfController::LockExit, "LockExit"},
{2, &ISelfController::UnlockExit, "UnlockExit"},
{11, &ISelfController::SetOperationModeChangedNotification,
"SetOperationModeChangedNotification"},
{12, &ISelfController::SetPerformanceModeChangedNotification,
"SetPerformanceModeChangedNotification"},
{13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
{14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
{16, &ISelfController::SetOutOfFocusSuspendingEnabled,
"SetOutOfFocusSuspendingEnabled"},
{40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
};
RegisterHandlers(functions);
}
private:
void SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
// Takes 3 input u8s with each field located immediately after the previous u8, these are
// bool flags. No output.
IPC::RequestParser rp{ctx};
struct FocusHandlingModeParams {
u8 unknown0;
u8 unknown1;
u8 unknown2;
};
auto flags = rp.PopRaw<FocusHandlingModeParams>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called");
}
void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called");
}
void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
bool flag = rp.Pop<bool>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
}
void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
bool flag = rp.Pop<bool>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
}
void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
// Takes 3 input u8s with each field located immediately after the previous u8, these are
// bool flags. No output.
IPC::RequestParser rp{ctx};
bool enabled = rp.Pop<bool>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
}
void LockExit(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called");
}
void UnlockExit(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called");
}
void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
// TODO(Subv): Find out how AM determines the display to use, for now just create the layer
// in the Default display.
u64 display_id = nvflinger->OpenDisplay("Default");
u64 layer_id = nvflinger->CreateLayer(display_id);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push(layer_id);
LOG_WARNING(Service, "(STUBBED) called");
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
};
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
public:
ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
static const FunctionInfo functions[] = {
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
{1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
{5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
{6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
{9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
};
RegisterHandlers(functions);
event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
}
private:
enum class FocusState : u8 {
InFocus = 1,
NotInFocus = 2,
};
enum class OperationMode : u8 {
Handheld = 0,
Docked = 1,
};
void GetEventHandle(Kernel::HLERequestContext& ctx) {
event->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event);
LOG_WARNING(Service, "(STUBBED) called");
}
void ReceiveMessage(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(15);
LOG_WARNING(Service, "(STUBBED) called");
}
void GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u8>(FocusState::InFocus));
LOG_WARNING(Service, "(STUBBED) called");
}
void GetOperationMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u8>(OperationMode::Handheld));
LOG_WARNING(Service, "(STUBBED) called");
}
void GetPerformanceMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
LOG_WARNING(Service, "(STUBBED) called");
}
Kernel::SharedPtr<Kernel::Event> event;
};
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
public:
explicit IStorageAccessor(std::vector<u8> buffer)
: ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
static const FunctionInfo functions[] = {
{0, &IStorageAccessor::GetSize, "GetSize"},
{11, &IStorageAccessor::Read, "Read"},
};
RegisterHandlers(functions);
}
private:
std::vector<u8> buffer;
void GetSize(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u64>(buffer.size()));
LOG_DEBUG(Service, "called");
}
void Read(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u64 offset = rp.Pop<u64>();
const auto& output_buffer = ctx.BufferDescriptorC()[0];
ASSERT(offset + output_buffer.Size() <= buffer.size());
Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service, "called");
}
};
class IStorage final : public ServiceFramework<IStorage> {
public:
explicit IStorage(std::vector<u8> buffer)
: ServiceFramework("IStorage"), buffer(std::move(buffer)) {
static const FunctionInfo functions[] = {
{0, &IStorage::Open, "Open"},
};
RegisterHandlers(functions);
}
private:
std::vector<u8> buffer;
void Open(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
LOG_DEBUG(Service, "called");
}
};
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
public:
IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
static const FunctionInfo functions[] = {
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
{21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
{22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
{66, &IApplicationFunctions::InitializeGamePlayRecording,
"InitializeGamePlayRecording"},
{67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
};
RegisterHandlers(functions);
}
private:
void PopLaunchParameter(Kernel::HLERequestContext& ctx) {
constexpr u8 data[0x88] = {
0xca, 0x97, 0x94, 0xc7, // Magic
1, 0, 0, 0, // IsAccountSelected (bool)
1, 0, 0, 0, // User Id (word 0)
0, 0, 0, 0, // User Id (word 1)
0, 0, 0, 0, // User Id (word 2)
0, 0, 0, 0 // User Id (word 3)
};
std::vector<u8> buffer(data, data + sizeof(data));
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<AM::IStorage>(buffer);
LOG_DEBUG(Service, "called");
}
void SetTerminateResult(Kernel::HLERequestContext& ctx) {
// Takes an input u32 Result, no output.
// For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
IPC::RequestParser rp{ctx};
u32 result = rp.Pop<u32>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);
}
void GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(SystemLanguage::English);
LOG_WARNING(Service, "(STUBBED) called");
}
void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called");
}
void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called");
}
void NotifyRunning(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
LOG_WARNING(Service, "(STUBBED) called");
}
};
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
public:
ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {}
};
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public:
IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
@@ -405,56 +33,56 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IAudioController>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
void GetDisplayController(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IDisplayController>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IDebugFunctions>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
void GetWindowController(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IWindowController>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
void GetSelfController(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISelfController>(nvflinger);
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ILibraryAppletCreator>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationFunctions>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
@@ -464,7 +92,7 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationProxy>(nvflinger);
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_AM, "called");
}
AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)

View File

@@ -15,12 +15,6 @@ class NVFlinger;
namespace AM {
// TODO: Add more languages
enum SystemLanguage {
Japanese = 0,
English = 1,
};
class AppletOE final : public ServiceFramework<AppletOE> {
public:
AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);

View File

@@ -33,7 +33,8 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode), config);
LOG_WARNING(Service_APM, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode),
config);
}
void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
@@ -45,7 +46,7 @@ private:
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0); // Performance configuration
LOG_WARNING(Service, "(STUBBED) called mode=%u", static_cast<u32>(mode));
LOG_WARNING(Service_APM, "(STUBBED) called mode=%u", static_cast<u32>(mode));
}
};

View File

@@ -49,7 +49,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(shared_mem);
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_HID, "called");
}
void LoadInputDevices() {
@@ -151,11 +151,37 @@ private:
buttons;
};
class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
public:
IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
static const FunctionInfo functions[] = {
{0, &IActiveVibrationDeviceList::ActivateVibrationDevice, "ActivateVibrationDevice"},
};
RegisterHandlers(functions);
}
private:
void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");
}
};
class Hid final : public ServiceFramework<Hid> {
public:
Hid() : ServiceFramework("hid") {
static const FunctionInfo functions[] = {
{0x00000000, &Hid::CreateAppletResource, "CreateAppletResource"},
{0, &Hid::CreateAppletResource, "CreateAppletResource"},
{1, &Hid::ActivateDebugPad, "ActivateDebugPad"},
{11, nullptr, "ActivateTouchScreen"},
{66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
{100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
{102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
{103, &Hid::ActivateNpad, "ActivateNpad"},
{120, nullptr, "SetNpadJoyHoldType"},
{124, nullptr, "SetNpadJoyAssignmentModeDual"},
{203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
};
RegisterHandlers(functions);
}
@@ -172,7 +198,44 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IAppletResource>(applet_resource);
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_HID, "called");
}
void ActivateDebugPad(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");
}
void StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");
}
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");
}
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");
}
void ActivateNpad(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_HID, "(STUBBED) called");
}
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IActiveVibrationDeviceList>();
LOG_DEBUG(Service_HID, "called");
}
};

View File

@@ -76,7 +76,7 @@ private:
addr += sizeof(MessageHeader);
if (!header.IsSingleMessage()) {
LOG_WARNING(Service, "Multi message logs are unimplemeneted");
LOG_WARNING(Service_LM, "Multi message logs are unimplemeneted");
return;
}
@@ -125,7 +125,7 @@ private:
if (line) {
output += std::to_string(line) + ':';
}
if (output.back() == ':') {
if (output.length() > 0 && output.back() == ':') {
output += ' ';
}
output += message;
@@ -150,7 +150,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<Logger>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_LM, "called");
}
LM::LM() : ServiceFramework("lm") {

View File

@@ -0,0 +1,161 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_a.h"
#include "core/hle/service/nifm/nifm_s.h"
#include "core/hle/service/nifm/nifm_u.h"
namespace Service {
namespace NIFM {
class IScanRequest final : public ServiceFramework<IScanRequest> {
public:
explicit IScanRequest() : ServiceFramework("IScanRequest") {
static const FunctionInfo functions[] = {
{0, nullptr, "Submit"},
{1, nullptr, "IsProcessing"},
{2, nullptr, "GetResult"},
{3, nullptr, "GetSystemEventReadableHandle"},
};
RegisterHandlers(functions);
}
};
class IRequest final : public ServiceFramework<IRequest> {
public:
explicit IRequest() : ServiceFramework("IRequest") {
static const FunctionInfo functions[] = {
{0, nullptr, "GetRequestState"},
{1, nullptr, "GetResult"},
{2, nullptr, "GetSystemEventReadableHandles"},
{3, nullptr, "Cancel"},
{4, nullptr, "Submit"},
{5, nullptr, "SetRequirement"},
{6, nullptr, "SetRequirementPreset"},
{8, nullptr, "SetPriority"},
{9, nullptr, "SetNetworkProfileId"},
{10, nullptr, "SetRejectable"},
{11, nullptr, "SetConnectionConfirmationOption"},
{12, nullptr, "SetPersistent"},
{13, nullptr, "SetInstant"},
{14, nullptr, "SetSustainable"},
{15, nullptr, "SetRawPriority"},
{16, nullptr, "SetGreedy"},
{17, nullptr, "SetSharable"},
{18, nullptr, "SetRequirementByRevision"},
{19, nullptr, "GetRequirement"},
{20, nullptr, "GetRevision"},
{21, nullptr, "GetAppletInfo"},
{22, nullptr, "GetAdditionalInfo"},
{23, nullptr, "SetKeptInSleep"},
{24, nullptr, "RegisterSocketDescriptor"},
{25, nullptr, "UnregisterSocketDescriptor"},
};
RegisterHandlers(functions);
}
};
class INetworkProfile final : public ServiceFramework<INetworkProfile> {
public:
explicit INetworkProfile() : ServiceFramework("INetworkProfile") {
static const FunctionInfo functions[] = {
{0, nullptr, "Update"},
{1, nullptr, "PersistOld"},
{2, nullptr, "Persist"},
};
RegisterHandlers(functions);
}
};
IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
static const FunctionInfo functions[] = {
{1, &IGeneralService::GetClientId, "GetClientId"},
{2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
{4, &IGeneralService::CreateRequest, "CreateRequest"},
{6, nullptr, "GetCurrentNetworkProfile"},
{7, nullptr, "EnumerateNetworkInterfaces"},
{8, nullptr, "GetNetworkProfile"},
{9, nullptr, "SetNetworkProfile"},
{10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
{11, nullptr, "GetScanDataOld"},
{12, nullptr, "GetCurrentIpAddress"},
{13, nullptr, "GetCurrentAccessPointOld"},
{14, &IGeneralService::CreateTemporaryNetworkProfile, "CreateTemporaryNetworkProfile"},
{15, nullptr, "GetCurrentIpConfigInfo"},
{16, nullptr, "SetWirelessCommunicationEnabled"},
{17, nullptr, "IsWirelessCommunicationEnabled"},
{18, nullptr, "GetInternetConnectionStatus"},
{19, nullptr, "SetEthernetCommunicationEnabled"},
{20, nullptr, "IsEthernetCommunicationEnabled"},
{21, nullptr, "IsAnyInternetRequestAccepted"},
{22, nullptr, "IsAnyForegroundRequestAccepted"},
{23, nullptr, "PutToSleep"},
{24, nullptr, "WakeUp"},
{25, nullptr, "GetSsidListVersion"},
{26, nullptr, "SetExclusiveClient"},
{27, nullptr, "GetDefaultIpSetting"},
{28, nullptr, "SetDefaultIpSetting"},
{29, nullptr, "SetWirelessCommunicationEnabledForTest"},
{30, nullptr, "SetEthernetCommunicationEnabledForTest"},
{31, nullptr, "GetTelemetorySystemEventReadableHandle"},
{32, nullptr, "GetTelemetryInfo"},
{33, nullptr, "ConfirmSystemAvailability"},
{34, nullptr, "SetBackgroundRequestEnabled"},
{35, nullptr, "GetScanData"},
{36, nullptr, "GetCurrentAccessPoint"},
{37, nullptr, "Shutdown"},
};
RegisterHandlers(functions);
}
void IGeneralService::GetClientId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
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 IGeneralService::CreateRequest(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IRequest>();
LOG_DEBUG(Service_NIFM, "called");
}
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) {
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
} // namespace Service

View File

@@ -0,0 +1,27 @@
// 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 NIFM {
class IGeneralService final : public ServiceFramework<IGeneralService> {
public:
IGeneralService();
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);
} // namespace NIFM
} // namespace Service

View File

@@ -0,0 +1,36 @@
// 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/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_a.h"
namespace Service {
namespace NIFM {
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"},
};
RegisterHandlers(functions);
}
} // namespace NIFM
} // namespace Service

View File

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

View File

@@ -0,0 +1,36 @@
// 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/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_s.h"
namespace Service {
namespace NIFM {
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"},
};
RegisterHandlers(functions);
}
} // namespace NIFM
} // namespace Service

View File

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

View File

@@ -0,0 +1,36 @@
// 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/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_u.h"
namespace Service {
namespace NIFM {
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"},
};
RegisterHandlers(functions);
}
} // namespace NIFM
} // namespace Service

View File

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

View File

@@ -52,7 +52,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
u32 handle = next_handle++;
handles[handle] = std::move(object);
LOG_WARNING(Service, "(STUBBED) size 0x%08X", params.size);
LOG_WARNING(Service_NVDRV, "(STUBBED) size 0x%08X", params.size);
params.handle = handle;
@@ -74,7 +74,7 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
object->addr = params.addr;
object->status = Object::Status::Allocated;
LOG_WARNING(Service, "(STUBBED) Allocated address 0x%llx", params.addr);
LOG_WARNING(Service_NVDRV, "(STUBBED) Allocated address 0x%llx", params.addr);
std::memcpy(output.data(), &params, sizeof(params));
return 0;
@@ -84,7 +84,7 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
IocGetIdParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_WARNING(Service, "called");
LOG_WARNING(Service_NVDRV, "called");
auto itr = handles.find(params.handle);
ASSERT(itr != handles.end());
@@ -99,7 +99,7 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
IocFromIdParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
auto itr = std::find_if(handles.begin(), handles.end(),
[&](const auto& entry) { return entry.second->id == params.id; });
@@ -121,7 +121,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
IocParamParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_WARNING(Service, "(STUBBED) called type=%u", params.type);
LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type);
auto itr = handles.find(params.handle);
ASSERT(itr != handles.end());

View File

@@ -11,7 +11,7 @@ namespace Service {
namespace Nvidia {
void NVDRV::Open(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
auto buffer = ctx.BufferDescriptorA()[0];
@@ -25,7 +25,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {
}
void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u32 fd = rp.Pop<u32>();
@@ -49,7 +49,7 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
}
void NVDRV::Close(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u32 fd = rp.Pop<u32>();
@@ -61,7 +61,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) {
}
void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0);
@@ -71,7 +71,7 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
pid = rp.Pop<u64>();
LOG_INFO(Service, "called, pid=0x%lx", pid);
LOG_INFO(Service_NVDRV, "called, pid=0x%lx", pid);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0);

View File

@@ -14,6 +14,7 @@ namespace NVFlinger {
BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {
native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle");
native_handle->Signal();
}
void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {

View File

@@ -18,7 +18,7 @@ void PCTL_A::GetService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IParentalControlService>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_PCTL, "called");
}
PCTL_A::PCTL_A() : ServiceFramework("pctl:a") {

View File

@@ -22,6 +22,7 @@
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/lm/lm.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/pctl/pctl.h"
#include "core/hle/service/service.h"
@@ -180,6 +181,7 @@ void Init() {
FileSystem::InstallInterfaces(*SM::g_service_manager);
HID::InstallInterfaces(*SM::g_service_manager);
LM::InstallInterfaces(*SM::g_service_manager);
NIFM::InstallInterfaces(*SM::g_service_manager);
Nvidia::InstallInterfaces(*SM::g_service_manager);
PCTL::InstallInterfaces(*SM::g_service_manager);
Sockets::InstallInterfaces(*SM::g_service_manager);

View File

@@ -13,18 +13,19 @@ namespace Service {
namespace Set {
void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u32 id = rp.Pop<u32>();
constexpr std::array<u8, 13> lang_codes{};
const auto& output_buffer = ctx.BufferDescriptorC()[0];
Memory::WriteBlock(output_buffer.Address(), lang_codes.data(), lang_codes.size());
IPC::ResponseBuilder rb{ctx, 4};
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u64>(lang_codes.size()));
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_SET, "(STUBBED) called");
}
SET::SET(const char* name) : ServiceFramework(name) {

View File

@@ -4,6 +4,7 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/session.h"
#include "core/hle/service/sm/controller.h"
namespace Service {
@@ -21,17 +22,21 @@ void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) {
}
void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
// TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong
// and that we probably want to actually make an entirely new Session, but we still need to
// verify this on hardware.
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
rb.Push(RESULT_SUCCESS);
rb.PushMoveObjects(ctx.Session());
Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client};
rb.PushMoveObjects(session);
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service, "called, session=%u", session->GetObjectId());
}
void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) {
DuplicateSession(ctx);
LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession");
DuplicateSession(ctx);
}
void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) {

View File

@@ -29,14 +29,14 @@ private:
const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch())
.count()};
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_Time, "called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(time_since_epoch);
}
void GetSystemClockContext(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_Time, "(STUBBED) called");
SystemClockContext system_clock_ontext{};
IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2};
rb.Push(RESULT_SUCCESS);
@@ -55,7 +55,7 @@ public:
private:
void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_Time, "called");
SteadyClockTimePoint steady_clock_time_point{cyclesToMs(CoreTiming::GetTicks()) / 1000};
IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2};
rb.Push(RESULT_SUCCESS);
@@ -76,7 +76,7 @@ public:
private:
void GetDeviceLocationName(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_Time, "(STUBBED) called");
LocationName location_name{};
IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2};
rb.Push(RESULT_SUCCESS);
@@ -84,7 +84,7 @@ private:
}
void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_Time, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0);
@@ -94,7 +94,7 @@ private:
IPC::RequestParser rp{ctx};
u64 posix_time = rp.Pop<u64>();
LOG_WARNING(Service, "(STUBBED) called, posix_time=0x%016llX", 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{};
@@ -109,28 +109,28 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISystemClock>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_Time, "called");
}
void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISystemClock>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_Time, "called");
}
void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISteadyClock>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_Time, "called");
}
void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ITimeZoneService>();
LOG_DEBUG(Service, "called");
LOG_DEBUG(Service_Time, "called");
}
Module::Interface::Interface(std::shared_ptr<Module> time, const char* name)

View File

@@ -11,6 +11,8 @@
#include "core/hle/service/nvflinger/buffer_queue.h"
#include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_m.h"
#include "core/hle/service/vi/vi_s.h"
#include "core/hle/service/vi/vi_u.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
@@ -427,7 +429,7 @@ private:
auto& output_buffer = ctx.BufferDescriptorB()[0];
auto buffer_queue = nv_flinger->GetBufferQueue(id);
LOG_WARNING(Service_VI, "(STUBBED) called, transaction=%x", transaction);
if (transaction == TransactionId::Connect) {
IGBPConnectRequestParcel request{input_data};
IGBPConnectResponseParcel response{1280, 720};
@@ -485,7 +487,6 @@ private:
ASSERT_MSG(false, "Unimplemented");
}
LOG_WARNING(Service, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -496,7 +497,7 @@ private:
s32 addval = rp.PopRaw<s32>();
u32 type = rp.Pop<u32>();
LOG_WARNING(Service, "(STUBBED) called id=%u, addval=%08X, type=%08X", id, addval, type);
LOG_WARNING(Service_VI, "(STUBBED) called id=%u, addval=%08X, type=%08X", id, addval, type);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -510,7 +511,7 @@ private:
// TODO(Subv): Find out what this actually is.
LOG_WARNING(Service, "(STUBBED) called id=%u, unknown=%08X", id, unknown);
LOG_WARNING(Service_VI, "(STUBBED) called id=%u, unknown=%08X", id, unknown);
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(buffer_queue->GetNativeHandle());
@@ -532,7 +533,7 @@ public:
private:
void SetLayerZ(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u64 layer_id = rp.Pop<u64>();
u64 z_value = rp.Pop<u64>();
@@ -558,7 +559,7 @@ public:
private:
void CloseDisplay(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u64 display = rp.Pop<u64>();
@@ -567,7 +568,7 @@ private:
}
void CreateManagedLayer(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u32 unknown = rp.Pop<u32>();
rp.Skip(1, false);
@@ -582,7 +583,7 @@ private:
}
void AddToLayerStack(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u32 stack = rp.Pop<u32>();
u64 layer_id = rp.Pop<u64>();
@@ -595,7 +596,7 @@ private:
};
void IApplicationDisplayService::GetRelayService(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
@@ -603,7 +604,7 @@ void IApplicationDisplayService::GetRelayService(Kernel::HLERequestContext& ctx)
}
void IApplicationDisplayService::GetSystemDisplayService(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
@@ -611,7 +612,7 @@ void IApplicationDisplayService::GetSystemDisplayService(Kernel::HLERequestConte
}
void IApplicationDisplayService::GetManagerDisplayService(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
@@ -620,7 +621,7 @@ void IApplicationDisplayService::GetManagerDisplayService(Kernel::HLERequestCont
void IApplicationDisplayService::GetIndirectDisplayTransactionService(
Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
@@ -628,7 +629,7 @@ void IApplicationDisplayService::GetIndirectDisplayTransactionService(
}
void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
auto name_buf = rp.PopRaw<std::array<u8, 0x40>>();
auto end = std::find(name_buf.begin(), name_buf.end(), '\0');
@@ -643,7 +644,7 @@ void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) {
}
void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u64 display_id = rp.Pop<u64>();
@@ -652,7 +653,7 @@ void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) {
}
void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
auto name_buf = rp.PopRaw<std::array<u8, 0x40>>();
auto end = std::find(name_buf.begin(), name_buf.end(), '\0');
@@ -702,7 +703,7 @@ void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx
}
void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u64 layer_id = rp.Pop<u64>();
@@ -712,7 +713,7 @@ void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ct
}
void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u32 scaling_mode = rp.Pop<u32>();
u64 unknown = rp.Pop<u64>();
@@ -722,7 +723,7 @@ void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext&
}
void IApplicationDisplayService::GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u64 display_id = rp.Pop<u64>();
@@ -757,6 +758,8 @@ IApplicationDisplayService::IApplicationDisplayService(
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) {
std::make_shared<VI_M>(nv_flinger)->InstallAsService(service_manager);
std::make_shared<VI_S>(nv_flinger)->InstallAsService(service_manager);
std::make_shared<VI_U>(nv_flinger)->InstallAsService(service_manager);
}
} // namespace VI

View File

@@ -11,7 +11,7 @@ namespace Service {
namespace VI {
void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);

View File

@@ -0,0 +1,31 @@
// 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/vi/vi.h"
#include "core/hle/service/vi/vi_s.h"
namespace Service {
namespace VI {
void VI_S::GetDisplayService(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger);
}
VI_S::VI_S(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
: ServiceFramework("vi:s"), nv_flinger(std::move(nv_flinger)) {
static const FunctionInfo functions[] = {
{1, &VI_S::GetDisplayService, "GetDisplayService"},
{3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
};
RegisterHandlers(functions);
}
} // namespace VI
} // namespace Service

View File

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

View File

@@ -0,0 +1,31 @@
// 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/vi/vi.h"
#include "core/hle/service/vi/vi_u.h"
namespace Service {
namespace VI {
void VI_U::GetDisplayService(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_VI, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger);
}
VI_U::VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger)
: ServiceFramework("vi:u"), nv_flinger(std::move(nv_flinger)) {
static const FunctionInfo functions[] = {
{0, &VI_U::GetDisplayService, "GetDisplayService"},
{3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
};
RegisterHandlers(functions);
}
} // namespace VI
} // namespace Service

View File

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