time: Implement GetSharedMemoryNativeHandle (#705)

- Implement Time SharedMemory
- Implement GetSharedMemoryNativeHandle
- Cleanup IStaticService
This commit is contained in:
Ac_K 2019-06-17 01:56:46 +02:00 committed by Thomas Guillemard
parent 70bfc01e5f
commit 3db9daa3bd
2 changed files with 52 additions and 7 deletions

View file

@ -32,6 +32,7 @@ namespace Ryujinx.HLE.HOS
internal const int HidSize = 0x40000; internal const int HidSize = 0x40000;
internal const int FontSize = 0x1100000; internal const int FontSize = 0x1100000;
internal const int IirsSize = 0x8000; internal const int IirsSize = 0x8000;
internal const int TimeSize = 0x1000;
private const int MemoryBlockAllocatorSize = 0x2710; private const int MemoryBlockAllocatorSize = 0x2710;
@ -84,6 +85,7 @@ namespace Ryujinx.HLE.HOS
internal KSharedMemory HidSharedMem { get; private set; } internal KSharedMemory HidSharedMem { get; private set; }
internal KSharedMemory FontSharedMem { get; private set; } internal KSharedMemory FontSharedMem { get; private set; }
internal KSharedMemory IirsSharedMem { get; private set; } internal KSharedMemory IirsSharedMem { get; private set; }
internal KSharedMemory TimeSharedMem { get; private set; }
internal SharedFontManager Font { get; private set; } internal SharedFontManager Font { get; private set; }
@ -161,20 +163,24 @@ namespace Ryujinx.HLE.HOS
ulong hidPa = region.Address; ulong hidPa = region.Address;
ulong fontPa = region.Address + HidSize; ulong fontPa = region.Address + HidSize;
ulong iirsPa = region.Address + HidSize + FontSize; ulong iirsPa = region.Address + HidSize + FontSize;
ulong timePa = region.Address + HidSize + FontSize + IirsSize;
HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase); HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);
KPageList hidPageList = new KPageList(); KPageList hidPageList = new KPageList();
KPageList fontPageList = new KPageList(); KPageList fontPageList = new KPageList();
KPageList iirsPageList = new KPageList(); KPageList iirsPageList = new KPageList();
KPageList timePageList = new KPageList();
hidPageList .AddRange(hidPa, HidSize / KMemoryManager.PageSize); hidPageList .AddRange(hidPa, HidSize / KMemoryManager.PageSize);
fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize); fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize);
iirsPageList.AddRange(iirsPa, IirsSize / KMemoryManager.PageSize); iirsPageList.AddRange(iirsPa, IirsSize / KMemoryManager.PageSize);
timePageList.AddRange(timePa, TimeSize / KMemoryManager.PageSize);
HidSharedMem = new KSharedMemory(this, hidPageList, 0, 0, MemoryPermission.Read); HidSharedMem = new KSharedMemory(this, hidPageList, 0, 0, MemoryPermission.Read);
FontSharedMem = new KSharedMemory(this, fontPageList, 0, 0, MemoryPermission.Read); FontSharedMem = new KSharedMemory(this, fontPageList, 0, 0, MemoryPermission.Read);
IirsSharedMem = new KSharedMemory(this, iirsPageList, 0, 0, MemoryPermission.Read); IirsSharedMem = new KSharedMemory(this, iirsPageList, 0, 0, MemoryPermission.Read);
TimeSharedMem = new KSharedMemory(this, timePageList, 0, 0, MemoryPermission.Read);
AppletState = new AppletStateMgr(this); AppletState = new AppletStateMgr(this);
@ -676,4 +682,4 @@ namespace Ryujinx.HLE.HOS
} }
} }
} }
} }

View file

