diff options
| author | emmauss <emmausssss@gmail.com> | 2018-02-20 22:09:23 +0200 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-02-20 17:09:23 -0300 |
| commit | 62b827f474f0aa2152dd339fcc7cf31084e16a0b (patch) | |
| tree | 0e5c55b341aee4db0ccb841a084f253ec5e05657 /Ryujinx.Core/OsHle/Services | |
| parent | cb665bb715834526d73c9469d16114b287faaecd (diff) | |
Split main project into core,graphics and chocolarm4 subproject (#29)
Diffstat (limited to 'Ryujinx.Core/OsHle/Services')
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceAcc.cs | 33 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceApm.cs | 16 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceAppletOE.cs | 16 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceAud.cs | 71 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceFriend.cs | 16 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceFspSrv.cs | 49 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceHid.cs | 56 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceLm.cs | 12 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceNvDrv.cs | 610 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServicePctl.cs | 16 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServicePl.cs | 35 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceSet.cs | 32 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceSm.cs | 48 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceTime.cs | 45 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/ServiceVi.cs | 18 |
15 files changed, 1073 insertions, 0 deletions
diff --git a/Ryujinx.Core/OsHle/Services/ServiceAcc.cs b/Ryujinx.Core/OsHle/Services/ServiceAcc.cs new file mode 100644 index 00000000..f25113e5 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceAcc.cs @@ -0,0 +1,33 @@ +using Ryujinx.Core.OsHle.Objects.Acc; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long AccU0ListOpenUsers(ServiceCtx Context) + { + return 0; + } + + public static long AccU0GetProfile(ServiceCtx Context) + { + MakeObject(Context, new IProfile()); + + return 0; + } + + public static long AccU0InitializeApplicationInfo(ServiceCtx Context) + { + return 0; + } + + public static long AccU0GetBaasAccountManagerForApplication(ServiceCtx Context) + { + MakeObject(Context, new IManagerForApplication()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceApm.cs b/Ryujinx.Core/OsHle/Services/ServiceApm.cs new file mode 100644 index 00000000..e1bc0d34 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceApm.cs @@ -0,0 +1,16 @@ +using Ryujinx.Core.OsHle.Objects.Apm; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long ApmOpenSession(ServiceCtx Context) + { + MakeObject(Context, new ISession()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceAppletOE.cs b/Ryujinx.Core/OsHle/Services/ServiceAppletOE.cs new file mode 100644 index 00000000..bbb2484b --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceAppletOE.cs @@ -0,0 +1,16 @@ +using Ryujinx.Core.OsHle.Objects.Am; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long AppletOpenApplicationProxy(ServiceCtx Context) + { + MakeObject(Context, new IApplicationProxy()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceAud.cs b/Ryujinx.Core/OsHle/Services/ServiceAud.cs new file mode 100644 index 00000000..a8ba7dc0 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceAud.cs @@ -0,0 +1,71 @@ +using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Objects.Aud; +using System.Text; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long AudOutListAudioOuts(ServiceCtx Context) + { + long Position = Context.Request.ReceiveBuff[0].Position; + + AMemoryHelper.WriteBytes(Context.Memory, Position, Encoding.ASCII.GetBytes("iface")); + + Context.ResponseData.Write(1); + + return 0; + } + + public static long AudOutOpenAudioOut(ServiceCtx Context) + { + MakeObject(Context, new IAudioOut()); + + Context.ResponseData.Write(48000); //Sample Rate + Context.ResponseData.Write(2); //Channel Count + Context.ResponseData.Write(2); //PCM Format + /* + 0 - Invalid + 1 - INT8 + 2 - INT16 + 3 - INT24 + 4 - INT32 + 5 - PCM Float + 6 - ADPCM + */ + Context.ResponseData.Write(0); //Unknown + + return 0; + } + + public static long AudRenOpenAudioRenderer(ServiceCtx Context) + { + MakeObject(Context, new IAudioRenderer()); + + return 0; + } + + public static long AudRenGetAudioRendererWorkBufferSize(ServiceCtx Context) + { + int SampleRate = Context.RequestData.ReadInt32(); + int Unknown4 = Context.RequestData.ReadInt32(); + int Unknown8 = Context.RequestData.ReadInt32(); + int UnknownC = Context.RequestData.ReadInt32(); + int Unknown10 = Context.RequestData.ReadInt32(); + int Unknown14 = Context.RequestData.ReadInt32(); + int Unknown18 = Context.RequestData.ReadInt32(); + int Unknown1c = Context.RequestData.ReadInt32(); + int Unknown20 = Context.RequestData.ReadInt32(); + int Unknown24 = Context.RequestData.ReadInt32(); + int Unknown28 = Context.RequestData.ReadInt32(); + int Unknown2c = Context.RequestData.ReadInt32(); + int Rev1Magic = Context.RequestData.ReadInt32(); + + Context.ResponseData.Write(0x400L); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceFriend.cs b/Ryujinx.Core/OsHle/Services/ServiceFriend.cs new file mode 100644 index 00000000..d1229bd4 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceFriend.cs @@ -0,0 +1,16 @@ +using Ryujinx.Core.OsHle.Objects.Friend; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long FriendCreateFriendService(ServiceCtx Context) + { + MakeObject(Context, new IFriendService()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceFspSrv.cs b/Ryujinx.Core/OsHle/Services/ServiceFspSrv.cs new file mode 100644 index 00000000..3fe41cf0 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceFspSrv.cs @@ -0,0 +1,49 @@ +using Ryujinx.Core.OsHle.Objects.FspSrv; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long FspSrvInitialize(ServiceCtx Context) + { + return 0; + } + + public static long FspSrvMountSdCard(ServiceCtx Context) + { + MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetSdCardPath())); + + return 0; + } + + public static long FspSrvMountSaveData(ServiceCtx Context) + { + MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetGameSavesPath())); + + return 0; + } + + public static long FspSrvOpenDataStorageByCurrentProcess(ServiceCtx Context) + { + MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs)); + + return 0; + } + + public static long FspSrvOpenRomStorage(ServiceCtx Context) + { + MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs)); + + return 0; + } + + public static long FspSrvGetGlobalAccessLogMode(ServiceCtx Context) + { + Context.ResponseData.Write(0); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceHid.cs b/Ryujinx.Core/OsHle/Services/ServiceHid.cs new file mode 100644 index 00000000..4b2e82ff --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceHid.cs @@ -0,0 +1,56 @@ +using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.Objects.Hid; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long HidCreateAppletResource(ServiceCtx Context) + { + HSharedMem HidHndData = Context.Ns.Os.Handles.GetData<HSharedMem>(Context.Ns.Os.HidHandle); + + MakeObject(Context, new IAppletResource(HidHndData)); + + return 0; + } + + public static long HidActivateTouchScreen(ServiceCtx Context) + { + long Unknown = Context.RequestData.ReadInt64(); + + return 0; + } + + public static long HidSetSupportedNpadStyleSet(ServiceCtx Context) + { + long Unknown0 = Context.RequestData.ReadInt64(); + long Unknown8 = Context.RequestData.ReadInt64(); + + return 0; + } + + public static long HidSetSupportedNpadIdType(ServiceCtx Context) + { + long Unknown = Context.RequestData.ReadInt64(); + + return 0; + } + + public static long HidActivateNpad(ServiceCtx Context) + { + long Unknown = Context.RequestData.ReadInt64(); + + return 0; + } + + public static long HidSetNpadJoyHoldType(ServiceCtx Context) + { + long Unknown0 = Context.RequestData.ReadInt64(); + long Unknown8 = Context.RequestData.ReadInt64(); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceLm.cs b/Ryujinx.Core/OsHle/Services/ServiceLm.cs new file mode 100644 index 00000000..1fdde552 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceLm.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long LmInitialize(ServiceCtx Context) + { + Context.Session.Initialize(); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/ServiceNvDrv.cs new file mode 100644 index 00000000..6c5fdaed --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceNvDrv.cs @@ -0,0 +1,610 @@ +using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.Ipc; +using Ryujinx.Core.OsHle.Utilities; +using Ryujinx.Graphics.Gpu; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + private delegate long ServiceProcessRequest(ServiceCtx Context); + + private static Dictionary<(string, int), ServiceProcessRequest> IoctlCmds = + new Dictionary<(string, int), ServiceProcessRequest>() + { + { ("/dev/nvhost-as-gpu", 0x4101), NvGpuAsIoctlBindChannel }, + { ("/dev/nvhost-as-gpu", 0x4102), NvGpuAsIoctlAllocSpace }, + { ("/dev/nvhost-as-gpu", 0x4106), NvGpuAsIoctlMapBufferEx }, + { ("/dev/nvhost-as-gpu", 0x4108), NvGpuAsIoctlGetVaRegions }, + { ("/dev/nvhost-as-gpu", 0x4109), NvGpuAsIoctlInitializeEx }, + { ("/dev/nvhost-ctrl", 0x001b), NvHostIoctlCtrlGetConfig }, + { ("/dev/nvhost-ctrl", 0x001d), NvHostIoctlCtrlEventWait }, + { ("/dev/nvhost-ctrl-gpu", 0x4701), NvGpuIoctlZcullGetCtxSize }, + { ("/dev/nvhost-ctrl-gpu", 0x4702), NvGpuIoctlZcullGetInfo }, + { ("/dev/nvhost-ctrl-gpu", 0x4705), NvGpuIoctlGetCharacteristics }, + { ("/dev/nvhost-ctrl-gpu", 0x4706), NvGpuIoctlGetTpcMasks }, + { ("/dev/nvhost-ctrl-gpu", 0x4714), NvGpuIoctlZbcGetActiveSlotMask }, + { ("/dev/nvhost-gpu", 0x4714), NvMapIoctlChannelSetUserData }, + { ("/dev/nvhost-gpu", 0x4801), NvMapIoctlChannelSetNvMap }, + { ("/dev/nvhost-gpu", 0x4808), NvMapIoctlChannelSubmitGpFifo }, + { ("/dev/nvhost-gpu", 0x4809), NvMapIoctlChannelAllocObjCtx }, + { ("/dev/nvhost-gpu", 0x480b), NvMapIoctlChannelZcullBind }, + { ("/dev/nvhost-gpu", 0x480c), NvMapIoctlChannelSetErrorNotifier }, + { ("/dev/nvhost-gpu", 0x480d), NvMapIoctlChannelSetPriority }, + { ("/dev/nvhost-gpu", 0x481a), NvMapIoctlChannelAllocGpFifoEx2 }, + { ("/dev/nvmap", 0x0101), NvMapIocCreate }, + { ("/dev/nvmap", 0x0103), NvMapIocFromId }, + { ("/dev/nvmap", 0x0104), NvMapIocAlloc }, + { ("/dev/nvmap", 0x0109), NvMapIocParam }, + { ("/dev/nvmap", 0x010e), NvMapIocGetId }, + }; + + public static long NvDrvOpen(ServiceCtx Context) + { + long NamePtr = Context.Request.SendBuff[0].Position; + + string Name = AMemoryHelper.ReadAsciiString(Context.Memory, NamePtr); + + int Fd = Context.Ns.Os.Fds.GenerateId(new FileDesc(Name)); + + Context.ResponseData.Write(Fd); + Context.ResponseData.Write(0); + + return 0; + } + + public static long NvDrvIoctl(ServiceCtx Context) + { + int Fd = Context.RequestData.ReadInt32(); + int Cmd = Context.RequestData.ReadInt32() & 0xffff; + + FileDesc FdData = Context.Ns.Os.Fds.GetData<FileDesc>(Fd); + + long Position = Context.Request.PtrBuff[0].Position; + + Context.ResponseData.Write(0); + + if (IoctlCmds.TryGetValue((FdData.Name, Cmd), out ServiceProcessRequest ProcReq)) + { + return ProcReq(Context); + } + else + { + throw new NotImplementedException($"{FdData.Name} {Cmd:x4}"); + } + } + + public static long NvDrvClose(ServiceCtx Context) + { + int Fd = Context.RequestData.ReadInt32(); + + Context.Ns.Os.Fds.Delete(Fd); + + Context.ResponseData.Write(0); + + return 0; + } + + public static long NvDrvInitialize(ServiceCtx Context) + { + long TransferMemSize = Context.RequestData.ReadInt64(); + int TransferMemHandle = Context.Request.HandleDesc.ToCopy[0]; + + Context.ResponseData.Write(0); + + return 0; + } + + public static long NvDrvQueryEvent(ServiceCtx Context) + { + int Fd = Context.RequestData.ReadInt32(); + int EventId = Context.RequestData.ReadInt32(); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(0xcafe); + + Context.ResponseData.Write(0); + + return 0; + } + + public static long NvDrvSetClientPid(ServiceCtx Context) + { + long Pid = Context.RequestData.ReadInt64(); + + Context.ResponseData.Write(0); + + return 0; + } + + private static long NvGpuAsIoctlBindChannel(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + int Fd = Context.Memory.ReadInt32(Position); + + return 0; + } + + private static long NvGpuAsIoctlAllocSpace(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Pages = Reader.ReadInt32(); + int PageSize = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + long Align = Reader.ReadInt64(); + + if ((Flags & 1) != 0) + { + Align = Context.Ns.Gpu.ReserveMemory(Align, (long)Pages * PageSize, 1); + } + else + { + Align = Context.Ns.Gpu.ReserveMemory((long)Pages * PageSize, Align); + } + + Context.Memory.WriteInt64(Position + 0x10, Align); + + return 0; + } + + private static long NvGpuAsIoctlMapBufferEx(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Flags = Reader.ReadInt32(); + int Kind = Reader.ReadInt32(); + int Handle = Reader.ReadInt32(); + int PageSize = Reader.ReadInt32(); + long BuffAddr = Reader.ReadInt64(); + long MapSize = Reader.ReadInt64(); + long Offset = Reader.ReadInt64(); + + HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle); + + if (NvMap != null) + { + if ((Flags & 1) != 0) + { + Offset = Context.Ns.Gpu.MapMemory(NvMap.Address, Offset, NvMap.Size); + } + else + { + Offset = Context.Ns.Gpu.MapMemory(NvMap.Address, NvMap.Size); + } + } + + Context.Memory.WriteInt64(Position + 0x20, Offset); + + return 0; + } + + private static long NvGpuAsIoctlGetVaRegions(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position); + + long Unused = Reader.ReadInt64(); + int BuffSize = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + + BuffSize = 0x30; + + Writer.WriteInt64(Unused); + Writer.WriteInt32(BuffSize); + Writer.WriteInt32(Padding); + + Writer.WriteInt64(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt64(0); + + Writer.WriteInt64(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt64(0); + + return 0; + } + + private static long NvGpuAsIoctlInitializeEx(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + + int BigPageSize = Reader.ReadInt32(); + int AsFd = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Reserved = Reader.ReadInt32(); + long Unknown10 = Reader.ReadInt64(); + long Unknown18 = Reader.ReadInt64(); + long Unknown20 = Reader.ReadInt64(); + + return 0; + } + + private static long NvHostIoctlCtrlGetConfig(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position + 0x82); + + for (int Index = 0; Index < 0x101; Index++) + { + Writer.WriteByte(0); + } + + return 0; + } + + private static long NvHostIoctlCtrlEventWait(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + + int SyncPtId = Reader.ReadInt32(); + int Threshold = Reader.ReadInt32(); + int Timeout = Reader.ReadInt32(); + int Value = Reader.ReadInt32(); + + Context.Memory.WriteInt32(Position + 0xc, 0xcafe); + + return 0; + } + + private static long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + Context.Memory.WriteInt32(Position, 1); + + return 0; + } + + private static long NvGpuIoctlZcullGetInfo(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemWriter Writer = new MemWriter(Context.Memory, Position); + + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + + return 0; + } + + private static long NvGpuIoctlGetCharacteristics(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position); + + //Note: We should just ignore the BuffAddr, because official code + //does __memcpy_device from Position + 0x10 to BuffAddr. + long BuffSize = Reader.ReadInt64(); + long BuffAddr = Reader.ReadInt64(); + + BuffSize = 0xa0; + + Writer.WriteInt64(BuffSize); + Writer.WriteInt64(BuffAddr); + Writer.WriteInt32(0x120); //NVGPU_GPU_ARCH_GM200 + Writer.WriteInt32(0xb); //NVGPU_GPU_IMPL_GM20B + Writer.WriteInt32(0xa1); + Writer.WriteInt32(1); + Writer.WriteInt64(0x40000); + Writer.WriteInt64(0); + Writer.WriteInt32(2); + Writer.WriteInt32(0x20); //NVGPU_GPU_BUS_TYPE_AXI + Writer.WriteInt32(0x20000); + Writer.WriteInt32(0x20000); + Writer.WriteInt32(0x1b); + Writer.WriteInt32(0x30000); + Writer.WriteInt32(1); + Writer.WriteInt32(0x503); + Writer.WriteInt32(0x503); + Writer.WriteInt32(0x80); + Writer.WriteInt32(0x28); + Writer.WriteInt32(0); + Writer.WriteInt64(0x55); + Writer.WriteInt32(0x902d); //FERMI_TWOD_A + Writer.WriteInt32(0xb197); //MAXWELL_B + Writer.WriteInt32(0xb1c0); //MAXWELL_COMPUTE_B + Writer.WriteInt32(0xb06f); //MAXWELL_CHANNEL_GPFIFO_A + Writer.WriteInt32(0xa140); //KEPLER_INLINE_TO_MEMORY_B + Writer.WriteInt32(0xb0b5); //MAXWELL_DMA_COPY_A + Writer.WriteInt32(1); + Writer.WriteInt32(0); + Writer.WriteInt32(2); + Writer.WriteInt32(1); + Writer.WriteInt32(0); + Writer.WriteInt32(1); + Writer.WriteInt32(0x21d70); + Writer.WriteInt32(0); + Writer.WriteByte((byte)'g'); + Writer.WriteByte((byte)'m'); + Writer.WriteByte((byte)'2'); + Writer.WriteByte((byte)'0'); + Writer.WriteByte((byte)'b'); + Writer.WriteByte((byte)'\0'); + Writer.WriteByte((byte)'\0'); + Writer.WriteByte((byte)'\0'); + Writer.WriteInt64(0); + + return 0; + } + + private static long NvGpuIoctlGetTpcMasks(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + + int MaskBuffSize = Reader.ReadInt32(); + int Reserved = Reader.ReadInt32(); + long MaskBuffAddr = Reader.ReadInt64(); + long Unknown = Reader.ReadInt64(); + + return 0; + } + + private static long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + Context.Memory.WriteInt32(Position + 0, 7); + Context.Memory.WriteInt32(Position + 4, 1); + + return 0; + } + + private static long NvMapIoctlChannelSetUserData(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + return 0; + } + + private static long NvMapIoctlChannelSetNvMap(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + int Fd = Context.Memory.ReadInt32(Position); + + return 0; + } + + private static long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position + 0x10); + + long GpFifo = Reader.ReadInt64(); + int Count = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int FenceId = Reader.ReadInt32(); + int FenceVal = Reader.ReadInt32(); + + for (int Index = 0; Index < Count; Index++) + { + long GpFifoHdr = Reader.ReadInt64(); + + long GpuAddr = GpFifoHdr & 0xffffffffff; + + int Size = (int)(GpFifoHdr >> 40) & 0x7ffffc; + + long CpuAddr = Context.Ns.Gpu.GetCpuAddr(GpuAddr); + + if (CpuAddr != -1) + { + byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, CpuAddr, Size); + + NsGpuPBEntry[] PushBuffer = NsGpuPBEntry.DecodePushBuffer(Data); + + Context.Ns.Gpu.ProcessPushBuffer(PushBuffer, Context.Memory); + } + } + + Writer.WriteInt32(0); + Writer.WriteInt32(0); + + return 0; + } + + private static long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + int ClassNum = Context.Memory.ReadInt32(Position + 0); + int Flags = Context.Memory.ReadInt32(Position + 4); + + Context.Memory.WriteInt32(Position + 8, 0); + + return 0; + } + + private static long NvMapIoctlChannelZcullBind(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + + long GpuVa = Reader.ReadInt64(); + int Mode = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + + return 0; + } + + private static long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + + long Offset = Reader.ReadInt64(); + long Size = Reader.ReadInt64(); + int Mem = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + + return 0; + } + + private static long NvMapIoctlChannelSetPriority(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + int Priority = Context.Memory.ReadInt32(Position); + + return 0; + } + + private static long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context) + { + long Position = Context.Request.PtrBuff[0].Position; + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position + 0xc); + + int Count = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Unknown8 = Reader.ReadInt32(); + long Fence = Reader.ReadInt64(); + int Unknown14 = Reader.ReadInt32(); + int Unknown18 = Reader.ReadInt32(); + + Writer.WriteInt32(0); + Writer.WriteInt32(0); + + return 0; + } + + private static long NvMapIocCreate(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Size = Context.Memory.ReadInt32(Position); + + int Id = Context.Ns.Os.NvMapIds.GenerateId(); + + int Handle = Context.Ns.Os.Handles.GenerateId(new HNvMap(Id, Size)); + + Context.Memory.WriteInt32(Position + 4, Handle); + + return 0; + } + + private static long NvMapIocFromId(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Id = Context.Memory.ReadInt32(Position); + + int Handle = -1; + + foreach (KeyValuePair<int, object> KV in Context.Ns.Os.Handles) + { + if (KV.Value is HNvMap NvMap && NvMap.Id == Id) + { + Handle = KV.Key; + + break; + } + } + + Context.Memory.WriteInt32(Position + 4, Handle); + + return 0; + } + + private static long NvMapIocAlloc(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Handle = Reader.ReadInt32(); + int HeapMask = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Align = Reader.ReadInt32(); + byte Kind = (byte)Reader.ReadInt64(); + long Addr = Reader.ReadInt64(); + + HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle); + + if (NvMap != null) + { + NvMap.Address = Addr; + NvMap.Align = Align; + NvMap.Kind = Kind; + } + + Logging.Debug($"NvMapIocAlloc at {NvMap.Address:x16}"); + + return 0; + } + + private static long NvMapIocParam(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Handle = Reader.ReadInt32(); + int Param = Reader.ReadInt32(); + + HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle); + + int Response = 0; + + switch (Param) + { + case 1: Response = NvMap.Size; break; + case 2: Response = NvMap.Align; break; + case 4: Response = 0x40000000; break; + case 5: Response = NvMap.Kind; break; + } + + Context.Memory.WriteInt32(Position + 8, Response); + + return 0; + } + + private static long NvMapIocGetId(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Handle = Context.Memory.ReadInt32(Position + 4); + + HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle); + + Context.Memory.WriteInt32(Position, NvMap.Id); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServicePctl.cs b/Ryujinx.Core/OsHle/Services/ServicePctl.cs new file mode 100644 index 00000000..9c4406bb --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServicePctl.cs @@ -0,0 +1,16 @@ +using Ryujinx.Core.OsHle.Objects.Am; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long PctlCreateService(ServiceCtx Context) + { + MakeObject(Context, new IParentalControlService()); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServicePl.cs b/Ryujinx.Core/OsHle/Services/ServicePl.cs new file mode 100644 index 00000000..21e6741c --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServicePl.cs @@ -0,0 +1,35 @@ +using Ryujinx.Core.OsHle.Ipc; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long PlGetLoadState(ServiceCtx Context) + { + Context.ResponseData.Write(1); //Loaded + + return 0; + } + + public static long PlGetFontSize(ServiceCtx Context) + { + Context.ResponseData.Write(Horizon.FontSize); + + return 0; + } + + public static long PlGetSharedMemoryAddressOffset(ServiceCtx Context) + { + Context.ResponseData.Write(0); + + return 0; + } + + public static long PlGetSharedMemoryNativeHandle(ServiceCtx Context) + { + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Context.Ns.Os.FontHandle); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceSet.cs b/Ryujinx.Core/OsHle/Services/ServiceSet.cs new file mode 100644 index 00000000..83ea5b2c --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceSet.cs @@ -0,0 +1,32 @@ +using ChocolArm64.Memory; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + private const int LangCodesCount = 13; + + public static long SetGetAvailableLanguageCodes(ServiceCtx Context) + { + int PtrBuffSize = Context.RequestData.ReadInt32(); + + if (Context.Request.RecvListBuff.Count > 0) + { + long Position = Context.Request.RecvListBuff[0].Position; + short Size = Context.Request.RecvListBuff[0].Size; + + //This should return an array of ints with values matching the LanguageCode enum. + byte[] Data = new byte[Size]; + + Data[0] = 0; + Data[1] = 1; + + AMemoryHelper.WriteBytes(Context.Memory, Position, Data); + } + + Context.ResponseData.Write(LangCodesCount); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceSm.cs b/Ryujinx.Core/OsHle/Services/ServiceSm.cs new file mode 100644 index 00000000..58abed24 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceSm.cs @@ -0,0 +1,48 @@ +using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.Ipc; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + private const int SmNotInitialized = 0x415; + + public static long SmInitialize(ServiceCtx Context) + { + Context.Session.Initialize(); + + return 0; + } + + public static long SmGetService(ServiceCtx Context) + { + //Only for kernel version > 3.0.0. + if (!Context.Session.IsInitialized) + { + //return SmNotInitialized; + } + + string Name = string.Empty; + + for (int Index = 0; Index < 8 && + Context.RequestData.BaseStream.Position < + Context.RequestData.BaseStream.Length; Index++) + { + byte Chr = Context.RequestData.ReadByte(); + + if (Chr >= 0x20 && Chr < 0x7f) + { + Name += (char)Chr; + } + } + + HSession Session = new HSession(Name); + + int Handle = Context.Ns.Os.Handles.GenerateId(Session); + + Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); + + return 0; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceTime.cs b/Ryujinx.Core/OsHle/Services/ServiceTime.cs new file mode 100644 index 00000000..a5fddcba --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceTime.cs @@ -0,0 +1,45 @@ +using Ryujinx.Core.OsHle.Objects.Time; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long TimeGetStandardUserSystemClock(ServiceCtx Context) + { + MakeObject(Context, new ISystemClock(SystemClockType.User)); + + return 0; + } + + public static long TimeGetStandardNetworkSystemClock(ServiceCtx Context) + { + MakeObject(Context, new ISystemClock(SystemClockType.Network)); + + return 0; + } + + public static long TimeGetStandardSteadyClock(ServiceCtx Context) + { + MakeObject(Context, new ISteadyClock()); + + return 0; + } + + public static long TimeGetTimeZoneService(ServiceCtx Context) + { + MakeObject(Context, new ITimeZoneService()); + + return 0; + } + + public static long TimeGetStandardLocalSystemClock(ServiceCtx Context) + { + MakeObject(Context, new ISystemClock(SystemClockType.Local)); + + return 0; + } + + } +}
\ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceVi.cs b/Ryujinx.Core/OsHle/Services/ServiceVi.cs new file mode 100644 index 00000000..75cdc31b --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceVi.cs @@ -0,0 +1,18 @@ +using Ryujinx.Core.OsHle.Objects.Vi; + +using static Ryujinx.Core.OsHle.Objects.ObjHelper; + +namespace Ryujinx.Core.OsHle.Services +{ + static partial class Service + { + public static long ViGetDisplayService(ServiceCtx Context) + { + int Unknown = Context.RequestData.ReadInt32(); + + MakeObject(Context, new IApplicationDisplayService()); + + return 0; + } + } +}
\ No newline at end of file |