@ -1,4 +1,5 @@
using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -6,6 +7,8 @@ namespace Ryujinx.HLE.HOS.Services.Time
{ {
class IStaticService : IpcService class IStaticService : IpcService
{ {
private int _timeSharedMemoryNativeHandle = 0;
private Dictionary<int, ServiceProcessRequest> _commands; private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands; public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
@ -16,15 +19,30 @@ namespace Ryujinx.HLE.HOS.Services.Time
{ {
_commands = new Dictionary<int, ServiceProcessRequest> _commands = new Dictionary<int, ServiceProcessRequest>
{ {
{ 0, GetStandardUserSystemClock }, { 0, GetStandardUserSystemClock },
{ 1, GetStandardNetworkSystemClock }, { 1, GetStandardNetworkSystemClock },
{ 2, GetStandardSteadyClock }, { 2, GetStandardSteadyClock },
{ 3, GetTimeZoneService }, { 3, GetTimeZoneService },
{ 4, GetStandardLocalSystemClock }, { 4, GetStandardLocalSystemClock },
{ 300, CalculateMonotonicSystemClockBaseTimePoint } //{ 5, GetEphemeralNetworkSystemClock }, // 4.0.0+
{ 20, GetSharedMemoryNativeHandle }, // 6.0.0+
//{ 30, GetStandardNetworkClockOperationEventReadableHandle }, // 6.0.0+
//{ 31, GetEphemeralNetworkClockOperationEventReadableHandle }, // 6.0.0+
//{ 50, SetStandardSteadyClockInternalOffset }, // 4.0.0+
//{ 100, IsStandardUserSystemClockAutomaticCorrectionEnabled },
//{ 101, SetStandardUserSystemClockAutomaticCorrectionEnabled },
//{ 102, GetStandardUserSystemClockInitialYear }, // 5.0.0+
//{ 200, IsStandardNetworkSystemClockAccuracySufficient }, // 3.0.0+
//{ 201, GetStandardUserSystemClockAutomaticCorrectionUpdatedTime }, // 6.0.0+
{ 300, CalculateMonotonicSystemClockBaseTimePoint }, // 4.0.0+
//{ 400, GetClockSnapshot }, // 4.0.0+
//{ 401, GetClockSnapshotFromSystemClockContext }, // 4.0.0+
//{ 500, CalculateStandardUserSystemClockDifferenceByUser }, // 4.0.0+
//{ 501, CalculateSpanBetween }, // 4.0.0+
}; };
} }
// GetStandardUserSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
public long GetStandardUserSystemClock(ServiceCtx context) public long GetStandardUserSystemClock(ServiceCtx context)
{ {
MakeObject(context, new ISystemClock(SystemClockType.User)); MakeObject(context, new ISystemClock(SystemClockType.User));
@ -32,6 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0; return 0;
} }
// GetStandardNetworkSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
public long GetStandardNetworkSystemClock(ServiceCtx context) public long GetStandardNetworkSystemClock(ServiceCtx context)
{ {
MakeObject(context, new ISystemClock(SystemClockType.Network)); MakeObject(context, new ISystemClock(SystemClockType.Network));
@ -39,6 +58,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0; return 0;
} }
// GetStandardSteadyClock() -> object<nn::timesrv::detail::service::ISteadyClock>
public long GetStandardSteadyClock(ServiceCtx context) public long GetStandardSteadyClock(ServiceCtx context)
{ {
MakeObject(context, new ISteadyClock()); MakeObject(context, new ISteadyClock());
@ -46,6 +66,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0; return 0;
} }
// GetTimeZoneService() -> object<nn::timesrv::detail::service::ITimeZoneService>
public long GetTimeZoneService(ServiceCtx context) public long GetTimeZoneService(ServiceCtx context)
{ {
MakeObject(context, new ITimeZoneService()); MakeObject(context, new ITimeZoneService());
@ -53,6 +74,7 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0; return 0;
} }
// GetStandardLocalSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
public long GetStandardLocalSystemClock(ServiceCtx context) public long GetStandardLocalSystemClock(ServiceCtx context)
{ {
MakeObject(context, new ISystemClock(SystemClockType.Local)); MakeObject(context, new ISystemClock(SystemClockType.Local));
@ -60,6 +82,23 @@ namespace Ryujinx.HLE.HOS.Services.Time
return 0; return 0;
} }
// GetSharedMemoryNativeHandle() -> handle<copy>
public long GetSharedMemoryNativeHandle(ServiceCtx context)
{
if (_timeSharedMemoryNativeHandle == 0)
{
if (context.Process.HandleTable.GenerateHandle(context.Device.System.TimeSharedMem, out _timeSharedMemoryNativeHandle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_timeSharedMemoryNativeHandle);
return 0;
}
// CalculateMonotonicSystemClockBaseTimePoint(nn::time::SystemClockContext) -> u64
public long CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context) public long CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context)
{ {
long timeOffset = (long)(DateTime.UtcNow - StartupDate).TotalSeconds; long timeOffset = (long)(DateTime.UtcNow - StartupDate).TotalSeconds;